目录
一、简介
在开始具体操作前,先简单介绍一下本文主要使用的两个关键开源项目及其地址。
1.Qwen2.5:开源模型
Qwen2.5 是阿里巴巴集团Qwen团队研发的最新开源的大语言模型和多模态系列,本文主要实验的是其语言模型——Qwen/Qwen2.5 - 7B - Instruct。
Qwen2.5版本在大规模数据(18万亿tokens)上做了预训练,支持根据特定数据集进行人为偏好训练微调。Qwen2.5还支持多国语言,128K tokens上下文长度,能生成 8K tokens文本。
Github项目地址:https://github.com/QwenLM/Qwen2.5
模型下载huggingface国内镜像源地址:https://hf-mirror.com/Qwen
2. LLaMA-Factory:微调工具
LLaMA-Factory 是一个简单易用的大语言模型的训练微调平台。其搭建的高效训练框架,可以仅使用yaml配置参数文件和简单指令,就可完成对模型的微调。
并且平台包含近百种模型,以及如(增量)预训练、(多模态)指令监督微调、奖励模型训练、PPO 训练、DPO 训练、KTO 训练、ORPO 训练等高效模型训练算法。支持FlashAttention-2等加速算法。
Github项目地址:https://github.com/hiyouga/LLaMA-Factory
二、环境搭建
本文逻辑顺序是,先进行微调训练模型,再进行本地部署。下图总览了整个训练所需的四个部分——环境、模型、数据、配置。
首先解决训练环境的安装,也就是 LLaMA-Factory 训练平台的配置。该部分本人花费大量时间进行实验,来处理报错和冲突,尽量按照相同的版本型号库安装。
1.Python和Pytorch版本
首先创建虚拟环境,定下使用的 python 和 torch 版本。根据官方文档的推荐选择。
Pytorch指令指南地址:https://pytorch.org/get-started/previous-versions/
# 创建 python3.11 和 torch2.4.0+CUxx环境(根据本地cuda版本选择)
conda create -n llama-factory python=3.11
conda activate llama-factory
# 这里本地的cuda版本是12.4
pip install torch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 --index-url https://download.pytorch.org/whl/cu124
2.llamafactory项目克隆安装
然后需要将训练平台 llamafactory 从github上克隆下载下来,并且安装到刚刚创建的虚拟环境中,这是为了后续直接使用指令就可以训练微调。
这里本机安装的是 llamafactory 0.9.2 版本。
# 克隆安装 llamafactory
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
# 如果克隆失败也可以先下载到本地,然后在本地目录运行下面的内容
cd LLaMA-Factory
pip install -e ".[torch,metrics]"
3.其他重要库安装
继续还有几个训练中会用到的关键包安装,请按照下面的版本进行安装,因为如果版本不匹配很有可能会在训练中报错。下面是官方推荐的版本号可做参考,其中红框内是本文实验环境必须安装的(推荐型号可能也会出现报错,最好按后面给出的具体版本搭配)
# 具体版本号的重要库安装pip指令
pip install transformers==4.46.1 datasets==3.1.0 accelerate==0.34.0 peft==0.12.0 trl==0.9.6 deepspeed==0.15.0 flash-attn==2.7.2.post1 numpy==1.26.3 pydantic==2.10.4 typing_extensions 4.12.2
其中的 flash-attn 库如果安装失败,可以去其对应的Github地址下载对应环境版本的wheel文件到本地后,用 pip install 加 wheel文件完整文件名安装。
flash-attn Github地址:https://github.com/Dao-AILab/flash-attention
三、模型微调
环境搭建好以后,还不能马上开始训练,还需要做两个准备。
一是预训练的模型参数,这个可以在命令指令中指定,但这样是在线从huggingface上下载模型到本地,大语言模型参数量都比较大,因此这种方式存在风险,最好是先下载到本地;
二是训练的数据集,可以使用官方提供的样例数据集,也可以自建数据集。
最后要达成下面的“三角稳定”的训练准备工作,并且通过yaml配置文件联系各个部分,才可以安心简单的使用指令进行“炼丹”。其中绿色的训练环境上述已搭建完毕。
1.预训练模型下载
首先来下载训练所需的预训练模型,本文选择在通义千问 Qwen2.5 - 7B 上进行微调,可以直接在hf-mirror镜像中下载到本地,访问以下网址:https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct下载 Files and versions下的所有文件。
单独创建一个文件夹保存下载内容,并且“记下”保存模型的绝对地址,这在之后的配置参数部分就代表你要进行微调的“模型名”。
# 模型参数信息(绝对地址)
model_name_or_path : ~/LLaMA_pretrained/Qwen2.5-7B
如果想要微调其他Qwen或者llama的预训练模型,也是上述相同方法。可以单独创建个总文件夹LLaMA_pretrained,把所有下载模型都保存在该区域,之后要用直接导航到该目录下即可。
下载并保存好要进行微调的模型参数后,就算完成预训练模型部分的准备工作了。继续就要准备训练数据了。
2.训练数据集
llamafactory平台的源码下有样例训练数据格式,先查看官方提供的训练集和说明文件,再根据规范搭建自己的数据集。同时更多信息可以直接参考源码 data 目录下的README_zh.md文件。
官方数据集:
在llamafactory源码的 LLaMA-Factory/data 文件夹下存放的是很多样例训练集,实际上该文件夹下主要存放的是两类文件和信息——数据集配置Json文件:dataset_info.json,和真实的具体对话文本内容的数据集Json文件:xxxx.json 。如下图所示。
dataset_info.json 下保存的是一个字典,字典里的键对应data 下不同文本对话数据的名称,字典的值是该数据集的配置,可以看到不同的数据集如果对应不同的数据格式,其对应配置(下图蓝框内容)是不同的。
自建数据集:
llama-factory支持多种对话的数据集格式,具体可以参考源码 data 目录下的README_zh.md 文件,或者访问github地址:https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README_zh.md
下图是部分其支持的对话文本Json 的内容格式,每种格式又对应各自的dataset_info.json中的配置信息。
本文选择一个最简单的自建数据例子进行测试微调——假设训练数据集中只包含两个内容:用户输入文本和模型输出文本(可以将其简单理解为一个翻译问题),特别的这里实际就是想训练一个给古文自动加标点的语言模型。
①创建对话文本数据
首先创建好对话文本信息的Json数据集,这里选用最简单的AIpaca格式,且只输入必填部分。这里需要注意,如果选填的内容信息没有,一定不要在数据集中加入。如不需要系统提示词信息,那么就不要出现“system”:‘’ 的内容,不然训练会报错,不需要的信息直接忽略就好。
②配置dataset_info
有了数据集以后,就要配置dataset_info.json文件了。这里可以选择新建一个配置文件然后将对话数据和配置放在一个文件夹下。
但是最好还是将自己数据放在 LLaMA-Factory/data 下,然后在已有的dataset_info.json 内添加自建数据集的配置信息。
# dataset_info.json配置文件中添加信息
"data": { "file_name": "data.json",
"columns": {
"prompt": "instruction",
"response": "output"}
},
file_name对应data目录下的数据集Json文件名,“columns”下是对话信息,这里只添加数据集中使用到的,如果要添加其他参考官方README,如下图。
还有一点很重要的是,下图红框中数据集定义的名称——data,这个是将数据集信息传入配置文件的接口名称,先记下。
# 数据集配置参数(名称)
dataset: data
按上述操作,创建好一个简单的对话文本信息数据集,就算完成了训练数据集部分的准备工作了,下面要进行的就是最后的训练 yaml 配置文件修改操作。
3.配置文件与训练
LLaMA-Factory/example 下是样例训练的 yaml 配置文件,具体如何使用这些配置文件进行指令训练可以参考 example 目录下的 README.md 文件。
在README.md文件中,可以看到 llamafactory 支持多种训练微调模式,包括全参数Full、LoRA、QLoRA等等,本文只简单测试全参数和 lora 有监督训练(sft)微调的流程。
对应 example 下的 yaml 配置文件如下图所示。其中第一个名称是使用的模型类型(有llama3或者qwen2vl的示例选择),第二个名称代表使用的微调模式(本文记录full全参数 & lora),第三个参数代表具体的算法模式(本文统一使用 sft 有监督训练,即有真实样本对照,可以看到样例中还有如ppo等这种无监督的强化学习算法,这些暂不在本章节考虑)
①全参数配置
有了上述筛选过程,可以直接定位到本文想要修改的全参数训练yaml配置文件地址——LLaMA-Factory-main / examples / train_full / qwen2vl_full_sft.yaml,打开样例配置文件,下面来看哪些是要根据实际情况需要修改的。
下面一图总览需要修改的地方,实际主要就是三个地方要根据实际情况配置——预训练模型参数地址、数据集名称、结果参数保存地址。
②全参数微调
有了上述全参数训练的 yaml 配置文件之后,算是填补了准备工作的最后一角了。下面就可以方便简单的直接使用指令开始训练了。
全参数训练指令如下。
# 全参数训练指令
FORCE_TORCHRUN=1 llamafactory-cli train examples/train_full/qwen2vl_full_sft.yaml
③LoRA配置
lora是一种更加快速高效的训练方式,这里不讨论其底层原理,直接导航到对应的训练配置文件地址为 LLaMA-Factory-main / examples / train_lora / qwen2vl_lora_sft.yaml,打开样例配置文件,跟之前一样,一图总览需要修改的地方。
和全参数一样,只不过其中一些其他参数做了变化修改,如 finetuning_type 修改为了lora。
但是,还没有结束,LoRA 和全参数训练最大不一样的地方在于,lora训练完的 output_dir 下的参数还不能直接使用,要使用 merge_lora 的指令合并结果。因此还要配置合并的配置文件,可以直接定位到 LLaMA-Factory-main / examples / merge_lora / qwen2vl_lora_sft.yaml ,合并配置文件修改内容一图总览如下。
④LoRA微调
根据上述配置文件的操作,可知lora训练也是分为两步指令:LoRA微调 + 合并
LoRA微调指令如下。
# LoRA训练
llamafactory-cli train examples/train_lora/qwen2vl_lora_sft.yaml.yaml
# LoRA结果合并
llamafactory-cli export examples/merge_lora/qwen2vl_lora_sft.yaml
四、模型部署
经过上述复杂的操作后,终于得到了在自建数据集上的微调模型结果,下面开始模型参数的部署到本机进行推理的操作。
1.推理环境
首先是推理的环境配置,当然直接用训练时的环境进行推理肯定是没问题的,但是可能存在使用性能更低的设备进行部署,或者使用CPU进行推理的问题,此时就需要重新搭建环境了。
这里直接将配置库图放在下面,按下面的库版本进行安装是没有运行报错的。可以着重检测红框中的关键库(部署环境没有安装flash-attn库,运行可能警告,但不影响最终结果)
2.Python代码推理
使用下面代码,替换模型地址 model_path 和 输入文本 prompt ,就可以得到不同输入对话的模型推理回答文本了。
这是通用的,因此官方模型参数和自己微调的参数都可以直接使用。
from transformers import AutoModelForCausalLM, AutoTokenizer
# 加载模型
def model(path):
model_name_or_path = path
model = AutoModelForCausalLM.from_pretrained(
model_name_or_path,
torch_dtype="auto",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
return model, tokenizer
# 模型对话推理
def infer(model, tokenizer, prompt):
device = "cuda" # the device to load the model onto
messages = [
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512
)
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
return response
if __name__=='__main__':
modelpath = '' # 模型参数地址
prompt = '你好,qwen' # 输入文本
model, tokenizer = model(modelpath)
response = infer(model, tokenizer, prompt)
print(f'用户输入:{prompt},\n模型回答:{response}')
下面两个例子分别是微调自建数据集实现的对古文进行添加标点处理,和官方模型对话返回结果图片。
古文标点添加模型测试结果:
官方参数模型对话测试结果:
标签:训练,配置文件,Qwen2.5,模型,微调,参数,model,最新版 From: https://blog.csdn.net/qq_58718853/article/details/145011117