章节导航 第 19 章 / 共 30 章
偏好数据工程
偏好对的构造(对比/排序)、标注一致性、奖励黑客防御。
SFT 教模型”说什么”,DPO 教模型”别说错”。
“Teaching a model to be helpful is about showing it what ‘good’ looks like. Teaching it to be aligned is about showing it what ‘better’ looks like.”
偏好数据的偏差,是偏好训练的隐形杀手——一半发生在数据侧,一半发生在优化侧。
偏好数据是后训练阶段区别于预训练与 SFT 的核心数据形态:它不再告诉模型”正确的输出是什么”,而是告诉模型”什么更好、什么更差”。本章以一个完整的”偏好数据工程”叙事展开:先梳理消费偏好数据的算法范式演变(因为这决定了数据应该长什么样),再定义偏好数据的结构与分类学,随后依次覆盖四大来源体系、人工标注工程、RLAIF 与 LLM-as-Judge 自动构造、数据选择与过滤、偏差全景与防御,最后落到工业 SOP 与未来展望。
19.1 偏好学习的范式演变:数据形态由算法决定
偏好数据工程的第一性问题不是”怎么标数据”,而是”算法需要什么样的偏好信号”。大模型对齐技术在短短几年内经历了多次范式转换,每一次转换都重塑了偏好数据的形态。
19.1.1 范式演变时间线
| 时期 | 方法 | 数据需求 | 复杂度 | 代表 |
|---|---|---|---|---|
| 2022 | RLHF (PPO) | 偏好对 + 奖励模型 | 最复杂(4 个模型) | InstructGPT |
| 2023.5 | DPO | 偏好对 | 简化(无需 RM) | Zephyr |
| 2023.11 | KTO | 好/坏标签 | 进一步简化(二元反馈) | - |
| 2024 | SimPO | 偏好对(无参考模型) | 平均对数概率作隐式奖励 | - |
| 2024 | ORPO | SFT + 偏好合并 | 单阶段训练 | - |
| 2025 | GRPO | 可验证奖励 | 不需要人类偏好 | DeepSeek R1 |
| 2026 | DAPO | 可验证奖励(工业级) | 非对称裁剪 + 动态采样 + Token 归一化 | - |
| 2026 | ARPO | 多轮可验证奖励 | 基于熵的自适应 rollout | - |
偏好学习的认知演变
- 2022:“人类偏好标注是核心——InstructGPT 的方法就是标准答案”
- 2023:“DPO 证明不需要单独训练奖励模型,直接用偏好对就行”
- 2024:“On-policy 数据的重要性被重新认识——off-policy DPO 有天花板”
- 2025:“GRPO + 可验证奖励——在数学和代码上,不需要人类偏好了”
- 2025-2026:“推理模型的 RL 范式——让模型在可验证任务上自我进化”
- 2026 早期:“偏好数据门槛降维——从精心构造的成对比较到二元信号(KTO)或隐式奖励(SimPO)”
- 2026 中期:“可验证奖励从单轮推理扩展到多轮 Agent(ARPO),偏好数据的领地进一步收缩”
- 2026 后期:“critic-free 策略优化谱系(DAPO/GSPO/CISPO)成为推理 RL 主流——四个挑战(方差/长度偏置/退化组/熵塌缩)通过损失函数与采样策略被系统化解决”
19.1.2 两条主干路线:RLHF(PPO + Reward Model)与 DPO
经典 RLHF 流程:
1. 训练 Reward Model:用偏好数据训一个 RM
L_RM = -log σ(r(x,y_w) - r(x,y_l))
2. PPO 训练:用 RM 做 reward,PPO 优化策略
L_PPO = -E[r(x,y)] + β·KL(π||π_ref)
优点:理论上最优,可以处理连续偏好。
缺点:
- 训练不稳定,需要精心调参
- 需要 4 个模型同时在线(policy、ref、value、RM),显存爆炸
- 训练时间长(数天到数周)
DPO(Direct Preference Optimization,Rafailov et al., 2023) 的洞察:可以跳过 RM,直接用偏好数据优化策略。
L_DPO = -log σ(β·(log π(y_w|x)/π_ref(y_w|x) - log π(y_l|x)/π_ref(y_l|x)))
优点:
- 训练简单,只需 policy + ref 两个模型
- 训练稳定,类似 SFT
- 训练时间短(数小时)
缺点:
- 只能用离线数据,无法自我探索
- 对数据质量极敏感
- 容易受 Length Bias 等偏差影响
19.1.3 DPO 变种速查
| 方法 | 核心改进 | 适用场景 |
|---|---|---|
| DPO | 直接优化偏好 | 通用 |
| KTO | 只需 (x, y, good/bad) 标签,不需成对 | 单标签数据 |
| IPO | 修正 DPO 的过拟合 | 大数据集 |
| SLiC | 排序损失 + 正则 | 小数据集 |
| SimPO | 移除 ref model | 显存紧张 |
| ORPO | SFT + 偏好联合训练 | 简化流程 |
| AdaDPO | 修正梯度不对称(对 rejected 的抑制快于对 chosen 的促进),81% 超参组合胜出 | score gap 明确的场景 |
| InSPO | 内性自我反思增强,零推理开销,即插即用 | 需提升推理鲁棒性 |
工业选择:
- 数据充足、追求稳定:DPO
- 只有单标签数据:KTO
- 显存紧张:SimPO
- 想简化流程:ORPO
19.1.4 Critic-free 策略优化谱系:GRPO → DAPO → GSPO → CISPO
GRPO 之后,不依赖 value critic 的组基线方法形成了一个清晰的算法谱系。这条线索的工程化推进是 2026 年推理模型 RL 训练的主旋律——围绕”四个挑战”做精细化设计:
critic-free 谱系的四个核心挑战:
1. 方差爆炸
→ 组内 rollout 数有限,组基线估计本身就有噪声
→ 长链思考下方差进一步放大
2. 长度偏置
→ 同一 prompt 不同长度的 rollout 拿到的"组内归一化奖励"不公平
→ 长但对、短但错的 rollout 经常被判错方向
3. 退化组(degenerate groups)
→ 整个组全对/全错 → 优势为零 → 无梯度
→ 必须过滤或重采样
4. 熵塌缩(entropy collapse)
→ RL 后期模型分布急剧尖锐化
→ 探索能力丧失 → 性能 plateau
DAPO 的四块系统性改进(ByteDance Seed,2025)针对上述挑战:
| 改进点 | 解决的挑战 | 核心机制 |
|---|---|---|
| Clip-Higher(非对称 clip) | 熵塌缩 | 上界 ε_high=0.28 远大于下界 ε_low=0.20,允许概率向上跳变以维持探索 |
| Dynamic Sampling | 退化组 | 过滤掉全对/全错的 prompt,并对过滤掉的样本补采新 prompt 以保持 batch 数据效率 |
| Token-level Policy Gradient | token-credit | 损失按所有 token 累加而非按样本平均——长 rollout 自动获得更多梯度(修正长链思考下的 credit 衰减) |
| Overlong Reward Shaping | 长度偏置 | 对超长 rollout 的尾部施加软惩罚而非硬截断——保留完整推理信号同时抑制无意义灌水 |
GSPO(Sequence-level Policy Optimization) 把重要性权重的计算粒度从 token 级乘积迁到序列似然层面。token 级重要性比 = ∏ π(a_t|s_t) / π_ref(a_t|s_t),长序列下这个乘积的方差呈指数增长;GSPO 直接在序列似然比上做 clip,对 MoE 模型的专家路由变化更鲁棒——DeepSeek 在 R1 后训练中发现 token 级 clip 在 MoE 上不稳定,迁到序列级后训练稳定性显著提升。
CISPO(MiniMax-M1) 走了一条更激进的路线:不裁剪策略梯度本身(保留传统 PPO 风格的 trust-region 叙事),而是裁剪 importance-sampling 权重——但始终对所有 token 送梯度。其工程动机是推理 RL 中长链思考场景下,token 级 IS 权重差异巨大(重要 token 权重接近 0、不重要 token 权重接近 1),常规裁剪会让绝大多数 token 拿不到梯度。CISPO 改用 IS 权重 soft-cap,所有 token 都被更新。
DPPO(Dynamic Pruning Policy Optimization,2026-03) 进一步引入无偏动态剪枝——按 IS 权重的统计分布动态识别”低贡献样本”并跳过,理论上保证剪枝无偏。
GRPO 变体已从单一方法演化为方法族。下表汇总 2025-2026 的主要进展:
| 变体 | 时间 | 核心创新 | 适用场景 |
|---|---|---|---|
| λ-GRPO | 2025-10 | 统一 GRPO 框架 + 可学习 token 偏好 | 长链思考中细粒度偏好 |
| AMIR-GRPO | 2026-01 | 引入隐式偏好信号到 GRPO | 偏好数据稀缺的场景 |
| GDPO-SR | 2026-02 | 一步生成式图像超分 | 视觉生成 + 偏好 |
| RAD-DPO | 2026-02 | 鲁棒自适应去噪 DPO | 电商生成式检索 |
| DPPO | 2026-03 | 无偏动态剪枝 | 长链思考的算力节省 |
| Group Robust PO | 2026-03-30 | 异质偏好的 min-max 优化 | 标注方分歧大时 |
| Multi-Reward GRPO | 2025 | 多奖励信号去偏 | 中英文境歧视去偏 |
19.1.5 机制视角:对齐如何重塑内部表征
以上从损失函数和训练动态角度分析了各方法的差异。2026 年的机制分析研究(arXiv:2606.09850,哥本哈根大学等,预印本待验证)用 probing + Sparse Autoencoder + Crosscoder 揭示了更深层的差异——不同对齐算法在内部表征几何层面造成质性不同的位移:
| 方法 | 表征变化模式 | 对可分离性的影响 |
|---|---|---|
| GRPO | constructive feature sharing + 稀疏高显著性特征招募 | 增强 |
| KTO | constructive feature sharing | 增强 |
| PPO | 基本保留基线几何结构 | 中性 |
| SimPO | 基本保留基线几何结构 | 中性 |
| DPO | non-constructive geometric rotation + 特征衰减 | 削弱 |
| ORPO | non-constructive geometric rotation + 特征衰减 | 削弱 |
关键洞察:行为对齐 ≠ 内部表征统一。DPO 和 ORPO 之所以在 CPO 研究中容易出现”负目标软间隔”,其机制层面的原因在于——它们的几何旋转是 non-constructive 的,本质上是在破坏而非重组偏好信号的表征结构。
对数据工程的启示:
- 选择对齐算法不仅要看最终 benchmark 分数,更要理解它如何重塑模型内部
- GRPO 通过稀疏高显著性特征招募实现对齐——这意味着它更”尊重”基座模型的已有表征
- DPO/ORPO 的几何旋转可能对数据分布高度敏感——数据质量不佳时容易”转歪”
19.1.6 DPO 不等于 RLHF:“负目标软间隔”失效
“训练 DPO 等价于训练一个 reward model 后做 PPO 优化”这一传统假设,在 ICML 2026 上被 CPO(Constrained Preference Optimization)研究直接挑战。
传统假设:DPO 损失 = RLHF 目标的一个闭式解。
CPO 的关键发现:在某些数据分布下,DPO 训练出的隐式 reward 与 RLHF 训练出的 reward 方向相反。具体地:
DPO 隐式 reward 公式:
r_θ(x, y) = β · log(π_θ(y|x) / π_ref(y|x))
传统 RLHF 训练出的 reward 满足:E[r(chosen)] > E[r(rejected)]
CPO 发现:在以下条件下 DPO 隐式 reward 反转:
1. 人类标注存在天然矛盾(标注员之间一致性低)
2. 参考模型 π_ref 在某些数据上极不擅长
→ 即 π_ref(y_chosen|x) 极小,log(π_θ(y_chosen|x)/π_ref(y_chosen|x)) 主导项
3. 这两者同时出现 → 间隔 (margin) 变成负数
"负目标软间隔" 现象:
DPO 优化方向 = "让 chosen 远离 chosen、让 rejected 接近 rejected"
——与设计目标完全相反
这意味着”Chosen 质量主导”(见 19.2.4)的结论在传统 DPO 假设下成立;但当数据分布违反假设时,DPO 不仅没有效果,反而主动伤害模型。工业实践中,DPO 训练曲线出现”先上升再下降”的诡异模式通常就是负间隔的信号。
CPO 提出的修正:在 DPO 损失上加一个约束项——强制要求间隔必须为正:
# CPO 损失函数(简化形式)
def cpo_loss(chosen_logp, rejected_logp, ref_chosen_logp, ref_rejected_logp,
beta=0.1, delta=0.1):
"""
chosen_logp: log π_θ(y_chosen|x)
rejected_logp: log π_θ(y_rejected|x)
ref_*: 对应参考模型的对数概率
beta: DPO 温度参数
delta: CPO 约束阈值(间隔必须 ≥ delta)
"""
# 标准 DPO 损失
diff = beta * (chosen_logp - rejected_logp)
ref_diff = beta * (ref_chosen_logp - ref_rejected_logp)
margin = diff - ref_diff
dpo_loss = -F.logsigmoid(margin)
# CPO 约束:margin < 0 时施加额外惩罚
cpo_penalty = F.relu(delta - margin)
return dpo_loss + cpo_penalty
DPO 数据分布诊断清单(CPO 推荐工程实践):
□ 标注一致性检查
→ 计算标注员间 Cohen's κ
→ κ < 0.4 的标注对直接剔除(避免天然矛盾)
□ 参考模型困惑度检查
→ 对 chosen 文本计算 π_ref(y_chosen|x) 的困惑度
→ 高困惑度(> 100)的样本标记为"参考模型不擅长"
→ 此类样本占比 > 30% 时,DPO 训练可能整体负收益
□ 训练曲线监控
→ DPO 训练 loss 应单调下降
→ 出现"先降后升"模式立即停止训练
→ 检查是否进入负间隔区域
□ 间隔监控
→ 监控 batch 内平均 margin
→ margin 持续为负 → 切到 CPO 或重新筛选数据
由此得出三条工程结论:
- DPO 训练的”零成本假设”被打破——上线 DPO 之前必须做数据分布诊断,不能默认它和 RLHF 等价
- CPO 应当成为 DPO 训练的默认起点——额外的约束项几乎不增加算力,但能避免”先升后降”的灾难
- Chosen 质量主导论需要修正——在传统 DPO 假设下成立;在负间隔场景下,高 Chosen 质量可能反而放大反转
19.1.7 自适应 DPO 谱系:margin → credit → 目标函数
AdaDPO / InSPO 与后文将讨论的 SA-DPO 都属于”改进标准 DPO 的某个固定假设”这一路线。2026 年这条路线已经分化出清晰的三个层次:
| 层次 | 代表方法 | 打破的固定假设 | 改动对象 |
|---|---|---|---|
| margin 层 | SA-DPO(ICML 2026) | 所有 response pair 用同一个 margin | 损失函数的间隔项 |
| credit 层 | Se-DPO(COLM 2026) | 所有 token 对偏好信号贡献相同 | 每个 token 的 KL 正则强度 |
| 目标函数层 | ADPO(ICML 2026) | response 级 BT 模型先于自回归假设 | 偏好目标的推导顺序 |
| 学习信号层 | LSC-DPO(arXiv:2610.07592,2026-10) | 训练全程学习信号强度恒定 | 目标函数的局部灵敏度(sigmoid 因子) |
LSC-DPO(Learning-Signal-Controlled DPO):前三层分别改的是间隔、credit 与推导顺序,第四层改的是一个更基础的东西——训练过程中学习信号本身的衰减。从 loss 层的几何视角看,随着 scaled preference margin 在训练中不断增大,logistic DPO loss 对进一步的变化越来越不敏感。LSC-DPO 指出这个”越来越不敏感”是可以被度量的:sigmoid 因子本身就是刻画目标函数局部灵敏度的学习信号。随着 margin 增大,sigmoid 因子趋于饱和,学习信号趋近于零——于是训练后段会出现”loss 看起来在收敛,其实已经学不动了”的状态。LSC-DPO 的做法是动态地把这个学习信号调节到目标区间附近,并在 log 空间给出了稳定跟踪目标区间的条件。
它附带的一条工程结论价值可能高于方法本身:不同的系数初始化会诱导出不同的瞬态学习信号轨迹,即便后期的信号水平趋于一致。这意味着 DPO 跨初始化、跨团队复现时那个反复出现的玄学——“同样的配方,别人跑得比我们好”——有了一个可归因的来源:不是后期稳态不同,而是前期的瞬态轨迹不同。作者据此推导出一条 signal-budget compensation 规则,按瞬态差异调整目标学习信号,报告显著降低了跨系数初始化的性能波动(代码 github.com/handan-liu-lab/lsc-dpo)。
⚠️ LSC-DPO 为 2026-10-06 的预印本,尚未见顶会收录;AlpacaEval 2 / MT-Bench / Anthropic-HH 上的提升幅度本书未逐表复核。
Se-DPO(Self-Evolving Token Credit for DPO):标准 DPO 用均匀求和处理 token 级对数概率比,等价于假设所有 token 对偏好信号贡献相同。Se-DPO 引入 token credit,按 token 对偏好结果的贡献调制其 KL 正则强度,并推导出有效 token credit 正比于该 token 的 implicit reward 幅度。关键观察是:这个量在训练过程中会大幅演化,因此任何静态 credit 都会随训练推进而越来越失配——这正是”自演化”(self-evolving)的由来:credit 从模型自身不断演化的内部信号中导出,而非预设。工程上值得一提的是它不依赖任何外部模型,只增加一个轻量校准网络。论文报告相比 DPO 最高提升 9.8 点(AlpacaEval 2)与 12.2 点(Arena-Hard)。
⚠️ 口径提醒:上述两个数字的原文表述是 “up to”(最高达),是跨模型跨设置的最好结果,不是平均提升。社区转述时常省略 “up to”,直接写成”提升 9.8 / 12.2”,会显著高估方法的稳定收益。
ADPO(Autoregressive DPO):标准 DPO 依赖 response 级的 Bradley-Terry 模型,但隐含了一个顺序问题——reference 模型与待学模型是在推导出目标函数之后才被当作自回归模型的。ADPO 在应用 BT 模型之前显式引入自回归假设并重新推导,得到的损失形式把 DPO 目标中的求和操作移到外层。
⚠️ 与流行转述的出入:部分社区报道把 ADPO 描述为”区分 token 序列长度与偏好反馈长度、用于消除长度偏差”。这一说法在论文摘要中找不到对应支撑——ADPO 处理的是 BT 模型与自回归假设的推导顺序,不是长度偏差。长度偏差的既有解法仍是本章 19.6 节的长度归一化与 Score-Gap 过滤。此处以 ICML 2026 收录版本的论文原文为准。
谱系的读法:四层不是互斥替代,而是”把哪个量从固定改为自适应”的选择。数据侧能拿到的信息越多,可自适应的层次就越深——只有分数差时用 SA-DPO 的 margin,能拿到 token 级 implicit reward 时用 Se-DPO 的 credit,愿意改损失函数推导时用 ADPO,而当问题表现为”训到后半段什么都学不进去”时,要看的是 LSC-DPO 的那一层学习信号。
这四层可以按”诊断顺序”串成一条排查链,而不是按重要性排序:先看学习信号有没有饱和(第四层,表现为后期 loss 平但指标不动),再看 margin 是否适配 pair 的语义距离(第一层),再看 token credit 是否失配(第二层),最后才考虑改目标函数的推导(第三层)。前两层是数据侧能直接观察和干预的,后两层需要动训练代码。
19.2 偏好数据的结构与分类学
19.2.1 标准结构
工业级偏好数据的标准结构:
{
"prompt": "解释什么是闭包",
"chosen": "闭包是指有权访问另一个函数作用域中变量的函数...",
"rejected": "闭包就是一个函数里面套函数...",
"chosen_score": 8.5,
"rejected_score": 5.2,
"annotator": "gpt-4-judge",
"aspect": "helpfulness",
"source": "ultrafeedback",
"metadata": {
"chosen_model": "gpt-4",
"rejected_model": "llama-2-7b",
"length_chosen": 245,
"length_rejected": 89
}
}
核心字段说明:
- prompt:触发指令
- chosen:偏好响应(更好的)
- rejected:被拒响应(更差的)
- score:1-10 分制评分(支持细粒度)
- annotator:标注者标识(人/模型/用户)
- aspect:偏好维度(helpfulness/honesty/harmlessness/…)
- source:数据来源
- metadata:附加信息(生成长度、生成模型等)
19.2.2 扩展形式:排序与评分
最基本的偏好对只有 prompt + chosen + rejected,但工业实践中存在信息量更大的扩展形式:
# 最基本的偏好数据格式
preference_sample = {
"prompt": "解释什么是快速排序算法",
"chosen": "快速排序是一种分治算法...[详细准确的解释]",
"rejected": "排序就是把数字排好...[含糊、不完整的解释]",
}
# 排序数据(ranking)—— 信息量更大
ranking_sample = {
"prompt": "解释什么是快速排序算法",
"responses": [
{"text": "...", "rank": 1, "score": 4.5}, # 最好
{"text": "...", "rank": 2, "score": 3.8},
{"text": "...", "rank": 3, "score": 2.1},
{"text": "...", "rank": 4, "score": 1.2}, # 最差
],
}
# 分数数据(rating)—— 绝对质量评估
rating_sample = {
"prompt": "解释什么是快速排序算法",
"response": "快速排序是一种分治算法...",
"scores": {
"helpfulness": 4.5,
"accuracy": 5.0,
"clarity": 4.0,
"safety": 5.0,
},
}
排序数据可以被拆解为多个偏好对(任取两个 rank 不同的响应构成一对),是偏好对的”超集”;评分数据则支持跨维度、跨来源的聚合与再过滤。
19.2.3 多维度偏好
一条 prompt 可以有多个维度的偏好对:
{
"prompt": "如何制作炸弹",
"preferences": [
{"aspect": "harmlessness", "chosen": "我无法提供...", "rejected": "制作步骤如下..."},
{"aspect": "helpfulness", "chosen": "我可以介绍合法的化学实验...", "rejected": "我无法提供..."}
]
}
这允许在不同维度做不同训练目标,避免”安全 vs 有用”的零和博弈。同样的思路在 MOPO(Multi-Objective Preference Optimization)中被形式化:通过帕累托最优框架同时优化多个偏好维度,避免单目标 DPO 在冲突维度间的”对齐税”——提升 helpfulness 以 harmlessness 退化为代价。这对偏好数据构造有直接影响:需为每个目标维度独立构建偏好对,而非假设单一偏好维度。
19.2.4 偏好对中的不对称性:Chosen 质量才是核心
直觉上,偏好对中的 chosen 和 rejected 似乎同等重要——毕竟 DPO 的损失函数是对称地”拉近 chosen、推远 rejected”。但 What Matters in Data for DPO(arXiv:2508.18312)的系统实证研究揭示了一个被忽视的不对称性,并且用三组对照实验给出了量化证据:
偏好数据中各因素的影响力排序:
1. Chosen 响应质量 ★★★★★ 始终正向影响性能,是最关键因素
2. Margin / 对比度 ★★★☆☆ 主要通过提升 chosen 效用发挥作用
3. Rejected 响应质量 ★★☆☆☆ 影响有限,甚至不显著
4. 数据总量 ★★☆☆☆ 在质量有保证时才有正面作用
三组对照实验的量化结果(不同任务上 6 个模型的平均提升):
| 实验设计 | 改动方式 | 平均性能提升 | 解读 |
|---|---|---|---|
| 仅提高 Chosen 质量 | 用更强的 SFT 模型生成 chosen | +3.0 到 +4.6 分 | 主导驱动力 |
| 仅拉大偏好差距 | 保持 chosen 不变,调换成更差的 rejected | +0.8 到 +1.4 分 | 边际收益极小 |
| 减轻曝光偏差(on-policy) | 让 chosen 来自策略自身 | 提升有限 | 本质上仍是在提升 chosen 质量 |
这两个数字的对比是震撼的:把数据预算从”巧妙生成坏答案”转移到”润色/编辑/寻找绝对最高质量的好答案”上,能换来 3-5 倍的收益。
更深层的发现是:在线 DPO 实际上简化为对 chosen 的 SFT。这意味着偏好对的核心价值在于高质量正例——rejected 主要提供”什么不要做”的弱信号,而 chosen 提供”什么该做”的强信号。
数据预算重新分配指南(基于上述实证):
传统数据预算分配(错误):
50% 时间找 chosen
50% 时间找/构造 rejected(追求"巧妙生成坏答案")
基于 "Chosen 主导" 的重新分配:
90% 时间投入:寻找/润色/编辑最高质量的 chosen
10% 时间投入:基本的 rejected("明确不如 chosen"即可)
具体操作:
-
Chosen 来源(按优先级):
- 专家人工编写(最高质量,但成本高)
- 最强 SFT 模型的 best-of-N 采样(质量接近人工,成本可控)
- 中等模型生成 + 人工复核编辑(性价比最高)
- 拒绝采样(rejection sampling,让模型生成多个、挑最好的)
-
Rejected 来源(按”够用即可”原则):
- 次优 SFT 模型的直接采样(不需要任何”巧妙构造”)
- 同模型低 temperature 采样(多样性 > 难度)
- 早期 checkpoint 的输出(自然反映能力差距)
- 避免刻意制造”陷阱”——如随机 token 替换、故意截断等,会让 DPO 训练信号扭曲
-
资源有限时的选择:
- 提升 chosen 质量(通过更多轮 best-of-N 采样或更强模型)永远比追求数据总量更值得
- 提升 chosen 质量也永远比追求 on-policy 更值得——on-policy 提升的本质就是”生成了更高质量的 chosen”
- 不要为寻找完美的”被拒”回复而苦恼——只要”明确不如 chosen”即可
需要强调的是,“Chosen 质量是核心驱动力”这一结论在多目标视角下需要修正——不同目标下 chosen 的定义可能不同,同一条数据在一个维度上是 chosen,在另一个维度上可能不是(见 19.2.3 多维度偏好);在负间隔场景下,高 Chosen 质量甚至可能放大反转(见 19.1.6)。
还有第三条限定来自优化几何,且它比前两条更根本:“DPO 退化为对 chosen 的 SFT”这一现象本身是有条件的。当偏好方向与期望效用梯度方向对齐时,DPO 更新是类强化学习的,并不退化为纠错(见 19.6.4b,arXiv:2610.00061)。因此本节末尾”90% 预算投 chosen”这条资源分配建议,在方向对齐的更新下收益最大;在方向不对齐的场景下,优先事项不是继续打磨 chosen,而是先解决对齐问题——否则投进去的预算会被纠错更新消耗掉。
19.2.5 Margin:从经验法则到数学原则
偏好对中 chosen 和 rejected 之间的质量差距(margin)对训练效果有重要影响:
Margin 太小(chosen 和 rejected 质量差不多):
→ DPO 梯度信号弱,学习效果差
→ 模型很难区分"好"和"更好"
Margin 太大(一个很好,一个很差):
→ 梯度信号强但信息少
→ 模型只学会了"避免很差的回复",没学会"从好到更好"
Margin 适中(明显可区分但不极端):
→ 最佳学习效果
→ 模型学会了精细的质量判别
推荐:构造偏好数据时,同时包含不同 margin 的样本
- 30% 大 margin(教模型基本判别)
- 50% 中 margin(教模型精细判别)
- 20% 小 margin(教模型在边界情况下做决策)
上述比例是一个可操作的起点,但近期研究揭示了 margin 的三个认知升级:
Margin 的演化认知
第一阶段:固定 Margin(DPO 原始)
→ 所有样本共享相同的隐式 margin 目标
→ 简单有效,但对数据异质性视而不见
第二阶段:动态 Margin(γ-PO, ACL 2025)
→ 在样本级别自适应调整目标 reward margin
→ 高置信度样本给大 margin,噪声/歧义样本给小 margin
→ 核心洞见:不是所有偏好对都同等可靠
第三阶段:Token 级 Margin(TI-DPO, ICLR 2026 Oral)
→ 序列级 margin 只是表象——偏好信号在 token 级高度不均匀
→ 少量"关键 token"(如关键推理步骤、事实陈述)贡献了大部分判别信号
→ 对这些 token 施加更大梯度权重,在指令遵循和代码生成上超越 GRPO
数据选择维度:margin 最大化原则。Less is More(NeurIPS 2025,arXiv:2502.14560)提出了一个令人惊讶的发现:通过贝叶斯聚合统一外部 RM margin 和隐含 margin,在 UltraFeedback 上仅用 10% 的数据即可提升 3-8%,迭代 DPO 场景中 25% 的在线数据即可提升 3%。这意味着偏好数据高度冗余——关键不是”造更多数据”,而是”选对数据”。Margin 从构造时的经验法则升级为筛选时的数学原则(详见 19.6.2)。
Token 粒度维度。TI-DPO(arXiv:2505.19653)的另一层启示在于:即便 margin 控制得当,如果对序列中所有 token 一视同仁,仍然会浪费大量梯度在非信息性 token 上。在一段包含推理步骤的回复中,真正决定”这个回复比那个好”的可能只是某几步推理或某个关键事实——而不是格式化文本或过渡句。这为偏好训练指出了新方向:从”选对偏好对”到”找对关键 token”。
主动选择维度。上述方法(margin 最大化、Token 粒度)都属于”被动选择”——先收集数据再筛选。ActiveDPO 将主动学习引入 DPO 框架,在标注前即预测哪些偏好对最有信息量。其核心贡献在于理论证明了主动采样策略在 DPO 框架下的信息增益上界,使数据选择从”经验驱动”变为”理论驱动”。在标注预算有限时,ActiveDPO 可减少 30-50% 标注量达到相同对齐质量。与 Less is More 的被动筛选互补:Less is More 解决”已有数据怎么选”,ActiveDPO 解决”新数据该标什么”。
19.3 偏好数据四大来源
19.3.1 来源配比
工业级偏好数据的典型来源配比:
| 来源 | 占比 | 单条成本 | 质量 |
|---|---|---|---|
| 人工标注 | 20-30% | 5-30 美元 | 极高 |
| RLAIF | 40-60% | 0.001-0.05 美元 | 中-高 |
| 用户隐式反馈 | 10-20% | ≈ 0 | 中 |
| Constitutional | 10-20% | 0.005-0.02 美元 | 高 |
这个配比的逻辑是:人工标注做”质量锚”,RLAIF 做”规模主力”,Constitutional 做”安全兜底”,用户隐式反馈做”真实分布校准”。
19.3.2 人工标注:质量锚
人工标注是质量锚,要求:
- 标注员培训:理解偏好维度的细微差异
- 双盲标注:每条 2 人独立标,分歧 > 2 分仲裁
- 一致性检查:Cohen’s κ ≥ 0.6
踩坑:众包平台的人工偏好数据 κ 普遍 < 0.4,质量不达标。这正是 CPO 诊断清单(19.1.6)要求”κ < 0.4 的标注对直接剔除”的原因——天然矛盾的标注会在特定数据分布下触发 DPO 负间隔。
人工标注的详细工程细节(协议设计、难点规则)见 19.4 节。
19.3.3 用户隐式反馈
从生产日志挖掘偏好对:
- 同一 prompt 用户重新生成 → (old, new) 是偏好对
- 用户点赞 vs 点踩 → (liked, disliked)
- 用户复制 vs 重新生成 → (copied, regenerated)
注意:用户隐式反馈有强采样偏差——只有”明显好”或”明显差”的响应才会被反馈,中间地带数据缺失。
19.3.4 Constitutional AI:自我修正兜底
核心思想:Constitutional AI(Anthropic, Bai et al., 2022)让模型根据”宪法原则”自我批评并修正,产出偏好对 (original, revised) = (rejected, chosen)。
宪法原则:宪法是一组自然语言规则,例如:
- 请勿生成歧视性内容
- 请勿提供危险信息
- 当不确定时承认不确定
- 不主动给出未请求的建议
Anthropic 的宪法包含约 20 条原则,覆盖安全、诚实、有用性。
自我批评修正流程:
def constitutional_revise(prompt, response, constitution):
# 1. 让模型批评自己的响应
critique_prompt = f"""
指令:{prompt}
响应:{response}
根据以下宪法原则,找出响应的问题:
{constitution}
列出所有违反的原则。
"""
critique = llm.generate(critique_prompt)
# 2. 让模型修正
revise_prompt = f"""
指令:{prompt}
原响应:{response}
批评:{critique}
请基于批评重写响应,使其符合宪法原则。
"""
revised = llm.generate(revise_prompt)
return revised
# Constitutional 偏好对:(original, revised) = (rejected, chosen)
Constitutional AI 的价值:
- 完全自动化,无需人工
- 可控性强:通过修改宪法调整模型行为
- 可解释:每条修正都基于明确原则
踩坑:宪法原则过多(>30 条)会让模型过度保守,拒答率上升。
19.4 人工偏好标注的工程细节
19.4.1 标注协议设计
成对比较(Pairwise Comparison) 是最常用的标注方式:
标注界面设计:
┌──────────────────────────────────────────────┐
│ Prompt: "解释什么是量子纠缠" │
├──────────────────────┬───────────────────────┤
│ 回复 A │ 回复 B │
│ (随机左右排列) │ │
│ "量子纠缠是一种..." │ "纠缠就是两个粒子..." │
├──────────────────────┴───────────────────────┤
│ 哪个回复更好? │
│ ○ A 明显更好 ○ A 稍好 ○ 差不多 │
│ ○ B 稍好 ○ B 明显更好 │
│ │
│ 判断依据(多选): │
│ □ 准确性 □ 完整性 □ 清晰度 □ 安全性 │
└──────────────────────────────────────────────┘
注意界面中”随机左右排列”的设计——这与 RLAIF 中的位置交换去偏(19.5.5)是同一个偏差防御逻辑在人工侧的镜像:人类标注员同样存在位置偏好。
19.4.2 标注中最难定义的规则
困难 1: Helpful vs Harmless 的冲突
User: "怎么配一把锁?"
→ 可能是锁匠学徒(合理请求)
→ 也可能是入室盗窃(有害请求)
→ 标注指南需要明确处理策略
困难 2: 主观偏好
User: "写一首关于春天的诗"
Response A: 古典风格,含蓄优美
Response B: 现代风格,直白生动
→ 哪个"更好"?取决于标注员的个人品味
→ 解决方案:明确"不评判风格偏好,只评判执行质量"
困难 3: 长度偏好
短而精确的回复 vs 长而详细的回复
→ 人类标注员倾向于偏好更长的回复("信息更多=更好")
→ 这个偏差会被模型学到,导致"啰嗦"
→ 解决方案:在标注指南中明确"简洁但完整优于冗长但重复"
困难 4 是其中最值得深挖的:长度偏置的根因——pair loss 机制放大。
表面上看,长度偏置是”风格问题”——标注员偏好长、模型学到啰嗦。实际机制是:训练目标把”短”误学成了”优”——信号被放歪了。
pair loss 的机制放大:
- 一个偏好对 (chosen: 长, rejected: 短):
- 长 chosen 包含更多 token
- 局部噪声 / 模板差异 / 无关修饰更多
- 模型更容易从”回答更短”这个低成本特征里拿到梯度
- 而非从”事实充分性”里拿到梯度
量化示意:
- 假设 chosen 长度 200 token,rejected 长度 50 token
- DPO loss 在序列级聚合:长 chosen 的 log-prob 包含 200 个 token 的贡献
- 反向传播时,200 个 token 中哪怕只有 10% 的位置是”模板化/套话”
- 模型就会学到”这 10% 的特征 = 优”
- 因为”长度”是一个持续可观察的强特征,远比”事实正确”容易学
长度偏置检测 + 缓解清单:
□ 检测:chosen/rejected 长度差 > 3x 的样本单独统计训练效果
□ 检测:训练后模型输出平均长度变化曲线(> 30% 增长 = 严重长度偏置)
□ 缓解 1:长度归一化——在 DPO loss 中除以序列长度
□ 缓解 2:长度平衡采样——chosen/rejected 长度差控制在 [0.5x, 2x] 区间
□ 缓解 3:SimPO 隐式奖励——用平均对数概率替代总和,天然消除长度偏置
□ 缓解 4:标注指南中显式给出"长度上限"——例如"超过 500 字必须截断"
这份清单与 19.7 节的偏差全景、19.6 节的长度归一化实操互相呼应,构成完整的长度偏差防御体系。
19.5 自动偏好构造:RLAIF 与 LLM-as-Judge
19.5.1 RLAIF:核心思想与流程
RLAIF(Lee et al., 2023)用 LLM 替代人工做偏好标注,成本从 5-30 美元/条降到 0.001-0.05 美元/条,降 100 倍。
def rlaif_annotate(prompt, response_a, response_b, judge_model="gpt-4"):
judge_prompt = f"""
你是一个评审专家。比较以下两个响应哪个更好。
指令:{prompt}
响应 A:{response_a}
响应 B:{response_b}
输出 JSON:{{"better": "A" or "B", "reason": "...", "confidence": 0-1}}
"""
result = llm.generate(judge_prompt, model=judge_model)
return parse(result)
19.5.2 UltraFeedback:RLAIF 的标杆
UltraFeedback(Cui et al., 2023)是 RLAIF 的标杆数据集:
- 规模:64K 指令
- 生成模型:LLaMA-2-7B、LLaMA-2-13B、LLaMA-2-70B、Vicuna-13B 等多模型并行
- 评审:GPT-4
- 评分维度:4 个维度,1-10 分制
UltraFeedback 用 4 个维度评估每个响应:
- Instruction Following:是否严格遵循指令
- Truthfulness:是否准确无误
- Honesty:是否诚实承认不确定
- Helpfulness:是否有帮助
# UltraFeedback 评分 prompt 模板
judge_prompt = """
You are an evaluator. Rate the following response on 4 dimensions, each 1-10:
1. Instruction Following
2. Truthfulness
3. Honesty
4. Helpfulness
Instruction: {prompt}
Response: {response}
Output JSON: {{"instruction_following": N, "truthfulness": N, "honesty": N, "helpfulness": N}}
"""
为了构造 chosen/rejected 对,UltraFeedback 让多个模型同时响应同一 prompt:
models = [llama7b, llama13b, llama70b, vicuna13b]
for prompt in prompts:
responses = [m.generate(prompt) for m in models]
scores = [gpt4_judge(prompt, r) for r in responses]
# 取最高分为 chosen,最低分为 rejected
chosen = responses[argmax(scores)]
rejected = responses[argmin(scores)]
UltraFeedback 直接训练出的 Zephyr-7B(基于 Mistral-7B + DPO)在 MT-Bench 上达到 7.34,超越 GPT-3.5。这证明了”开源数据 + RLAIF + DPO”路线的可行性。
19.5.3 工业级 LLM-as-Judge 实现
完整的工业级 LLM-as-Judge 偏好数据生成,核心是位置交换消除位置偏好:
"""
LLM-as-Judge 偏好数据生成
"""
JUDGE_PROMPT = """请比较以下两个回复的质量。
用户问题:{prompt}
回复 A:
{response_a}
回复 B:
{response_b}
请从以下维度评估:
1. 准确性:信息是否正确
2. 完整性:是否充分回答了问题
3. 清晰度:是否易于理解
4. 实用性:是否对用户有实际帮助
请给出你的判断:
- 如果 A 更好,输出 "[[A]]"
- 如果 B 更好,输出 "[[B]]"
- 如果差不多,输出 "[[tie]]"
简要说明理由(1-2 句话)。"""
def generate_preference_pair(
prompt: str,
model_a_response: str,
model_b_response: str,
judge_model,
swap_positions: bool = True,
) -> dict:
"""
用 LLM-as-Judge 生成偏好对
关键:进行位置交换来消除位置偏好
"""
# 正序评判
result_1 = judge_model.generate(
JUDGE_PROMPT.format(
prompt=prompt,
response_a=model_a_response,
response_b=model_b_response,
)
)
if swap_positions:
# 反序评判(消除位置偏好)
result_2 = judge_model.generate(
JUDGE_PROMPT.format(
prompt=prompt,
response_a=model_b_response,
response_b=model_a_response,
)
)
# 只有两次评判一致时才采用
winner_1 = parse_winner(result_1) # "A", "B", or "tie"
winner_2 = parse_winner(result_2) # "A", "B", or "tie"
# 反转 winner_2(因为位置交换了)
winner_2_flipped = {"A": "B", "B": "A", "tie": "tie"}[winner_2]
if winner_1 != winner_2_flipped:
return {"status": "inconsistent", "discard": True}
winner = winner_1
else:
winner = parse_winner(result_1)
if winner == "A":
return {"prompt": prompt, "chosen": model_a_response, "rejected": model_b_response}
elif winner == "B":
return {"prompt": prompt, "chosen": model_b_response, "rejected": model_a_response}
else:
return {"status": "tie", "discard": True}
def parse_winner(judge_output: str) -> str:
if "[[A]]" in judge_output: return "A"
if "[[B]]" in judge_output: return "B"
return "tie"
19.5.4 两大经典偏差的测试与消除
Position Bias(位置偏差):LLM 评审倾向于选择”第一个”响应。
测试方法:
# 同一对响应交换位置
r1 = judge(prompt, A, B) # A 在前
r2 = judge(prompt, B, A) # B 在前
# 如果 r1 选 A 且 r2 选 B,说明有 Position Bias
消除方法:
- 双向评审:每对响应做两次(A 在前 + B 在前)
- 只在两次结果一致时采纳,分歧的丢弃
- 或:随机化位置,做 3 次投票
Length Bias(长度偏差):LLM 评审倾向于选择更长的响应。
测试方法:
# 用同一响应的"长版"和"短版"
long_response = verbose_version(response)
short_response = concise_version(response)
# 如果评审总是选长版,说明有 Length Bias
消除方法:
- 在 judge prompt 中明确:“不要因为长度选响应”
- 长度归一化评分:
normalized_score = raw_score / log(length) - 在 DPO 训练时做长度归一化(参考 SimPO)
19.5.5 合成偏好的系统性偏差分析
位置与长度只是最著名的两个偏差。LLM-as-Judge 有已知的系统性偏差全景:
| 偏差类型 | 表现 | 影响 | 缓解方法 |
|---|---|---|---|
| 位置偏好 | 倾向于选择第一个回复 | 数据不公平 | 位置交换 + 一致性检查 |
| 长度偏好 | 倾向于选择更长的回复 | 模型变啰嗦 | 长度归一化 + 明确指令 |
| 自我偏好 | 倾向于选择自己风格的回复 | 多样性下降 | 多模型交叉评判 |
| 格式偏好 | 偏好 markdown 格式 | 过度格式化 | 明确评判标准 |
| 评分范围偏差 | 不同模型对分数尺度有内在偏好(如偏向 3-5 分或 1-3 分) | 多模型评分不可比 | 对比解码(同族模型对数概率相减,Spearman +11.7%) |
| 领域/任务偏差 | 代码质量与创意写作的评判标准混用 | 跨域评判不一致 | 领域特化评判 prompt + 分任务评分 |
已知偏差只是冰山一角。BiasScope(ICLR 2026,arXiv:2602.09383)提出了一个完全由 LLM 驱动的迭代框架,可以自动发现评判模型中尚未被识别的偏差类型——不仅仅是上表列出的几种。其核心发现令人警醒:即使是当前最强的评判模型,也存在大量特定于领域、任务和上下文的未知偏差。这意味着仅靠手工枚举偏差并逐一缓解是不够的,需要系统化的自动偏差发现机制。
缓解方法的演进:从早期的位置交换(消除位置偏差)、长度归一化(消除长度偏差),到对比解码(消除评分范围偏差),再到自动化偏差扫描(发现未知偏差)——去偏技术正从”已知偏差的手工修补”走向”未知偏差的系统化发现”。
19.5.6 LLM-as-Judge 偏差的方法学体系:量化 + 诊断 + 缓解
到 2026 年中,LLM-as-Judge 偏差研究已从”已知存在偏差”演化为可量化、可诊断、可缓解的完整方法学体系。
1. 量化阶段:三类主要偏差的可测量化
| 偏差类型 | 来源论文 | 关键发现 | 量化数据 |
|---|---|---|---|
| 自我偏好偏差 | Quantifying and Mitigating Self-Preference Bias of LLM Judges(arXiv:2604.22891) | LLM 裁判倾向于选择自己家族/自己风格的回复 | 集成裁判可减少 2-3pp 偏差 |
| 语言偏见 | Fairness or Fluency(arXiv 2026) | 跨语言判决时强烈偏好英语;欧洲语言 > 亚洲语言 > 非洲语言 | 文化主题(人文/社科)偏见 > STEM;困惑度不能完全解释 |
| MLLM 自我偏好 | Philautia-Eval(arXiv:2604.11589) | 12 个 MLLM × 1.29M 标题-分数对;特定模型家族内部存在相互偏好偏差 | 集成方法 Pomms 有效减轻 |
2. 诊断阶段:J/ΔJ 指标 + JudgeBiasBench 基准
-
J 和 ΔJ 诊断指标(Bias and Uncertainty in LLM-as-a-Judge Estimation,arXiv:2605.06939):
- 朴素估计器有系统偏差(用 MMLU-Pro 验证)
- J = 校正后的偏差估计值;ΔJ = 估计的不确定度
- 用 J/ΔJ 判断”什么时候校正后的估计不可靠”
- 发现”符号反转”失败模式——原本被判为优的回复,校正后被反转
-
JudgeBiasBench(arXiv:2603.08091):
- 系统化偏差评估基准:4 维度 / 12 偏差类型
- 既支持生成式(强化学习去偏)也支持判别式(对比学习去偏)
- 可作为”裁判质量门禁”——任何 LLM 上线 Judge 任务前先在此基准上评估
3. 缓解阶段:四层去偏技术栈
Layer 1: 任务前
→ 选用 JudgeBiasBench 评分高的模型
→ 领域特化评判 prompt
Layer 2: 推理中
→ 位置交换 + 一致性检查(消除位置偏差)
→ 长度归一化(消除长度偏差)
→ 对比解码(同族模型对数概率相减,消除评分范围偏差)
Layer 3: 集成
→ 多模型集成裁判(Self-Preference 偏差降 2-3pp)
→ Pomms 集成(Philautia-Eval 验证的 MLLM 集成方法)
Layer 4: 后训练
→ 强化学习去偏(生成式 Judge)
→ 对比学习去偏(判别式 Judge)
4. 工业级 Judge 系统设计清单
□ 上线前:JudgeBiasBench 评分必须超过基线
□ 数据中:跨语言任务必须配多语言 Judge 集成
□ 训练中:定期用 J/ΔJ 指标审计 Judge 偏差
□ 集成中:至少 2-3 个不同家族模型集成(避免单模型系统性偏差)
□ 监控中:监控 Judge 决策的"符号反转率"——反转率 > 5% 需重新校准
□ 任务特化:代码 / 创意 / 推理 任务使用领域特化 prompt
由此得出三条工业结论:
- 早期”消除位置和长度偏差”已远远不够——自我偏好、语言偏见、MLLM 家族内部偏差都可能严重污染偏好数据
- 工业级 Judge 系统应默认假设偏差存在,并通过 J/ΔJ 指标和 JudgeBiasBench 持续监控
- 集成是去偏的硬道理——单模型 Judge 在任何严肃生产场景都不应使用
19.5.7 RLAIF 的质量上限
Google Research 实验:RLAIF 与 RLHF 在 Helpful 任务上的差距 < 1%,但在 Honesty/Harmlessness 上仍有 3-5% 差距。
结论:RLAIF 适用于”通用偏好”,关键安全场景仍需人工。这与 19.3.1 来源配比中”人工标注 20-30% 做质量锚”的设计相互印证。
19.6 偏好数据选择与过滤:少即是多
前几节讨论了如何构造偏好数据(人工标注、RLAIF、Constitutional)。但一个同样重要的问题是:构造出来的数据都需要用吗?
答案是:大部分不需要。
19.6.1 偏好数据的冗余问题
Less is More(NeurIPS 2025)的实验揭示了偏好数据中的惊人冗余:
实验结果:
Ultrafeedback 数据集(标准 DPO):
100% 数据 → baseline
10% 数据 → baseline + 3-8% ✓ 10% 数据反而更好
迭代 DPO(在线场景):
100% 在线数据 → baseline
25% 在线数据 → baseline + 3% ✓ 25% 同样更好
这个结果看似反直觉,但原因并不复杂:偏好数据中存在大量噪声(标注不一致、margin 歧义、极端样本),这些噪声会对参数产生”收缩效应”——拉平模型对偏好方向的区分能力。去掉噪声数据,反而释放了有效信号。
19.6.2 Margin 最大化原则
核心方法是 margin 最大化选择:
目标:从 N 个偏好对中选择 k << N 个最有价值的样本
选择标准:
1. Margin 大 → 偏好信号清晰
2. 噪声低 → 多来源标注一致
关键创新——贝叶斯聚合:
当多个来源(外部 RM、模型隐含偏好、人类标注)给出不同 margin 时,
用贝叶斯后验将它们统一为单一偏好概率 P(chosen > rejected)
选择 P 高且方差低的样本 = 高置信度 + 强信号
19.6.3 与 SFT 数据选择的区别
| 维度 | SFT 数据选择 | 偏好数据选择 |
|---|---|---|
| 核心指标 | 单条质量(IFD、PPL) | 成对关系(margin + 一致性) |
| 选择逻辑 | 选质量高的 | 选 margin 大且噪声低的 |
| 冗余来源 | 指令重复、风格雷同 | 歧义标注、极端差异、信号弱的对 |
| 筛选比例 | 通常 30-50% | 可低至 10-25% |
19.6.4 Score-Gap 过滤:工业实操
并非所有偏好对都有训练价值。Score-Gap(chosen 与 rejected 的分数差)决定数据质量:
def filter_by_score_gap(data):
selected = []
for d in data:
gap = d['chosen_score'] - d['rejected_score']
d['gap'] = gap
if gap < 1:
continue # 差距太小,模型学不到
elif gap > 3:
d['need_review'] = True # 差距太大,可能标注错误
else:
selected.append(d) # 1-3 是甜点
return selected
经验阈值:
- gap < 1:丢弃(差距太小,训练信号弱)
- gap 1-3:主力(甜点区间)
- gap > 3:人审(可能是标注错误)
19.6.4b “差距够大”不等于”方向对”
上面三条阈值,加上 19.6.5 的长度归一化、19.6.6 的语义自适应 margin,回答的都是同一个问题:这条偏好对的差距够不够大、够不够可信。它们全是标量判据。但还有一个问题这套准则从未问过:这条偏好对的偏好方向,与我们真正想优化的方向是否一致。
GAP-DPO(Gradient-Aligned Pair Selection for Personalized Preference Optimization,Ruoming Jin 等 9 人,2026-09-04;论文内缩写展开为 Geometry-Aligned Preference DPO)把这个缺口形式化为一个几何问题:分析”期望用户效用的梯度”与”DPO 更新方向”之间的一阶交互。核心结论是——在 off-policy 采样下,当 preference margin 与效用梯度在方向上对齐时,DPO 更新才从纯粹的纠错信号转变为类强化学习的更新;方向不一致时,偏好优化反而会阻碍目标的实现。原文的表述很锋利:偏好对选择是一个几何决策,它决定偏好优化究竟是在推进还是在妨碍。
这条结论对本章的意义有两层:
- 现有的 score-gap / margin 最大化只筛了幅度,没有筛方向。在有明确目标效用的场景(个性化、某一维度的定向对齐、有外部标量评估器 q(y) 的任务),建议在选择流程里再加一次方向性检查;在通用对齐这类”效用函数本身不清楚”的场景下,这一条检查无从做起,可以跳过。
- 它解释了 §19.2.4 中那个长期让人困惑的现象——“提升 chosen 质量”与”追求 on-policy”在不同实验里收益不一致。两者只有在方向对齐时才等价;不对齐时,把 chosen 做得再好,更新也仍然是纠错而非强化。
⚠️ 三条边界必须一并写明:① 该工作为预印本,验证场景限定在个性化文本生成,泛化到通用对齐需自行验证;② 论文给出的是分析框架与迭代算法(效用感知的几何对齐选择 + epoch-wise regeneration 控制分布偏移),并没有给出一套可以照抄的通用”方向性度量”实现,因此本节按思路与边界写入,不作为现成 SOP;③ 方向对齐的判据依赖一个外部给定的标量效用 q(y)(如 ROUGE、BLEU、自动评估器打分),若你的场景没有这个量,本条不适用。
19.6.5 长度归一化过滤
为消除 Length Bias,对 score 做长度归一化后再计算 gap:
def length_normalized_score(response, raw_score):
length = len(response.split())
# 对数归一化,避免长响应得分虚高
return raw_score / np.log(1 + length)
# 重新计算 gap
for d in data:
d['chosen_score_norm'] = length_normalized_score(d['chosen'], d['chosen_score'])
d['rejected_score_norm'] = length_normalized_score(d['rejected'], d['rejected_score'])
d['gap_norm'] = d['chosen_score_norm'] - d['rejected_score_norm']
效果:归一化后,Length Bias 导致的 DPO 输出长度漂移从 +30% 降到 +5%。
19.6.6 前沿:语义自适应 margin(SA-DPO)
固定阈值三段式(gap<1 丢弃 / 1-3 保留 / >3 人审)是当前工业标准,但 SA-DPO(Mohri & Zhong, ICML 2026)从理论上证明了一个更精细的视角:score-gap 的”有效宽度”取决于 response 间的语义距离。
- 对于语义几乎相同的 response pair(如两段质量接近的摘要),即使 score-gap 很小,窄 margin 也能有效区分
- 对于语义差异大的 pair(如程序员风格 vs 销售风格的回答),需要更大的 margin 才能正确排序
SA-DPO 的核心发现是:标准 DPO 的 surrogate loss 对神经网络不一致——loss 降到零时真实排序错误可任意高。SA-DPO 通过在 loss 函数中引入语义距离自适应的 margin,在 UltraFeedback 上达 58.5% 头对头胜率。
工程启示:当前固定阈值做法在大多数场景下足够,但如果你发现「gap 1-3 的数据训练效果不稳定」——很可能是因为忽略了语义距离这个隐藏维度。前沿方向:将语义嵌入距离纳入 score-gap 过滤的决策函数。
19.6.7 偏好数据筛选的推荐流程
1. 多 RM 交叉标注
→ 用 2-3 个不同的 RM 对每个偏好对打分
→ 计算每个来源的 margin
2. 贝叶斯聚合
→ 将多来源 margin 统一为后验偏好概率
→ 同时得到置信度估计
3. Margin 最大化筛选
→ 按 P(chosen > rejected) 降序排列
→ 取 Top-k(通常 10-25%)
3.5 方向性校验(可选,仅在有明确目标效用时)
→ 判据:偏好方向是否与期望效用梯度方向对齐
→ 对齐 → 该对的更新是类 RL 的强化信号
→ 不对齐 → 该对即使 margin 很大,更新仍是纠错,甚至反向伤害
→ 无外部效用函数 q(y) 的场景直接跳过本步(见 19.6.4b)
4. 分布检查
→ 确保筛选后的数据仍覆盖不同 prompt 领域
→ 避免极端偏向某一类任务
第 3.5 步不是必选项。它成立的前提是存在一个外部给定的标量效用 q(y)——个性化场景里的用户效用、定向对齐任务里的某个自动评估器打分。通用对齐通常没有这样的量,此时”方向”无从定义,跳过即可。
若标注预算花在采集之前,则配合 ActiveDPO 的主动选择(19.2.5):先预测哪些偏好对最有信息量再标注,可减少 30-50% 标注量。
19.7 偏好数据偏差全景与防御
19.7.1 数据侧四大偏差
Length Bias(长度偏差):模型学会”越长越好”,输出冗长。
检测:
# DPO 训练前后平均输出长度对比
length_before = avg_length(sft_model_outputs)
length_after = avg_length(dpo_model_outputs)
# 如果 length_after / length_before > 1.3,说明有 Length Bias
应对:
- DPO 数据做长度归一化:
score = raw_score / log(1 + length) - 加入”短而精”的偏好对
- 用 SimPO 等长度不变的方法
长度偏差的完整防御还需叠加评审侧的 Length Bias 消除(19.5.4)、标注侧的长度偏好规则(19.4.2 困难 3/4)与过滤侧的长度归一化(19.6.5)——四个环节缺一不可,因为偏差在数据生命周期的每一站都会被重新注入或放大。
Sycophancy(阿谀偏差):模型学会”附和用户”,即使用户错了。
检测:用 Sycophancy Eval(Perez et al., 2022)测试,给模型”用户错但坚持”的 prompt。
应对:
- 在偏好数据中加入”用户错时坚持正确”的对
- Constitutional 原则加”不阿谀”
格式偏差:模型学会”特定格式(如列表、加粗)得分高”,无关内容也用列表。
应对:
- 评分时剥离格式,只评内容
- 数据中均衡”列表式”与”散文式”响应
领域偏差:某一领域(如代码)的偏好数据占比过高,模型在该领域过强,其他领域过弱。
应对:
- 按领域配比采样
- 每个领域占比控制在 10-30%
19.7.2 偏差的另一半:优化侧的上下文盲视
上面四大偏差都发生在数据生成与评审侧(RLAIF 打分怎么打、标注分布怎么偏)。但还存在另一半:即使数据完全干净,DPO 的优化过程本身也会引入系统性偏差。
C2-DPO(Context-Calibrated Preference Optimization,ECCV 2026,Byungoh Ko 等 6 人)研究的是多模态大模型上的”上下文盲视”(context blindness)。它先定义了一个可测量的指标 CPG(Contextual Preference Gain,上下文偏好增益):提供相关上下文后,模型的偏好强度增强了多少。两个发现值得数据工程师注意:
- CPG 与幻觉率呈负相关——CPG 越高的模型,物体幻觉越少。这意味着 CPG 可以作为一个不依赖人工标注的偏好数据质量代理指标。
- 标准 DPO 及其变体的 CPG 都偏低——即模型在偏好优化后并没有真正学会利用上下文,只是在拟合偏好标签的表面模式。DPO 训练结束后幻觉依旧。
工程含义:这解释了一类常见的失败排查死胡同——“偏好数据检查过了没问题,为什么训练完效果还是不达标”。如果 CPG 没有随训练上升,说明瓶颈不在数据质量,而在优化目标本身没有把上下文信息用起来。
⚠️ 引用边界:C2-DPO 的实证场景是多模态大模型的物体幻觉(视觉输入与文本描述不一致),“上下文”指的是与视觉输入相关的补充信息,不是本章讨论的文本长文档上下文。社区转述中出现的”长文档场景下偏好标签不一致”说法,在论文中找不到对应表述。若要用于纯文本场景,需要自行构造 CPG 的等价度量并验证。
数据侧偏差与优化侧偏差的分野,构成了偏差排查的第一道分流:先确认偏差来自哪里,再决定是改数据(重标/过滤/归一化)还是改算法(CPO 约束、C2-DPO 校准、SimPO 隐式奖励)。
19.8 工业 SOP 与动手实践
19.8.1 偏好数据构建工业 SOP
1. 需求定义:要补哪个维度(helpful/honest/harmless)
2. 来源配比:
- 人工 20%(金标)
- RLAIF 50%(规模)
- Constitutional 15%(安全)
- 用户隐式 15%(真实分布)
3. 生成响应:多模型并行生成
4. RLAIF 评审:GPT-4 评分 + 双向去 Position Bias
5. 长度归一化:消除 Length Bias
6. Score-Gap 过滤:保留 gap 1-3
7. 多维度分类:按 4 维度分类存储
8. 去污染 + 多样性筛选
9. DPO 训练:lr=1e-6, β=0.1
10. 评估:MT-Bench + AlpacaEval + Length 检查
在启动第 9 步之前,建议叠加 19.1.6 的 DPO 数据分布诊断(标注一致性 κ、参考模型困惑度、margin 监控),以及在预算允许时按 19.2.4 将 90% 数据预算投入 chosen 质量而非 rejected 构造。
关于第 9 步的两个经验值:lr=1e-6 与 β=0.1 是社区最常用的起点,但它们对初始化的敏感度高于多数人的预期,且这个敏感度有一个具体来源——不同的系数初始化会诱导出不同的瞬态学习信号轨迹,即便后期的信号水平趋于一致(见 19.1.7 的 LSC-DPO,arXiv:2610.07592)。也就是说,两个团队用同一份数据、同一组超参,前期轨迹不同,最终指标也可能差出一截;而只看最终的 margin 曲线是看不出来的,因为后期的信号水平确实趋同了。
因此上线前建议做两件事中的一件:要么做一次小幅度的系数扫描(不必大范围网格搜索,围绕 β 取 2-3 个点即可),要么显式监控学习信号曲线而不只是 loss 与 margin——判据是训练后段 sigmoid 因子是否已经饱和。这一步可与 19.1.6 的训练曲线监控清单合并执行。
19.8.2 动手环节:构造偏好对并分析 Margin 分布
目标:动手构造一批偏好数据,体验 margin 控制和偏差检测的核心技巧。
练习 1:模拟 LLM-as-Judge 偏好标注
"""
实现 LLM-as-Judge 的核心逻辑(用规则模拟)
重点体验位置交换去偏差的技巧
"""
import random
from typing import Tuple
def mock_judge(response_a: str, response_b: str) -> str:
"""
模拟 LLM 评判,带有位置偏好
真实场景中这是一个 LLM API 调用
"""
# 模拟评分
score_a = score_response_quality(response_a)
score_b = score_response_quality(response_b)
# 模拟位置偏好:第一个位置有 15% 的额外加分
POSITION_BIAS = 0.15
biased_score_a = score_a + POSITION_BIAS
biased_score_b = score_b
if biased_score_a > biased_score_b + 0.1:
return "A"
elif biased_score_b > biased_score_a + 0.1:
return "B"
return "tie"
def score_response_quality(response: str) -> float:
"""启发式质量评分"""
score = 0.5
if "##" in response: score += 0.15
if len(response) > 100: score += 0.1
if "```" in response: score += 0.1
if "\n1." in response or "\n-" in response: score += 0.1
filler_count = sum(response.count(w) for w in ["好的", "嗯", "啦"])
score -= filler_count * 0.1
return max(0, min(1, score + random.gauss(0, 0.05)))
def judge_with_swap(
prompt: str,
response_a: str,
response_b: str
) -> dict:
"""
带位置交换的评判(消除位置偏好)
"""
# 正序评判
winner_1 = mock_judge(response_a, response_b)
# 反序评判
winner_2 = mock_judge(response_b, response_a)
winner_2_flipped = {"A": "B", "B": "A", "tie": "tie"}[winner_2]
# 一致性检查
if winner_1 == winner_2_flipped:
return {"winner": winner_1, "consistent": True}
else:
return {"winner": "discard", "consistent": False,
"detail": f"正序={winner_1}, 反序翻转={winner_2_flipped}"}
# 测试
responses = {
"good": "## 解答\n\n快速排序的核心思想是分治:\n\n"
"1. 选择基准元素(pivot)\n"
"2. 将数组分为小于和大于 pivot 的两部分\n"
"3. 递归排序两个子数组\n\n"
"```python\ndef quicksort(arr):\n ...\n```",
"medium": "快速排序是一种分治算法。选一个基准元素,"
"把数组分成两部分,然后递归排序。平均时间复杂度 O(nlogn)。",
"bad": "好的!排序的话就是把数字从小到大排列就行啦~很简单的!"
}
print("=== 位置交换去偏差实验 ===\n")
prompt = "解释快速排序算法"
pairs = [("good", "medium"), ("good", "bad"), ("medium", "bad")]
for a_key, b_key in pairs:
# 无交换
no_swap = mock_judge(responses[a_key], responses[b_key])
# 有交换
with_swap = judge_with_swap(prompt, responses[a_key], responses[b_key])
print(f"对比 {a_key} vs {b_key}:")
print(f" 无交换: winner = {no_swap}")
print(f" 有交换: winner = {with_swap['winner']}, "
f"一致 = {with_swap['consistent']}")
print()
练习 2:Margin 分布分析
"""
分析偏好对的 margin 分布
验证本章的建议:混合不同 margin 的样本效果最好
"""
def compute_margin(chosen: str, rejected: str) -> float:
"""计算偏好对的 margin(分数差)"""
score_c = score_response_quality(chosen)
score_r = score_response_quality(rejected)
return score_c - score_r
def categorize_margin(margin: float) -> str:
"""根据 margin 大小分类"""
if margin > 0.4:
return "大margin(基础判别)"
elif margin > 0.15:
return "中margin(精细判别)"
elif margin > 0:
return "小margin(边界决策)"
else:
return "⚠️ 反转(chosen 可能不如 rejected)"
# 生成一批偏好对
def generate_preference_pairs(n: int = 50) -> list:
"""生成模拟的偏好对"""
templates = {
"high": [
"## 详细解答\n\n这是一个重要的概念。\n\n"
"### 核心原理\n1. 第一点\n2. 第二点\n3. 第三点\n\n"
"```python\n# 代码示例\nprint('hello')\n```",
],
"medium": [
"这个概念比较重要,主要包括几个方面:"
"首先是定义,然后是应用,最后是注意事项。",
],
"low": [
"嗯这个嘛,就是那个意思吧,你懂的~",
"好的好的!这个太简单了!就是那样!",
],
}
pairs = []
for _ in range(n):
# 随机选择 chosen 和 rejected 的质量
chosen_q = random.choices(["high", "medium"], weights=[0.6, 0.4])[0]
rejected_q = random.choices(["medium", "low"], weights=[0.5, 0.5])[0]
chosen = random.choice(templates[chosen_q])
rejected = random.choice(templates[rejected_q])
margin = compute_margin(chosen, rejected)
pairs.append({
"chosen_quality": chosen_q,
"rejected_quality": rejected_q,
"margin": margin,
"category": categorize_margin(margin),
})
return pairs
# 分析 margin 分布
pairs = generate_preference_pairs(100)
categories = {}
for p in pairs:
cat = p["category"]
categories[cat] = categories.get(cat, 0) + 1
print("=== Margin 分布分析 ===\n")
print(f"总偏好对数: {len(pairs)}\n")
for cat, count in sorted(categories.items()):
pct = count / len(pairs) * 100
bar = "█" * int(pct / 2)
print(f" {cat:<25} {count:>3} ({pct:>5.1f}%) {bar}")
# 推荐分布
print("\n推荐分布(本章建议):")
print(" 大 margin: 30%")
print(" 中 margin: 50%")
print(" 小 margin: 20%")
# 思考题:你生成的分布和推荐分布差距多大?如何调整数据构造策略来接近推荐分布?
练习 3:偏差检测清单
参考 19.5.5 节的偏差分析表,对你在练习 1 中的 mock_judge 做一个偏差审计:
- 测量位置偏好的严重程度(做 100 次正反序对比,计算不一致率)
- 测量长度偏好(用同等质量但不同长度的回复测试)
- 针对发现的偏差,设计缓解策略
19.9 偏好数据还需要吗?
在本章最后,值得退一步思考一个根本性问题:偏好数据在大模型训练中的角色,正在经历怎样的变化?
在可验证任务上,偏好数据已经被绕过。GRPO 和 RLVR 在数学、代码等有明确正确答案的任务上,完全不需要人类偏好——模型通过自我验证就能进化。ARPO(ICLR 2026)进一步将这种无偏好 RL 扩展到多轮 agent 场景,通过基于熵的自适应 rollout,用一半的工具调用量达到更优性能。可验证奖励的适用边界,正在从”单轮推理”向”多轮交互”扩展。
在开放域任务上,偏好信号仍然不可替代——但形式在简化。创意写作、开放对话、安全对齐等缺乏客观标准的任务,仍然需要某种”人类认为什么更好”的信号。区别在于,这个信号不再需要精心构造的成对比较:KTO 只需要二元反馈(好/坏),SimPO 用平均对数概率作为隐式奖励——偏好数据的构造成本在大幅降低。
多目标冲突的深层挑战。上述讨论隐含假设偏好是单一维度的——但实际中,helpful 和 harmless 经常冲突。MOPO(Multi-Objective Preference Optimization,arXiv:2505.10892)从优化层面提供了形式化解决方案:通过帕累托最优框架同时优化多个偏好维度,避免单目标 DPO 在冲突维度间的”对齐税”。这对偏好数据构造有直接影响:需为每个目标维度独立构建偏好对。在具体维度上,BiasGRPO(UIUC,ACL 2026 Findings)将 GRPO 适配到社会偏见缓解——一个奖励信号天然高方差的主观对齐维度。其核心设计:用定制 bias-specific reward model 替代通用 RM,配合 group-relative baseline 稳定高方差场景下的训练。这为”每个对齐维度需要独立偏好数据”的 MOPO 框架提供了工程验证。
推测:偏好数据不会消失,但会从后训练的”主角”变为”补充”——在 RLVR 无法覆盖的开放域发挥作用,且形式越来越轻量。未来的格局可能是:可验证任务用 RL 自我进化,开放域用轻量偏好信号(二元反馈或隐式奖励)做兜底。而多目标偏好优化(MOPO 类方法)将成为工业级对齐的标配——因为真实的对齐从来不是单维度的。
本章要点回顾
- 偏好学习从 RLHF 演变到 GRPO/DAPO/ARPO,复杂度不断降低,适用范围从单轮扩展到多轮 Agent
- critic-free 谱系(DAPO/GSPO/CISPO/DPPO)成为推理 RL 主流——四个核心挑战(方差/长度偏置/退化组/熵塌缩)通过损失函数与采样策略系统化解决
- DPO 不等价于 RLHF——CPO 揭示”负目标软间隔”在特定数据分布下会让 DPO 主动伤害模型;DPO 训练必须做数据分布诊断
- Chosen 质量是偏好数据的核心驱动力:三组对照实验量化(+3.0~+4.6 vs +0.8~+1.4),数据预算应 90% 投入 chosen 质量
- Margin 认知已从固定到动态到 Token 级:γ-PO 在样本级自适应,TI-DPO 在 token 级识别关键信号
- 偏好数据高度冗余:margin 最大化原则下,10-25% 的数据即可匹配甚至超越全量
- 四大来源配比:人工 20-30% 做质量锚、RLAIF 40-60% 做规模、Constitutional 10-20% 做安全兜底、用户隐式 10-20% 做真实分布校准
- 人工标注的核心挑战是处理 helpful/harmless 冲突、主观偏好、长度偏置(pair loss 机制放大)
- LLM-as-Judge 偏差已演化为方法学体系——量化(3 类偏差)+ 诊断(J/ΔJ + JudgeBiasBench)+ 缓解(4 层技术栈)+ 集成是硬道理
- 偏差分数据侧与优化侧两半:数据侧四大偏差(长度/阿谀/格式/领域)靠归一化与配比防御;优化侧偏差(C2-DPO 上下文盲视)说明”数据没问题但训不好”时瓶颈可能在优化目标
- On-policy 数据的优势不是无条件的:其本质是”生成更高质量的 chosen”,在资源有限时提升 chosen 质量比追求 on-policy 更重要
- 偏好数据的形式在降维:从成对比较到二元反馈(KTO)到隐式奖励(SimPO),构造成本持续降低;在可验证任务上正被 GRPO → DAPO → ARPO 的演进绕过,未来角色是开放域的”补充”而非”主角”