DPO 直接偏好优化(Direct Preference Optimization)
所属:01-fundamentals / 02-post-training
面试权重:★★★
来源:通用领域知识;未做一手考证
相关项目:Own — Writing Copilot(DPO → GRPO 两阶段对齐的第一阶段,用于压制过度拒答)、HKGAI LLM(SFT + DPO 两阶段)→ 见02-interview/projects/writing-copilot.md、hkgai-llm.md
一句话#
DPO 发现:带 KL 约束的 RLHF 目标存在闭式最优解,把这个解代回偏好模型后,奖励项可以被「策略相对于参考模型的 log 概率比」完整替代 —— 于是奖励模型被彻底消掉,整个 RL 问题塌缩成一个在偏好对上的二分类损失(对 chosen 提高相对概率、对 rejected 压低相对概率)。
为什么重要(面试角度)#
DPO 是当下最常用的对齐算法,几乎必问,而且追问一定会到数学直觉这一层:
- 「为什么可以没有 reward model」如果答成「因为 DPO 更简单」,等于没答。
- 面试官真正想看的是你能不能说出 Z(x) 在配对差分里被约掉 这个关键点 —— 这是整个推导的枢纽。
β的作用、reference model 的作用、以及 DPO 的失效模式(likelihood displacement / 长度偏置) 是区分「跑过 DPO」和「理解 DPO」的分水岭。- Writing Copilot 项目里「为什么先 DPO 再 GRPO」这个顺序,只有理解了 DPO 的离线性质才能讲透。
核心内容#
从 RLHF 到 DPO:三步推导#
第一步:写清楚 RLHF 在优化什么。 带 KL 约束的目标是
也就是「最大化奖励,但别离参考模型太远」, 就是这个约束的强度。
第二步:这个目标有闭式最优解。 对每个 prompt 分别求解(变分法),最优策略是
直觉:最优策略就是在参考模型的基础上,按「奖励有多高」做指数加权的重加权。奖励高的回答被抬高,奖励低的被压低, 控制这个抬压的陡峭程度。
第三步:把 反解出来,代进偏好模型。 上式两边取对数整理,得
注意: 只依赖 ,与 无关。现在套用 Bradley-Terry 偏好模型
把 的表达式代入,两项 相减时被完全约掉,而 正是那个不可计算的配分函数 —— 它消失了,这正是 DPO 能成立的全部秘密。于是:
第四步(最后的形态): 用负对数似然定义损失,得到 DPO 的最终目标:
这就是全部。 没有 reward model,没有 RL 循环,没有采样 —— 一个普通的、可直接用梯度下降优化的分类式损失。
为什么不需要奖励模型#
因为奖励被「隐式」地参数化在策略自身里了:
DPO 原论文里那句常被引用的话就是这个意思:你的语言模型其实本身就是一个 reward model。训练中,模型提高某条回答相对参考模型的概率,等价于在说「这条回答的隐式奖励更高」。
三个必须说清的推论:
- 不需要单独训 reward model,也不需要它常驻显存 —— 这是显存与工程复杂度的直接下降。
- 不需要在线采样(rollout),直接在固定的偏好数据集上做离线优化 —— 这是时间成本与稳定性的直接下降(没有 RL 循环、没有价值模型、没有重要性采样)。
- reference model 依然必须在场。它定义了隐式奖励的「原点」: 是相对于 ref 的对数比。没有 ref,这个比值无从定义,约束也就消失了。
β 的角色(以及一个容易踩的口径坑)#
就是把 RLHF 目标里那个 KL 系数原样带进来的。在闭式解 中可以直接读出方向:
- β 越大 → 指数项的差异被压平 → 最优策略越贴近 reference → 更保守、更不容易跑偏、但学到的偏好更弱。
- β 越小 → 允许策略偏离 reference 越远 → 对齐更强,但更容易退化成重复、语言崩坏、以及放大数据里的偏置。
一个必须主动说的实现细节: 在 DPO 损失里同时出现在 sigmoid 的自变量里,所以它不仅决定「等价 RL 目标中的 KL 强度」,还直接缩放了 loss 的梯度和有效温度。这意味着 与学习率是耦合的 —— 单改 不等于只改 KL 约束强度。
⚠️ 诚实提醒:不同实现、不同博客对 β 方向的注释口径并不完全一致(有些地方把它写作温度、方向相反)。答题时的安全做法是以定义为准:「β 是等价 RL 目标里的 KL 惩罚系数,越大越贴近 reference」,并主动说明它与 lr 的耦合。不要凭记忆给一个具体数值当「标准值」—— 它高度依赖模型与数据。
偏好数据与 reference model 的两个硬约束#
- reference 必须是策略的起点模型(通常是同一个 SFT 模型)。如果 reference 与 policy 的初始权重不一致, 这个比值从一开始就带着一个系统性的偏置,等于在噪声上做对照。
- rejected 必须有信息量(详见
data-engineering.md)。DPO 的梯度只会沿着「偏好对给出的方向」走,数据里正负样本的差异维度决定了模型学到的到底是什么。用随机负例得到的是随机方向。
失效模式(必须能主动讲出来)#
1. Likelihood displacement(似然位移) DPO 的损失只约束差值 ,它不直接要求 上升。只要把 rejected 压得比 chosen 更快,差值就变大、loss 就下降。后果是:chosen 的绝对概率也可能同步下降,模型的偏好排序变好了,但它「更不愿意生成好回答」了。这是 DPO 与 RLHF 结构上最本质的差异之一(RLHF 里的奖励和 KL 是显式锚定的)。
2. 冗长偏置(verbosity / length bias) 人类标注者和 LLM 裁判都倾向给更长的回答更高分,偏好数据里就编码了「长 = 好」这个虚假特征;DPO 会把它放大。更糟的是,隐式奖励 是逐 token 对数概率之和,本身就与序列长度相关 —— 长回答天然有更大的求和项数,这是 DPO 结构上的长度敏感性来源。缓解方式:长度受控的偏好配对、长度归一化、或对长度差做显式惩罚。
3. 对偏好数据过拟合 / 通用能力退化
一个容易被误解的点:KL 约束在 DPO 里是「隐式编码」在闭式推导里的,而不是像 PPO 那样有一个显式的、可以实时观测和调制的 KL 项。所以 DPO 缺少一个直接的「跑偏了没有」的仪表盘,实际约束强度由 β 和训练步数共同决定。在小数据集上训太多 epoch,同样会过拟合、掉通用能力(见 catastrophic-forgetting.md)。
4. 与数据分布脱节(offline 的本质限制) DPO 只看固定的偏好数据集,不会探索。数据集中没覆盖到的回答空间,DPO 无法改善;数据集的分布与被优化策略的实际输出分布之间的差距(distribution shift),会随训练增大。这正是「迭代式 / 在线 DPO」类变体想补的短板:用当前策略采样新偏好对(并重新标注)再训一轮。
5. 对噪声标签敏感 DPO 是分类式损失,标注噪声(本该 chosen 的被标成 rejected)会直接把策略往反方向推,而且没有「重要性权重」这类机制来抑制它。偏好数据质量就是 DPO 的天花板。
DPO vs RLHF(PPO):一张对照表#
| 维度 | DPO | RLHF + PPO |
|---|---|---|
| 常驻模型 | 2 个(policy + frozen reference) | 4 个(+ reward + value) |
| 奖励信号 | 隐式: | 显式 reward model |
| 数据 | 离线、固定的偏好集 | 在线采样(on-policy rollout) |
| 采样成本 | 无 | 高(墙钟主要开销) |
| 稳定性 / 复现性 | 高(就是一个监督式损失) | 低(RL 循环 + 非平稳 value model + 超参敏感) |
| 能否探索数据之外的区域 | ❌ 不能 | ✅ 能 |
| 典型失败模式 | likelihood displacement、冗长偏置、离线分布偏移 | reward hacking、训练崩溃、长度漂移 |
| 主要旋钮 | β(+步数) | β、clip ε、lr、GAE、batch |
结论式回答:DPO 用「闭式解消掉 reward model」把对齐从 RL 问题降维成监督问题,因此更便宜、更稳、更可复现;代价是失去了在线探索能力,且换来了自己的一套失效模式。在有明确可验证奖励或需要探索超出数据分布的场景(如推理训练),在线 RL 方法(GRPO/PPO)仍有优势 —— 这也是 Writing Copilot 里 DPO 之后还要接 GRPO 的原因:DPO 负责把分布挪到正确区域,GRPO 负责在该区域内做精细优化。
常见面试问法#
Q:DPO 为什么不需要 reward model?请给出直觉层面的解释。 A:因为 KL 约束下的 RLHF 目标有闭式最优解,把该解代回 Bradley-Terry 偏好模型后,奖励项可以完全写成策略相对 reference 的 log 概率比,且与 无关的配分项 在配对相减时被约掉。于是策略本身就隐式地编码了奖励,不需要单独训一个 RM。(完整四步推导见上文。)
Q:DPO 还需要 reference model 吗?它的作用是什么? A:需要。它定义了隐式奖励的原点 —— 是相对量。没有它,损失只在差值的绝对尺度上失去约束,模型可以把 chosen 和 rejected 一起推高(或一起压低)而不改变差值,退化解空间会变得非常大。同时 ref 承担了 PPO 里 KL 惩罚的角色(隐式地编码在闭式解里)。
Q:β 调大调小分别发生什么? A:β 是等价 RL 目标中的 KL 系数。β 大 → 策略被压得贴近 reference → 保守、通用能力保留好、但偏好对齐效果弱;β 小 → 允许更大的分布偏移 → 对齐更强,但容易退化(重复、语言崩坏)并放大数据偏置。另一个必须提的点:β 同时缩放 loss 的梯度,与学习率耦合,所以它不是纯粹的「KL 强度旋钮」。
Q:DPO 训练时 loss 正常下降,但模型的输出质量变差了,可能是什么原因? A:优先怀疑 likelihood displacement —— 损失只约束 chosen 与 rejected 的差值,chosen 的绝对概率可能同时下降。排查方式:直接监控 与 的绝对值随时间的变化,而不只看 loss 或偏好准确率。其他候选:冗长偏置、偏好数据噪声、训练步数过多导致的过拟合。
Q:DPO 和 RLHF 的取舍是什么?什么场景你会坚持用 PPO/GRPO? A:DPO 更便宜、更稳、可复现,但离线、无探索。坚持用在线 RL 的场景:① 有可验证奖励、需要模型探索出训练数据之外的正确解法(推理、SQL、代码这类);② 需要在线适应一个不断变化的策略分布;③ 偏好数据难以一次性覆盖答案空间。实践中常见的折中是迭代式 DPO:用当前策略采样新偏好对再训一轮,用离线方法的稳定性换回一部分探索能力。
Q:为什么在 Writing Copilot 里先 DPO 再 GRPO,而不是反过来? A:模型原有的拒答行为在输出分布里是一组很强的先验。直接用 GRPO 对抗它,需要奖励信号穿过这片高概率壁垒,学习效率低、不稳定,且容易把安全能力一起训坏(变成什么都答)。DPO 是离线且稳定的 —— 它能有针对性地把「拒答」这个模式的相对概率压低,同时保住安全边界,即把分布平移到正确的区域。之后 GRPO 在这个已经合理的起点上用定制奖励做细粒度优化,效率才高。顺序反了,要么训不动,要么把安全边界一起破坏掉。
易错点#
- ❌ 说「DPO 就是把 reward model 换成模型自己」而不解释 Z(x) 在配对差分中约掉 这个关键步骤 —— 这是全篇最重要的点。
- ❌ 认为 DPO 不需要 reference model —— 恰恰相反,它是隐式奖励的锚点。
- ❌ 把 β 说成「学习率」或「温度」而不提它是 KL 系数;或给出一个「标准值」当成普适结论。
- ❌ 认为 DPO 的 KL 是显式的、可观测的 —— 它是隐式编码在闭式解里的,这正是它缺少「跑偏仪表盘」的原因。
- ❌ 忘记 likelihood displacement 和冗长偏置这两个失效模式 —— 这两条是「你真的训过 DPO」的分界线。
- ❌ 认为 DPO 全面优于 RLHF:它失去的是在线探索能力和数据之外区域的可改善性。
- ❌ 把「偏好准确率(preference accuracy)上升」直接当成「模型变好了」—— 它只说明排序对了,不说明绝对生成质量。
- ❌ 用随机负例或长度失控的偏好对。
自测#
1. 逐步说明 DPO 推导中,「reward model 被消掉」的关键一步是什么,为什么那个不可计算的项会消失。
答案
关键步骤是:先从 KL 约束的 RLHF 目标的闭式最优解 中反解出奖励
再代入 Bradley-Terry 偏好模型 。
需要遍历全词表内的所有序列,是不可计算的配分函数。但它只依赖 prompt ,不依赖回答 ,因此在 的配对差分中被完全约掉。留下的是策略相对 reference 的对数概率比 —— 于是损失可以直接在策略上优化,不需要任何 reward model。
2. DPO 的损失函数里为什么只出现「差值」这件事,会带来什么具体故障?
答案
因为损失是 ,优化目标只关心 chosen 相对 rejected 的对数比之差,不直接约束各自的绝对值。
具体故障是 likelihood displacement:即使 的绝对概率下降,只要 下降得更快,差值仍然变大、loss 仍然下降。结果是模型对好回答的偏好排序改善了,但生成好回答的绝对倾向可能变弱。诊断方式是直接监控 与 随时间的变化,而不是只看损失和偏好准确率。这也是 DPO 与显式奖励 + KL 锚定的 RLHF 在结构上的根本差异。
3. 一个团队报告「DPO 之后离线偏好准确率从 60% 提到 85%,但用户没有感觉到变好」。列出三种可能,并各给一个验证方法。
答案
① likelihood displacement:排序对了但绝对生成质量下降。验证:画出 与 自身的绝对曲线,看 chosen 的绝对概率是否下降;并让模型自由生成(不给 chosen/rejected 提示)后人工评比。
② 冗长偏置:模型学会了「更长 = 更好」,而偏好准确率的提升主要来自长度。验证:比较训练前后的平均输出长度分布;用长度受控的评测集再看一次偏好准确率是否还成立。
③ 评测集与真实需求脱节或已被污染:偏好集由同一批人或同一个 LLM 裁判构造,它的偏好方向不等于真实用户的偏好方向。验证:用一个独立的、由真实用户偏好(或第三方评测)构造的留出集重测;检查偏好集是否有覆盖盲区。
(其他可获得部分分的答案:过拟合导致通用能力退化;reference model 与 policy 起点不一致导致隐式奖励有系统偏置。)
4. 为什么说 DPO「便宜但天花板受数据限制」?如果想兼得稳定与探索,可以怎么做?
答案
便宜:不需要 reward model 与 value model,不需要在线 rollout,只有一个监督式损失,因此显存、时间、调参和复现成本都大幅下降。
天花板受数据限制:DPO 是纯离线的,只在固定偏好集上优化,无法探索数据未覆盖的回答空间;同时随训练进行,策略分布会逐渐偏离数据集的分布(distribution shift),而 DPO 没有机制去纠正这一点。
兼得的方式:迭代式 / 在线 DPO —— 用当前策略采样多条回答,用 reward model、规则判定或 LLM 裁判重新标注偏好对,再训一轮,如此迭代。它在保留「每轮都是稳定的监督式优化」的同时,让偏好数据跟上策略的当前分布,恢复了一部分探索能力。另一种折中是先 DPO 把分布搬到合理区域,再用 GRPO/PPO 在该区域内做在线精调(Writing Copilot 的两阶段方案)。
5. 给你一份 (prompt, chosen, rejected) 数据,你怎么在训练前就预判 DPO 会不会出事?
答案
训练前做数据侧体检,而不是等训练曲线:
① 长度分布:chosen 与 rejected 的平均长度差、长度与「被选中」的相关性。如果 chosen 系统性更长,几乎一定会学到长度偏置 —— 先做长度受控配对或加长度归一化。
② 信息量:正负例是「只在目标维度上有差异」还是「处处都差」。用裁判模型给两者打分,看差异是否集中在少数可解释维度上;差异维度过于分散意味着梯度方向模糊。
③ 噪声率:抽样人工复核,尤其检查有没有把更好的回答标成 rejected。DPO 对标签噪声敏感,且没有重要性加权来抑制它。
④ 覆盖度:偏好对覆盖了哪些 prompt 类型,是否存在盲区。盲区在 DPO 里无法被改善。
⑤ reference 一致性:确认 reference 就是 policy 的起点权重,且所用 chat template 与推理一致。
⑥ 训练侧护栏:设定最大步数/epoch,并把「chosen 绝对对数概率」与「平均输出长度」纳入监控 —— 这两个指标能在 loss 还好看的时候提前发现 likelihood displacement 与冗长偏置。