← 返回首页
06_posttraining_viz.html

Phase 2 开篇 · 后训练白皮书

Phase 1 练出来的是一台只会续写底座模型。 这一页是 Phase 2 的地图与术语对齐:从"会续写"到"会听话"要经过哪几步、有哪两个容易混的轴、 SFT 到底改了什么、 偏好对齐里 RLHF 和 DPO 是什么关系。先建立全景,再去写代码。

STEP 1
你练出来的底座
STEP 2
后训练地图
STEP 3
任务 × 手段
STEP 4
SFT 机制
STEP 5
偏好对齐
STEP 6
路线图 & 达标
这一关 底座 GPT-2 124M 参数量/脑容量 训练数据 10B token 读过多少书 语言 英文 base 只见过英文 目标 会听话答题 SFT 起步

① 你练出来的,是一台"底座":两个独立的数字

描述一个模型,先分清两个各管各、互不替代的数字:参数量(模型多大 / 脑容量)和 训练数据量(喂了多少 token / 读过多少书)。点下面任一行,看它在两个轴上的位置。

轴一参数量 · 模型有多大
轴二训练数据 · 喂了多少 token
你的模型 = 参数量 124M(GPT-2 small 配置)× 训练数据 10B token(FineWeb-Edu)。 这两个数字一个量"脑子多大",一个量"读过多少书",不能互相换算、也不能合成一个数
身份这台底座现在会 / 不会什么
✅ 会:顺着上文续写 ❌ 不会:听指令答题 ❌ 不会:主动停下(不知道何时该收尾) 🌐 只会:英文(语料全英文)

base 模型的本性就是 "预训练= 学会把话说得像"。让它"说得对、答得上、该停就停",是 Phase 2 要补的课。

↳ 下一步:从"会续写"到"会听话",中间要经过哪几道工序?看后训练地图。

② 后训练地图:预训练 → SFT → 偏好对齐

现代大模型是一条流水线下来的。你现在站在第一段的终点。点每一段,看它用什么数据、把模型改成什么样

你在这
STAGE 1
预训练 Pre-training
海量纯文本,学"预测下一个 token"。产出 = 只会续写的 base。
STAGE 2
SFT 监督微调
「指令→回答」成对数据,教它听指令、按格式答、答完就停。
STAGE 3
偏好对齐
人类偏好(A 比 B 好),把回答调得更合口味、更安全。
三段是叠加,不是替换。SFT 在预训练的权重上继续调,偏好对齐又在 SFT 的基础上继续调 —— 后一段都站在前一段的肩膀上。本项目 Phase 2 做第 2、3 段
↳ 下一步:同样是"微调",为什么有人说"全量",有人说"LoRA"?那是另一个轴。

③ 别混:"任务"和"手段"是两个正交的轴

任务(教什么:SFT / 偏好对齐)和手段(怎么改权重:全量微调 / LoRA)是两件独立的事。 任何一个任务,都能用任意一种手段去做。点格子看每种组合是什么。

全量微调
更新所有参数
LoRA / PEFT
只更新旁挂小矩阵
SFT
全量 SFT
改全部权重学答题
06_sft.py
LoRA SFT
冻主干,旁路学答题
07_lora.py
偏好对齐
DPO
全量 DPO
改全部权重学偏好
08_dpo.py
LoRA DPO
旁路学偏好
08_dpo.py
看这张表就懂两件事:① "全量微调"只是一整列(一种手段),它能做 SFT 也能做 DPO —— 所以"全量微调 = SFT"是把手段误当成了任务。② "全量 vs LoRA"是同一件事换种省钱方式, 不是先后步骤,而是二选一。
那为什么本项目先"手写 LoRA",而不是先讲 SFT?
概念顺序是 SFT 在前(它是目标),LoRA 在后(它是省钱手段)。但动手顺序里, SFT 的训练循环几乎等于 Phase 1 的预训练循环,没有新机制;真正值得像手搓 attention 那样 手搓的新零件是 LoRA 的低秩旁路。所以白皮书按"先懂 SFT、再懂 LoRA"讲, 脚本则把 LoRA 当成动手重点。
↳ 下一步:SFT 到底改了什么?其实只在预训练的 loss 上动了三处。

④ SFT 机制:同一个 loss,只动三处

SFT 和预训练用的是同一个交叉熵(预测下一个 token),没有新数学。 改动只有三处:① 数据换成「指令→回答」对、② 套对话模板并在结尾放 EOS、③ loss 只算回答那一段。 下面把整条样本拼出来,拨一下"loss 算在哪些 token 上"。

灰底 = 指令/模板(prompt) 橙底 = 回答(response) ↑ 边框高亮 = 这个 token 算进 loss × = 标成 -100 不算

