卷2 · LLM 内功
2.5 SFT 与指令微调实战
展开本章目录与同卷章节
1. 为什么 base 模型”不听话”2. 数据格式与 loss mask(本章最重要的技术细节)3. 数据从哪来,质量与数量的关系4. LLaMA-Factory 实战(寒假主线的工具)5. SFT 的失败模式6. 自测题7. 动手作业(寒假里程碑第一段)8. 延伸资源同卷章节2.1 语言模型前史:n-gram → RNN → 注意力(20 分钟走完 30 年)2.2 BPE tokenizer 原理与实现2.3 GPT 架构工程版:从 TinyGPT 到 nanoGPT2.4 预训练:数据、Scaling Law 与训练稳定性2.5 SFT 与指令微调实战2.6 参数高效微调:LoRA 与 QLoRA2.7 对齐技术:RLHF → DPO → GRPO2.8 推理优化与 vLLM:把模型变成服务2.9 架构前沿:MoE、长上下文与注意力变体2.10 小模型时代的科研机会:1B–7B 甜点区本章目标:把”会续写”的 base 模型变成”会回答”的助手——理解指令微调的原理、数据格式、loss mask,并用 LLaMA-Factory 跑通第一次真实微调。学完标准:能独立完成一次 SFT 并解释每个配置项在做什么。
1. 为什么 base 模型”不听话”
预训练模型是补全机:给它”中国的首都是”,它可能续写”一个国家的发展史……”(网页常见模式)。它不是不知道答案,而是没学过”问答”这种交互形式。SFT(Supervised Fine-Tuning)教的就是行为格式:把成千上万条”指令 → 高质量回答”喂给模型,让它进入”对话回答”的模式。
认知要点:知识几乎全部来自预训练,SFT 只是对齐格式、调出已有能力(这就是为什么 1000 条高质量数据也能显著改变行为——LIMA 论文的核心结论:“对齐可能是浅层的”)。反过来,SFT 也不能给模型注入它预训练时没见过的新知识——想让模型学领域知识,要么继续预训练,要么用 RAG。这个边界感是新手最常犯的认知错误。
2. 数据格式与 loss mask(本章最重要的技术细节)
一条指令数据的通用结构(Alpaca 风格):
{"instruction": "解释什么是过拟合", "input": "", "output": "过拟合是指模型……"}
多轮对话则用 role 结构(system/user/assistant)。训练时由 chat template 拼成最终文本:
<|im_start|>system
你是一个有用的助手。<|im_end|>
<|im_start|>user
解释什么是过拟合<|im_end|>
<|im_start|>assistant
过拟合是指模型……<|im_end|>
关键:loss mask。SFT 只在 assistant 回复的 token 上计算 loss,prompt 部分的标签置 −100(PyTorch 交叉熵的忽略值)。为什么:我们不想让模型”学着生成问题”,只想让它学回答。框架帮你做了,但你要知道它在哪——自己写 Trainer 或排查 loss 不降时,第一个查这里:
labels = input_ids.clone()
labels[:, :prompt_len] = -100 # prompt 不参与 loss
loss = F.cross_entropy(logits.view(-1, V), labels.view(-1), ignore_index=-100)
chat template 不一致是 SFT 的头号 bug:训练用什么模板,推理就必须用什么模板(包括 special token、换行、空格)。模板错位不会报错,只会让模型输出诡异——性能暴跌的第一嫌疑人。
3. 数据从哪来,质量与数量的关系
| 来源 | 特点 | 场景 |
|---|---|---|
| 人工标注 | 贵、质量最高 | 产品级模型 |
| 蒸馏强模型(现在主流) | 用 GPT-4o/Qwen-Max 生成回答 | 快速起步、领域数据 |
| 自指令(Self-Instruct) | 模型自举生成 | 老方法,质量一般 |
| 开源数据集 | Alpaca、ShareGPT 格式社区集合 | 练手 |
铁律:质量 > 数量。500 条覆盖面准、回答精的数据,胜过 5 万条平庸数据。蒸馏数据时最该花时间的是清洗:去重、长度过滤、答案质量再筛(可用强模型当裁判打分——“LLM-as-a-judge”,也是一套方法论)。领域微调(比如你未来的”美学 VLM”)的竞争壁垒就在这批数据上。
4. LLaMA-Factory 实战(寒假主线的工具)
LLaMA-Factory 是国内开源生态最常用的微调框架(同类:ModelScope SWIFT),整合了各模型的 template、LoRA、量化、评测:
- 安装:
git clone+pip install -e ".[torch,metrics]"; - 注册数据:把你的 json 放
data/,在data/dataset_info.json里登记(columns 映射 + tags 指定角色标签); - 写配置(yaml 一份,比命令行好维护):
model_name_or_path: Qwen/Qwen2.5-1.5B-Instruct # 练手先小模型
stage: sft
finetuning_type: lora
lora_target: all
lora_rank: 16
lora_alpha: 32
dataset: my_dataset
cutoff_len: 2048
learning_rate: 1.0e-4 # LoRA 的 lr,比全参大 10 倍(2.6 详述)
num_train_epochs: 3
per_device_train_batch_size: 2
gradient_accumulation_steps: 8
output_dir: saves/qwen-sft
- 训练:
llamafactory-cli train my.yaml; - 对话验证:
llamafactory-cli chat(必须用与训练一致的 template!)。
超参直觉:小数据(<5k)epoch 3,大数据 epoch 1~2;cutoff_len 够用就好(序列长度平方吃显存);LoRA 配置的完整讲解在 2.6。
5. SFT 的失败模式
- 复读机 / 多样性坍塌:epoch 太多或数据太少——模型背下了回答模板;
- 灾难性遗忘:模型忘了通用能力,只会你教的几十种句式——解法:混入通用数据(比如 1:1)、降 epoch、用 LoRA 而非全参;
- 模板错位:见 §2;
- 数据泄漏进验证集:评测虚高——去重后再切分。
6. 自测题
- SFT 能给模型注入新知识吗?为什么?(几乎不能;它改变行为分布,知识容量来自预训练——领域知识要靠继续预训练或 RAG)
- loss mask 为什么必要?忽略标签值是多少?(只学回答不学问题;−100)
- LIMA 的结论和它的边界?(1000 条高质量可对齐行为;但知识仍来自底座)
- 模板错位的症状和处理?(输出诡异不报错;逐字符比对训练/推理模板)
- 灾难性遗忘的两个解法?(混通用数据;LoRA 限制改动量)
- 为什么蒸馏数据的清洗比生成更花时间?(生成靠强模型,质量方差大:重复、幻觉、模板腔——不清洗就训进模型)
7. 动手作业(寒假里程碑第一段)
- 构造一个 500 条的垂直数据集(建议直接用强模型蒸馏:主题选你导师方向,比如”看画描述/流派判断/构图分析”——一鱼两吃);
- 用 LLaMA-Factory 对 Qwen2.5-1.5B 做 LoRA SFT,训练前后各截 10 个对比案例;
- 故意制造三个失败:epoch=10(复读机)、模板错位(输出诡异)、数据不清洗(质量差)——各写 100 字诊断,这是面试时最值钱的经验;
- 把数据构造脚本 + 配置 + 对比案例整理成 repo。
8. 延伸资源
- LIMA 论文(Zhou et al., 2023)——“对齐是浅层的”
- LLaMA-Factory 官方文档——照着走一遍 full pipeline
- Self-Instruct / Alpaca 论文——历史脉络
