04 / Post-Training研究

偏好优化:DPO、KL 与在线数据

把概率比、参考策略和梯度方向连接到真实训练 batch。

从 KL 约束目标推到 DPO,理解参考模型、序列 mask、分布偏移和在线偏好更新。

READ WITH A QUESTION

读完这一章,你应该能够

  • 推导并检查 DPO 梯度方向
  • 审计 reference 与 completion mask
  • 分清在线采样、参考策略与旧策略
前置理解 对数概率 · 链式法则;可先看梯度旁路
本章目录 · 0 个小节

一个常见失败:偏好准确率接近满分,回答却退化

假设训练集把“详细回答”标为 chosen,把简短但正确的回答标为 rejected。模型可以通过长度和措辞赢得偏好分类,却没有提高任务成功率。偏好目标是数据中判断标准的数学表达,不会自动纠正标准本身。

课程分析:先分清能力评价与行为偏好。格式、帮助性、准确性、成本常有冲突;可执行正确性尽量独立评估。用单一总分掩盖冲突,往往比优化器选错更难诊断。

从 KL 约束到可训练的概率比

考虑每个提示 xx 的目标:

max⁡π  Ey∼π[r(x,y)]−βDKL(π(⋅∣x)∥πref(⋅∣x)).\max_\pi\;\mathbb E_{y\sim\pi}[r(x,y)]-\beta D_{\rm KL}(\pi(\cdot|x)\|\pi_{\rm ref}(\cdot|x)).

在有限动作、参考分布正概率覆盖和可优化分布的条件下,对归一化约束引入拉格朗日乘子,得到 π∗(y∣x)∝πref(y∣x)er(x,y)/β\pi^*(y|x)\propto\pi_{\rm ref}(y|x)e^{r(x,y)/\beta}。代回 Bradley–Terry 偏好概率,归一化常数在同一个提示内相消:

z=β[log⁡πθ(y+∣x)πref(y+∣x)−log⁡πθ(y−∣x)πref(y−∣x)],LDPO=−log⁡σ(z).z=\beta\left[\log\frac{\pi_\theta(y^+|x)}{\pi_{\rm ref}(y^+|x)}-\log\frac{\pi_\theta(y^-|x)}{\pi_{\rm ref}(y^-|x)}\right],\qquad \mathcal L_{\rm DPO}=-\log\sigma(z).

这是 DPO 论文的标准 sigmoid 目标。理论变换不代表在有限、有偏、离线数据上训练神经网络就能精确恢复最优策略。公式来源

一个容易混淆的细节:β\beta 在理想奖励最大化问题里控制偏离参考分布的代价,在 DPO 实现里又直接缩放分类 logit。因此不能仅从“增大 β\beta 会让即时梯度变大”推出“最终偏离参考模型更远”;瞬时优化尺度与收敛解的正则含义不同。

快速补充:梯度到底往哪里走

如果对 backward() 到参数更新的过程还没有画面,先打开梯度与反向传播旁路,逐步观察前向值、局部导数与梯度累积,再回到这个偏好目标。

把 Δ\Delta 定义为方括号中的概率比差,则:

∂L∂Δ=−βσ(−βΔ).\frac{\partial\mathcal L}{\partial\Delta}=-\beta\sigma(-\beta\Delta).

它为负。梯度下降更新一个独立的 Δ\Delta 时,会增加 Δ\Delta,也就是增大 chosen 相对 rejected 的参考校正优势。神经网络里两条序列共享大量参数,因此不能保证 chosen 的绝对概率在每一步都上升;只看 margin 会遗漏整体概率下降和分布外退化。

脑中的图应是:参数产生 logits,log-softmax 给出实际 token 的对数概率,mask 后求和得到两条序列分数,减去参考分数形成 margin,最后经 sigmoid 损失反向传导。反向传播负责计算链式法则;优化器负责使用梯度更新参数。二者不是同一个动作。

源码导读:公式对应哪些张量

读取固定版本 b8721872beaf3e8b6e78b6c991f15682d17d86d2 的 trl/trainer/dpo_trainer.py,真实符号是 DPOTrainer._compute_loss,上层由 compute_loss 调用。固定源码

公式对象源码数据审计问题
自回归条件概率shift_logits / shift_labels是否错开一个 token
仅回答部分的概率shift_completion_maskprompt、padding 是否被排除
两个序列分数chosen_logps / rejected_logps拼接顺序是否一致
参考校正chosen_logratios / rejected_logratiosreference 是否冻结且模板一致
标准 DPOdelta_score 与 -F.logsigmoid(...)是否确实配置 standard reverse-KL + sigmoid

