跳到主要内容

指令微调 — 教模型听懂人话

这一章讲三件事: 指令数据怎么来(四条路,包括让模型自己造数据);训练策略怎么选(防遗忘);预算不够怎么微调(LoRA 家族)和能读的篇幅怎么加长。 它对应流水线的第二站:几十块加速卡、几天时间、拼数据质量的阶段。

1. 为什么预训练模型不会对话

指令微调又称有监督微调(SFT):在预训练模型基础上,用标注成「指令-回答」形式的自然语言数据继续训练,让模型获得指令遵循能力1

为什么非要这一步?因为训练目标错位。预训练的目标是「续写」——你问「复旦大学有几个校区」,它见过无数包含这句话的网页,于是接着往下写别的网页内容;它「知道」答案,但没人教过它问题要配一个直接回答。指令微调改变的就是这个行为格式。

技术上它与预训练高度相似(用的还是同一套训练方法),最大的差别只有一处:损失只针对回答部分计算——指令部分不算损失,模型只为「答案答得好不好」受罚2。数据长这样(书里的原例):

User:复旦大学有几个校区?
Assistant:复旦大学共有四个校区,分别是邯郸校区、江湾校区、
枫林校区和张江校区。……

多轮对话(一问一答连续好几轮)也用同样的格式塞进来:把最后一轮回答之前的所有内容当输入,最后一轮回答当输出——模型由此学会「联系前文」3

2. 指令数据从哪来:四条路

人工构建

最直接:请人手写指令和回答,或从网络收集真实问答再标准化。代表:Databricks 员工写的 dolly-15K;全球超过 13500 名志愿者众包的 OASST1;多语言的 Aya 数据集(119 个国家、2997 名贡献者、20.4 万条、65 种语言,遵循「发现-改进-核实」流程)4。优点是质量可控,缺点写在脸上:贵、慢。

现有数据集转换

把多个现成数据集合并成指令格式。Flan 2022 汇集了 1836 个数据集,还发明了两个增强技巧:输入反转(把对话的前文和回答对调,生成新训练样本)和任务混合(把不同任务的样本混在一起训)5。坑也明确:不同数据集对同一任务打的标签规则不一致,直接混会让模型记住特定数据集的怪规则。

自动构建:让模型造数据

这是本章主走查的路。

主走查:Self-Instruct 的一轮循环

Self-Instruct 的核心想法:用模型自己生成指令数据,再拿来训练模型自己。它从一个人工编的小种子出发,滚雪球式扩张6:

初始:175 条人工写的种子指令(指令池)

▼ 每一轮:从指令池随机采样 8 条
其中 6 条来自人工种子,2 条是模型此前生成的
── 把这 8 条拼成示例,让 GPT-3 照葫芦画瓢 ──▶ 产出新指令

▼ 判断新指令是否属于「分类任务」
(分类和非分类后续处理不同)
▼ 为新指令配输入输出
非分类:先想输入,再生成输出
分类:先列出全部类别标签,再给每类补输入
(防止模型只生成某一类,类别失衡)
▼ 过滤:与池中任何一条的 ROUGE-L 相似度 ≥ 0.7 就丢弃
再删含特定关键词、重复、过长过短的

▼ 存回指令池,进入下一轮

斯坦福用这套方法生成 5.2 万条指令,微调 LLaMA 得到 Alpaca——一个 7B 参数的模型在多项评测里逼近 GPT-3.5 的行为。数据是模型生成的,质量却够用:这个事实本身改写了「打标签靠人海」的假设。

表层对齐(只教格式)假设:1000 条就够?

LIMA 论文给出了更激进的结论。表层对齐假设说:模型的知识与能力绝大部分在预训练阶段已经形成,指令微调教的只是「回答该用什么格式」——对齐是表层的7。若假设成立,数据可以极少。LIMA 精选 1000 条(高质量社区问答 + 人工编写,全部统一成 AI 助手口吻),微调 65B 模型,效果媲美用 5.2 万条数据的 Alpaca8

