揭秘DPO技术:简化RLHF的终极方案
目录
4.5 SimPO:去掉 reference model 的简化 DPO
4.8 CPO:名称容易混淆,常见是 Contrastive Preference Optimization
4.9 cDPO / Robust DPO:处理偏好标签噪声
结论
DPO 类技术的核心目标:用偏好数据替代复杂 RLHF,把“人更喜欢哪个回答”转成一个可直接反向传播的 loss。
工程上可以这样选:
| 场景 | 推荐方案 | 原因 |
|---|---|---|
你有 prompt + chosen + rejected 成对偏好数据 |
DPO | 最成熟、实现最多、调参相对简单 |
| 你显存紧张,不想保留 reference model | SimPO / ORPO | reference-free,训练更省显存 |
| 你只有“这个回答好/不好”的单条标签,没有成对比较 | KTO | 不要求 chosen/rejected 成对数据 |
| 偏好数据噪声大 | cDPO / Robust DPO / IPO | 对过拟合和错误偏好更稳 |
| 你要训练数学、代码、可验证任务的推理能力 | GRPO / PPO 类在线 RL | DPO 是离线偏好学习,不直接等价于可验证奖励优化 |
DPO 原论文的关键点是:它不显式训练 reward model,也不使用 PPO 采样更新,而是把 RLHF 的 KL 约束目标重写成一个二分类形式的 preference loss。(arXiv)
1. 先理解 RLHF、DPO、偏好优化的关系
传统 RLHF 通常是三步:
SFT 模型
↓
训练 Reward Model:判断哪个回答更好
↓
PPO / GRPO 等 RL 方法优化策略模型
问题是:复杂、显存大、训练不稳定、超参多。RRHF 论文也指出,PPO 标准实现通常需要多个模型,且对超参数敏感。(arXiv)
DPO 把它简化成:
SFT 模型
↓
准备成对偏好数据:prompt, chosen, rejected
↓
直接训练模型:提高 chosen 概率,降低 rejected 概率
DPO 训练数据通常长这样:
{
"prompt": "解释一下什么是 RAG?",
"chosen": "RAG 是检索增强生成,它会先从外部知识库检索相关信息,再交给大模型生成回答……",
"rejected": "RAG 是一种数据库。"
}
2. DPO 的具体训练原理
2.1 DPO 训练时有两个模型
| 模型 | 作用 |
|---|---|
πθ |
当前正在训练的模型 |
πref |
reference model,通常是 SFT 后冻结的模型 |
训练时不会让模型自由生成,而是对 chosen 和 rejected 做 teacher forcing,计算它们在模型下的 log probability。
也就是计算:
log πθ(chosen | prompt)
log πθ(rejected | prompt)
log πref(chosen | prompt)
log πref(rejected | prompt)
2.2 DPO 的核心 loss
DPO 的 loss 可以写成:
L_DPO = - log σ(
β * [
log πθ(y_w|x) - log πref(y_w|x)
-
log πθ(y_l|x) + log πref(y_l|x)
]
)
更清晰地写:
reward_chosen =
log πθ(chosen | prompt) - log πref(chosen | prompt)
reward_rejected =
log πθ(rejected | prompt) - log πref(rejected | prompt)
loss =
-log sigmoid(β * (reward_chosen - reward_rejected))
其中:
| 符号 | 含义 |
|---|---|
x |
prompt |
y_w |
winner,也就是 chosen |
y_l |
loser,也就是 rejected |
πθ |
当前训练模型 |
πref |
冻结的参考模型 |
β |
控制模型偏离 reference model 的强度 |
直观理解:
如果当前模型相比 reference model 更偏向 chosen:
loss 变小
如果当前模型相比 reference model 更偏向 rejected:
loss 变大,梯度会强烈纠正
所以 DPO 不是简单地让 chosen 概率变大,而是让:
chosen 相对于 reference 的提升幅度
>
rejected 相对于 reference 的提升幅度
这点很重要,因为它保留了 KL regularization 的味道,避免模型训练后偏离原模型太远。
3. DPO 为什么可以替代 Reward Model?
传统 RLHF 会训练一个 reward model:
r(x, y)
表示回答 y 对 prompt x 的奖励分数。
RLHF 的目标大致是:
最大化 reward
同时不要偏离 reference model 太远
也就是:
max E[r(x, y)] - β KL(πθ || πref)
DPO 的推导发现,在这个目标下,最优策略和 reward 可以互相表示:
r(x, y) ≈ β * [log πθ(y|x) - log πref(y|x)]
于是 reward model 就不需要单独训练了。
也就是说:
模型本身的 log probability ratio
≈
隐式 reward
这就是 DPO 论文标题里 “Your Language Model is Secretly a Reward Model” 的含义。(arXiv)
4. DPO 类技术横向对比
4.1 DPO:最标准的偏好优化
适合:
prompt + chosen + rejected
训练目标:
让模型更偏向 chosen,而不是 rejected
同时通过 reference model 限制偏移
优点:
-
实现成熟
-
不需要显式 reward model
-
不需要 PPO 采样
-
Hugging Face TRL、LLaMA-Factory、Unsloth 等都支持
缺点:
-
需要 reference model,显存更高
-
对偏好数据质量敏感
-
容易学到长度偏好、风格偏好
-
如果 chosen/rejected 差异太弱,信号不明显
-
如果 rejected 太差,训练价值也有限
Hugging Face TRL 当前的 DPOTrainer 支持原始 DPO 的 sigmoid loss,也支持 IPO、hinge、robust、NCA、AOT、APO 等多种 loss type。(Hugging Face)
4.2 IPO:修正 DPO 过拟合问题
IPO,全称通常指 Identity Preference Optimization。
它针对 DPO 的一个问题:
当偏好标签非常确定时,DPO 可能不断拉大 chosen 和 rejected 的 log-ratio 差距,导致过拟合。
DPO 更像是:
只要 chosen > rejected,就继续推大差距
IPO 更像是:
我希望 chosen 和 rejected 的差距达到一个合适 margin
不要无限变大
常见形式可以理解为:
loss_IPO =
(log_ratio_gap - target_margin)^2
其中:
log_ratio_gap =
[log πθ(chosen) - log πref(chosen)]
-
[log πθ(rejected) - log πref(rejected)]
适合:
-
偏好数据规模较小
-
数据有重复模板
-
DPO 训练后出现明显过拟合
-
模型回答变得过度迎合、啰嗦、风格单一
缺点:
-
实际效果依赖数据和超参
-
工程默认优先级低于 DPO
-
不是所有训练框架都同等完善支持
IPO 相关研究指出,DPO 在确定性偏好数据上可能忽略 KL 正则项并产生过拟合,IPO 尝试通过替代损失缓解这个问题。(arXiv)
4.3 KTO:不需要成对偏好数据
KTO,全称 Kahneman-Tversky Optimization。
DPO 需要:
prompt, chosen, rejected
KTO 可以只需要:
prompt, response, label
例如:
{
"prompt": "介绍一下 Transformer",
"response": "Transformer 是一种基于注意力机制的神经网络架构……",
"label": "desirable"
}
或者:
{
"prompt": "介绍一下 Transformer",
"response": "Transformer 是一种数据库。",
"label": "undesirable"
}
KTO 的思想来自 prospect theory,也就是人类对收益和损失的感知不对称。它不直接最大化 pairwise preference likelihood,而是最大化一种人类感知效用。KTO 论文指出,它可以只从“输出是否 desirable”的二元信号中学习,并且在 1B 到 30B 模型规模上可以达到或超过一些基于偏好对的方法。(arXiv)
适合:
-
你没有 chosen/rejected 对
-
只有单条回答的好坏标签
-
数据来自审核、打分、规则过滤
-
比如医疗、金融、政策问答中的合规/不合规样本
缺点:
-
如果你已经有高质量成对偏好数据,DPO 通常更直接
-
KTO 的超参和数据配比会影响明显
-
undesirable 数据过多时可能导致模型保守
4.4 ORPO:把 SFT 和偏好优化合到一起
ORPO,全称 Odds Ratio Preference Optimization。
它的核心思想是:
不再分 SFT 阶段和 preference alignment 阶段
而是在一个目标里同时做:
1. 学 chosen
2. 拉开 chosen 和 rejected 的 odds ratio
ORPO 的 loss 可以粗略理解为:
L_ORPO =
L_SFT(chosen)
+
λ * L_preference(chosen, rejected)
其中 preference 部分使用 odds ratio:
odds(y) = P(y) / (1 - P(y))
它希望:
odds(chosen) > odds(rejected)
ORPO 论文称其为 reference-free、monolithic preference alignment 方法,目标是省掉额外的 preference alignment 阶段。(arXiv)
适合:
-
你想一阶段训练
-
数据里既有 instruction tuning,又有 rejected
-
显存有限,不想挂 reference model
-
小模型快速对齐
缺点:
-
如果你的 SFT 已经做得很好,ORPO 不一定比 DPO 稳
-
one-stage 训练更依赖数据清洗
-
对 chosen 质量要求较高
4.5 SimPO:去掉 reference model 的简化 DPO
SimPO,全称 Simple Preference Optimization。
DPO 需要:
πθ 和 πref 的 log-ratio
SimPO 直接用当前模型的平均 log probability 作为隐式 reward:
reward(y) =
average_log_prob(y)
常见形式:
L_SimPO =
-log σ(
β * [
avg_logπθ(chosen)
-
avg_logπθ(rejected)
]
-
γ
)
其中:
| 参数 | 作用 |
|---|---|
β |
控制 preference 差异放大 |
γ |
target reward margin,让 chosen 和 rejected 拉开一定距离 |
avg_log_prob |
对长度做归一化,减少长回答偏差 |
SimPO 论文的核心设计是:使用序列平均 log probability 作为隐式 reward,从而不需要 reference model;同时引入 target reward margin。论文报告它在 AlpacaEval 2、MT-Bench、Arena-Hard 等评测中优于 DPO 的若干设置。(arXiv)
适合:
-
显存紧张
-
不想加载 reference model
-
LoRA/QLoRA 微调 7B/14B
-
快速做偏好实验
缺点:
-
reference-free 也意味着少了一个“别偏离原模型太远”的锚
-
如果数据质量差,可能更容易学偏
-
需要关注长度归一化和 margin 设置
4.6 SLiC-HF:用排序/间隔校准概率
SLiC-HF,全称 Sequence Likelihood Calibration with Human Feedback。
它不是从 RLHF 推导 reward ratio,而是更直接:
让 chosen 的序列似然高于 rejected
并且至少高出一个 margin
类似:
loss_rank =
max(0, margin - score(chosen) + score(rejected))
其中:
score(y) = log πθ(y|x)
通常还会结合 SFT loss:
L =
L_rank
+
λ * L_SFT
SLiC-HF 论文显示,它可以使用为其他模型收集的人类反馈数据,作为一种比 PPO RLHF 更简单、更高效的替代方案。(arXiv)
适合:
-
你想要简单 ranking loss
-
你有多个候选回答排序
-
你不想引入复杂 DPO 推导
缺点:
-
理论上不如 DPO 和 RLHF 的 KL-constrained objective 贴合
-
容易受长度影响
-
现在工程社区热度低于 DPO / ORPO / SimPO
4.7 RRHF:让模型按人类排序给回答打概率
RRHF,全称 Rank Responses to Align Language Models with Human Feedback。
它的输入可以是:
prompt
response_1, score_1
response_2, score_2
response_3, score_3
...
训练目标是:
人类评分更高的 response
应该有更高的模型 log probability
也就是:
如果 score_i > score_j
那么 logπ(response_i) > logπ(response_j)
RRHF 论文强调,它可以利用来自不同来源的 sampled responses,通过 log conditional probability 排序训练模型,而且相比 PPO 需要更少模型、更少复杂超参。(arXiv)
适合:
-
你有多个候选回答和排序分数
-
你用 GPT-4/Claude/DeepSeek 做 judge,得到 rank
-
你想做 best-of-n 风格的偏好学习
缺点:
-
依赖候选回答质量
-
如果候选都很差,排序学习价值有限
-
现在常规对齐训练中使用频率不如 DPO
4.8 CPO:名称容易混淆,常见是 Contrastive Preference Optimization
CPO 在不同论文里可能指不同东西。比较常见的一类是 Contrastive Preference Optimization。
它在机器翻译场景里比较典型:
不是简单模仿参考翻译,而是让模型避免生成“还可以但不够好”的翻译。CPO 论文主要面向机器翻译,强调通过 contrastive preference 训练提升中等规模 LLM 的翻译质量。(arXiv)
适合:
-
机器翻译
-
摘要改写
-
风格改写
-
有“好版本 vs 差一点版本”的对比数据
缺点:
-
不是最通用的 chat alignment 默认选择
-
不同实现里的 CPO 细节可能不完全一致
4.9 cDPO / Robust DPO:处理偏好标签噪声
标准 DPO 默认:
chosen 一定比 rejected 好
但真实数据里经常不是这样。
比如:
chosen 只是更长
chosen 事实错误但语气更好
rejected 更短但其实更准确
judge 打错了
cDPO / Robust DPO 通常会引入 label smoothing 或噪声建模,让训练不要完全相信每个偏好对。
可以理解为:
不是 100% 相信 chosen > rejected
而是 90% 相信,10% 保留不确定性
TRL 的 DPOTrainer 文档里也包含 robust loss 和 label_smoothing 等噪声相关配置。(Hugging Face)
适合:
-
偏好数据由大模型 judge 自动生成
-
judge 质量不稳定
-
chosen/rejected 差异很细
-
医疗、金融、法律等高风险领域
5. 和 PPO / GRPO 的区别
DPO、IPO、KTO、ORPO、SimPO 大多属于:
offline preference optimization
也就是用已有数据训练。
PPO / GRPO 属于:
online RL / reward-based optimization
它们会让模型生成新答案,再根据 reward 计算优势并更新。
GRPO 是 PPO 的一种变体,DeepSeekMath 论文介绍其通过组内分数估计 baseline,省掉 critic model,从而降低 PPO 类训练资源消耗。(arXiv)
区别如下:
| 方法 | 是否在线采样 | 是否需要 reward | 是否需要 reference | 典型用途 |
|---|---|---|---|---|
| DPO | 否 | 否,隐式 reward | 是 | 通用偏好对齐 |
| IPO | 否 | 否 | 是 | 缓解 DPO 过拟合 |
| KTO | 否 | 否 | 通常需要参考约束 | 单条好/坏反馈 |
| ORPO | 否 | 否 | 否 | SFT + preference 一阶段 |
| SimPO | 否 | 否 | 否 | 低显存偏好优化 |
| PPO | 是 | 是 | 通常需要 | RLHF |
| GRPO | 是 | 是 | 通常需要 | 数学/代码/可验证推理 |
6. 工程选型建议
推荐方案:SFT → DPO / SimPO
如果你现在是训练 7B 级模型,最稳妥路线是:
Step 1:高质量 SFT
Step 2:构造 chosen/rejected 偏好数据
Step 3:先跑 DPO baseline
Step 4:显存不够或 DPO 效果一般,再试 SimPO / ORPO
Step 5:用任务评测集验证,而不是只看 loss
为什么先 DPO?
因为 DPO 是当前最成熟的 baseline:
-
论文基础清楚
-
框架支持完善
-
数据格式简单
-
方便和其他方法对比
-
失败原因更容易排查
适合你的工程场景:
如果你要做行业研究、RAG、agent 输出质量对齐,可以构造:
prompt: 研究任务 / 用户问题
chosen: 有证据链、有引用、结构清晰、结论稳健的回答
rejected: 无来源、推断过强、格式混乱、幻觉较多的回答
然后用 DPO 拉开两者差距。
备选方案:ORPO / SimPO
如果你的约束是:
单卡显存有限
reference model 放不下
想快速试验
优先试:
ORPO 或 SimPO
ORPO 适合:
你还没做充分 SFT,希望一次完成 instruction tuning + preference tuning
SimPO 适合:
你已有 SFT 模型,只想低成本做偏好对齐
7. 最小可执行训练骨架
7.1 DPO 数据格式
{"prompt": "请分析某省新能源产业政策的可信度", "chosen": "结论:该政策可信度较高。理由如下:第一,文件来源为省政府官网……", "rejected": "这个政策肯定是真的,因为看起来很正式。"}
{"prompt": "判断这篇行业报告是否适合作为证据源", "chosen": "不建议作为一级证据源。该报告来自商业媒体转载,缺少原始数据表……", "rejected": "可以用,这个网站看起来比较专业。"}
7.2 TRL DPO 训练骨架
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOConfig, DPOTrainer
model_name = "Qwen/Qwen2.5-7B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(
model_name,
trust_remote_code=True
)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto",
trust_remote_code=True
)
# 通常 reference model 可以不手动传,TRL 会基于当前模型构造
# 但工程上为了清晰,也可以显式加载一个 ref_model
ref_model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype="auto",
device_map="auto",
trust_remote_code=True
)
dataset = load_dataset("json", data_files="preference_train.jsonl")["train"]
training_args = DPOConfig(
output_dir="./dpo-output",
per_device_train_batch_size=1,
gradient_accumulation_steps=8,
learning_rate=5e-7,
num_train_epochs=1,
beta=0.1,
max_prompt_length=1024,
max_length=2048,
logging_steps=10,
save_steps=500,
)
trainer = DPOTrainer(
model=model,
ref_model=ref_model,
args=training_args,
processing_class=tokenizer,
train_dataset=dataset,
)
trainer.train()
8. 关键超参怎么理解
| 参数 | 推荐起点 | 作用 |
|---|---|---|
learning_rate |
5e-7 ~ 2e-6 |
DPO 不宜太大,太大会破坏 SFT 能力 |
beta |
0.05 ~ 0.2 |
控制偏离 reference 的程度 |
max_prompt_length |
按任务设置 | prompt 太长会挤压 answer 空间 |
max_length |
prompt + answer 总长 | 对长文本任务很关键 |
gradient_accumulation_steps |
视显存而定 | 稳定 batch |
num_train_epochs |
1~3 | 偏好数据小,过多 epoch 容易过拟合 |
经验判断:
DPO loss 下降,不代表模型一定变好。
必须看:
chosen/rejected accuracy
真实评测集 win-rate
事实性
长度分布
拒答率
幻觉率
格式稳定性
9. 你真正要注意的失败点
9.1 chosen 不等于越长越好
很多偏好数据会隐式奖励长回答:
chosen: 结构完整、很长
rejected: 简短
模型学到的可能不是“更准确”,而是:
回答越长越好
解决:
-
控制 chosen/rejected 长度差
-
加 length-controlled eval
-
使用 SimPO 这类 length-normalized 方法
-
构造“短但正确 > 长但废话”的样本
9.2 rejected 太差,训练价值低
例如:
chosen: 高质量答案
rejected: 胡说八道
这种样本太简单,模型很快学完。
更好的 rejected 是:
表面合理,但有事实错误
结构完整,但证据不足
语气自信,但结论过度
引用存在,但来源等级低
这类 hard negative 对 agent/RAG/研究助手更有价值。
9.3 DPO 不会自动提升知识上限
DPO 主要改变模型偏好,不是注入大量新知识。
如果你的目标是行业研究系统,顺序应该是:
继续预训练 / SFT:补知识和任务格式
DPO / ORPO / SimPO:调偏好、格式、证据链习惯
RAG / tool calling:解决实时知识和可审计证据
不要指望 DPO 解决所有幻觉。
10. 简单总结
你可以这样记:
SFT:教模型“怎么回答”
DPO:教模型“两个回答哪个更好”
IPO:让 DPO 别过度拉开差距
KTO:没有成对偏好也能学好/坏
ORPO:把 SFT 和偏好优化合成一阶段
SimPO:去掉 reference model,省显存
SLiC-HF / RRHF:用排序或 margin 校准回答概率
PPO / GRPO:在线采样 + reward 优化,更适合可验证推理
对真实项目落地:
第一优先级:SFT + DPO
显存不足:SFT + SimPO
只有好/坏标签:KTO
想一阶段训练:ORPO
做数学/代码推理:GRPO
不确定项是:没有一种 DPO 变体在所有模型、所有数据、所有任务上稳定最优。KTO 论文也明确提到,不存在一个 universally superior 的 human-aware loss,最佳 loss 取决于具体任务和数据偏置。(arXiv)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)