源码观察:该实现默认路径先对 completion token log-prob 求和;其可选的长度加权和其他 divergence 分支改变目标。不能拿 standard DPO 的公式解释所有可配置分支。返回 loss 之前还会聚合统计,模型为 MoE 时可能涉及辅助损失;阅读配置和分支比只搜索论文名更重要。源码

课程分析:参考分数预计算能省训练时前向算力,但缓存键应包含模型版本、tokenizer、chat template、最大长度和 mask 规则。缓存被旧模板污染时,训练日志不一定报错,却优化了一个不存在的“参考策略”。

reference、old policy、behavior policy 不是同一对象

对象回答的问题生命周期
Reference policy希望相对哪个分布控制漂移通常一段训练中固定,刷新需明确
Old policy本轮 surrogate 目标相对哪个策略计算更新比率通常每个采样周期更新
Behavior policy这条样本实际由谁、在何种采样配置下生成必须随轨迹保存

标准离线 DPO 不需要 PPO 式 importance ratio;在线 RL 则必须处理行为分布与当前策略不一致。异步系统中 old 与 behavior 也可能不同。只存一个名为 log_prob 的字段不足以消除歧义;要保存各自含义和版本。RL 实现参照

在线偏好训练可以循环“当前策略采样 → 评分或标注 → 构造偏好对 → 更新”。它能刷新错误分布,但并不消除 grader 偏差,并增加生成、评分和版本治理成本。在线不等于无偏,离线也不等于无用。

教学实现:有限差分检查你的直觉

CODE / 可复制
python3 -m labs.run --experiment preference --seed 7

实验是独立编写的有限动作实现,不是 TRL 源码替代品。比较解析导数和中心差分:

gFD=L(θ+h)−L(θ−h)2h.g_{\mathrm{FD}}=\frac{\mathcal L(\theta+h)-\mathcal L(\theta-h)}{2h}.

预期二者接近,整体偏好目标改善。默认配置的参考运行中,loss 从约 0.7250 降到 0.6565,解析梯度与差分的绝对误差约 7.0×10−137.0\times10^{-13}。样本之间存在冲突,并非每个偏好对都能同时改善。先用双精度标量检查符号,再将相同目标移植到 PyTorch。若用过大的 hh,离散近似误差上升;若 hh 过小,浮点抵消会破坏差分。实验通过意味着局部导数正确,不能说明偏好标签正确。

生产版增加了 [2B,T,V] logits、梯度累积、分布式归约与混合精度。核对 loss 的归一化:按序列平均与按 token 平均对长短回答的权重不同;当多个 worker 的有效 token 数不同,本地均值的简单平均不一定等于全局 token 均值。

日志该同时看四个面

课程分析:至少分开记录 chosen/rejected 对数概率、偏好 margin 与准确率、相对参考策略漂移、独立任务成功率。加入响应长度和类别分桶,才能发现“靠变长获胜”。KL 的估计器、采样分布和归约规则应写进实验元数据;日志里叫 kl 不代表估计的是同一个量。

偏好 loss 下降但 chosen 与 rejected 概率一起下降:检查长度分布、共享参数效应和偏好约束外的分布变化。参考分数突然整体平移:检查模板或缓存变更。训练准确率很高而 holdout 无变化:检查任务去重、标签冲突和分布外覆盖。

工程任务:构造一个正确性与长度冲突的偏好集。先训练原始版本,再用长度匹配与执行验证重新标注。报告 margin、chosen log-prob、长度、执行正确率及固定预算下的差异。另提交一份 reference cache 指纹设计,说明缓存失效的条件。

MAKE IT RUN

把这一章放进实验里

调整变量,观察机制,再运行本地 Python 实验验证。

进入实验

本章证据与源码

引用代表相应来源支持的结论,不意味着公开了完整训练配方。

论文实验Direct Preference OptimizationRafailov et al. / Stanford · arXiv:2305.1源码观察TRL:DPOTrainer 的当前偏好损失入口huggingface · b8721872beaf源码观察verl:GRPO 组内优势与 PPO clipped lossvolcengine · 8e03c039f9a7

留下你的工程判断

记录一个还没有解释清楚的现象,或下一次实验要控制的变量。笔记仅保存在当前浏览器。

自动保存在本机 · 可在“我的学习笔记”导出
理解机制,比记住结论更重要。