DPO 直接偏好优化论文
DPO(Direct Preference Optimization)绕过 RLHF 中的奖励模型和强化学习阶段,直接从人类偏好数据优化语言模型策略,以更简单稳定的训练流程实现了与 RLHF 相当的对齐效果。
从 RLHF 到 DPO
RLHF 的三阶段流程复杂且不稳定,DPO 的核心洞察是:
偏好数据本身已隐含了奖励信息,无需显式训练奖励模型。
数学推导
RLHF 的最优策略可以表示为:
$$\pi^*(y|x) = \frac{1}{Z(x)} \pi_{ref}(y|x) \exp\left(\frac{1}{\beta} r(x,y)\right)$$
由此可以反推出奖励函数:
$$r(x,y) = \beta \log \frac{\pi^*(y|x)}{\pi_{ref}(y|x)} + \beta \log Z(x)$$
将此代入 Bradley-Terry 偏好模型,配分函数 Z(x) 被消除:
$$p(y_w \succ y_l|x) = \sigma\left(\beta \log \frac{\pi_\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)}\right)$$
import torch
import torch.nn.functional as F
def dpo_loss(policy_chosen_logps, policy_rejected_logps,
reference_chosen_logps, reference_rejected_logps, beta=0.1):
"""DPO 损失函数"""
# 对数比率
chosen_logratios = policy_chosen_logps - reference_chosen_logps
rejected_logratios = policy_rejected_logps - reference_rejected_logps
# DPO 损失
logits = beta * (chosen_logratios - rejected_logratios)
loss = -F.logsigmoid(logits).mean()
# 选择的奖励差(用于监控)
chosen_rewards = beta * chosen_logratios
rejected_rewards = beta * rejected_logratios
return loss, chosen_rewards.mean(), rejected_rewards.mean()DPO vs RLHF
| 维度 | RLHF | DPO |
|---|---|---|
| 训练阶段 | SFT → RM → PPO | SFT → DPO |
| 奖励模型 | 需要显式训练 | 隐式学习 |
| 稳定性 | PPO 训练不稳定 | 简单分类损失 |
| 计算成本 | 高(4个模型) | 低(2个模型) |
| 超参数 | 多(KL系数、PPO参数) | 少(β) |
DPO 的简洁性
DPO 将 RLHF 的复杂流程简化为一个简单的分类问题:给定一对偏好数据 (chosen, rejected),训练模型增大 chosen 的概率、降低 rejected 的概率。这使得 DPO 的实现和调试都远比 RLHF 简单。
DPO 的变体
IPO(身份偏好优化)
IPO 使用更稳健的损失函数,避免 DPO 在偏好数据噪声较大时过拟合:
$$\mathcal{L}{IPO} = \mathbb{E}\left[\left(\log \frac{\pi\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)} - \frac{1}{2\beta}\right)^2\right]$$
KTO(Kahneman-Tversky 优化)
仅需要二元反馈(好/坏),不需要成对偏好数据:
- 更容易收集数据
- 基于前景理论的非对称损失
ORPO(几率比偏好优化)
将 SFT 和偏好对齐合并为单一训练阶段。
实践建议
- β 选择:0.1-0.5 之间,越大模型越保守
- 数据质量:DPO 对偏好数据质量非常敏感
- 参考模型:必须冻结参考模型
- 训练长度:DPO 通常比 RLHF 需要更少的训练步数