✅ 只算回答(标准做法)

模型学的是"给定这条指令,该怎么回答"。prompt 段标成 -100 被忽略,梯度只来自回答。

⚠️ 连指令也算(跑偏)

模型还会去学"怎么生成用户的指令",注意力被带偏,答题质量下降。所以 prompt 一定要 mask。
对照预训练 vs SFT:只有两行不一样

预训练

loss:交叉熵 · 算 loss 的位置:每个 token · 数据:连续纯文本 · 学习率:较大

SFT

loss:完全一样 · 算 loss 的位置:只回答段 · 数据:指令→回答对+模板 · 学习率:小 1~2 个量级
结尾那个 EOS 为什么重要?
base 模型的老毛病是不会停,会一直往下续写。SFT 在每条回答末尾放一个 <EOS>(结束标记)并让它算进 loss,就是在教模型"答完就输出 EOS、然后停"。 没有这一步,模型答完正事还会继续瞎扯。
↳ 下一步:SFT 教会"能答",但答得"合不合人意"靠偏好对齐 —— RLHF 和 DPO 是什么关系?

⑤ 偏好对齐:同一个目标,两条不同的路

"偏好对齐"是目标(让回答更合人类口味),实现它有两条路。它们共享数据(都用"A 比 B 好"的人类偏好), 但手段不同。点下面切换看两条路。

关键澄清:DPO 不是 PPO 的变体或衍生版,它俩是实现"偏好对齐"的两条平行路线 —— RLHF 走真强化学习(PPO), DPO 不走 RL(直接在偏好对上做类监督损失)。DPO 的卖点正是"不用 RL 那套笨重机器,也能拿到 RLHF 的效果"。
本项目的取舍:偏好对齐只做 DPO(轻、单机能跑、覆盖教学目标);RLHF / PPO 只在白皮书里讲清原理, 不写成脚本 —— 它要额外训奖励模型 + 在线采样,工程量数倍,对"理解偏好对齐"边际收益低。
↳ 下一步:这些都落到几个脚本里?用哪个底座?训成什么样算达标?

⑥ Phase 2 路线图 · 底座 · 达标标准

把前面的概念落到三个脚本。每个脚本对应一个值得手搓的新机制,合起来覆盖"任务 × 手段"那张表。

06_sft.py
全量 SFT
新机制:对话模板 / EOS / loss mask。在 124M 上跑通"会答题"。
规划中
07_lora.py
手搓 LoRA + LoRA SFT
新机制:低秩 A·B 旁路、冻结主干。只训 ~1% 参数拿到同款效果。
规划中
08_dpo.py
DPO(全量 / LoRA 开关)
新机制:偏好对比损失。一个文件覆盖全量 DPO 和 LoRA DPO。
规划中
底座沿用 124M,不往上加。 目标是"看懂机制 + 看到行为变化",124M 完全够演示; 放大只增加成本、不增加新知识点。(注意:124M 是英文玩具级,SFT 后是"像在答题"而非能真聊天; 想要能中文对话的助手是另一条线,得换含中文的开源底座。)
达标训成什么样算到位(玩具级 · 看行为,不刷榜)
Q&A开工前的常见疑问
"参数量 124M"和"训练数据 10B"到底哪个是模型大小?
参数量 124M 才是模型大小(脑容量),10B 是喂进去的 token 数(读过多少书)。两个数字各管各: 同样 124M 的模型,喂 0.3B 和喂 10B,脑子一样大,但后者"读得多、说得好"。它们不能互相换算。
全量微调和 LoRA,是要先做一个再做另一个吗?
不是先后,是二选一:做某一次微调,要么全量、要么 LoRA。本项目两个都写,纯粹是为了对照着学 (看 LoRA 怎么用 ~1% 参数逼近全量效果),不是流程上必须先全量再 LoRA。
偏好对齐就是强化学习吗?DPO 算 RL 吗?
偏好对齐是目标,不等于 RL。实现它有两条路:RLHF 走 RL(PPO),DPO 不走 RL(直接在偏好对上做类监督损失)。 所以 DPO 不算强化学习,也不是 PPO 的变体,而是绕开 RL 的另一条路。
SFT 之后,这个 124M 能跟我聊天了吗?
能"像在答题",但别期待真能基础沟通。124M 是非常小的模型,且只见过英文。SFT 让它学会答题的格式与姿态, 产出是玩具级。要一个能流畅对话(尤其中文)的助手,得换更大、且预训练含中文的开源底座 —— 那是另一条线。
🎉 Phase 2 地图已对齐
你已经分清:参数量 vs 数据量 · 任务 vs 手段 · SFT 改了哪三处 · RLHF vs DPO。接下来就是 06_sft.py 动手。