判断(我们的,不是书里的): 表层对齐假设解释力强,但有一个被书里一笔带过的边界——它成立的前提是预训练语料里已经「躺着」足够的任务能力。对主流任务(问答、写作、翻译)它成立;对一个预训练语料几乎没覆盖的全新领域(比如某企业的内部规程),1000 条格式示范教不出能力,此时数据质量论要退位于数据覆盖论。 如果错,会错在: 如果对齐改动的其实是能力本身而不只是格式(有研究认为 RLHF——基于人类反馈的强化学习——阶段确实改变了模型内部表征),那么「预训练决定上限」的表述就会高估预训练、低估后训练——实践后果是错误地把预算全押在预训练上。

数据多少、怎么选:三条实验规律

书里引的实验把「多少数据、什么数据」量化了。其一,60 条就能把问答任务教会;某实验里用 960 条「预训练时没记准」的数据微调,问答准确率反而掉到 30% 左右——喂模型没学过的知识,不如不喂9。其二,质量筛选有效:用 IFD 这类打分尺子只选 5% 的数据,多个评测超过全量训练10。其三,训练策略有讲究:书里对比了四种多任务训练方案,结论是多任务混训保领域能力但伤通用能力,多阶段顺序训练反之;最优的是双阶段混合——最后一阶段在全量通用数据里掺 1/256 的领域数据,LLaMA-7B 数学准确率从 32.6% 升到 41.92%,代码从 15.24% 升到 17.68%——掺一点旧领域数据,显著缓解灾难性遗忘11

3. 省钱微调:LoRA 家族

全参数微调要为每个参数存梯度和优化器状态(第 05 章算过 16 字节/参数的账),千亿模型根本玩不起。LoRA 的出发点是一条实证观察:微调之后的权重变化量,本征秩(本质上需要多少条独立方向才能拼出来)很低——那何不干脆不改原权重,只在旁边加一个低秩(用两条细长小矩阵相乘来表示大改动的)补丁?12

具体做法:原权重 W0 冻结(钉死不改)不动,训练一个分解 ΔW = B·A,其中 B、A 是两个瘦长矩阵,中间的秩 r 取很小的数(如 4 或 8)。前向计算变成 h = W0·x + B·A·x13。初始化有讲究:B 全零、A 随机——训练开始时补丁恰好是零,模型行为与原模型完全一致,从零偏离。

它的省,有具体数字:GPT-3 上取 r=4、只给注意力层加补丁,可训练参数骤减后保存的检查点(训练到某刻存下的完整模型档案)从 350GB 缩到 35MB(万分之一);训练显存从 1.2TB 降到 350GB,出结果还快四分之一14

更妙的是推理时可以把补丁合并回主权重(W = W0 + BA),不增加任何推理延迟——这是它对 Adapter(插入新层,推理变慢)和前缀微调(挤占能读的篇幅)的结构性优势15

家族成员各管一摊:AdaLoRA 给重要的层多分点秩、不重要的少分点(按平滑后的参数敏感性排序裁剪)

QLoRA(量化了的 LoRA)走的是另一条路。

先把主模型压到 4-bit 存储,再挂 LoRA,650 亿参数的模型一块 48GB 显卡就能微调——4-bit 数据类型 NF4 按分位数设计(让每个压缩后的取值区间装同样多的数),再对「记录压缩方式的参数」本身做二次压缩,额外开销从每参数 0.5 比特压到 0.127 比特16

4. 上下文窗口:从 2048 到 32768

模型一次能「看」多长的文本,由训练时的位置编码范围决定。LLaMA 初版只能处理 2048 个词元。三条扩展路17:

  • 直接换大窗口微调:朴素但低效——书里的实验,训了一万多个批次窗口才从 2048 挪到 2560;
  • 换外推型位置编码:ALiBi 不给词向量加位置,而是在注意力分数上按距离加惩罚——离得越远扣得越多,不同注意力头用不同的扣分斜率。小窗口训练,大窗口推理;
  • 位置插值(PI):不换位置编码,把「位置号」按比例压缩——要扩 8 倍窗口,就把所有位置号除以 8,让它们落回训练时见过的范围。只需约 1000 步微调,就能把 LLaMA 的窗口从 2048 扩到 3276818

