完成ENGINEERING NOTE
LLaMA-Factory实现大模型微调
梳理大模型微调的目的、SFT、RLHF 与 RAG 的差异,并记录使用 LLaMA-Factory 准备环境、模型和训练数据的实践过程。
关于微调
什么是大模型微调
大模型微调(Fine-tuning)是一种通过在预训练模型基础上使用特定任务的数据进行进一步训练的技术。这个过程能够让通用大语言模型更好地适应特定领域或任务的需求,提高模型在目标场景下的表现。 微调过程通常包括准备领域特定数据、选择合适的训练参数、使用较小的学习率对模型进行训练等步骤。相比于从头训练模型,微调能够大大减少计算资源的消耗,同时保持模型的基础能力。
为什么需要微调大模型
- 提高模型对企业专有信息的理解、增强模型在特定行业领域的知识。
- 提供个性化和互动性强的学习
SFT、RLHF、RAG
- SFT**(Supervised Fine-Tuning)有监督微调** 通过提供人工标注的数据,进一步训练预训练模型,让模型能够更加精准地处理特定领域的任务
- RLHF(Reinforcement Learning from Human Feedback)强化学习
- DPO(Direct Preference Optimization) 核心思想:通过人类对比选择(例如:A 选项和 B 选项,哪个更好)直接优化生成模型,使其产生更符合用户需求的结果;调整幅度大。
- PPO(Proximal Policy Optimization) 核心思想:通过 奖励信号(如点赞、点踩)来 渐进式调整模型的行为策略;调整幅度小。
- RAG(Retrieval-Augmented Generation)检索增强生成 将外部信息检索与文本生成结合,帮助模型在生成答案时,实时获取外部信息和最新信息
选择微调还是RAG?
- 微调:
- 适合:拥有非常充足的数据
- 能够直接提升模型的固有能力;无需依赖外部检索;
- RAG:
- 适合:只有非常非常少的数据;动态更新的数据
- 每次回答问题前需耗时检索知识库;回答质量依赖于检索系统的质量;
- 总结:
- 少量企业私有知识:最好微调和 RAG 都做;资源不足时优先 RAG;
- 会动态更新的知识:RAG
- 大量垂直领域知识:微调
使用LLama-Factory在Window系统上实现微调
- 安装部署LLama-Factory LLaMA-Factory 的 Github地址:https://github.com/hiyouga/LLaMA-Factory
- 克隆仓库
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
- 创建conda虚拟环境(需使用3.10的python版本,不然不兼容)
conda create -n llama-factory python=3.10
- 初始化cmd终端 在Window使用anaconda虚拟环境时需要先激活才能使用。 在管理员权限下执行:
conda init
- 激活虚拟环境
conda activate llama-factory
- 在虚拟环境中安装相关依赖
pip install -e ".[torch,metrics]"
- 检查安装是否成功
llamafactory-cli version
- 启动可视化界面
llamafactory-cli webui
- 从HuggingFace下载基座模型
- 安装huggingface下载工具
pip install -U huggingface_hub
- 下载基座模型
huggingface-cli download --resume-download deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
- 准备用于训练的数据集 训练集是一个json格式的数据,包括instruction、input和output。
- instruction(指令):描述任务要求或问题,告诉模型应该做什么,比如“翻译以下文本”、“总结下面的内容”等。
- input(输入):需要模型处理的具体内容。某些任务可能不需要input,这种情况下input字段可以为空。
- output(输出):期望模型产生的结果,用作训练时的标准答案。 例如:
[
{
"instruction": "请问你是谁",
"input": "",
"output": "您好,我是蟹堡王的神奇海螺,很高兴为您服务!我可以回答关于蟹堡王和汉堡制作的任何问题,您有什么需要帮助的吗?"
},
{
"instruction": "怎么修复这个报错",
"input": "我正在使用蟹堡王全自动智能汉堡制作机,报错信息是:汉堡食谱为空",
"output": "根据您提供的错误信息,'汉堡食谱为空' 可能是因为系统没有加载正确的食谱文件或食谱文件被删除。您可以尝试以下步骤:\n1. 检查食谱文件是否存在,并确保文件路径正确。\n2. 重新加载或更新食谱文件。\n3. 如果问题依然存在,尝试重启机器并检查是否有软件更新。\n希望这些步骤能帮助您修复问题。如果仍有困难,请与蟹堡王技术支持联系。"
}
]
修改dataset_info.json 文件,添加数据集配置:
"magic_conch": {
"file_name": "magic_conch.json"
},
将数据集 magic_conch.json 放到 LLama-Factory 的 data 目录 下。
- 在页面上进行微调的相关设置,开始微调
- 选择微调算法 Lora
- 添加数据集 magic_conch
- 修改其他训练相关参数,如学习率、训练轮数、截断长度、验证集比例等
- 学习率(Learning Rate):决定了模型每次更新时权重改变的幅度。过大可能会错过最优解;过小会学得很慢或陷入局部最优解
- 训练轮数(Epochs):太少模型会欠拟合(没学好),太大会过拟合(学过头了)
- 最大梯度范数(Max Gradient Norm):当梯度的值超过这个范围时会被截断,防止梯度爆炸现象
- 最大样本数(Max Samples):每轮训练中最多使用的样本数
- 计算类型(Computation Type):在训练时使用的数据类型,常见的有 float32 和 float16。在性能和精度之间找平衡
- 截断长度(Truncation Length):处理长文本时如果太长超过这个阈值的部分会被截断掉,避免内存溢出
- 批处理大小(Batch Size):由于内存限制,每轮训练我们要将训练集数据分批次送进去,这个批次大小就是 Batch Size
- 梯度累积(Gradient Accumulation):默认情况下模型会在每个 batch 处理完后进行一次更新一个参数,但你可以通过设置这个梯度累计,让他直到处理完多个小批次的数据后才进行一次更新
- 验证集比例(Validation Set Proportion):数据集分为训练集和验证集两个部分,训练集用来学习训练,验证集用来验证学习效果如何
- 学习率调节器(Learning Rate Scheduler):在训练的过程中帮你自动调整优化学习率
- 页面上点击启动训练,或复制命令到终端启动训练
- 实践中推荐用
nohup命令将训练任务放到后台执行,这样即使关闭终端任务也会继续运行。同时将日志重定向到文件中保存下来
- 实践中推荐用
- 在训练过程中注意观察损失曲线,尽可能将损失降到最低
- 如损失降低太慢,尝试增大学习率
- 如训练结束损失还呈下降趋势,增大训练轮数确保拟合
- 微调结束,评估微调效果
- 观察损失曲线的变化;观察最终损失
- 在交互页面上通过预测/对话等方式测试微调好的效果
- 检查点:保存的是模型在训练过程中的一个中间状态,包含了模型权重、训练过程中使用的配置(如学习率、批次大小)等信息,对LoRA来说,检查点包含了训练得到的 B 和 A 这两个低秩矩阵的权重
- 若微调效果不理想,可以:
- 使用更强的预训练模型
- 增加数据量
- 优化数据质量(数据清洗、数据增强等,可学习相关论文如何实现)
- 调整训练参数,如学习率、训练轮数、优化器、批次大小等等
11. 导出合并后的模型
- 为什么要合并:因为 LoRA 只是通过低秩矩阵调整原始模型的部分权重,而不直接修改原模型的权重。合并步骤将 LoRA 权重与原始模型权重融合生成一个完整的模型
- 先创建目录,用于存放导出后的模型
mkdir -p Models/deepseek-r1-1.5b-merged
- 在页面上配置导出路径,导出即可。