第 19 章 篇三:后训练数据工程

偏好数据工程

偏好对的构造(对比/排序)、标注一致性、奖励黑客防御。

偏好数据 RLHF 标注

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 范式演变时间线

时期方法数据需求复杂度代表
2022RLHF (PPO)偏好对 + 奖励模型最复杂(4 个模型)InstructGPT
2023.5DPO偏好对简化(无需 RM)Zephyr
2023.11KTO好/坏标签进一步简化(二元反馈)-
2024SimPO偏好对(无参考模型)平均对数概率作隐式奖励-
2024ORPOSFT + 偏好合并单阶段训练-
2025GRPO可验证奖励不需要人类偏好DeepSeek R1
2026DAPO可验证奖励(工业级)非对称裁剪 + 动态采样 + Token 归一化-
2026ARPO多轮可验证奖励基于熵的自适应 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显存紧张
ORPOSFT + 偏好联合训练简化流程
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 Gradienttoken-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 的主要进展:

变体时间核心创新适用场景
λ-GRPO2025-10统一 GRPO 框架 + 可学习 token 偏好长链思考中细粒度偏好
AMIR-GRPO2026-01引入隐式偏好信号到 GRPO偏好数据稀缺的场景
GDPO-SR2026-02一步生成式图像超分视觉生成 + 偏好
RAD-DPO2026-02鲁棒自适应去噪 DPO电商生成式检索
DPPO2026-03无偏动态剪枝长链思考的算力节省
Group Robust PO2026-03-30异质偏好的 min-max 优化标注方分歧大时
Multi-Reward GRPO2025多奖励信号去偏中英文境歧视去偏

19.1.5 机制视角:对齐如何重塑内部表征

以上从损失函数和训练动态角度分析了各方法的差异。2026 年的机制分析研究(arXiv:2606.09850,哥本哈根大学等,预印本待验证)用 probing + Sparse Autoencoder + Crosscoder 揭示了更深层的差异——不同对齐算法在内部表征几何层面造成质性不同的位移:

方法表征变化模式对可分离性的影响
GRPOconstructive feature sharing + 稀疏高显著性特征招募增强
KTOconstructive feature sharing增强
PPO基本保留基线几何结构中性
SimPO基本保留基线几何结构中性
DPOnon-constructive geometric rotation + 特征衰减削弱
ORPOnon-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 或重新筛选数据

由此得出三条工程结论:

  1. DPO 训练的”零成本假设”被打破——上线 DPO 之前必须做数据分布诊断,不能默认它和 RLHF 等价
  2. CPO 应当成为 DPO 训练的默认起点——额外的约束项几乎不增加算力,但能避免”先升后降”的灾难
  3. 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 来源(按优先级):

    1. 专家人工编写(最高质量,但成本高)
    2. 最强 SFT 模型的 best-of-N 采样(质量接近人工,成本可控)
    3. 中等模型生成 + 人工复核编辑(性价比最高)
    4. 拒绝采样(rejection sampling,让模型生成多个、挑最好的)
  • Rejected 来源(按”够用即可”原则):

    1. 次优 SFT 模型的直接采样(不需要任何”巧妙构造”)
    2. 同模型低 temperature 采样(多样性 > 难度)
    3. 早期 checkpoint 的输出(自然反映能力差距)
    4. 避免刻意制造”陷阱”——如随机 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 美元极高
RLAIF40-60%0.001-0.05 美元中-高
用户隐式反馈10-20%≈ 0中
Constitutional10-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)。

宪法原则:宪法是一组自然语言规则,例如:

  1. 请勿生成歧视性内容
  2. 请勿提供危险信息
  3. 当不确定时承认不确定
  4. 不主动给出未请求的建议

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 个维度评估每个响应:

  1. Instruction Following:是否严格遵循指令
  2. Truthfulness:是否准确无误
  3. Honesty:是否诚实承认不确定
  4. 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 更新才从纯粹的纠错信号转变为类强化学习的更新;方向不一致时,偏好优化反而会阻碍目标的实现。原文的表述很锋利:偏好对选择是一个几何决策,它决定偏好优化究竟是在推进还是在妨碍。

这条结论对本章的意义有两层:

  1. 现有的 score-gap / margin 最大化只筛了幅度,没有筛方向。在有明确目标效用的场景(个性化、某一维度的定向对齐、有外部标量评估器 q(y) 的任务),建议在选择流程里再加一次方向性检查;在通用对齐这类”效用函数本身不清楚”的场景下,这一条检查无从做起,可以跳过。
  2. 它解释了 §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,上下文偏好增益):提供相关上下文后,模型的偏好强度增强了多少。两个发现值得数据工程师注意:

  1. CPG 与幻觉率呈负相关——CPG 越高的模型,物体幻觉越少。这意味着 CPG 可以作为一个不依赖人工标注的偏好数据质量代理指标。
  2. 标准 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 做一个偏差审计:

  1. 测量位置偏好的严重程度(做 100 次正反序对比,计算不一致率)
  2. 测量长度偏好(用同等质量但不同长度的回复测试)
  3. 针对发现的偏差,设计缓解策略

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 类方法)将成为工业级对齐的标配——因为真实的对齐从来不是单维度的。