为什么 RoPE 不能直接外推而插值可以?书里的解释:注意力的基函数拟合能力太强,训练时没见过的位置区间里系数可以取到很大的值,直接外推注意力分数会失控(困惑度飙升);插值把新位置全部映射(换算着搬)进旧区间,数值天然稳定19

5. 作者的判断与证据

  • 有证据的: Self-Instruct 的过滤阈值(分数线,过线才留)、LIMA 的 1000 条对照、60 条样本实验、双阶段混合的准确率表、LoRA 的 1/10000 检查点、位置插值的 1000 步——全部有文献出处。
  • 作者的判断: 四类数据构建方法的划分、各方法的优缺点排序,是作者的整理框架。
  • 书里的坦白: 「指令微调需要多少数据」在通用能力和领域任务上答案相反(通用约 1000 条后饱和,领域任务随数据持续提升)——书里明确说不能一概而论20

6. 边界与局限

  • 数据质量评估(式 5.1 的三维分解)是综述性框架,实操中「清晰度/准确性/明确性」怎么折算成数字,书里没有给全。

  • 上下文(能读的篇幅)扩展只讲到位置插值;后来的更多方案(YaRN 等)不在本书范围。

  • DeepSpeed-Chat 实践一节以代码走读为主,机制增量少,本章略去;需要跑通时直接看原书 5.4-5.5 节。

  • 指令数据的安全维度(怎么避免教出有害服从)本书放在第 11 章评估体系里讲,此处未展开。

7. 可带走的

  1. SFT 改变的不是知识,是行为格式;损失只算回答部分是它与预训练在计算层面的唯一差别;
  2. 指令数据四条来路:人工(贵而稳)、转换(注意标签规则不一致)、模型自生成(Self-Instruct)、精选(LIMA);
  3. 表层对齐假设值得默认相信、边界牢记:预训练没覆盖的新领域,1000 条格式示范救不了;
  4. 喂「模型没记住的知识」做 SFT 会倒扣分(960 条错误数据 → 准确率 30%)——先探明模型会什么,再决定教什么;
  5. 多阶段训练的最后一段掺 1/256 旧领域数据,是对抗灾难性遗忘的廉价保险;
  6. LoRA 的三笔账:检查点缩小一万倍(350GB→35MB)、显存从 1.2TB 到 350GB、推理零开销(可合并);
  7. QLoRA 把「微调 650 亿模型」的门槛降到单卡 48GB——个人和小团队微调的现实起点;
  8. 扩上下文优先想位置插值(千步微调扩 16 倍),别上来就重训。

8. 原文地图

主题原书章原文位置
SFT 定义与动机5 指令微调text/05-ch05.txt:3(搜「指令微调又称有监督微调」)
损失只算输出5 指令微调text/05-ch05.txt:19(搜「输出部分来计算损失」)
复旦校区数据例5 指令微调text/05-ch05.txt:38(搜「复旦大学共有四个校区」)
多轮对话格式5 指令微调text/05-ch05.txt:90(搜「最后一轮」)
OASST1 等人工数据5 指令微调text/05-ch05.txt:128(搜「OASST1」)
输入反转与任务混合5 指令微调text/05-ch05.txt:164(搜「输入反转」)
Self-Instruct 种子与采样5 指令微调text/05-ch05.txt:202(搜「种子指令集」) · text/05-ch05.txt:204(搜「6 条来自人工编写的种子」)
ROUGE-L 过滤5 指令微调text/05-ch05.txt:278(搜「ROUGE-L」)
Alpaca5 指令微调text/05-ch05.txt:282(搜「Alpaca」)
表层对齐假设5 指令微调text/05-ch05.txt:453(搜「表层对齐假设」)
LIMA 1000 条5 指令微调text/05-ch05.txt:459(搜「1000 个提示」) · text/05-ch05.txt:473(搜「52,000 条」)
60 条样本实验5 指令微调text/05-ch05.txt:498(搜「60 个训练样本」)
倒扣分现象5 指令微调text/05-ch05.txt:548(搜「30% 左右」)
四种训练策略与 1/2565 指令微调text/05-ch05.txt:624(搜「1/256」) · text/05-ch05.txt:625(搜「41.92%」)
LoRA 本征秩5 指令微调text/05-ch05.txt:716(搜「本征秩」)
LoRA 结构与初始化5 指令微调text/05-ch05.txt:721(搜「零初始化」)
LoRA 数字账5 指令微调text/05-ch05.txt:854(搜「350GB 变为 35MB」)
Adapter/前缀对比5 指令微调text/05-ch05.txt:726(搜「前缀微调」)
QLoRA 48GB5 指令微调text/05-ch05.txt:915(搜「48GB」) · text/05-ch05.txt:940(搜「0.127」)
窗口限制与三路5 指令微调text/05-ch05.txt:947(搜「2048 个」) · text/05-ch05.txt:953(搜「ALiBi」)
直接微调低效5 指令微调text/05-ch05.txt:957(搜「2560」)
ALiBi 斜率5 指令微调text/05-ch05.txt:986(搜「斜率」)
位置插值与 327685 指令微调text/05-ch05.txt:1006(搜「位置插值法」) · text/05-ch05.txt:1053(搜「32768」)
RoPE 外推失控5 指令微调text/05-ch05.txt:1017(搜「飙升」)

