上一章《RLHF 与 PPO》要装四个模型、调六个超参、跑一个随时可能崩的 RL 循环。 2023 年有人问了一个很尖的问题: 既然奖励函数可以从策略推出来,那为什么还要单独训一个? 把那一项代回去,整个 RL 循环就消失了。
这类「奖励 − β × 偏离度」的目标有现成的答案——不用迭代搜索,最优策略可以直接写出来:
中间的 ∝ 读作「正比于」:最优策略是参考模型的概率乘上 exp(r(x,y)/β),
再整体缩放到所有回答的概率加起来等于 1。缩放用的那个数记作 Z(x)——它只跟问题 x 有关,跟回答 y 无关。
接下来是那个关键的换位。把上式两边取对数、移项,奖励 r 就被解了出来:
奖励可以被「新策略和参考策略的对数概率比」精确表示出来。
多出来的那一项 β·log Z(x) 只跟问题 x 有关、跟回答 y 无关——
同一个问题的两个回答放在一起比较时,它会相减抵消。奖励模型就这样从损失里消失了。
尺子为什么可以不造?你要量的那个东西,本身就是用尺子的刻度定义的——
于是直接比较两个东西的相对长短就行。
这个类比管到相对高低为止:尺子量不出绝对好坏,DPO 学到的也是「谁比谁好」,不是一个能量绝对值的分数。
把这个 r 代回 Bradley-Terry 偏好损失(上一章写过:−log σ(r胜 − r负))——
同一个问题的两个回答共享同一个 x,两边共同的 β·log Z(x) 相减时抵消。
奖励模型没了,只剩一个二分类损失。整章的主公式长什么样、每一项管什么,下一节配着能拖的图拆。
对比 · 奖励模型是怎么被"删掉"的
上面那一行多出来的橙色盒子,就是整章要删掉的东西。
互动 · 把四个对数概率一起抬高,损失一动不动
下面这一块在按定义算 DPO 损失。定义两个量: Δ 是两个回答之间的隐式奖励差,而隐式奖励 = β × 对数概率比。
互动 · DPO 损失与更新力度(真实公式)
上面那行是活的:β 跟着第一根滑杆变,损失跟着第二根(Δ)变。把鼠标移到公式里的符号上,对应的滑杆会亮起来。
β 管拴绳的松紧。「要偏离多远」= Δ / β:β 越小,同样的 Δ 要求模型离参考模型越远—— β 小 = 绳松,模型容易过度自信。(β 不是学习率。)
Δ 管信号还在不在。损失是 −log σ(Δ),更新力度(梯度权重)σ(−Δ):Δ 很大(模型已经很确信)时它趋近 0, 这个样本就不再产生训练信号。而 DPO 的 Δ 可以无限增长——训练越久 Δ 越大,隐式奖励被「吹」得越高, 学到的东西并没有变多。
训练 DPO 时,你会看到一个非常熟悉的曲线形状: 训练集上的隐式奖励差一路飙升,但真实质量先涨后跌。 (图里那条「真实质量」是演示用的假想真值,真实训练里看不到,只能靠人工评测和留出的测试集去估。)
互动 · 拖着训练往前走,看两条曲线什么时候分岔(示意曲线,非实测数据)
DPO 里没有奖励模型,但它有一个隐式奖励——就是 β × 对数概率比。
训练不断把这个隐式奖励推高(因为损失在降),但偏好数据只覆盖了训练集里的样本分布。
当策略偏离分布之后,那些"没被标注过"的文本区域的隐式奖励就没有任何意义了。
上一章的 reward hacking 是奖励模型被钻了空子;这里没有奖励模型可钻,
是策略跑出了数据覆盖的范围,自己把分数推高。两者都表现为"奖励涨、质量跌",
但一个是代理错了,一个是分布错了。它只是在把自己越推越自信,而不是越推越正确。
三条常规做法:
① 早停——用一批留出的偏好数据算准确率,不再提升就停。
② 少跑几轮——DPO 通常 1~3 个 epoch 就够;跑到 10 个 epoch 往往开始过拟合(社区经验,没有硬界限)。
③ 换损失函数——IPO 就是为修这个问题设计的(见下面的谱系表)。
| 维度 | RLHF(PPO) | DPO |
|---|---|---|
| 需要奖励模型吗 | 需要,而且它本身要训练 | 不需要 |
| 需要在线采样吗 | 需要——每一轮都要用当前策略生成新样本 | 不需要——用现成的偏好数据直接训 |
| 要装几个模型 | 4 个(策略/参考/奖励/价值) | 2 个(策略/参考) |
| 要先做 SFT 吗 | 要——RLHF 的第一阶段就是它 | 要——实践中两份权重都从 SFT 后的模型出发(DPO 论文 §3) |
| 要调几个超参 | 六个(学习率、KL 系数 β、裁剪 ε、GAE 的平滑系数、batch 大小、优势归一化方式) | 主要只有学习率和 β |
| 实现复杂度 | 高——RL 循环、优势估计、裁剪、GAE(上一章算优势的那套) | 低——就是一个二分类损失的训练循环 |
| 稳定性 | 差——对超参极敏感,随时可能崩 | 好——和普通监督训练差不多 |
| 能否探索 | 能——策略可以生成训练数据里没有的回答 | 不能——DPO 是 off-policy(离策略:学的是固定的旧数据),只能在这些回答之间排序 |
| 理论上限 | 高(有探索、有在线反馈) | 受数据分布限制 |
| 适合什么任务 | 有可验证奖励的任务(数学、代码)——探索真正有价值 | 偏好类任务(写作风格、安全性、有用性)——数据已经够了 |
互动 · 显存里到底要装几个模型(fp16,以 7B 为例)
DPO 用「少两个模型、少一整套 RL 循环」换掉了「可能更高的上限」。 在工业界这笔交易通常划算——一个能稳定复现的 85 分,好过一个难以复现的 90 分。 反过来,如果任务的可验证性很强(比如数学题有标准答案),DPO 就吃不到「探索」的好处, 这时候在线方法(GRPO)会明显更强。
| 方法 | 核心损失 | 修了什么 |
|---|---|---|
| DPO 2023 |
−log σ(β·h) | 原始版本。简单有效,但会过度优化 |
| IPO 2023 |
(h − 1/(2β))² | 把 log-sigmoid 换成平方损失,给 h 一个明确的目标值。 从"越大越好"变成"达到某个值就好"——从根上消除过度优化 |
| KTO 2024 |
E[λy − v(x,y)] | 不再需要成对数据。E 表示对很多样本取平均;λy 是每个样本的权重: 好样本给 λD、坏样本给 λU(D = desirable,U = undesirable)。 它们来自前景理论的价值函数:行为经济学的发现,人对损失比对同样大的收益更敏感 (这个「价值函数」和 RLHF 的价值模型/critic 不是一回事)。于是"这条回答好"这种更便宜的数据也能用 |
| ORPO 2024 |
LSFT + λ·(−log σ(log 几率比)) | 把 SFT 和偏好学习合成一步,而且不需要参考模型。 这里「几率」= P(y|x)/(1−P(y|x)),λ 是偏好项的权重;训练成本再砍一半 |
| SimPO 2024 |
−log σ( β·(平均logπw − 平均logπl) − γ ) | 去掉参考模型,用长度归一化(平均对数概率)避免"越长越好"的偏差; γ 是要求胜者领先的最小间隔。省显存,效果常常更好 |
| CPO 2024 |
SFT + DPO 的联合目标 | 和 ORPO 思路接近,把两阶段压成一段 |
表里的 h 是对数比值差(§2 的 Δ ÷ β);IPO 的目标值 1/(2β) 是对它说的。
互动 · 两种损失的形状:一个没有底,一个有底
谱系图 · 每一条支线各删掉了什么
两条改进路线。一条把
前面几节把「奖励模型被消掉了」讲完了。消掉之后,一条偏好样本到底走哪几步? 四个对数概率进网络,出来就是一个数。下面把它摊开看。
互动 · 对数比值 → Δ → 损失(全部当场算)
互动 · 每个符号管图上的哪一块
动手验一下。把 β 拖到 0.02:Δ 被压扁,损失贴到 0.69(就是 ln 2)—— β 小 = 拴绳松:同样的对数比值只能换到更小的 Δ;要拿到同样的 Δ, 模型得比 β 大时跑得更远。 再把负者的对数比值拖到和胜者一样:Δ 归零,损失卡在 0.69—— 模型分不出谁更好时,损失就是抛硬币的那个值。
| 坑 | 具体表现 | 怎么缓解 |
|---|---|---|
| ① off-policy,学不到新东西 | DPO 只在"偏好数据里出现过的回答"上做对比。 如果数据里的 20 个回答都很平庸,模型就永远学不出那个没被写出来的更好的回答 | 提高偏好数据的覆盖度;或者混合一部分在线采样 |
| ② 对数据分布很敏感 | 成对数据里两个回答差距太大时,模型对胜者早就很确信、Δ 很大,更新力度 σ(−Δ) 接近 0, 这个样本几乎不再贡献信号;差距太小又噪声大 | 筛选"有信息量"的偏好对;这也是为什么数据质量比数量重要得多。量级参考:DPO 论文的对话实验用了 17 万条对话样本(每条含一对回答,DPO 论文 §6),本页代码里的 ultrafeedback_binarized 约 6.2 万条训练对, 都够用,不是越多越好 |
| ③ 过度优化 | 隐式奖励被一路推高,真实质量先升后降 | 早停;1~3 个 epoch;换 IPO / CPO 这类有目标的损失 |
| ④ 长度偏差 | DPO 会倾向于生成更长的回答——因为"更长"在隐式奖励上通常占便宜, 而人类也倾向于给长回答打高分 | SimPO 的长度归一化;或者在数据里做长度平衡 |
互动 · 长度偏差:奖励的尺度会跟着长度一起涨
DPO 训练时参考模型 πref 是冻结的,但它的对数概率每次都要重算一遍——
这意味着参考模型的前向传播必须跑,显存和时间都省不掉。
很多人以为"DPO 不用 RL 所以很轻",结果发现只能省掉一个奖励模型,
参考模型还得好端端放在显存里。SimPO / ORPO 去掉参考模型,才是真正省显存的那一步。
| 场景 | 建议 | 为什么 |
|---|---|---|
| 有可验证奖励 数学、代码、格式约束 |
GRPO / PPO | 不用训奖励模型,对错是程序判的。 而且在线采样能让模型探索出数据里没有的解法——这正是推理模型的训练方式 |
| 只有主观偏好 写作风格、语气、安全性 |
DPO / SimPO | 偏好数据已经够用,没必要引入 RL 的不稳定性 |
| 需要探索新策略 | PPO / GRPO | DPO 只能模仿数据里已有的回答,无法"发现"更好的 |
| 算力/人手有限 | DPO / ORPO | 实现简单、稳定、能复现。工程可控性在这里比理论上限重要 |
对比 · 在线能撞见新的更好的回答,离线只能在已有的里面排序
这就是为什么推理模型(数学、代码)在 2024 年后又回到了在线 RL。
决策图 · 这一章什么时候不该用
两条线并存,各管一段:通用
所以"DPO 取代了 RLHF"这个说法不准确——它取代的是 RLHF 里的偏好对齐那一半,
而 RL 那一半在推理模型时代反而更重要了。
这一章公式很多,但它只属于七条线里的一条。看懂那一行,后面的推导都只是细节。
回到第 3 节那张过度优化图。把「训练步数」滑块往右拖到 800~1200—— 你会看到“训练集隐式奖励”一路涨,而“真实质量”在某个点之后开始掉。
那个分岔的瞬间,你看到的就是“用排序代替搜索”的代价: 模型把那个被写死的偏好假设(“胜者分数更高”)越推越极端,而它并没有变得更符合你真正想要的。
| 线 | 为什么这章不是它 |
|---|---|
| ① 表达力 vs 泛化 | DPO 不改变策略能表达什么,它只改变拿什么信号去训 |
| ② 没有免费午餐 | ✅ 这章真正的位置:把一个假设用来消掉奖励函数,就必须接受那个假设不成立时的后果——过度优化就是后果本身 |
| ③ 规模会赢 | 沾边——DPO 让偏好对齐便宜到小团队也做得起,但它不是“规模”现象 |
| ④ 学习即压缩 | 不涉及 |
| ⑤ 高维里的低维 | 不涉及 |
| ⑥ 层层组合 | 不涉及——DPO 不搭特征、不叠层,它换的是训练信号 |
| ⑦ 拧得动 | 沾边——损失还是一个光滑的二分类损失,梯度照样拧得动; DPO 只是把奖励从一个单独要训的模型,搬进了策略自己的概率里 |
| 暗线 | 这一章的回答 |
|---|---|
| A 信息流动 | 数据形状:一条偏好样本 = 提示 x + 一对回答(y胜, y负);
过 πθ 和 πref 各得到 4 个对数概率,
两两相减 → 1 个标量 Δ → 过 σ → 1 个标量损失。整条链路最后塌成一个数;
反向传播只更新 πθ,πref 全程冻结 |
| B 什么被牺牲了 | 换稳定,牺牲探索:on-policy 的 RL 每轮会重新采样、可能发现新解法; DPO 的数据集一旦固定,模型就只能在这批回答里学排序。 这就是“推理模型时代 RL 又重新变重要”的根本原因 |
| C 参数账本 | 按 fp16 权重 + fp16 优化器状态的口径(以 7B 模型为例):训练时要同时驻留 策略 + 参考模型两份权重,
fp16 下每份 ≈ 14 GB,两份 ≈ 28 GB;再加梯度(14 GB)和 Adam 状态(策略权重的 2 份,≈ 28 GB),
光这四项就约 70 GB,还没算 |
| D 跑在什么上 | DPO 的训练是成批的大矩阵乘,GPU 算得快、等数据少(算力受限,不是带宽受限)。 最贵的固定动作是「每个样本算两遍前向」——policy 一遍、reference 一遍, 这笔开销跟模型大小成正比、省不掉。完整账在 《硬件与算力账本》 |
| E 它假设了什么 | 假设偏好可以被一个标量奖励、用 Bradley-Terry 两两比较表示出来 (即偏好可传递、且由单一分数诱导);还假设“好回答”离参考模型不会太远(KL 约束)。 这两个都不是世界的性质,而是人的选择——它们不成立时,DPO 学到的就是错的东西 |
| F 违背了哪个直觉 | 直觉是“要优化一个奖励,先得有个奖励”。DPO 说:奖励早就藏在策略里了,
你只需要把策略和参考模型的概率比读出来。 第二个反直觉:“更弱的算法”有时更好——在有限偏好数据上, 放弃探索反而让结果更稳、更可复现 |
它接住了上一章的什么:《RLHF 与 PPO》摆了四个模型和一个 RL 循环, 这一章删掉奖励模型和价值模型,只留下“策略”和“参考”两份权重。
它给下一章留了什么:DPO 只能在数据里已有的回答之间排序;任务有标准答案时,排序就浪费了模型的探索能力。 → 下一章 《RLVR 与 GRPO》把 RL 请回来。 想便宜、不动全部参数?→ 更后面的 《LoRA 与高效微调》。
DPO 的整个推导只有一步:把最优策略里那个奖励函数 r 反解出来,代回偏好损失——
于是奖励模型消失了,剩下一个纯粹的对比学习目标。
它的代价是从 on-policy(在线采样)变成了 off-policy(固定数据):
学不到偏好数据里没出现过的回答,用理论上的探索能力换来了工程上的稳定。
它的著名失败模式是过度优化——隐式奖励一路涨,真实质量先升后降;
修法是早停,或者换成 IPO 这种"有目标值"的损失。
后续所有变体(ORPO / SimPO)都在做同一件事:继续删模型——先删奖励模型,再删参考模型。
上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。
上面讲的推导,工业界在用的是什么样子?TRL 里训一个 DPO 就是下面二十来行。
你在第 2 节拖的那根 β 滑杆,在代码里就是 beta;参考模型在代码里是 ref_model(就是第 4 节显存图里那根紫色柱)。