🐸 青蛙编程网
首页 / AI / 微调 LLaMA-Factory / 4. SFT 实战

4. SFT 实战

这是什么:SFT(supervised fine-tuning,监督微调)= 拿「问题 + 标准答案」当教材,教模型按你期望的方式回答;LoRA 是只训练小补丁矩阵的省显存做法。

为什么用:前两章把环境和数据备好了,现在要动手。微调不是一条命令就完事,配置里几十个参数各有脾气,踩错一个就训出一堆废权重。

如何用:本章直接用官方示例配置 examples/train_lora/qwen3_lora_sft.yaml,先跑通,再逐项拆解,最后用 chat 验证模型真的变了。

4.1 先跑通官方示例

进到仓库目录,先确认一下你的 GPU:

nvidia-smi

然后直接开跑:

llamafactory-cli train examples/train_lora/qwen3_lora_sft.yaml

你会看到(示意):

[INFO] Loading model weights from disk: ...
[INFO] Fine-tuning method: LoRA
[INFO] Number of trainable parameters: 16,515,072
[INFO] dataset: identity,alpaca_en_demo -> 1000 samples
[INFO] Num examples = 1000, Total train batch size = 8
  3%|▎         | 11/375 [00:04<02:08, 2.98it/s, loss=1.234, lr=1.00e-04]
{'train_runtime': 418.3, 'train_loss': 0.9871, 'train_samples_per_second': 2.39}

Total train batch size = 8 是 per_device_train_batch_size(1)乘 gradient_accumulation_steps(8)算出来的;1000 条样本 ÷ 8 = 125 步一轮,3 轮一共 375 步。

第一次运行会自动从 HuggingFace 下载 Qwen/Qwen3-4B-Instruct-2507(约 8GB),国内网络慢就 export HF_ENDPOINT=https://hf-mirror.com。

跑完后去 saves/qwen3-4b/lora/sft/ 看一眼,LoRA 权重就存那儿了。

4.2 配置文件逐项拆解

官方示例分六块,我们一块块看。

model(模型)

配置项 示例值 含义
model_name_or_path Qwen/Qwen3-4B-Instruct-2507 基座模型,可以写 HuggingFace 仓库名或本地路径
trust_remote_code true 允许加载模型仓库里自带的 Python 代码
quantization_bit 不填 填 4 就是 QLoRA 4bit
quantization_method 不填 量化后端:bnb / hqq / eetq

method(怎么训)

配置项 示例值 含义
stage sft 训练阶段:pt / sft / rm / ppo / dpo / kto
do_train true 明确表示这次是训练而不是评测
finetuning_type lora 微调方式:lora / oft / freeze / full
lora_rank 8 LoRA 矩阵的秩,越大容量越大、学得越细
lora_target all 挂到哪些层上,all 表示所有线性层

lora_alpha 不写时默认取 lora_rank * 2,一般不用改。

dataset(数据)

配置项 示例值 含义
dataset identity,alpaca_en_demo 数据集注册名,多个用逗号隔开
template qwen3_nothink 对话模板,训练推理必须一致
cutoff_len 2048 样本最大 token 数,超了截断
max_samples 1000 每个数据集最多取多少条(调试用)
preprocessing_num_workers 16 预处理数据的进程数
dataloader_num_workers 4 读数据的进程数,Windows 报错就设 0

identity 这个数据集很关键——它专门教模型「你是谁」,是所有微调的标配。

output(产物)

配置项 示例值 含义
output_dir saves/qwen3-4b/lora/sft 权重和日志的存放目录
logging_steps 10 每几步打印一次 loss
save_steps 500 每几步存一次检查点
plot_loss true 画出 loss 曲线图
overwrite_output_dir true 允许覆盖同名输出目录
report_to none 训练监控:none / wandb / tensorboard / swanlab / mlflow

train(训练超参)

