对齐
第 11 课:对齐
上一课我们把基座训成了"会听话的助手",但它只是照着示范说话,并不知道哪个回答更好——SFT(监督微调)的极限就在这里。这一课讲清"对齐"这条线:为什么照着示范学教不了取舍、偏好怎么变成能求导的数字、为什么不直接最大化奖励、PPO(用强化学习按人类偏好小步调模型)贵在哪、DPO(把成对偏好数据当分类问题来训)怎么把强化学习换成一次分类、GRPO(不训练价值模型、改用同一题多次采样的平均分当基线)又为什么能把 critic(专门预测"这么答下去能得多少分"的价值模型)删掉。
② 手推 DPO 的分类损失,并解释 Z(x) 为什么会自动消失
③ 会算 PPO/GRPO/DPO 三者的显存账,并给出选型判据
上一张卡片我们把 SFT 跑完了:模型学会了"把输入当任务执行"。但它只学会了照着示范说话——示范里没有的信息,它学不到。所以问它"帮我写封道歉邮件",它能写出一个像样的邮件,但同一封邮件写成热情一点还是克制一点更好?它无从判断。
因为SFT 的损失函数要求每条样本里存在一个"正确输出"(即那条被写下来的示范),所以它只能表达"照这个写",表达不了"这两个里哪个更好"。可以把这类比成临摹字帖:临摹能让你写得像,但字帖不会告诉你"这幅作品比那幅好",因为它只给了你一幅。
| 对比项 | SFT(示范) | 对齐(比较) |
|---|---|---|
| 一条数据是什么 | 1 个问题 + 1 个示范答案 | 1 个问题 + 若干候选 + 人类排序 |
| 损失在拟合什么 | 这一条示范的分布 | "哪个更好"的相对关系 |
| 能否表达取舍 | 不能(只有一个正样本) | 能(同题候选互为参照物) |
| 量 | 数值 | 说明 |
|---|---|---|
| 奖励模型的 prompt 数 | 约 33,000 条 | InstructGPT 论文 |
| 每个 prompt 的候选数 K | 4 ~ 9 | 同一 prompt 采多次 |
| K=4 时的两两比较对 | C(4,2) = 6 对 | 组合数 |
| K=9 时的两两比较对 | C(9,2) = 36 对 | 组合数 |
| 这批 prompt 的总比较对 | 约 19.8 万 ~ 118.8 万 对 | 33,000 × 6 与 33,000 × 36 |
| 要训练的行为 | 示范能教吗 | 比较能教吗 |
|---|---|---|
| 格式与语气(要有小标题) | 能(示范里有) | 能 |
| 事实与推理(答案对错) | 能(示范里有) | 能 |
| 得体、安全、取舍(哪个更好) | 不能(没有唯一正确答案) | 能 |
SFT 与对齐的分界不是"数据多少",而是数据形状:SFT 学的是"应该长这样"(绝对),对齐学的是"这个比那个好"(相对)。因为"有用、无害、得体"这些标准没有唯一正确答案,所以只能用比较来表达——这就是为什么 SFT 之后必须再走一步。
上一张卡片我们确认了:SFT 只会照着示范写、教不了取舍,所以对齐必须用「成对比较」当训练信号。但这里藏着一个一直被默认的前提——这些比较,究竟是谁做的?
因为训练信号的质量上限由标注者的判断决定,所以「谁来当人类」直接决定了整条流水线的成本、可扩展性与偏差来源。可以把这类比成请阅卷老师:请真人逐份判卷又贵又慢,请一个 AI 判卷又快又省,但这位 AI 老师的口味一旦有偏,会原样传给学生。
纯人工路线为什么不可扩展?InstructGPT 的偏好数据是约 33,000 个 prompt、每个 prompt 采 4~9 个候选——按上一张卡片的算法,一轮就要 19.8 万 ~ 118.8 万次人工比较;而偏好对齐往往要反复迭代,跑到第 10 轮就是 198 万 ~ 1,188 万次。人需要培训、会疲劳、产能有硬上限,加钱也快不了——这正是「把裁判换成 AI」的直接动机。
| 量 | 符号 | 取值 |
|---|---|---|
| 被选中的回答的分数 | rw | 1.2 |
| 被拒绝的回答的分数 | rl | 0.4 |
| 分数差 | rw − rl | 1.2 − 0.4 = 0.8 |
| 人类选胜者的概率 | P = σ(0.8) | 0.690 |
| 这条样本的损失 | −ln σ(0.8) | 0.371 |
| 方法 | 谁当裁判 | 偏好数据怎么来 | 关键读数 |
|---|---|---|---|
| RLAIF(用 AI 代替人类做偏好标注,再据此做强化学习) | 一个现成的大模型 | 给它「文本 + 两个候选」,让它输出更喜欢的那个 | 摘要任务上,人类对 RLAIF 与 RLHF 的胜率为 71% / 73%,两者直接对比的胜率是 50%(无显著差异) |
| Constitutional AI(让模型按一份原则清单自我批评、再改写的方法) | 模型自己 + 一部「宪法」(一组写给模型的行为原则) | 先让模型自评自改生成示范,再用 AI 偏好训奖励模型 | 不依赖任何「有害输出」的人工标签即可训出无害助手 |
| 维度 | 人类标注 | AI 反馈(RLAIF / Constitutional AI) |
|---|---|---|
| 标注成本 | 高(按条或按小时付酬) | 低(按 token 付推理费) |
| 可扩展性 | 受限(人要培训、会疲劳、有产能上限) | 高(加机器即可并行,规模近乎线性) |
| 偏差来源 | 标注者的口味、疲劳与分歧 | 判官模型自身的偏差(位置、长度、自我偏好),且会被继承并放大 |
| 适用场景 | 主观、高风险、真正需要人类判断的取舍 | 可规模化、评判标准清晰、或需要迭代自评的场景 |
| 路线 | 单价(示意) | 10,000 对的总额 |
|---|---|---|
| 人类标注 | $0.67 / 对(行业报价区间约 $0.30 ~ $0.67) | 10,000 × 0.67 = $6,700 |
| AI 反馈 | 每次判断读约 1,200 token、写约 10 token;示意价 输入 $3 / 百万 token、输出 $15 / 百万 token | 1,200 ÷ 106 × 3 + 10 ÷ 106 × 15 = $0.00375 / 对 → 10,000 × 0.00375 = $37.5 |
| 倍数 | 6,700 ÷ 37.5 ≈ 179 倍 | |
偏好数据从哪来,直接决定三件事:成本(人按条付费 vs AI 按 token 付费)、可扩展性(人要培训排期 vs 加机器)、偏差来源(标注者的口味 vs 判官模型的口味)。把裁判从人换成 AI 并没有取消偏差,只是把「人监督」换成了「模型监督」:判官的位置偏差、长度偏好与自我偏好会被写进偏好数据,再经奖励模型放大——这就是「谁来监督监督者」的问题。它在无害性任务上甚至能反过来占优(AI 裁判不会像人那样久读有害内容而疲劳),但在判官自己分辨不了的细粒度取舍上,被继承的偏差就是训练信号里的噪声。
上一张卡片我们得到了一个可求导的奖励。那最直接的做法就是把它最大化——但这里有个陷阱。为什么?
因为奖励模型只在那 33,000 个 prompt 附近见过数据,策略一旦被推到没见过的区域,它给出的分数只是外推,可能一路虚高。所以必须用 KL 惩罚把策略拴在 SFT 模型附近。可以把这类比成按一个不完美的评分表排练:你把评分表的每一条都做到极致,最后拿到高分,但评委(真实人类)看的是另一套标准。
换句话说,「直接最大化」就等于把 KL 系数 β 设成 0:Gao 等的实验显示,真实奖励在优化强度越过拐点(示例中 d ≈ 2.718)后掉头向下,而代理奖励还在往上爬——这正是「分数涨了、人却更不满意」的量化形态。
| 项 | 含义 |
|---|---|
| d | 策略相对初始策略的 KL 距离的平方根 √DKL(单位 √nat,其中 nat = 自然对数单位、1 nat ≈ 1.44 bit)——原论文为把曲线写成 d 的简单形式,刻意用 KL 的平方根作图,不是 KL 本身 |
| R(d) = d(a − b ln d) | 真实(金标准)奖励随优化强度的变化 |
| a = 1、b = 0.5 | 示意参数——原论文把这两个系数写作 α、β,它们由奖励模型规模与数据量拟合得到;为避免与 KL 系数 β 混淆,本课记作 a、b |
| d = √KL(√nat) | R = d(1 − 0.5 ln d) | 方向 |
|---|---|---|
| 0.5 | 0.673 | 上升 |
| 1.0 | 1.000 | 上升 |
| 2.0 | 1.307 | 上升 |
| 2.718 | 1.359 | 峰值 |
| 5.0 | 0.976 | 下降 |
| 7.389 | 0.000 | 降到 0 |
| 10.0 | −1.513 | 已为负 |
| 证据 | 读数 | 来源 |
|---|---|---|
| Gao 等的结论 | 真实奖励先升后降,代理奖励持续上升 | arXiv:2210.10760 |
| KL 惩罚是否治本 | 不治本,只是延后——β 的选取基本靠经验 | InstructGPT(β = 0.02) |
| 前沿模型的作弊比例 | 某基准套件上 o3 有 30.4% 的 run 出现奖励作弊 | METR 报告:RE-Bench 子集 39/128 = 30.4%(2025-06-05) |
RLHF 的目标不是"奖励最大化",而是"在离 SFT 模型不太远的约束下最大化奖励"。KL 惩罚系数的意义就在这里:它把优化强度 d 限制在峰值(示例中 d ≈ 2.7 √nat)以内。因为奖励模型只是代理,优化得越狠就越是在拟合它的外推误差——所以"奖励涨了"和"变好了"是两件事,必须分开看。
上一张卡片说明了必须有 KL 惩罚。加上它之后,RLHF 第三段同时要跑四样东西——这就是它贵的原因。
因为critic 要预测"未来回报",它的规模必须和策略相当,所以这一步的显存不是"一个模型加一点开销",而是"两个大模型都在训练态"。可以把这类比成同时开着四台机器:一台在学(策略)、一台在打分(奖励)、一台做参照(参考模型)、一台在预测未来(critic)——后三台都得一直通电。
更早的做法是不用 critic、直接拿原始回报更新(策略梯度 / REINFORCE 一类):同一题采 8 条回答,回报可能是 0、1、1、0……,样本均值本身就在抖,直接拿它当信号会把这个抖动放大成高方差梯度,训练来回震荡、收敛很慢;critic 的作用正是提供一个「基线」,把回报减去它来降方差——代价就是多养一个与策略同规模的模型。
| 角色 | 作用 | 是否训练态 |
|---|---|---|
| 策略(policy) | 被优化的模型 | 是 |
| 参考(reference) | 算 KL 惩罚的锚点 | 否(冻结、只前向) |
| 奖励(reward) | 给回答打分 | 否(已训好、只前向) |
| critic(价值模型) | 估计未来回报当基线 | 是 |
| 项 | 每参数字节 | 7B 合计 |
|---|---|---|
| bf16 权重(单个模型) | 2 | 14.0 GB |
| 混合精度训练态(权重 2 + 梯度 2 + fp32 主权重 4 + Adam m 4 + Adam v 4) | 16 | 112.0 GB |
| 参考 + 奖励两个只前向的模型(策略的 bf16 权重已含在上一行的训练态里,不重复计) | 2 × 2 | 28.0 GB |
| 方案 | 同时在场的模型 | 模型状态合计(7B 量级) |
|---|---|---|
| PPO | 策略 + critic + 参考 + 奖励 | 16 + 16 + 2 + 2 = 36 字节/参数 → 252 GB |
| GRPO | 删掉 critic | 16 + 2 + 2 = 20 → 140 GB |
| DPO | 只有策略 + 参考 | 16 + 2 = 18 → 126 GB |
"贵"的根源不是某一个模型大,而是同类模型被复制了多份、且其中两份都在训练态。critic 之所以是首要下刀对象,是因为它与策略同规模、又要付完整的训练态开销(示例里占 16/36 = 44%)。看懂这张账,才能理解下一张卡片为什么能"把 RL 换成分类"——那等于一次砍掉 critic 与奖励模型两个模型(4 → 2)。
上一张卡片我们看到 PPO 要同时装四个模型。那能不能把强化学习整个拿掉?——DPO 的答案是能,靠一次代数替换。
因为加了 KL 约束的最优化问题有解析解,所以可以先把"最优策略长什么样"写出来,再反解出奖励。于是奖励不再需要一个独立网络,它藏在策略自己的概率里。可以把这类比成解方程:与其迭代逼近(RL 采样试错),不如先把方程解出来——解的形式告诉你答案长什么样。
更自然的做法是继续用 PPO——四个模型驻留(7B 量级约 252 GB)、每轮都要在线采样。DPO 的取舍是把它离线化:只用一份固定的成对偏好数据做分类,模型从 4 个降到 2 个(约 126 GB),代价是失去「从当前策略再采样、发现数据里没有的好答案」的能力。
| 符号 | 含义 |
|---|---|
| πref | 参考策略(就是 SFT 模型,冻结) |
| r(x, y) | 奖励函数 |
| β | KL 惩罚系数(与上一张卡片的 β 同源) |
| π*(y|x) = πref(y|x)·er(x,y)/β / Z(x) | 最优策略:奖励高的回答按指数加权 |
| Z(x) = Σy πref(y|x)·er(x,y)/β | 归一化项(normalization,即配分函数)——正是它让计算不可行 |
| 步骤 | 结果 |
|---|---|
| 对闭式解两边取对数再整理 | r(x, y) = β·ln(πθ(y|x) / πref(y|x)) + β·ln Z(x) |
| 这一项叫什么 | 隐式奖励——策略本身就是奖励模型 |
| 代入 Bradley-Terry:P(胜) = σ(rw − rl) | 两个 β·ln Z(x) 都是同一个 x 的项,相减时抵消 |
| 最终损失 | L = −ln σ( β·ln(πθ(yw)/πref(yw)) − β·ln(πθ(yl)/πref(yl)) ) |
| 量 | 被选中的回答 yw | 被拒绝的回答 yl |
|---|---|---|
| 策略对数概率 ln πθ(y|x) | −20.0 | −18.0 |
| 参考对数概率 ln πref(y|x) | −23.2 | −17.0 |
| 对数比(策略 − 参考) | −20.0 − (−23.2) = +3.2 | −18.0 − (−17.0) = −1.0 |
| 取 β = 0.1 后的差值 Δ | 0.1 × (3.2 − (−1.0)) = 0.42 | |
| σ(Δ) 与损失 | σ(0.42) = 0.603,L = −ln 0.603 = 0.505 | |
| β | 差值 β×4.2 | σ(Δ) | 损失 |
|---|---|---|---|
| 0.1 | 0.42 | 0.603 | 0.505 |
| 1.0 | 4.20 | 0.985 | 0.015 |
DPO 的本质是一次代数替换,而不是一个新算法:闭式解 → 反解奖励 → 归一化项在成对差值中抵消。代价也很明确:它只在固定偏好数据上做离线分类,不再从当前策略采样、也就不再探索;而 RL 能在训练中不断生成新样本、发现数据里没有的好答案。"省掉三个模型"换的是"失去在线探索"。
上一张卡片我们看到 DPO 省了模型,但代价是失去探索。所以需要探索的场景仍要走 RL——那能不能既保留在线采样、又不要 critic?
因为critic 的职责只是提供一个"基线"(把回报减去一个参照以减少方差),所以如果同一个问题有多个候选,就用这些候选的平均分当基线即可。可以把这类比成考试排名:不知道分数线是多少,但同一张卷子考了 4 个人,谁高于平均分一目了然——你不需要额外请一位"预言家"来预测分数线。
更早的 PPO 为什么要单独养一个 critic?因为它只能逐位置预测「这么答下去能得多少分」,这个预测越准、基线越好——于是 critic 被迫长得和策略一样大,开销并不小:上一张卡片的账里,critic 占了 16/36 = 44% 的训练态开销。GRPO 的洞见是:同一个 prompt 一次采一组回答,「组内平均分」本身就是现成的基线,何必再训一个模型去猜它。
| 第 i 个回答 | 奖励 ri | ri − 均值 | ÷ 标准差 = 优势 Ai |
|---|---|---|---|
| 1 | 1(对) | +0.5 | +1.0 |
| 2 | 0(错) | −0.5 | −1.0 |
| 3 | 1(对) | +0.5 | +1.0 |
| 4 | 0(错) | −0.5 | −1.0 |
| 组内奖励分布 | 标准差 | 全部优势 | 这条 prompt 的梯度 |
|---|---|---|---|
| 2 对 2 错(上表) | 0.5 | +1 / −1 | 正常,有效 |
| 4 对 0 错 | 0 | 全为 0 | 零梯度(白跑一次前向) |
| 0 对 4 错 | 0 | 全为 0 | 零梯度(且失去"这题太难"的信号) |
| 做法 | 重要性比率的定义 | 一条 500 token 回答的数值示例 |
|---|---|---|
| GRPO(token 级) | wi,t = πθ(yi,t)/πold(yi,t) | 单 token 比率可达 1.5(示意:某个偏离最大的 token;噪声大、逐个裁剪) |
| GSPO(序列级) | si = (πθ(yi)/πold(yi))1/|yi| | 1.51/500 = 1.00081(偏离 1 的幅度从 0.5 压到 8.1×10⁻⁴,即 10⁻¹ 量级 → 10⁻³ 量级) |
去掉 critic 的代价不是"精度变差",而是基线的可靠性变成了一个统计问题:组内方差为 0 时,组相对优势完全失效(同组全对/全错 → 零梯度)。所以这条线的演进都在回答两个问题——怎么让基线更稳(GSPO 的序列级比率、SAPO 的平滑门控)、怎么不浪费批次(DAPO 的动态采样)。选型判据可以浓缩成三问:奖励可验证吗?需要在线探索吗?显存够装几个模型?