Direct Preference Optimization
直接偏好优化(DPO)通过单个损失函数,让语言模型根据偏好和不偏好的回答对进行对齐,无需奖励模型或强化学习。
直接偏好优化(DPO)是一种通过直接使用成对的回答训练大型语言模型(LLM),使其符合人类偏好的方法;每对回答包含一个偏好的回答和一个不接受的回答,并使用单一分类式损失函数。它无需单独的奖励模型,也无需在训练期间从模型采样的强化学习循环,就能实现基于人类反馈的强化学习(RLHF)的目标。斯坦福大学的 Rafael Rafailov、Archit Sharma、Eric Mitchell、Stefano Ermon、Christopher Manning 和 Chelsea Finn 于 2023 年在 NeurIPS 2023 上发表的论文《直接偏好优化:你的语言模型其实暗中就是一个奖励模型》中提出了该方法。其核心思想是,正在训练的语言模型定义了自己的隐式奖励,因此奖励模型和策略可以一步拟合完成。
DPO 的工作原理#
每个训练样本都是一个提示,包含一个选定回答和一个拒绝回答,由人类或另一个模型标注。训练从已经过监督微调的模型开始,通常是指令微调,并保留其冻结副本作为参考模型。对于每个回答,DPO 会比较待训练模型和参考模型给出的对数概率。回答的隐式奖励是 β 乘以该对数比值;损失则是对选定回答奖励与拒绝回答奖励之差取负Sigmoid的对数。最小化损失会提高选定回答相对于拒绝回答的概率;对于模型仍然排序错误的回答对,更新幅度更大。
系数 β 在 RLHF 中起到 KL 惩罚项的作用。Rafailov 等人证明,RLHF 中使用的 KL 约束奖励最大化存在闭式最优策略:将参考概率按奖励除以 β 的指数函数重新加权;他们还重排了该公式,以便通过策略本身表示奖励。β 越小,训练就越能让模型偏离参考模型。
这个 PyTorch示例使用 Hugging Face Transformers 中的 GPT-2 和两组客服偏好回答对运行十个 DPO 步骤,然后检查模型从未训练过的第三组回答对:
import copy
import torch
import torch.nn.functional as F
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
policy = AutoModelForCausalLM.from_pretrained("gpt2")
reference = copy.deepcopy(policy).requires_grad_(False) # frozen copy of the starting model
optimizer = torch.optim.Adam(policy.parameters(), lr=1e-5)
# Preference pairs: (prompt, chosen reply, rejected reply)
train = [
("My order arrived broken.", " Sorry about that, we will send a replacement today.", " That is not our problem."),
("I was charged twice.", " Sorry for the trouble, we have refunded the extra charge.", " Check your bank again."),
]
held_out = ("My package is a week late.", " Sorry for the delay, we will track it down for you.", " Be more patient.")
def log_prob(model, prompt, reply):
"""Sum of the log-probabilities the model gives the reply tokens after the prompt."""
ids = tokenizer(f"Customer: {prompt}\nAgent:{reply}", return_tensors="pt").input_ids
token_logps = model(ids).logits[0, :-1].log_softmax(-1).gather(1, ids[0, 1:, None])
return token_logps[-len(tokenizer(reply).input_ids) :].sum()
def margin(prompt, chosen, rejected):
"""Policy-to-reference log-ratio of the chosen reply minus that of the rejected reply."""
chosen_ratio = log_prob(policy, prompt, chosen) - log_prob(reference, prompt, chosen)
return chosen_ratio - (log_prob(policy, prompt, rejected) - log_prob(reference, prompt, rejected))
for step in range(10):
loss = sum(-F.logsigmoid(0.1 * margin(*pair)) for pair in train) / len(train) # DPO loss, beta = 0.1
if step in {0, 9}:
print(f"Step {step}: training loss {loss.item():.3f}")
optimizer.zero_grad()
loss.backward()
optimizer.step()
with torch.no_grad():
print(f"Held-out margin: {margin(*held_out).item():+.1f}")在第 0 步,它会输出 0.693 的训练损失,即 ln 2,因为策略仍与参考模型相同,两个回答的隐式奖励都为零。到第 9 步时,损失为 0.047,留出回答对的差值为 +7.8:对于模型从未见过的投诉,模型对道歉回复的对数概率相对于参考模型的提升,比冷漠回复高出 7.8。
DPO 与 RLHF 的区别#
经典 RLHF 会先用偏好回答对训练奖励模型,再通过近端策略优化(PPO)对语言模型进行优化。PPO 每一步都需要从模型中采集新样本,并且需要在内存中同时保留策略模型、价值模型、奖励模型和参考模型。DPO 只需要策略模型和参考模型,并像普通监督学习一样在固定数据集上训练,因此更容易调优,运行成本也低得多。在原始实验中,在相同 KL 预算下,DPO 在控制生成电影评论的情感倾向方面胜过 PPO。在 TL;DR Reddit 摘要任务中,GPT-4 在采样温度为 0 时,有 61% 的情况下认为 DPO 摘要优于人工撰写的参考摘要;相比之下,PPO 在其最佳温度下的比例为 57%。在 Anthropic 的有帮助且无害的对话数据上,DPO 是受测方法中唯一一种计算效率较高、且能改进数据集中偏好回答的方法。
代价在于,DPO 只能从给定的回答对中学习。像群体相对策略优化(GRPO)这样的在线 RL 方法会在训练期间为当前模型生成的新样本打分,因此在数学和代码领域的可验证奖励强化学习(RLVR)中占据主导地位,因为检查器可以为每个新答案评分。偏好标签也可以来自遵循书面原则的 AI 模型,例如宪法式 AI;DPO 以同样的方式使用这类标签进行训练。
DPO 的应用场景#
DPO 已成为开源权重聊天机器人后训练的标准步骤。Hugging Face 的 Zephyr-7B-β 将其应用于 AI 排序的 UltraFeedback 数据;Meta 的 Llama 3模型则通过多轮监督微调和后续 DPO 完成对齐。TRL 库提供了开箱即用的 DPO 训练器。Ultralytics LLM 接口可通过任何兼容 OpenAI 的端点调用模型,包括本地服务器,因此经过 DPO 对齐的开源模型可以为Ultralytics YOLO26视觉流水线生成文本部分。
该方法也适用于图像。Diffusion-DPO针对扩散模型改写了损失函数,并使用 Pick-a-Pic 数据集中的 851,000 组众包成对偏好数据,对 Stable Diffusion XL 基础模型进行微调,从而提升了文生图生成中的提示词匹配度和视觉吸引力。针对视觉语言模型(VLM),RLHF-V 收集了人类对幻觉式图像描述的分段级修正,并使用密集型 DPO 变体进行训练;仅用 1,400 个标注样本,就将基础模型的幻觉率降低了 34.8%。
DPO 的变体#
- IPO(恒等偏好优化):将对数 Sigmoid 替换为针对固定边界的平方损失,从而避免隐式奖励不断增长,并防止模型在同一回答总是胜出的情况下过拟合。
- KTO(卡尼曼-特沃斯基优化):从标记为可取或不可取的单个回答中学习,因此不需要成对比较。
- ORPO(赔率比偏好优化):移除参考模型,并在监督微调损失中加入赔率比惩罚,将指令微调和偏好对齐合并为一个阶段。
- SimPO(简单偏好优化):使用按长度归一化的回答平均对数概率作为奖励,移除参考模型,并要求选定回答与拒绝回答的奖励之间达到目标边界。










