从续写到对话助手
预训练只教会模型续写;要让它听懂指令、像 ChatGPT 那样对话,还要经过指令微调和人类反馈对齐。
满腹知识,却不知道你想要什么
预训练好的大模型暴露了一个落差:它的训练目标是「预测下一个词」,所以它学到的是 模仿语料去续写 ,而不是 回答问题、遵循指令 。
它有满腹知识,却不知道你想要它「干什么」。同样一句「请翻译这句话」,预训练模型可能继续续写更多类似的句子,而不是真的去翻译。从 GPT 到 ChatGPT,差的正是这一步,即 对齐(alignment) 。
先看全景:大模型训练的完整链路
把一个能对话的助手训出来,通常要走三步:
第一步决定「能力有多强」,后两步决定「好不好用」。预训练我们已经讲透,下面看后两步。
指令微调 SFT:把数据换成优质问答对
指令微调(SFT,Supervised Fine-Tuning,监督微调) 的做法:收集大量 「指令 → 理想回答」 配对,例如:
指令:把这句话翻成英文:今天天气真好 回答:The weather is really nice today.
然后继续用 「预测下一个词」 的方式训练模型去生成那段 理想回答 。训练目标 本质没变 ,仍是下一个词预测,变的主要是数据,从「任意网络文本」换成「人写的优质问答对」。另外还有一处训练细节, 只对回答部分计算损失 ,后面构造样本时会具体看到。
人类反馈对齐 RLHF:按偏好打磨
SFT 之后,模型会回答了,但回答有好有坏。 RLHF(基于人类反馈的强化学习) 负责进一步打磨,分四步走:
三种「在预训练之上的适配方式」
到这里,可以把见过的几种「在预训练通用能力之上做适配」的方式放在一起对照:
三者机制不同,但都建立在 同一块地基 上,也就是「预训练得到的通用能力」。这正是「预训练到微调」这一范式在不同方向上的展开。
动手:构造一条 SFT 样本
把一组「指令 + 回答」按 对话模板 拼成一段文本。模板里的 <|user|> 、 <|assistant|> 是 角色标记 ,用来划出指令和回答的边界, <|user|> 之后是用户的指令, <|assistant|> 之后是模型要生成的回答,模型靠它学会在哪里开口作答。拼好后再标注 只对回答部分计算损失 ,指令部分不计损失,因为我们要模型学会「答」,而不是「重复问」:
把它和预训练数据对照。预训练对 每个 位置都算损失,SFT 则 只对回答 算损失。这一处「loss mask」的差别,正是「学会回答」而非「学会续写」的关键。
图中 token id 为示例分词器的编号,随分词器不同而变;固定不变的是掩码规则。指令位的 label 被置为 -100(不计损失),回答位的 label 保留 token 的 id(计损失)。
动手:对齐前后,差别有多大
对齐分两步走:先 指令微调 SFT ,再 人类反馈对齐 RLHF 。把同一个底座模型在这三个阶段的版本, 仅预训练的 base 版 、 SFT 后 、 RLHF 后 ,对同一个问题作答,并排看:
base 版续写跑题,SFT 后学会正面作答,RLHF 再把回答对齐到人类偏好。下面选个问题,把三个阶段的回应摆在一起看。
回顾这一路
大语言模型的来龙去脉,到这里闭环了。把这条线索串起来:
- 从完整的 encoder-decoder Transformer 出发,它的两半各自独当一面;
- 编码器路线 催生 BERT,双向理解 + 预训练微调;
- 解码器路线 催生 GPT,自回归生成 + 自监督预训练;
- 再把解码器升级为现代大模型 LLaMA3 ,用上 RMSNorm、RoPE、SwiGLU、GQA、KV 缓存;
- 最后用 SFT 与 RLHF 把「续写模型」对齐成「对话助手」。
「能续写下一个词」的朴素目标,一路堆叠、升级、对齐,最终长成了今天我们用的对话大模型。
能力就绪,怎么用好它
我们已经有了一个会对话的大模型。但要让它真正解决现实问题,还有更多课题:
- 让它 查阅外部资料 再回答(检索增强 RAG);
- 让它 调用工具、执行动作 (智能体 Agent);
- 用很小的代价为自己的领域 定制 (参数高效微调,如 LoRA)。
大模型的「能力」已经就绪,如何「用好」它,是后续的故事。