花开月下机器人 LLaMA-Factory 实现大模型 LoRA-SFT 微调指南
LLaMA-Factory 实现大模型 LoRA-SFT 微调指南
一、背景与概述
1.1 什么是 LoRA-SFT
SFT(Supervised Fine-Tuning,监督微调) 是大语言模型对齐流程中的关键一步:在预训练基座模型之上,用人工标注的「指令-回复」对进行监督学习,让模型学会按指令格式回答问题。
LoRA(Low-Rank Adaptation,低秩适配) 是一种参数高效微调方法(PEFT),核心思想是:冻结原始模型权重,只在旁路注入两个低秩矩阵 A 和 B(W' = W + ΔW = W + B·A),训练时只更新 A 和 B。 这样可将可训练参数量降低到原模型的 0.1%~1%,极大降低显存和存储开销。
LoRA-SFT = 用 LoRA 方式做 SFT,兼顾效果与效率,是目前社区最主流的微调范式。
1.2 为什么选 LLaMA-Factory
LLaMA-Factory 是当前最活跃的开源大模型微调框架之一,核心优势:
| 特性 | 说明 |
|------|------|
| 模型覆盖广 | 支持 LLaMA、Qwen、ChatGLM、Mistral、Yi、DeepSeek 等主流架构 |
| 训练方法全 | SFT / DPO / PPO / ORPO / KTO 一站式覆盖 |
| 微调策略灵活 | Full / Freeze / LoRA / QLoRA 多种策略可选 |
| WebUI 可视化 | 提供 LLaMA Board 网页界面,零代码操作 |
| 数据格式统一 | alpaca / sharegpt 等主流格式开箱即用 |
| 推理部署集成 | 训练完可直接用框架自带推理,支持 vLLM 加速 |
| 分布式训练 | 支持 DeepSpeed ZeRO / FSDP 多卡并行 |
---
二、环境准备
2.1 硬件要求
| 模型规模 | LoRA 微调显存(FP16) | QLoRA 微调显存(4-bit) |
|---------|----------------------|------------------------|
| 1.5B~3B | ≥ 8GB | ≥ 4GB |
| 7B~8B | ≥ 16GB | ≥ 8GB |
| 13B~14B | ≥ 32GB | ≥ 16GB |
| 32B~34B | ≥ 64GB | ≥ 24GB |
实践建议:消费级显卡(如 RTX 3090/4090 24GB)推荐用 QLoRA 微调 7B~14B 模型;更大模型需要多卡或 A100/H100。
2.2 软件依赖
建议使用 conda 创建独立环境
conda create -n llama-factory python=3.11 -y
conda activate llama-factory
克隆仓库
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
安装依赖(基础版 + LoRA 训练所需)
pip install -e ".[torch,metrics]"
如需 QLoRA 4-bit 量化训练,额外安装
pip install bitsandbytes
如需 FlashAttention2 加速
pip install flash-attn --no-build-isolation
如需多卡分布式训练
pip install deepspeed
验证安装:
llamafactory-cli version
2.3 下载基座模型
以 Qwen2.5-7B-Instruct 为例(也可换 LLaMA3-8B、ChatGLM3 等):
方式一:ModelScope(国内推荐,速度快)
pip install modelscope
modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir ./models/Qwen2.5-7B-Instruct
方式二:HuggingFace
huggingface-cli download Qwen/Qwen2.5-7B-Instruct --local-dir ./models/Qwen2.5-7B-Instruct
---
三、数据准备
3.1 数据格式
LLaMA-Factory 支持多种数据格式,最常用的是 alpaca 和 sharegpt 两种。
Alpaca 格式
[
{
"instruction": "请把下面的句子翻译成英文。",
"input": "今天天气真好。",
"output": "The weather is really nice today.",
"system": "你是一个专业的翻译助手。"
},
{
"instruction": "简要解释什么是过拟合。",
"input": "",
"output": "过拟合是指模型在训练数据上表现很好,但在未见过的测试数据上泛化能力差的现象。常见原因包括模型复杂度过高、训练数据不足等。",
"system": ""
}
]
| 字段 | 说明 | 是否必填 |
|------|------|---------|
| instruction | 用户指令/问题 | ✅ 必填 |
| input | 指令附带的输入内容(如待翻译文本) | 可空 |
| output | 期望的模型回复 | ✅ 必填 |
| system | 系统提示词,定义模型角色/行为约束 | 可空 |
ShareGPT 格式(适合多轮对话)
[
{
"conversations": [
{"from": "human", "value": "帮我写一首关于秋天的诗。"},
{"from": "gpt", "value": "秋风萧瑟落叶黄,\n雁阵南飞过寒塘。\n独坐窗前思故里,\n一壶浊酒入愁肠。"},
{"from": "human", "value": "再写一首关于冬天的。"},
{"from": "gpt", "value": "北风卷地白草折,\n胡天八月即飞雪。\n忽如一夜春风来,\n千树万树梨花开。"}
]
}
]
3.2 注册数据集
将你的 JSON 数据文件放到 data/ 目录下,然后在 data/dataset_info.json 中注册:
{
"mysftdataset": {
"filename": "mysft_data.json",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output",
"system": "system"
}
}
}
关键点:datasetinfo.json 中的 key(如 mysft_dataset)就是后续训练参数中 --dataset 要填的值。
3.3 数据质量建议
数量:通用任务 1,000~10,000 条即可见效;垂直领域 500~5,000 条高质量数据往往优于 5 万条低质数据
质量 > 数量:确保回复准确、格式统一、无有害内容
多样性:覆盖目标场景的多种问法、不同难度、不同长度
长度控制:单条 instruction + output 建议不超过 2048 token,过长会浪费显存
---
四、LoRA-SFT 训练
4.1 命令行方式
llamafactory-cli train \
--stage sft \
--do_train True \
--modelnameor_path ./models/Qwen2.5-7B-Instruct \
--finetuning_type lora \
--lora_rank 8 \
--lora_alpha 16 \
--lora_dropout 0.05 \
--loratarget qproj,vproj,kproj,oproj,gateproj,upproj,downproj \
--dataset mysftdataset \
--template qwen \
--cutoff_len 2048 \
--max_samples 100000 \
--learning_rate 5e-5 \
--numtrainepochs 3 \
--perdevicetrainbatchsize 4 \
--gradientaccumulationsteps 4 \
--lrschedulertype cosine \
--warmup_ratio 0.05 \
--fp16 True \
--logging_steps 10 \
--save_steps 500 \
--output_dir ./output/qwen25-7b-lora-sft \
--plot_loss True \
--report_to tensorboard
4.2 关键参数详解
| 参数 | 说明 | 推荐值 |
|------|------|-------|
| --stage | 训练阶段 | sft |
| --finetuningtype | 微调策略 | lora(QLoRA 用 lora + --quantizationbit 4) |
| --lora_rank | LoRA 秩,决定旁路矩阵大小 | 8(轻量)/ 16(均衡)/ 32(高容量) |
| --lora_alpha | LoRA 缩放系数,相当于 ΔW 的学习率放大 | 通常设为 rank 的 2 倍 |
| --lora_dropout | LoRA 层 dropout | 0.05~0.1 |
| --loratarget | 注入 LoRA 的模块名 | 全模块(推荐)或 qproj,v_proj |
| --template | 对话模板,必须与基座模型匹配 | qwen / llama3 / chatglm 等 |
| --cutoff_len | 最大序列长度 | 1024~4096,越长越耗显存 |
| --learning_rate | 学习率 | 5e-5~1e-4(LoRA 通常比全量微调高) |
| --numtrainepochs | 训练轮数 | 3~10,配合 early stopping |
| --perdevicetrainbatchsize | 单卡 batch size | 2~8,根据显存调 |
| --gradientaccumulationsteps | 梯度累积步数 | 4~16,等效 batch = perdevice × accumulation × numgpus |
4.3 QLoRA 4-bit 量化训练(低显存方案)
在上述命令基础上增加:
--quantization_bit 4 \
--quantization_method bitsandbytes \
QLoRA 会先将基座模型量化为 4-bit 存储,再在量化模型上训练 LoRA 适配器。显存可降低约 60%,但训练速度会慢 10%~20%,且推理时需要反量化,有轻微精度损失。
4.4 多卡分布式训练
使用 DeepSpeed ZeRO-2
llamafactory-cli train \
--deepspeed dsz2config.json \
...(其余参数同上)
或使用 FSDP(PyTorch 原生)
llamafactory-cli train \
--enable_fsdp True \
--fsdpconfig fsdpconfig.json \
...(其余参数同上)
DeepSpeed ZeRO-2 配置示例(dsz2config.json):
{
"bf16": { "enabled": true },
"zero_optimization": {
"stage": 2,
"allgather_partitions": true,
"allgatherbucketssize": 5e8,
"overlap_comm": true,
"reduce_scatter": true,
"reducebucketssize": 5e8,
"contiguous_gradients": true
},
"gradientaccumulationsteps": "auto",
"trainbatchsize": "auto",
"trainmicrobatchsizeper_gpu": "auto"
}
4.5 WebUI 方式(零代码)
llamafactory-cli webui
浏览器打开 http://localhost:7860,在界面中:
Model 标签页:选择模型路径、微调类型选 lora
Data 标签页:选择已注册的数据集
Train 标签页:设置学习率、epoch、batch size 等参数
点击 Start 开始训练
WebUI 底层生成的命令会在日志中显示,方便复用为 CLI 命令。
---
五、训练监控与调优
5.1 监控训练过程
启动 TensorBoard
tensorboard --logdir ./output/qwen25-7b-lora-sft --port 6006
关注以下指标:
| 指标 | 健康表现 | 异常信号 |
|------|---------|---------|
| train_loss | 持续下降并趋于平稳 | 不降或反弹 → 学习率过大/数据有问题 |
| evalloss | 与 trainloss 同步下降 | 远高于 train_loss → 过拟合 |
| learning_rate | 按 scheduler 曲线变化 | — |
| grad_norm | 稳定在 0.1~10 之间 | 突然飙升 → 梯度爆炸,需降学习率 |
5.2 常见问题与调优方向
| 问题 | 可能原因 | 解决方案 |
|------|---------|---------|
| Loss 不下降 | 学习率太小 / 模板不匹配 | 调高 lr 到 1e-4;检查 --template 是否正确 |
| Loss 先降后升 | 过拟合 / 学习率过大 | 减少 epoch;降低 lr;增大 lora_dropout |
| 显存不足(OOM) | batch 太大 / 序列太长 | 减小 batchsize;增大 gradientaccumulation;降低 cutoff_len;用 QLoRA |
| 生成重复/啰嗦 | 数据中重复模式多 | 清洗数据;增加数据多样性 |
| 指令遵循差 | system prompt 不一致 / 数据量不足 | 确保训练数据 system 字段与推理时一致;增加数据量 |
5.3 LoRA 超参数选择建议
轻量任务(风格迁移、简单问答):
rank=8, alpha=16, target=qproj,vproj
通用任务(多轮对话、指令跟随):
rank=16, alpha=32, target=全模块
高难度任务(代码生成、数学推理):
rank=32~64, alpha=64~128, target=全模块
---
六、模型评估
6.1 快速验证(Chat 模式)
训练完成后,直接加载 LoRA 权重进行对话测试:
llamafactory-cli chat \
--modelnameor_path ./models/Qwen2.5-7B-Instruct \
--adapternameor_path ./output/qwen25-7b-lora-sft \
--template qwen \
--finetuning_type lora
6.2 批量评估
准备评估数据集(格式同训练数据),注册后运行:
llamafactory-cli eval \
--modelnameor_path ./models/Qwen2.5-7B-Instruct \
--adapternameor_path ./output/qwen25-7b-lora-sft \
--template qwen \
--finetuning_type lora \
--dataset eval_dataset \
--outputdir ./evalresults
6.3 人工评估要点
指令遵循率:模型是否按指令格式回答(如要求 JSON 输出时是否输出 JSON)
事实准确性:回答内容是否正确,有无幻觉
风格一致性:语气、格式是否与训练数据一致
对比基座模型:同一 prompt 对比微调前后输出,确认改进
---
七、模型合并与导出
LoRA 训练产出的是适配器权重(几十 MB),推理时需与基座模型一起加载。如需独立部署,可将 LoRA 权重合并进基座模型:
llamafactory-cli export \
--modelnameor_path ./models/Qwen2.5-7B-Instruct \
--adapternameor_path ./output/qwen25-7b-lora-sft \
--template qwen \
--finetuning_type lora \
--export_dir ./output/qwen25-7b-merged
合并后的模型是完整的 HF 格式权重,可独立加载推理,也可直接用 vLLM / TGI 等推理框架部署。
---
八、推理部署
8.1 使用 LLaMA-Factory 内置推理
llamafactory-cli api_demo \
--modelnameor_path ./output/qwen25-7b-merged \
--template qwen
8.2 使用 vLLM 高性能部署
安装 vLLM
pip install vllm
启动 OpenAI 兼容 API 服务
python -m vllm.entrypoints.openai.api_server \
--model ./output/qwen25-7b-merged \
--port 8000 \
--max-model-len 4096
客户端调用:
from openai import OpenAI
client = OpenAI(baseurl="http://localhost:8000/v1", apikey="empty")
response = client.chat.completions.create(
model="./output/qwen25-7b-merged",
messages=[
{"role": "system", "content": "你是一个专业的技术助手。"},
{"role": "user", "content": "解释一下什么是梯度消失。"}
],
temperature=0.7,
max_tokens=512
)
print(response.choices[0].message.content)
---
九、完整流程速查
准备环境 → 下载数据 → 注册数据集 → 训练 → 评估 → 合并导出 → 部署
| | | | | | |
conda data/ dataset_ llamafactory chat export vLLM /
install *.json info.json train eval CLI api_server
核心命令速查:
训练
llamafactory-cli train --stage sft --finetuning_type lora ...
测试对话
llamafactory-cli chat --adapternameor_path ./output/xxx ...
合并导出
llamafactory-cli export --adapternameorpath ./output/xxx --exportdir ./output/merged
部署
python -m vllm.entrypoints.openai.api_server --model ./output/merged
---
十、注意事项与最佳实践
模板必须匹配:--template 要与基座模型一致(Qwen 用 qwen,LLaMA3 用 llama3,ChatGLM 用 chatglm),否则训练效果会大打折扣
数据 system 字段一致性:训练数据的 system prompt 应与实际推理时使用的 system prompt 保持一致
学习率选择:LoRA 微调学习率通常设为 5e-5~1e-4,比全量微调(1e-5~5e-5)高一个数量级
保存 checkpoint:设置合理的 --save_steps,训练中断后可从 checkpoint 恢复
避免灾难性遗忘:如需保留基座模型通用能力,可在训练数据中混入部分通用指令数据(如 alpaca_gpt4 的一部分)
LoRA 权重很小:典型 7B 模型的 LoRA 权重仅 20~80MB,可方便地保存、切换和分享多个适配器
版本管理:建议记录每次训练的完整参数配置(可保存为 YAML 文件),方便复现和对比
---
总结:LLaMA-Factory 将 LoRA-SFT 微调流程简化为「准备数据 → 一条命令训练 → 一条命令导出」的清晰链路。核心在于选对模板、备好数据、调好超参。对于大多数垂直领域应用,500~5000 条高质量数据 + LoRA rank 16 即可获得显著效果提升,是性价比最高的微调方案。