ORPO
胜算比偏好优化
ORPO: Monolithic Preference Optimization without Reference Model
ORPO 是一种用于大语言模型偏好对齐的方法。它的核心想法很简单:
把监督微调和偏好优化合并到同一个目标函数里,一边继续学习更优回答,一边对较差回答施加一个较弱但明确的惩罚。
ORPO 这个名字来自 Odds Ratio Preference Optimization。这里的 odds ratio 可以理解成 胜算比:如果模型对更优回答的“胜算”明显高于较差回答,那么说明模型更符合偏好数据。
ORPO = 监督微调 + 胜算比惩罚。
它想解决什么问题
在很多偏好对齐方法里,训练流程通常比较长:
- 先做监督微调;
- 再引入奖励模型或参考模型;
- 再做一轮偏好优化。
ORPO 认为,这样的流程有两个明显问题:
- 训练链路更长,算力和显存开销更大;
- 监督微调和偏好优化被拆成两个阶段,目标不够统一。
于是 ORPO 的思路是:
能不能在监督微调时,顺手把“更喜欢哪种回答”的信息也一起学进去?
它给出的答案是:可以。做法就是在普通监督微调损失之外,再加一个基于胜算比的偏好项。
训练数据
ORPO 使用的是 成对偏好数据。
对同一个输入
- 一条是人类更偏好的回答,记成
; - 一条是人类不那么偏好的回答,记成
。
这里下标:
表示 winner,也就是更优回答;表示 loser,也就是较差回答。
所以一条训练样本通常写成:
这说明 ORPO 仍然需要成对偏好数据,只是它不再额外引入参考模型。
先定义一个序列得分
为了比较两条回答谁更“像模型更愿意生成的回答”,ORPO 先定义了一个长度归一化后的序列得分。
给定输入
这里:
是当前语言模型; 是回答长度; - 右边是逐 token 对数概率的平均值。
要特别注意:
这里的
之所以这样写,是因为如果直接使用整句概率,长回答天然会因为 token 更多而更容易吃亏;做平均以后,长度影响会小很多。
所以这一项可以粗略理解成:
模型平均而言有多愿意生成这条回答。
胜算
有了上面的序列得分,ORPO 再定义一条回答的 胜算:
这条式子的意思是:
- 如果
越大,说明模型越倾向于这条回答; - 那么对应的胜算也会越大。
生成这条回答,相对于“不生成这条回答”,模型有多偏向它。
胜算比
接下来,ORPO 不是单独看某一条回答的胜算,而是比较两条回答的胜算之比,也就是 胜算比:
如果这个值大于 1,说明模型更偏向更优回答;
如果这个值很大,说明模型明显更偏向更优回答;
如果它小于 1,反而说明模型更偏向较差回答,这显然不是我们想要的。
所以 ORPO 的目标就是:
让更优回答的胜算比越来越大。
把胜算比写成对数形式
为了更方便优化,ORPO 使用的是 对数胜算比。
先把上面的式子取对数:
再把
所以:
ORPO 不是单纯想让更优回答的分数更高,它同时还在看:
- 更优回答是不是足够高;
- 较差回答是不是应该被压低。
也就是说,它天然同时包含“拉高优选回答”和“压低拒选回答”两层作用。
ORPO 的偏好损失
有了对数胜算比之后,论文把偏好项写成:
其中
这条式子怎么理解?
那么损失就是:
这个形式和很多二分类偏好目标很像。它的性质很简单:
- 如果
很大,也就是更优回答明显优于较差回答,那么 接近 1,损失就很小; - 如果
很小甚至是负的,也就是模型没有明显偏向更优回答,损失就会很大。
所以最小化这个损失,本质上就是:
让对数胜算比越来越大。
为什么要套一层 Sigmoid
如果只把目标写成“直接最大化
这样做有两个好处:
第一,它把目标变成了一个更标准的、数值上更稳定的分类式损失。
第二,它让“更优回答胜过较差回答”这件事,变成一个明确的偏好判别目标。
所以这一步可以简单理解成:
把“更优回答应该赢”这件事,包装成一个平滑的可优化损失。
ORPO 的完整目标函数
ORPO 的总目标由两部分组成:
- 监督微调项;
- 胜算比偏好项。
论文写成:
其中:
是普通监督微调损失; 是上面定义的胜算比偏好损失; 是权重系数,用来平衡这两部分。
监督微调项在做什么
ORPO 里的监督微调项并不神秘,本质上就是普通的负对数似然。常见写法可以写成:
它的作用是:
强力拉高更优回答的生成概率。
这一步非常重要。因为如果只做偏好比较,而没有一个稳定的“朝更优回答靠拢”的主干目标,模型训练可能会不够稳,也更难快速进入目标分布。
所以 ORPO 的直觉可以概括成:
- 监督微调项负责“强适配”到更优回答;
- 胜算比项负责“弱惩罚”较差回答。
这也是原论文图示里强调的:
strong adaptation + weak penalty
这条损失到底在推动什么
把完整目标再看一遍:
它同时在做两件事。
第一件事:学会更优回答的风格
监督微调项会直接提升更优回答
这意味着模型会更像在学“老师答案”。
第二件事:别把较差回答也一起抬上去
如果只做监督微调,模型确实会越来越会生成更优回答的风格,但很多时候,较差回答的概率也会一起上升。
ORPO 论文正是基于这个观察,认为单靠监督微调不足以完成偏好对齐,因为它没有显式地压制不想要的回答风格。
于是胜算比项就补上了这一刀:
- 希望
的胜算更大; - 希望
的胜算更小。
所以从作用上看,ORPO 不是“普通 SFT 再加一点点花样”,而是:
在 SFT 主干上,加入一条明确区分优选回答和拒选回答的偏好约束。
为什么 ORPO 不需要参考模型
这是 ORPO 最重要的卖点之一。
像 DPO 这一类方法,常常会显式用到一个 参考模型,用来衡量“当前策略相对初始策略变化了多少”。
而 ORPO 没有这一步。它的偏好信息完全来自:
- 当前模型对优选回答的得分;
- 当前模型对拒选回答的得分;
- 以及它们之间的胜算比。
也就是说,ORPO 的偏好优化是在当前模型内部完成的,而不是通过“当前模型 vs 参考模型”的差值来完成。
这就是为什么它常被称为:
- 无参考模型偏好优化
- 单体偏好优化
- 单阶段偏好对齐
这里的“单体”意思就是:
整个训练目标只围绕一个模型展开,不再额外挂一个参考模型。
为什么说它是“单阶段”的
ORPO 还有一个关键词叫 monolithic,可以翻成 单体式 或 单阶段式。
它的含义是:
监督微调和偏好优化不再分两段训练,而是直接合并成一个统一目标,一次训练完成。
这和很多“先 SFT、再偏好优化”的流程很不一样。
所以 ORPO 的训练链路更短,也更节省资源。
ORPO 和 DPO 的一个直观区别
- DPO 更强调“当前模型相对参考模型,应该更偏向优选回答而不是拒选回答”;
- ORPO 更强调“在监督微调主目标上,直接用胜算比把优选回答和拒选回答拉开”。
所以 ORPO 的味道更像:
把偏好对齐做成一个带偏好惩罚的监督微调。
而不是把它拆成独立的“参考模型对比优化”。
一个小例子
假设对同一个问题
那么两者的胜算分别是:
于是胜算比是:
取对数得到:
这时偏好损失是:
因为
这表示模型已经明显更偏向优选回答。
如果反过来,模型对较差回答的得分更高,那么胜算比就会掉到 1 以下,
ORPO 的优点
ORPO 最突出的优点主要有四个。
1. 训练链路更短
它把监督微调和偏好优化合在同一个目标里,不需要再拆成多阶段流程。
2. 不需要参考模型
这会减少显存占用,也会让训练实现更简单。
3. 目标很直观
它直接围绕“优选回答胜过拒选回答”这件事构造损失,解释起来比较顺。
4. 和监督微调天然兼容
ORPO 并不是完全抛开监督微调,而是在监督微调主目标上附加偏好约束,所以训练往往比较稳。
ORPO 的局限
当然,ORPO 也不是没有代价。
1. 它仍然需要成对偏好数据
如果没有
2. 它对权重 有依赖
如果
如果
3. 它并不等于“绝对正确的价值函数”
ORPO 学到的是“在这批偏好数据上,更优回答应该胜过较差回答”,而不是某种完美、普适、无偏的人类价值函数。
总结
胜算比偏好损失:
完整 ORPO 目标:
ORPO 是一种无参考模型、单阶段的偏好对齐方法。它不是把监督微调和偏好优化拆开做,而是把两者合成一个统一目标:一边用监督微调项强力学习优选回答,一边用对数胜算比损失把优选回答和拒选回答拉开。
它的核心创新在于,不再依赖额外参考模型,而是直接利用当前模型对两条回答的长度归一化序列得分,构造胜算和胜算比,从而把“偏好对齐”写成一个可以直接优化的训练目标。
ORPO = 在监督微调损失上,加一个让优选回答胜过拒选回答的对数胜算比损失。