后训练:从续写到听话、推理、做事
主线定位
- 上游 · C0–C11:一个「预测下一个 token」的模型已经训好,做大、做省。贯穿例句「小明把苹果给了小王」在本章升级成一个提问:「小明把苹果给了小王。」苹果现在在谁手里?——在 Qwen3.8 的词表里是 13 个 token,预训练模型看到它,只会接着往下编。
- 本章:把续写的模型变成助手。先教它按格式回答(SFT),再教它分辨好坏(偏好、RL),再教它想得久又能收住(思考),让小模型直接继承(蒸馏),最后在环境里学会做事(agentic RL)。
- 下游:C13 推理——RL 的 rollout 就是 decode;C14 评测——benchmark 分数能信多少(pass@k 见本章岔路);编码 Agent 课——模型吐出一段「调用工具」的文字,然后呢?
本章问题链
每一课只回答一个问题;上一课的失败,逼出下一课的问题。
| 课 | 这一课的问题 | 朴素方案在哪个真数字上失败 | 一句话 |
|---|---|---|---|
| 第 1 课 | 预训练模型只会续写,怎么让它回答问题? | 我们的小模型 SFT 前 64 token 内停下的比例 0%;整段都算 loss 时,86 个预测目标里 63 个在背模板和用户的话 | SFT 用的还是「预测下一个 token」,只是换了数据、只在回答上算 loss |
| 第 2 课 | 好回答写不出来,但能比较:怎么把「比较」变成训练信号? | 只示范 A 时,SFT 对好回答 B 和拒答 F 的概率永远逐位相同 | 把「更好」拟合成打分,用 RL 往高分推,KL 拴住 |
| 第 3 课 | 能不能不训奖励模型? | RLHF 显存里 4 个模型(Qwen3.8 规模约 1,000 GB) | DPO 只看对数比之差;第一步 loss 恰为 ln 2 |
| 第 4 课 | PPO 的 value model 能不能去掉? | critic 与策略一样大;λ = 0.95 时 PPO 明显差于 GRPO | 组内互为基线;全组一样就没有信号 |
| 第 5 课 | 学出来的奖励会被骗,有没有骗不了的? | 用奖励模型做 RL,50 步内正确率 0.40 → 0.055 | 能核对就给对 / 错;RLVR 是奖励来源,不是优化器 |
| 岔路 | RL 扩展了能力,还是只把会的排到前面? | — | 小 k 看效率、大 k 看边界 |
| 第 6 课 | 怎么让模型想得更久,又能控制? | 思维链提示对约 100B 以下的模型没有正向收益 | 思考是被 RL 训出来的 token;力度与预算决定想多久 |
| 第 7 课 | 小模型怎么继承大模型? | Qwen2.5-32B 自己做 RL:AIME 47.0;蒸馏:72.6 | 学老师的整个分布,在自己的路上学 |
| 第 8 课 | 从答题到做事,怎么训? | SFT 模仿修 bug 轨迹:格式 96.2%,修对 29.6% | 只训模型写的 token,奖励来自环境 |
| 实验课 | 在我们自己的模型上做一次 SFT | — | 格式 50 步就学会,代价是预训练 loss 涨 0.27 |
演进地图
八代做法按「问题链」排,每一代写清它解决了什么、卡在哪个真数字上;下面第二张图把优化器和信号来源画成两条独立的轴——旧版课程把「PPO → GRPO → RLVR」讲成一条砍法线,那是错的。每一课都会再出现这张图,高亮那一课的位置。
- 解决了学会了「预测下一个 token」:贯穿提问在 Qwen3.8 词表里是 13 个 token,模型看到的只是一段要接着写的文字。卡在FLAN 原文:不做指令微调的 GPT-3 175B 零样本,25 个数据集里有 20 个输给 137B 的指令微调模型。
- 解决了同一个交叉熵,只在回答 token 上算:Qwen3.8 模板里一条 87 token 的样本只有 24 个算 loss;LIMA 只用 1,000 条示范。卡在只有正例:教学世界里只示范 A,SFT 对另一个好回答 B 和拒答 F 的梯度逐位相同,两者概率永远相等(第 2 课浏览器实算)。
- 解决了人只需比较两个回答;InstructGPT 的 1.3B 模型胜过 175B GPT-3,175B 版对 GPT-3 的胜率 85 ± 3%。卡在显存里同时放 4 个模型:按 Qwen3.8-27B 规模,policy 与 value 各 444.5 GB、RM 与参考模型各 55.6 GB,合计1000.1 GB。
- 解决了闭式解把 RLHF 折成分类损失,第一步 loss 恰为 ln 2 = 0.6931;不采样、不训 RM。卡在只看成对之差:教学世界里 A 在 3 对偏好里是被选中的一方,概率却从 0.30 掉到0.002(第 3 课浏览器实算)。
- 解决了同一题采一组回答,组内标准化当优势;按 Qwen3.8 规模省掉 444.5 GB 的 value 模型。卡在全对或全错的组优势恰为 0:正确率 0.9、每组 8 个时,43.0% 的组白算;错的长回答每个 token 被罚得更轻(第 4 课)。
- 解决了R1-Zero 纯 RL:AIME 2024 pass@1 从 15.6% 升到 71.0%(v1)/ 77.9%(v2)。卡在学出来的奖励会被钻空子:教学世界里用 RM 做 RL,50 步内真实正确率从 0.40 掉到0.055(第 5 课浏览器实算)。
- 解决了pass@k 无偏估计:10 次里对 3 次,pass@1 = 0.30,pass@5 = 0.917——k 决定结论。卡在Qwen3 表 21:RL 把 pass@1 从 55.0 提到 67.6,pass@64 90.0 → 90.0 不变。
- 解决了Qwen3-235B 推理 RL:3,995 个 query-verifier 对,AIME’24 170 步内 70.1 → 85.1;同一个模型能想能不想。卡在小模型自己做 RL:Qwen2.5-32B 直接做 R1-Zero 式 RL,AIME 2024 只有 47.0。
- 解决了同一个 32B 底座蒸馏 R1 的 80 万条数据:72.6;Qwen3 on-policy 蒸馏只用 RL 的 1/10 GPU 时。卡在会答题不等于会做事:一条两轮修 bug 轨迹 443 个 token,工具返回的 42 个不是模型写的,不能照单全训。
- 解决了奖励来自环境本身(测试过没过);Llama3-SWE-RL-70B 在 SWE-bench Verified 上 41.0%。卡在→ 交接 Agent 课:模型吐出一段「调用工具」的文字,然后呢?
| 信号来源 ↓ / 优化器 → | 模仿交叉熵(SFT、拒绝采样 SFT) | PPOcritic + GAE + clip | 离线偏好损失DPO 系,不采样 | 组内基线GRPO / DAPO / GSPO | 蒸馏对老师分布的 KL |
|---|---|---|---|---|---|
| 人写的示范 | FLAN · LIMA2021 · 2023 显存里 1 个模型 | ||||
| 人类偏好(学出的 RM) | Ziegler 20192019 显存里 4 个模型 InstructGPT2022 显存里 4 个模型 | Llama 3 · Tülu 3 偏好阶段2024 显存里 2 个模型 | DeepSeekMath2024-02 显存里 3 个模型 | ||
| 可验证规则 | Tülu 3 RLVR2024-11 显存里 3 个模型 | DeepSeek-R1-Zero2025-01 显存里 2 个模型 DAPO2025-03 显存里 1 个模型 SWE-RL2025-02 显存里 2 个模型 GLM-5 推理 RL2026-02 显存里 1 个模型 | |||
| 环境反馈 | GLM-5.2 / 5.3 SAO2026-07 模型数:未全部披露 | DeepSeek-V3.2 agent RL2025-12 模型数:未全部披露 | |||
| 老师模型的分布 | Qwen3 strong-to-weak2025-05 显存里 2 个模型 V4 OPD · K3 MOPD2026 模型数:未全部披露 |
橙框两格是旧课讲错的地方:Tülu 3 的 RLVR 用的是 PPO,DeepSeekMath 的 GRPO 用的是学出来的奖励模型。「RLVR」说的是奖励从哪来,「GRPO」说的是梯度怎么算,两件事可以任意组合。悬停格子里的系统看出处要点。
三层交互
| 层 | 本章里的组件 | 在哪一课 |
|---|---|---|
| 概念动画 | 后训练流水线七站;PPO 数据流环路逐步走(rollout → RM → KL → 奖励 → value → GAE → clip) | 每课开头、第 2 课 |
| 算法模拟器(真算法、小数据) | 教学世界(6 个回答的玩具策略):SFT 梯度、Bradley-Terry 奖励模型、DPO 与闭式解、PPO 多轮更新的 clip、GRPO 真训练与零方差组、三种奖励下的过优化;lm_head 漂移;pass@k 估计与交叉;多数投票二项式;K3 预算规则;温度与正向 / 反向 KL 拟合 | 第 1–7 课、岔路 |
| 真模型 / 真数据 | Qwen3.8-27B 真 tokenizer + 官方聊天模板的逐 token 渲染与两种 loss 掩码(含 transformers 与 TRL 的真实行为);我们自己的 3.7M 模型的 SFT 真实日志;Agent 课项目的真实修 bug 运行(轨迹、组内优势、rollout 长尾);R1、Qwen3、SWE-RL、InstructGPT 的原文数字 | 第 1、6、8 课与实验课 |
项目推进:把我们的模型微调成会回答的样子
对应 04-实践项目/MILESTONES.md 的「C12 后训练(SFT)」。分工照旧:代码 AI 来写,决策你来做。minillm/sft.py 与 experiments/exp_c12_posttrain.py 已经写好:从语料里抽「某某曰:「……」」构造问答对,只在回答上算 loss,从预训练 checkpoint 出发训 300 步。
你要拍板的三件事
- 模板长什么样,结束符用哪个?用分词器自带、预训练里没出现过的
<|endoftext|>(不扩词表),还是新增专门的特殊 token(要扩 embedding、改vocab_size)?(第 1 课、实验课) - loss 要不要屏蔽提示部分?本项目的提示比回答长得多、样本只有 6,750 条——正是 Shi et al. 2024 说「对指令也算 loss」可能更好的条件。先写下预测,再跑对照。(第 1 课误解一、实验课)
- 学习率与步数怎么定?格式在前 50 步就学会了,之后每一步都在涨预训练 loss。(实验课)
验收标准(全部可测):
tests/test_extensions.py::TestSFTMask通过:提示 token 的梯度恰为 0。- SFT 后留出提示的 eos_rate(贪心 64 token 内输出结束符的比例)≥ 95%;回答 loss 与结束符 loss 分开报告。
- 预训练验证集 val loss 的涨幅(遗忘)写进表里;以本页基线为准,任何改动不能让它变大;两个设置相差小于项目噪声底线(C14:同配置 5 次重跑极差 0.016,3σ ≈ 0.020)时不下结论。
进阶(选做,对应旧版 M5 的项目步骤):偏好对齐与 RL 在 3.7M 的模型上做不出有意义的结果;想动手,用第 2–5 课的教学世界组件,或者在一个 0.5B 左右的开源模型上用 TRL 的 DPOTrainer / GRPOTrainer 跑一遍——注意第 1 课讲的聊天模板与掩码坑。
坑与带走
| 坑 | 症状 | 后果 | 怎么办 |
|---|---|---|---|
| 用错聊天模板 | 不报错,回答质量莫名变差 | 模型在没见过的边界 token 上工作,静默变笨 | 用模型配套的模板(第 1 课) |
| base 模型没对齐结束符 | 生成停不下来 | 回答顶满长度上限 | 结束符进 loss;我们的项目结束符 loss 16.84 → 0.37(第 1 课、实验课) |
| 信任官方模板的助手掩码 | transformers 只打一行日志 | Qwen3.8 这条样本 0 / 87 个 token 被训练 | 用带 {% generation %} 的训练版模板(TRL main 会自动换并在全 0 时报错)(第 1 课) |
| 整段都算 loss | loss 看着正常 | 大部分梯度花在背模板和猜用户的话 | 只算助手 token;指令很长、样本很少时可以做对照(第 1 课) |
| 以为 SFT 在灌知识 | 拼命堆数据量 | 数据多、效果不涨,遗忘更多 | 知识在预训练;SFT 重质不重量(第 1 课) |
| LoRA 只用在注意力层 | 效果明显不如全量微调 | 结论被错误配置拖累 | LoRA 用在所有权重矩阵上,学习率调高(第 1 课) |
| SFT 多轮次猛训 | 训练 loss 很低 | 过拟合、遗忘 | 看留出集与预训练 loss,不要只看训练 loss(第 1 课、实验课) |
| 让人给回答打绝对分 | 标注者之间尺度不一 | 奖励信号噪声大 | 用成对比较 chosen / rejected(第 2 课) |
| RL 不加 KL | 奖励一路涨 | 策略跑到奖励模型没见过的地方 | 加 KL 锚点,或者换可验证奖励(第 2、5 课) |
| 以为 clip 是概率上限 | ratio 超过 1.2 以为是 bug | 误读训练日志 | clip 只去掉继续推的激励(第 2 课) |
| DPO 只看 loss | loss 降了,chosen 的概率也在降 | 模型塌到少数回答上 | 同时盯 chosen / rejected 的对数概率(第 3 课) |
| GRPO 不写标准差口径 | 复现时数字对不上 | 结论无法比较 | 写明总体还是样本标准差(第 4 课) |
| 题目太难或太容易 | 大量组全对或全错 | 采样算力白花 | 动态采样、按难度筛题(第 4、8 课) |
| 按回答长度平均损失 | 回答越来越长 | 错的回答尤其长 | token 级损失或 Dr. GRPO(第 4 课) |
| 盲信奖励模型 | 奖励一路涨、真实效果先升后降 | reward hacking | 能核对就用规则;不能就加长度控制与 KL(第 5 课) |
| 验证器写得太松 | 奖励很高,人看了不对 | 模型学会两头下注 | 严格抽取答案、跑完整测试(第 5 课) |
| 只看 pass@1 就说能力提升 | — | 误判 RL 的作用 | 同时报告大 k 的 pass@k(岔路) |
| 蒸馏温度设太高 | 学生分布趋于均匀 | 软目标里的差异太弱,学得慢(排序不变) | 适中的 T,并把软目标乘回 T²(第 7 课) |
| 工具返回也算 loss | 模型去学预测环境输出 | 学习信号被污染 | 只训模型写的 token(第 8 课) |
| 同步等最慢的 rollout | GPU 利用率很低 | 训练慢几倍 | 部分 rollout、异步,并处理过期 token(第 8 课) |
| 记错出处 | 说 GRPO 是 R1 发明的、DPO 是 Anthropic 的、RLHF 始于 InstructGPT、PPO 原文就有 KL | 讲错演进史 | GRPO:DeepSeekMath 2024-02;DPO:Stanford 2023;RLHF 用于语言模型:Ziegler 2019;PPO 原文是 Atari / MuJoCo |
这一章你应该带走的(各课「一句话」):
- SFT 用的还是「预测下一个 token」,只是换了数据、只在回答上算 loss:它教的是格式和行为,知识来自预训练。
- 人写不出最好的回答,但能说出两个里哪个更好:把「更好」拟合成一个打分,再用 RL 把策略往高分推,KL 拴住它别跑偏。
- DPO 把「先训奖励、再做 RL」折成一个分类损失:只看好回答和差回答的对数比之差;代价是只能在给定的偏好对上学。
- GRPO 用同一题的一组回答互相当基线:比组内平均好就推高,差就压低;全组一样就没有信号。
- 能自动核对的答案给「对 / 错」,奖励就很难被骗——但前提是验证器本身写得严;RLVR 是奖励来源,不是优化器。
- 小 k 看效率、大 k 看边界:同一组数,k 取多大决定你得出哪个结论。
- 思考是模型自己生成的 token:RL 让它学会在需要时多想,模式融合让同一个模型能想能不想,预算和力度决定想多久。
- 蒸馏让小模型直接学老师的整个分布,而不是自己摸索;在自己走出来的路上学(on-policy),才不怕推理时走偏。
- 做事就是多轮生成:模型写的 token 才训练,工具和环境的返回只是上下文,奖励来自环境里的那个「测试过没过」。
有不明白的? 随时在对话里问,问题会按课 ID 记到 05-问答记录/,真实提问会展开成新的岔路课。
深入这一章
每条都在 2026-09-26 实际打开核对过,写清它讲清了什么、对应哪一课、为什么推荐。外部链接都要联网;论文优先链本地 PDF。
🎮 想更直观 10–30 分钟
🔬 想吃透原理 1–3 小时
📄 想读原文 按需
排除了什么(也是筛选标准):① CSDN、知乎上大量「DPO vs PPO vs GRPO 完全指南」——同质化转载、只贴公式不讲动机,多数还把 GRPO 记成 R1 发明的;② 把「PPO → GRPO → RLVR」讲成一条砍法线的解读(包括本课程旧版)——混淆了优化器与奖励来源;③ 复述型的 R1 解读——多数不区分 v1(71.0%)与 Nature 版(77.9%)的数字;④ 只教调用 API 的 GRPO / DPO 速通教程——拿到的是参数表,拿不到「朴素方案为什么失败」;⑤ 李沐的 GRPO / R1 精读——多次检索未找到,不存在就不列。另注:OpenAI 的 o1 博客对脚本访问返回 403,第 6 课引用的数字经搜索结果核对,浏览器打开需联网。