Footnotes

  1. 出处:「5 指令微调」第 3 段(text/05-ch05.txt:3,搜「指令微调又称有监督微调」)。

  2. 出处:「5 指令微调」第 19 段(text/05-ch05.txt:19,搜「输出部分来计算损失」)。

  3. 出处:「5 指令微调」第 90 段(text/05-ch05.txt:90,搜「最后一轮」)。

  4. 出处:「5 指令微调」第 128 段(text/05-ch05.txt:128,搜「OASST1」)与第 131 段(text/05-ch05.txt:131,搜「Aya」)。

  5. 出处:「5 指令微调」第 164 段(text/05-ch05.txt:164,搜「输入反转」)。

  6. 出处:「5 指令微调」第 202-207 段(text/05-ch05.txt:202,搜「种子指令集」;text/05-ch05.txt:204,搜「6 条来自人工编写的种子」)与第 278 段(text/05-ch05.txt:278,搜「ROUGE-L」)。

  7. 出处:「5 指令微调」第 453 段(text/05-ch05.txt:453,搜「表层对齐假设」)。

  8. 出处:「5 指令微调」第 459 段(text/05-ch05.txt:459,搜「1000 个提示」)与第 473 段(text/05-ch05.txt:473,搜「52,000 条」)。

  9. 出处:「5 指令微调」第 498 段(text/05-ch05.txt:498,搜「60 个训练样本」)与第 548 段(text/05-ch05.txt:548,搜「30% 左右」)。

  10. 出处:「5 指令微调」第 374 段(text/05-ch05.txt:374,搜「5% 的数据」)。

  11. 出处:「5 指令微调」第 624 段(text/05-ch05.txt:624,搜「1/256」)与第 625 段(text/05-ch05.txt:625,搜「41.92%」)。

  12. 出处:「5 指令微调」第 716 段(text/05-ch05.txt:716,搜「本征秩」)。

  13. 出处:「5 指令微调」第 721 段(text/05-ch05.txt:721,搜「零初始化」),即原书式 (5.7) 的构造说明。

  14. 出处:「5 指令微调」第 854 段(text/05-ch05.txt:854,搜「350GB 变为 35MB」)。

  15. 出处:「5 指令微调」第 726 段(text/05-ch05.txt:726,搜「前缀微调」)与第 732 段(text/05-ch05.txt:732,搜「合并」)。

  16. 出处:「5 指令微调」第 915 段(text/05-ch05.txt:915,搜「48GB」)、第 917 段(text/05-ch05.txt:917,搜「NF4」)与第 940 段(text/05-ch05.txt:940,搜「0.127」)。

  17. 出处:「5 指令微调」第 953 段(text/05-ch05.txt:953,搜「ALiBi」)与第 957 段(text/05-ch05.txt:957,搜「2560」)。

  18. 出处:「5 指令微调」第 1053 段(text/05-ch05.txt:1053,搜「32768」)。

  19. 出处:「5 指令微调」第 1017 段(text/05-ch05.txt:1017,搜「飙升」)。

  20. 出处:「5 指令微调」第 631 段(text/05-ch05.txt:631,搜「1000 个样本后趋于平稳」)。