配置项 示例值 含义
per_device_train_batch_size 1 每张卡一次喂几条
gradient_accumulation_steps 8 攒几步再更新,等效 batch = 1 × 8 = 8
learning_rate 1.0e-4 学习率,LoRA 用 1e-4 左右,全参要小到 1e-5
num_train_epochs 3.0 训练轮数
lr_scheduler_type cosine 学习率调度策略
warmup_ratio 0.1 前 10% 的步数用来热身
bf16 true 用 bfloat16 算,显存减半且更稳
resume_from_checkpoint null 填检查点路径可以断点续训

等效 batch size 很重要:显存不够时把 per_device_train_batch_size 降到 1,用 gradient_accumulation_steps 补上去,训练效果几乎不变。

eval(验证)

默认是注释掉的,想开验证集就把这几行取消注释:

eval_dataset: alpaca_en_demo
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500

4.3 显存不够?换 QLoRA

按第 2 章的账,4B 模型用 LoRA 只要 8GB 左右,24GB 卡完全够。但如果你要微调 7B 以上的模型,就得上 QLoRA——加两行就行:

quantization_bit: 4
quantization_method: bnb

官方示例在 examples/train_qlora/qwen3_lora_sft_otfq.yaml。quantization_method 可选 bnb(bitsandbytes)、hqq、eetq;quantization_bit 可选 8(bnb/hqq/eetq)、4(bnb/hqq)、3(hqq)、2(hqq)。

4.4 训练完先聊两句

llamafactory-cli chat examples/inference/qwen3_lora_sft.yaml

你会看到(示意):

User: 用一句话介绍你自己
Assistant: 我是一个专注于回答问题的 AI 助手,可以帮你解答各类知识与生活问题。

User: 介绍一下 LLaMA-Factory
Assistant: LLaMA-Factory 是一个开源的大模型微调框架...

这个配置文件长这样:

model_name_or_path: Qwen/Qwen3-4B-Instruct-2507
adapter_name_or_path: saves/qwen3-4b/lora/sft
template: qwen3_nothink
infer_backend: huggingface  # choices: [huggingface, vllm, sglang, ktransformers]
trust_remote_code: true

注意 adapter_name_or_path 指向你刚训出来的 LoRA 目录,template 和训练时一模一样——这两处不一致,模型就会答非所问。

4.5 看 loss 曲线

report_to 设成 tensorboard 就能看实时曲线:

report_to: tensorboard
tensorboard --logdir saves/qwen3-4b/lora/sft

你会看到(示意):

loss: 1.24 → 0.71 → 0.52 → 0.41

loss 稳步下降是好信号;如果 loss 突然归零,多半是数据集太简单或者学过头(过拟合),把 num_train_epochs 降到 1~2 再试。想接 Wandb、MLflow、SwanLab 也是改 report_to 一个字段的事。

4.6 常见报错速查

报错 原因 解法
CUDA out of memory 显存不够 降 batch、开 QLoRA、减 cutoff_len
Can't pickle local object Windows 多进程 dataloader_num_workers: 0
dataset not found 没注册 检查 data/dataset_info.json
回答全是乱码/不搭调 template 不一致 训练和推理用同一个 template
loss 是 nan 学习率过大 调小 learning_rate,确认 bf16

动手改

  1. 把 max_samples 改成 50、num_train_epochs 改成 1,快速跑一次,理解每个参数的影响
  2. 把 lora_rank 从 8 改成 32,对比输出目录里 adapter 权重大小和 trainable parameters 的变化
  3. 打开 report_to: tensorboard 训一次,把 loss 曲线截图保存,想想哪些样本可能没被学到

小结

  • SFT 就是拿「问题 + 标准答案」当教材;LoRA 只训练小补丁矩阵,最省显存
  • 官方示例 examples/train_lora/qwen3_lora_sft.yaml 直接能跑,先跑通再改
  • 配置分六块:model / method / dataset / output / train / eval,stage、finetuning_type、dataset、template 是四个最关键的
  • 显存不够就加 quantization_bit: 4 + quantization_method: bnb 上 QLoRA
  • 训完用 llamafactory-cli chat 验证,adapter_name_or_path 和 template 必须对
  • report_to 可以接 tensorboard / wandb / swanlab / mlflow 看 loss 曲线

下一章:偏好对齐 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。