在机器学习领域,直接偏好优化(Direct Preference Optimization, DPO)是一种新兴的强化学习技术,它绕过了传统RLHF(基于人类反馈的强化学习)中复杂的奖励建模步骤。本文将从头推导DPO损失函数,揭示其数学本质和工程实现原理。
在开始推导前,我们需要建立偏好概率模型。给定一对响应(y₁, y₂)和提示x,假设人类偏好服从Bradley-Terry模型:
P(y₁ ≻ y₂ | x) = σ(r(x,y₁) - r(x,y₂))
其中σ是sigmoid函数,r(x,y)是潜在的奖励函数。这个模型表示人类更倾向于选择奖励值更高的响应。
传统RLHF流程包含三个步骤:
DPO的关键突破在于发现可以直接将策略参数θ与隐含奖励函数联系起来,通过变量替换消除显式奖励建模。
我们从KL约束的最优策略开始:
π*(y|x) = (1/Z(x))π_ref(y|x)exp(r(x,y)/β)
其中β是温度参数,Z(x)是配分函数。取对数并整理得到:
r(x,y) = βlog(π*(y|x)/π_ref(y|x)) + βlogZ(x)
将这个表达式代入Bradley-Terry模型,神奇的事情发生了 - Z(x)项在比较中抵消:
P(y₁ ≻ y₂ | x) = σ(βlog(π*(y₁|x)/π_ref(y₁|x)) - βlog(π*(y₂|x)/π_ref(y₂|x)))
这就是DPO的核心洞察:我们可以直接用策略比表示偏好概率,完全避开奖励建模。
基于上述概率模型,我们可以构建标准的负对数似然损失:
L_DPO(π*; π_ref) = -E_(x,y_w,y_l)~D[logσ(βlog(π*(y_w|x)/π_ref(y_w|x)) - βlog(π*(y_l|x)/π_ref(y_l|x)))]
其中y_w是偏好响应,y_l是被拒绝的响应。
计算损失对策略参数θ的梯度:
∇_θL_DPO = -βE[σ(r_θ(x,y_l) - r_θ(x,y_w))[∇_θlogπ_θ(y_w|x) - ∇_θlogπ_θ(y_l|x)]]
其中r_θ(x,y) = βlog(π_θ(y|x)/π_ref(y|x))。这个梯度形式直观地展示了DPO如何运作:
在实践中,π_ref通常选择SFT模型。关键考虑因素包括:
β控制着策略偏离参考策略的程度:
高效实现需要注意:
python复制# 伪代码示例
dpo_loss = DPO_Loss(β=0.2)
optimizer = AdamW(model.parameters(), lr=5e-6)
for batch in dataloader:
x, y_w, y_l = batch
logp_w = model(x, y_w)
logp_l = model(x, y_l)
with torch.no_grad():
logp_ref_w = ref_model(x, y_w)
logp_ref_l = ref_model(x, y_l)
loss = dpo_loss(logp_w, logp_l, logp_ref_w, logp_ref_l)
loss.backward()
optimizer.step()
将二元偏好推广到n个响应的排序:
P(y_1 ≻ y_2 ≻ ... ≻ y_n | x) = ∏{i=1}^{n-1} σ(r(x,y_i) - r(x,y))
对应的损失函数需要相应调整。
可以结合离线DPO和在线数据收集:
扩展基础DPO以处理多个奖励维度:
在实际项目中应用DPO时,有几个关键经验值得分享:
数据质量比数量更重要:精心筛选的10k高质量偏好对往往比100k嘈杂数据效果更好。建议:
渐进式训练策略:
监控体系设计:
计算效率优化:
安全防护措施: