KTO 偏好对齐

KTO (Kahneman-Tversky Optimization)

KTO 是 2024 年提出的无需成对偏好的对齐算法:只需「被人类喜欢的样本」和「被人类讨厌的样本」两个集合,就能做偏好对齐,比 DPO 节省一半标注成本。

详细解释

KTO(Kahneman-Tversky Optimization,卡尼曼-特沃斯基优化) 以诺贝尔经济学奖得主 Daniel Kahneman 与 Amos Tversky 命名,是 2024 年 2 月由 Allen Institute 研究员提出的”偏好对齐算法里最省事的一位”。DPO 需要你每条样本给”两个候选回答做一对一排序(chosen vs rejected 成对)“,KTO 直接允许”单边”标注:你只需要把历史回答分成两堆——“这堆用户点了满意/复制/用了(positive)“和”这堆用户投诉/重问/举报了(negative)“,甚至两堆可以来源于完全不同的 prompt,完全不需要是同一个问题的两个候选,就能训练。对于 99% 的真实业务,这个数据格式天然就是你后台已经在存的日志(用户点👍点👎的历史),不用专门搭两两比较的标注工具——这是 KTO 最大的商业价值。

KTO 的直觉:前景理论套入 RLHF

Kahneman & Tversky 的”前景理论(Prospect Theory)“是行为经济学鼻祖:人对”失去”的痛苦要比同等量级”得到”的快乐强 2 倍左右——赢 100 块的开心,需要赢 200 到 250 块才能对冲输掉 100 块的难受。KTO 把这个心理规律写成了损失函数的两个分支:

  • positive 样本(人类喜欢的回答):最小化 −log σ(β (KL_ref_policy − desirable_utility))。直观 = “SFT 参考模型本来就会说这个回答,但你还要比参考模型更爱说它一点”(KL 越大、损失越小)。
  • negative 样本(人类讨厌的回答):最小化 −log σ(β (undesirable_utility − KL_ref_policy))。直观 = “这种回答 SFT 就已经不太爱说了,你要比参考模型更讨厌它,越远离越好。”

β 是 KTO 的唯一新超参数(desirable / undesirable 不对称温度),一般取 β=0.1 至 0.5,对应”人对讨厌的东西要比喜欢的东西敏感度几倍”。

数据格式对比(一眼看懂 KTO 省了多少事)

假设你有后台日志:

时间用户问了什么模型回答了什么用户反馈
T1如何把 CSV 导入 pandas?pd.read_csv("a.csv")👍 Positive
T2如何把 CSV 导入 pandas?用 MySQL 的 LOAD DATA 命令去……👎 Negative
T3帮我写一首关于海的诗“海浪轻轻拍打着礁石……”👍 Positive
T4翻译一下这句话成英语(乱输出了一堆奇怪字符)👎 Negative
  • 做 DPO 需要:把同一个问题下的正回答和负回答配对 → 产生 (prompt, chosen=T1回答, rejected=T2回答)(prompt, chosen=T3回答, rejected="假设生成的另一首差诗")成对 样本。T4 根本没配对对象,要么扔了,要么你得再用 SFT 给它额外生成一个”好回答”才能凑对。
  • 做 KTO 需要:直接用 4 条单边样本,不管 prompt 相同不相同 → 2 条 labeled positive、2 条 labeled negative → 丢进去就跑。

对于日志系统,KTO 直接能用历史 ↑/↓ 记录;DPO 每一条都要重新生成/重排,标注链路成本翻倍不止。

与 DPO / RLHF 的效果对比(公开基准,截至 2025 Q1)

算法AlpacaEval 2.0 胜率MT-Bench 平均分需要成对偏好?显存开销标注成本
SFT(基线)25%6.21×Model最低
KTO71%7.7❌ 单边即可2×Model(+Reference)最低
DPO73%7.9✅ 需要成对2×Model(+Reference)中等
PPO RLHF75%8.1✅ 需要成对 + RM4×Model最高

结论:KTO 用 DPO 一半的标注成本(少了配对手工),拿到了离 DPO 只差 1 到 2 个百分点的效果,在标注投入预算有限的早期团队 ROI 明显最高。唯元智创 的对齐任务面板默认支持 3 种格式 JSONL 自动识别,同一套日志 {prompt, completion, label: pos/neg} 拖进去就能跑 KTO,无需任何预处理脚本。

常见问题

我后台只有 👍 数据没有 👎 数据,KTO 能跑吗?
能,学术界叫”UKN(Unknown Negatives)“合成负例的做法,KTO 官方代码和 HuggingFace TRL 都支持了。做法:把 positive 池里抽 20% 出来,当成”隐含负样本”——即你没有明确的讨厌样本,就从”模型本来会说的回答里”随机选另一个 prompt 的回答当 negative,效果会比全有标注下降 2% 左右,但远高于不做对齐。经验:只要 positive 负 positive 的比例 ≥ 1:5(一条负至少配 5 条正),KTO 就能稳定工作。
KTO 会不会因为 negative 来源不同 prompt,学到”跨 prompt 错误的偏好”?
不会,因为 KTO 的损失函数里每一条样本都还是基于 “(prompt, 模型自己的回答, 参考 KL)” 三要素计算的。把一个翻译任务里的”差回答”标记成 negative,并不会”让写诗任务也要避开这些字符”,因为计算 KTO negative 分支时,用的是写诗那个 prompt 下 SFT 模型生成该负回答的参考概率——这个概率极低,相当于”这两个 prompt 根本不搭,模型本来就不会这么回答”,损失为 0 自然不会学。KTO 学的是”给定 prompt,模型对回答的偏好分布形状”,而不是”回答字符串本身是好是坏”,所以跨 prompt negative 其实是无害的噪声。
KTO 和 SimPO / ORPO 怎么选?
看你手上的数据格式:(1)有成对偏好(chosen/rejected 同 prompt)→ 上 DPO 或 SimPO(2024 新起,不带参考模型,效果略好)。(2)只有单边 👍/👎 日志,没成对 → 上 KTO。(3)既有成对又想把 SFT 和对齐合并成一步 → 上 ORPO(把 SFT loss + 偏好 loss 叠加,省掉单独 SFT 阶段)。效果差距都在 ±1% 内,选最省你标注成本的那个,比纠结算法本身更重要。