本章要点回顾

  1. 偏好学习从 RLHF 演变到 GRPO/DAPO/ARPO,复杂度不断降低,适用范围从单轮扩展到多轮 Agent
  2. critic-free 谱系(DAPO/GSPO/CISPO/DPPO)成为推理 RL 主流——四个核心挑战(方差/长度偏置/退化组/熵塌缩)通过损失函数与采样策略系统化解决
  3. DPO 不等价于 RLHF——CPO 揭示”负目标软间隔”在特定数据分布下会让 DPO 主动伤害模型;DPO 训练必须做数据分布诊断
  4. Chosen 质量是偏好数据的核心驱动力:三组对照实验量化(+3.0~+4.6 vs +0.8~+1.4),数据预算应 90% 投入 chosen 质量
  5. Margin 认知已从固定到动态到 Token 级:γ-PO 在样本级自适应,TI-DPO 在 token 级识别关键信号
  6. 偏好数据高度冗余:margin 最大化原则下,10-25% 的数据即可匹配甚至超越全量
  7. 四大来源配比:人工 20-30% 做质量锚、RLAIF 40-60% 做规模、Constitutional 10-20% 做安全兜底、用户隐式 10-20% 做真实分布校准
  8. 人工标注的核心挑战是处理 helpful/harmless 冲突、主观偏好、长度偏置(pair loss 机制放大)
  9. LLM-as-Judge 偏差已演化为方法学体系——量化(3 类偏差)+ 诊断(J/ΔJ + JudgeBiasBench)+ 缓解(4 层技术栈)+ 集成是硬道理
  10. 偏差分数据侧与优化侧两半:数据侧四大偏差(长度/阿谀/格式/领域)靠归一化与配比防御;优化侧偏差(C2-DPO 上下文盲视)说明”数据没问题但训不好”时瓶颈可能在优化目标
  11. On-policy 数据的优势不是无条件的:其本质是”生成更高质量的 chosen”,在资源有限时提升 chosen 质量比追求 on-policy 更重要
  12. 偏好数据的形式在降维:从成对比较到二元反馈(KTO)到隐式奖励(SimPO),构造成本持续降低;在可验证任务上正被 GRPO → DAPO → ARPO 的演进绕过,未来角色是开放域的”补充”而非”主角”

🛠️ 本章衍生工具

⚖️

数据工程·偏好对构建工作台

《AI 数据全书》第 19 章「偏好数据工程」配套——① Chosen 主导实验室:预算分配滑杆驱动三条真算曲线(合计提升 / chosen 分量 / rejected 分量 + 右轴单位预算边际收益比,101 点逐点求值,非拟合),⭐ 把「chosen 收益是 rejected 的 3-5 倍」还原成单位预算边际收益之比(2.14~5.75,中值 3.45)并明写它不是总分之比;八组陷阱样本(事实错误 / 长度欺诈 / 安全越狱 / 代码缺陷 / 谄媚 / 格式刷分 / 多维冲突 / 边界 margin)逐条给「为什么这条数据有毒」;§19.2.3 多维度冲突矩阵(helpfulness ↑ 但 harmlessness ↓ 的对齐税)+ DPO 数据分布诊断三件套(标注一致性 Cohen's κ 真算 + 高困惑度占比 + CPO 负间隔监控灯)· ② Margin 调音台:Score-Gap 三桶分流(lo/hi 双阈值互相钳制 + 50 条样本实时改桶)+ 长度归一化开关 `score/log(1+L)`,🔴 专门做一张「中文长度怎么切」对照表——按空格切(错,中文全篇只有 1 个 token)vs 按字切(对),并点名 `split(/\s+/)` 这个坑;margin 三档配比(大/中/小,TVD 实时算目标 vs 实际)· SA-DPO 语义自适应 margin(语义距离权重滑杆 + 固定阈值 vs 自适应阈值 Venn 图,明标⚠ 线性形式是教学模型、58.5% 胜率是文献值不可互证)· ③ 偏差扫描仪:⭐ Position Bias 双向评审实测(同一对样本跑两轮、第 2 轮交换呈现顺序,按 §19.5.4 判据判定「是否真的位置偏差」而不只是猜)+ Length Bias 实测(同一回答详略两版、质量真值同为 7.8,长度比 / 真值差 / 双向判定 / 是否触发 >1.3 检测口径四个指标分开看)+ 16 条批量扫描(双向一致率 / 触发位置偏差 / 被丢弃 / 标签正确率)+ §19.5.5 六偏差矩阵(评分范围偏差带 📖 Spearman +11.7% 引文)+ BiasScope 残差对比(显式建模两类已知偏差后残差仍存,呼应原文「已知偏差只是冰山一角」)+ §19.7.1 四大数据侧偏差 + C2-DPO 引用边界红字警示 · ④ 少即是多筛选器:§19.6.7 四步 SOP + 贝叶斯聚合后验(高斯共轭融合多来源评分,可拖 k / τ / 隐式负例率 / 先验方差 / 方差惩罚)+ ⭐ 分布塌缩警报(Top-k 筛选后某领域占比跌破 10% 直接红色报警并给出「按领域分层取 Top-k」的修法)+ 数据量 vs 效果曲线(96 点逐点真算下游得分 / 纯度 / TVD,📖 §19.6.1 文献锚点与 🧮 本机实算严格左右分栏、各自注明不可比)+ 被动 vs 主动选择(ActiveDPO 采样量对比,附「文献 30-50% 节省来自不同数据集,不可比」)+ §19.8.1 工业 SOP 十步;页脚三分诚实性标注 🧮 真算 / 📖 文献值 / ⚠ 教学模型