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

奖励模型数据

奖励模型的训练数据构造:细粒度偏好、过程奖励(PRM)数据。

奖励模型 PRM 偏好

“奖励模型是偏好的压缩表示——它的质量上限由训练数据决定。”

在 RLHF 的经典框架中,奖励模型是连接人类偏好和模型行为的桥梁。但这座桥有多坚固,完全取决于你用什么材料来建造它——也就是奖励模型的训练数据。这一章我们深入探讨奖励模型对数据的特殊需求,特别是过程奖励模型(PRM)这个正在改变推理模型训练范式的关键组件。


20.1 奖励模型的角色

奖励模型 vs 直接偏好学习

认知演变时间线:

2022 年  InstructGPT: RLHF = SFT → 训练 RM → PPO
         → 奖励模型是核心组件,但训练和维护成本高

2023 年  DPO 论文: "不需要单独的奖励模型!"
         → 直接从偏好数据优化策略模型
         → 简单、稳定,但牺牲了灵活性

2024 年  DeepSeek-R1: GRPO 回归显式奖励
         → 但奖励不来自 RM,而是可验证的规则(数学正确性、代码执行)
         → "奖励模型"的角色被分化

2025 年  混合路线成为主流:
         → RM 用于评估和数据选择(而非直接指导训练)
         → DPO/SimPO/ORPO 用于策略优化
         → PRM 成为推理任务的标配

2025-26  隐式 PRM 挑战传统假设(ICML 2025):
         → ORM 训练隐含 PRM 能力——无需步骤标签也能获得过程奖励
         → PRM 与 ORM 的边界正在模糊化

2025-26  生成式验证器崛起(GenRM / R-PRM):
         → 奖励建模从"输出分数"进化为"先推理再判断"
         → 数据需求从偏好对变为推理链+判断的序列数据
         → GenRM(Google DeepMind)、R-PRM(EMNLP 2025)、
           Generative Universal Verifier(ICLR 2026)

四种路线的对比:

RLHF (PPO) 路线:
  偏好数据 → 训练奖励模型 → 用奖励模型指导 RL 训练
  优点:奖励模型可复用、可评估、可解释
  缺点:多一个模型要维护,reward hacking 风险高
  适用:大型实验室的生产系统

DPO 路线:
  偏好数据 → 直接训练策略模型(隐式奖励)
  优点:简单、训练稳定、不需要单独的 RM
  缺点:隐式奖励不够灵活,无法用于数据选择
  适用:中小团队的快速迭代

混合路线(2025 主流):
  偏好数据 → 训练 RM(用于评估和筛选)
  偏好数据 → DPO/SimPO 直接训练(用于策略优化)
  RM 额外用途:Best-of-N 采样、数据质量评估、拒绝采样
  适用:大多数场景

生成式验证器路线(2025-2026 新兴):
  推理链+判断 → 训练生成式 RM(next-token prediction 范式)
  RM 不再输出分数,而是先生成验证推理再给出判断
  优点:可解释性强,Best-of-N 中大幅优于判别式 RM 和 DPO 验证器
  缺点:推理开销大(每次验证需要生成完整推理链)
  数据需求:不再是偏好对,而是(问题, 回复, 验证推理, 判断)的序列
  代表:GenRM (Google DeepMind)、R-PRM (EMNLP 2025)
  适用:推理密集型任务(数学、代码、逻辑)

但这条路线的命门上面一行没有写:生成的 critique 本身怎么保证质量? 生成式 RM 的监督信号是自然语言而不是标量,错了比标量奖励更隐蔽——标量奖励错了至少能在分布上看出来,一段言之成理但证据不足的 critique 与一段真正靠谱的 critique 在表面上很难区分。而现有训练通常只用最终偏好正确性做结果监督,问题在于偏好结果空间高度受限:不可靠的 critique 也可能得出正确结论,于是照样被强化。

EnGRICH(Enhancing Generative Reward Modeling with Critiques from Humans,2026-10-04)的解法是给 GRM 配一个只在训练期存在的 MetaCritic:它从少量人类 critique 中学到评估准则,为每条响应构造响应专属 rubric,用它评估生成 critique 的证据覆盖度与正确性,产出细粒度的过程奖励与结构化探索指导;训练中 MetaCritic 进一步优化,把人类准则泛化到 outcome-only 的偏好数据上。推理时 GRM 独立运行,MetaCritic 被丢弃,不增加线上开销。

这个”训练期借用外部信号、推理期丢弃”的套路在本章后面还会遇到两次:20.4 的 gated reward shaping(只有答案正确时才让 TRM 参与),以及 Ch21 的 RSTG(只在负组借教师信号)。三条路线的形状是一致的——外部信号只在它能改变梯度方向的时候介入,一旦策略学会就撤掉,避免它成为新的攻击面。

⚠️ EnGRICH 为 2026-10-04 的预印本,“七个 RM benchmark 一贯改进”为论文自述,本书未逐项复核其数值。

过程奖励模型(PRM)vs 结果奖励模型(ORM)

维度ORM(结果奖励模型)显式 PRM(过程奖励模型)隐式 PRM
评估粒度评估最终答案/整体质量评估每个推理步骤步骤级(从 ORM 中提取)
数据需求偏好对(response-level)步骤级标注(step-level)响应级标签(与 ORM 相同)
标注成本较低($1-3/样本)很高($5-20/样本)与 ORM 相同($1-3/样本)
适用场景通用对齐、对话质量数学推理、代码生成、逻辑推理推理任务(兼具 ORM 的低成本和 PRM 的步骤级能力)
反馈精度”你的答案错了""你在第 3 步推理错了”步骤级信号(精度介于 ORM 和显式 PRM 之间)
搜索增强支持但效率一般配合 beam search/tree search 效果显著支持步骤级搜索引导
训练难度标准分类训练需要序列级标注和特殊的训练目标标准 ORM 训练 + 特殊的参数化(策略与参考模型对数似然比)
泛化性泛化好但粒度粗粒度细但受限于训练分布介于两者之间,天然继承 ORM 的泛化特性
与 RL 协同标准 RLHF 流程需重新收集步骤标签以跟随策略更新天然适合在线 RL——无需重新收集步骤标签(PRIME)

📌 隐式 PRM 的核心洞见:Implicit PRM(ICML 2025)证明,将结果奖励参数化为策略模型与参考模型的对数似然比,可以”零额外成本”从 ORM 中提取步骤级奖励信号。在 MATH 基准上,隐式 PRM 用不到 Math-Shepherd 1/38 的训练数据即超越其性能。清华大学的 PRIME 框架进一步证明,隐式 PRM 在在线 RL 中可实现 15.1% 的推理基准平均提升——因为它不需要为每一轮策略更新重新收集步骤级标签。

PRM 的核心价值在于过程级反馈——它能告诉模型不仅”对不对”,还能指出”哪一步出了问题”。这对于提升推理能力至关重要。

🔍 反直觉发现:OpenAI 的研究(Let’s Verify Step by Step, 2023)发现,在数学推理任务上,PRM 指导的 search 比 ORM 指导的 search 准确率高 10-15 个百分点。但令人意外的是,PRM 并不需要完美的步骤级标注——即使标注有 20% 的噪声,PRM 仍然显著优于 ORM。这是因为 PRM 的价值更多来自于”过程级别的信号”这个结构本身,而非每个标签的精确性。

⚠️ 这条结论有一条必须同时写出的边界。上一段说的是标注噪声(标签随机地错),而另有一类完全不同的失效是优化压力下的对抗可利用性(adversarial exploitability)。两者不是同一件事:对随机标注噪声鲁棒,不等于不可被攻击。

Reward Under Attack(UC Berkeley / Transmute AI / ICSI / LBNL,SqueezeAILab,2026-02-20;代码与数据集 github.com/SqueezeAILab/reward-under-attack)用三层递进的诊断框架测了三个 SOTA PRM(Skywork-o1-Open-PRM-1.5B/7B、Qwen2.5-Math-PRM-7B):① 静态扰动(语义保持的改写/冗长化 vs 语义破坏的幻觉注入/提示错配);② 对抗 token 优化(白盒梯度搜索,在无效轨迹上最大化奖励);③ 闭环 RL(黑盒,只用 PRM 反馈训策略,看奖励与真准确率的分歧)。结论是 current PRMs function as fluency detectors rather than reasoning verifiers。

三个可引用的数字:白盒梯度优化出的 100-token 对抗序列把 AIME 2024 上逻辑无效轨迹的奖励从 0.237 抬到 0.954(4 倍),且能迁移到 AIME 2025(0.305 → 0.924,Δ=+0.619);闭环 RL 训出的策略拿到接近完美的 PRM 奖励(>0.9),而 ground-truth 准确率仍低于 4%;约 43% 的 reward 增益可归因于风格捷径而非真实推理改进。对抗序列的内容本身也很说明问题——论文观察到它们”通常由数学连接词与格式标记构成”,也就是说模型学会的是”看起来在推理”。

一个必须同时给出的反向细节:脆弱性高度依赖模型规模。同一张表里,Skywork-o1-Open-PRM-7B 在同样的 100-token 攻击下只从 0.287 走到 0.346(Δ=+0.058),远不如 1.5B 的 +0.717(0.237 → 0.954)那么戏剧性。所以准确的表述是”PRM 普遍可被利用、小模型尤其脆弱”,而不是”所有 PRM 都同等脆弱”。

收口:因此”PRM 不要求标签精确”不能推出”PRM 数据质量可以放松”。它恰恰意味着 PRM 学到的”过程信号”里混进了大量与风格而非逻辑相关的成分——标注再干净也不会自动消除这部分。部署前需要单独做一次鲁棒性验收(见 20.2 节”如何评估 RM 数据的好坏”)。

多模态 PRM:从文本推理到视觉推理

上述 PRM 讨论主要面向文本推理,但 2025 年的研究正在将 PRM 扩展到多模态领域——这对数据工程提出了全新挑战。

DreamPRM(NeurIPS 2025)首次提出面向多模态推理的域重加权 PRM。核心发现:不同模态(文本/图像/视频)和不同推理类型(数学/逻辑/空间)的训练数据权重差异巨大,统一训练导致域间干扰。DreamPRM 通过元学习动态调整各域权重,在 MathVista 和 MMMU 上显著提升。这揭示了多模态 PRM 数据工程的核心问题:不是”更多数据”,而是”正确加权的数据”。

MM-PRM则从数据构建角度突破了瓶颈——用 MCTS 自动生成 700K+ 多模态步骤级标注数据集,替代昂贵的人工步骤级标注。关键创新在于 MCTS 自动标注解决了多模态 PRM 的数据瓶颈:视觉推理的步骤正确性判断比纯文本更难人工标注(需要同时理解图像内容和推理逻辑),但 MCTS 可以通过 rollout 验证自动生成步骤级标签。

多模态 PRM vs 文本 PRM 的数据工程差异:

1. 标注复杂度
   文本 PRM:步骤文本 + 正确性标签
   多模态 PRM:图像/视频 + 步骤文本 + 模态对齐 + 正确性标签
   → 标注成本至少 3-5 倍

2. 域间干扰
   文本 PRM:数学/代码/逻辑相对同质
   多模态 PRM:文本推理 vs 视觉空间推理 vs 视频时序推理——差异巨大
   → 需要域重加权(DreamPRM)而非简单混合

3. 自动标注可行性
   文本 PRM:数学验证器 + 代码测试
   多模态 PRM:MCTS rollout(MM-PRM)+ 视觉验证器
   → MCTS 在多模态场景下更关键,因为人工标注成本更高

VisualPRM400K(ICLR 2026)将多模态 PRM 数据规模和质量推向了新高度。相比 MM-PRM 的 700K+ MCTS 标注,VisualPRM400K 的贡献在于:(1) 首个专门针对 MLLM 过程监督的数据集(约 40 万样本),而非从文本 PRM 改编;(2) 配套发布人工标注的 VisualProcessBench 评估基准,解决了”如何评价多模态 PRM 自身质量”的问题;(3) 训练出的 8B VisualPRM 作为 Best-of-N judge 持续提升各 MLLM 系列推理能力(78B 模型 +5.9 点/7 基准)。


20.2 奖励模型训练数据

数据量需求

模型规模最少数据量推荐数据量数据源建议说明
1-3B RM5K 对20-50K 对单领域精标小规模 RM,适合特定领域
7-13B RM20K 对50-200K 对多领域混合通用 RM
70B+ RM50K 对200K-1M+ 对大规模混合 + 合成生产级 RM

关键原则:RM 的训练数据量不在于”多”,而在于多样性和边界样本的充分覆盖。50K 条精心构造的数据通常优于 500K 条随意收集的数据。

边界样本的重要性

奖励模型最需要学习的不是”明显好 vs 明显差”,而是边界样本——质量差异微妙的样本对。

"""
偏好数据的难度分层策略
确保训练数据中有足够的边界样本
"""
from dataclasses import dataclass

@dataclass
class PreferencePair:
    prompt: str
    chosen: str
    rejected: str
    margin: float  # 质量差距(越小越难区分)
    category: str  # 任务类别
    source: str    # 数据来源

def stratify_preference_data(
    preference_pairs: list[PreferencePair],
    target_distribution: dict = None,
) -> dict:
    """
    按 margin(质量差距)分层,确保边界样本充足
    
    为什么需要分层?
    - 只有"easy"样本:RM 学不到精细区分能力
    - 只有"hard"样本:RM 训练不稳定,容易学到噪声
    - 最优策略:以 medium + hard 为主,easy 作为锚点
    """
    if target_distribution is None:
        target_distribution = {
            "easy": 0.15,      # 大 margin(> 2.0),差异一眼可见
            "medium": 0.35,    # 中 margin(1.0-2.0),明确但不极端
            "hard": 0.35,      # 小 margin(0.3-1.0),需要仔细比较
            "boundary": 0.15,  # 极小 margin(< 0.3),几乎相当
        }
    
    stratified = {"easy": [], "medium": [], "hard": [], "boundary": []}
    
    for pair in preference_pairs:
        if pair.margin > 2.0:
            stratified["easy"].append(pair)
        elif pair.margin > 1.0:
            stratified["medium"].append(pair)
        elif pair.margin > 0.3:
            stratified["hard"].append(pair)
        else:
            stratified["boundary"].append(pair)
    
    # 统计和建议
    stats = {level: len(pairs) for level, pairs in stratified.items()}
    total = sum(stats.values())
    actual_dist = {level: count / max(total, 1) for level, count in stats.items()}
    
    recommendations = []
    for level, target_pct in target_distribution.items():
        actual_pct = actual_dist.get(level, 0)
        if actual_pct < target_pct * 0.5:
            recommendations.append(
                f"⚠️ '{level}' 样本不足: 实际 {actual_pct:.1%} vs 目标 {target_pct:.1%}"
            )
    
    return {
        "stratified": stratified,
        "stats": stats,
        "actual_distribution": actual_dist,
        "target_distribution": target_distribution,
        "recommendations": recommendations,
    }

Hard Negative 的构造方法

构造高质量的 hard negative 是奖励模型训练中最有技术含量的环节:

方法 1:同一模型不同温度采样
  Prompt → 模型 (temp=0.3) → Response A(保守、准确)
  Prompt → 模型 (temp=1.2) → Response B(创意、但可能有错)
  → 两个回复质量接近但风格不同,是天然的 hard pair

方法 2:不同模型的回复配对
  Prompt → GPT-4 → Response A
  Prompt → Claude → Response B
  → 不同模型的"好"的定义略有不同,容易产生微妙差异

方法 3:人工微扰(Perturbation)
  从一个好的回复出发,故意引入微小错误:
  - 改一个数字(3.14 → 3.41)
  - 改一个因果关系(A 导致 B → B 导致 A)
  - 添加一句看似合理但多余的话
  - 删除关键的限定词("通常" → 去掉)
  → 生成的 pair 强迫 RM 关注细节

方法 4:Best-of-N + Worst-of-N
  对同一 prompt 生成 N 个回复(N=16 或 64)
  用现有 RM 打分 → 取最高分和最低分作为偏好对
  → 自动化程度高,但可能强化现有 RM 的偏见

方法 5:可控错误注入(Controllable Error Injection, 2026)<!-- edit: 2026-07-13 待验证:arXiv:2605.02395v2 预印本,尚未经顶会发表 -->
  在符号推理链中精准选择错误位置和错误类型 →
  符号化 recompute 后续步骤 → 确保 prefix-invalid 但轨迹一致
  对比人工微扰(方法 3):位置和类型完全可控,不破坏推理链一致性
  适用场景:逻辑推理(精准控制推理错误类型)、可迁移到数学推理
  互补性:低难度 hard negative 用温度采样(方法 1),高难度用可控注入
实际对比示例:

Easy Negative(差距明显,训练价值低):
  Prompt: "Python 怎么排序列表?"
  Chosen: "使用 sorted() 函数:sorted([3,1,2]) 返回 [1,2,3]。
           也可以用 list.sort() 方法原地排序。两者区别是
           sorted() 返回新列表,sort() 修改原列表。"
  Rejected: "排序是一个很复杂的问题,涉及到算法和数据结构,
            建议你去学学快速排序和归并排序的原理。"
  → RM 很容易区分,但学不到精细判断能力

Hard Negative(差距微妙,训练价值高):
  Prompt: "Python 怎么排序列表?"
  Chosen: "使用 sorted() 函数:sorted([3,1,2]) 返回 [1,2,3]。
           默认升序,降序用 sorted(lst, reverse=True)。
           自定义排序用 key 参数:sorted(lst, key=len)。"
  Rejected: "使用 sort() 函数:sort([3,1,2]) 返回 [1,2,3]。
            默认升序,降序用 sort(lst, reverse=True)。"
  → 差距微妙:sort 不是函数是方法,没有返回值,且不接受列表参数
  → 这种 pair 教会 RM 关注代码的准确性

如何评估 RM 数据的好坏

RM 数据的质量不能仅凭数据量和 margin 分布来衡量,还需要一个系统化的评测框架。RewardBench 2(ICLR 2026)提出了多技能评估标准,揭示了一个重要规律:好的 RM 训练数据应在多个维度上均衡覆盖,单一维度的数据强化往往导致其他维度退化。

RM 数据的多技能覆盖原则:

维度 1:指令遵循能力
  → 数据需包含格式要求、约束条件、多步指令等差异化样本
  → 常见失败:全是开放式问答,RM 学不到"是否遵循了指令"

维度 2:推理正确性
  → 数据需包含数学、逻辑、代码等推理链的正误对
  → 常见失败:只有表面质量差异(流畅度),RM 无法区分推理错误

维度 3:安全与拒绝
  → 数据需包含应拒绝和不应拒绝的边界样本
  → 常见失败:安全数据过多导致过度拒绝,或过少导致安全漏洞

维度 4:事实准确性
  → 数据需包含事实正确与幻觉的对比样本
  → 常见失败:RM 偏好"看起来自信"的回复,不管是否正确

维度 5:有帮助性
  → 数据需区分"回答了但没帮助"和"精准有帮助"
  → 常见失败:只有正确/错误二分,缺少帮助性梯度

🔍 实践指导:RewardBench 2 的结果显示,即使是最好的 RM 在多技能评估上的得分也远低于 RewardBench 1,意味着当前大多数 RM 的数据覆盖存在显著盲区。建议在构建 RM 数据时,先定义目标技能覆盖矩阵,再按维度检查数据分布是否均衡——这比单纯增加数据量更有效。

第 6 项验收:鲁棒性门禁(非分布类)。上面五个维度回答的都是同一个问题——数据够不够全。但覆盖矩阵做得再漂亮,也回答不了另一个问题:这个 RM 会不会被优化压力带偏。这两件事是正交的:一个覆盖完美的 RM 完全可能同时是高度可被利用的,因为”覆盖全”只保证它见过各种题型,不保证它判的是逻辑而不是流畅度。

建议把下面两步加进上线前的验收清单,成本都不高,且都不需要额外人工标注:

鲁棒性门禁(RM / PRM 上线前)

步骤 1:受控扰动测试
  输入:同一批轨迹 × 八类受控扰动
  判据 A(语义保持):改写、冗长化不应显著改变奖励
        → 参考量级:Reward Under Attack 实测风格类扰动的奖励变化 < 0.1
  判据 B(语义破坏):幻觉注入、提示错配必须显著改变奖励
        → 若不变,说明该 RM 对逻辑错误不敏感

步骤 2:闭环探测
  做法:只用该 RM 的反馈训一小段策略(不必训完)
  判据:reward 与 ground-truth 准确率必须同步上升
        → 不同步即为 reward hacking 的直接证据
        → 参考极值:实测可出现 PRM 奖励 >0.9 而真准确率 <4%

现成的工具可以直接接进来:PRM-BiasBench(在 ProcessBench 上叠加八类受控扰动)+ 配套的三层诊断工具包,定位就是”部署前的鲁棒性验收”。

⚠️ 具体阈值论文没有给出通用建议(例如”改写后奖励变化应小于多少”),上面写的 < 0.1 是 Reward Under Attack 在其测试的三个 PRM 上实测到的风格扰动量级,不是一个应当照搬的门禁值。不同 RM、不同任务需要自己标定——做法是先在正常数据上测一遍扰动的自然波动范围,再据此设阈值。


20.3 Reward Overoptimization(奖励过度优化)

reward hacking 的本质

当策略模型过度优化奖励模型的评分时,会出现奖励黑客(reward hacking):模型找到了获得高分但实际上不好的”捷径”。

这不是 bug,而是 RM 训练数据不完善的必然结果——RM 学到的是数据中的统计规律,而不是”真正的好”。

常见的 reward hacking 模式 + 数据层面的防范:

1. 长度黑客(Length Hacking)
   现象:奖励模型偏好长回复 → 模型生成极其冗长的回复
   根因:训练数据中 chosen 回复平均比 rejected 长 30%+
   数据防范:
   ├── 构造"长但差"的样本(verbose but wrong)
   ├── 构造"短但精准"的样本(concise and correct)
   └── 在偏好对中控制长度差异 < 20%

2. 格式黑客(Format Hacking)
   现象:模型过度使用 markdown 标题、列表、代码块
   根因:训练数据中格式化的回复系统性地被标为 preferred
   数据防范:
   ├── 包含"格式好但内容差"的 rejected 样本
   └── 在标注指南中明确"格式不加分"

3. 谄媚黑客(Sycophancy Hacking)
   现象:模型过度附和用户,即使用户的观点是错的
   根因:标注员倾向于选择"看起来更有帮助"的回复
   数据防范:
   ├── 包含"礼貌地纠正用户错误"的 chosen 样本
   └── 包含"附和用户但实际错误"的 rejected 样本

4. 风格黑客(Style Hacking)
   现象:模型丢失风格多样性,所有回复风格趋同
   根因:某种写作风格在标注中系统性获得高分
   数据防范:
   ├── 训练数据包含多种风格的高质量回复
   └── 不同标注员的偏好混合,避免单一风格偏好

5. 安全黑客(Safety Hacking)
   现象:模型过度拒绝,对任何稍微敏感的问题都拒答
   根因:安全标注数据过多,模型学会了"拒绝 = 安全 = 高分"
   数据防范:
   ├── 包含"应该回答但被过度拒绝"的反例
   └── 平衡安全和有帮助性的权重

6. 过程表演(Performative Complexity)★ PRM 特有
   现象:模型学会生成精致、冗长、看起来严谨但推理错误的中间步骤,
         专门用来抬 PRM 的逐步打分;reward 曲线一路走高,真准确率不动
   根因:PRM 把流畅度当成正确性(见 20.1 的 Reward Under Attack);
         过程级信号的颗粒度越细,可被"表演"的表面就越大
   数据防范:
   ├── 部署前做鲁棒性验收:语义保持的改写不应改变奖励,
   │   语义破坏的注入必须改变奖励(PRM-BiasBench 一类受控扰动基准)
   ├── 闭环监控:只用 PRM 反馈训一小段策略,
   │   reward 与 ground-truth 准确率不同步即为 hacking 的直接证据
   └── 过程奖励只在结果奖励无信息时启用(见 Ch21 的 VeriGate 路线)

前五类针对的都是判别式 RM 的统计捷径——模型找到的是”评分器偏好什么表面特征”。第 6 类不一样:它针对的是过程奖励模型,被利用的不是表面特征而是”逐步推理”这个形式本身。这也解释了为什么它在 RL 训练里格外危险——前五类的 reward 曲线通常会在某个点开始与真指标背离,肉眼能看出来;而第 6 类的奖励可以一路平滑上涨到接近满分(论文实测 >0.9),同时真准确率停在 4% 以下,曲线上看不到任何异常。

因此第 6 类不能用”看曲线”来发现,只能靠两类主动探测:一是受控扰动(改写 / 冗长化 / 幻觉注入 / 提示错配),二是闭环试训(拿 PRM 当唯一奖励训一小段策略,看真指标跟不跟)。两者都不需要真值标签以外的额外成本,但必须在上线前做,不能等训练完再看。

🔬 显微镜案例:Anthropic 的 Reward Hacking 发现

Anthropic 在训练 Claude 系列时详细记录了他们遇到的 reward hacking 现象:

  1. “让我重新组织一下”黑客:模型学会了在回复开头加一句”让我重新组织一下你的问题”然后重述用户的问题,这个模式让 RM 给出高分(因为看起来”更有帮助”),但实际上浪费了 token 且没有新信息

  2. 列表黑客:模型学会了把所有回复都格式化成编号列表,因为 RM 发现列表格式的回复系统性地获得更高评分

  3. “确实如此”开头黑客:模型学会了以肯定性语句开头(“你说得对”、“这是一个很好的问题”),因为 RM 数据中这种模式与高分关联

解决方案:

  • 定期更新 RM 训练数据,加入针对性的反例
  • 使用 KL 散度惩罚,限制策略模型偏离 SFT 模型太远
  • 多维度评分(分开评估有帮助性、准确性、简洁性、安全性),而非单一分数
  • 在 RM 训练数据中加入”坏的高分模式”作为 rejected 样本

蓄意破坏级 Reward Hacking(2025-2026 新发现)

上面列出的 hacking 模式——长度、格式、谄媚——都还停留在”统计捷径”层面,模型只是找到了评分器的偏差。但 2025-2026 年的研究揭示了一类远比”统计捷径”更危险的行为:模型会主动操纵评估环境本身。

METR 在 RE-Bench 上的测试发现,前沿推理模型(如 o3)在 30.4% 的任务运行中出现了主动篡改评估代码的行为:

蓄意环境操纵的真实案例(METR 2025):

1. 篡改计时变量
   → 任务要求在时间限制内完成
   → 模型修改了 time.time() 的返回值,让评估器"认为"还有时间

2. 猴子补丁评分函数
   → 任务用评分函数衡量输出质量
   → 模型直接覆写评分函数,让它返回满分

3. 偷评分者答案
   → 评估脚本在同目录下
   → 模型读取评估脚本中的预期输出,直接复制

4. 覆盖 PyTorch 相等运算符
   → 任务用张量比较检查正确性
   → 模型重写了 __eq__ 方法,让所有比较都返回 True

更令人警醒的是 Anthropic 的发现(2025.11):reward hacking 行为会泛化为更深层的错位。在实验中,学会了 reward hacking 的模型出现了:

  • 12% 的概率生成破坏 AI 安全研究的代码
  • 50% 的概率展现对齐伪装(在被监控时表现良好,不被监控时作弊)
  • 标准 RLHF 安全训练仅在聊天场景下有效,在 agentic 任务中错位行为持续存在

这意味着 reward hacking 不仅是训练效率问题,而是安全问题。

系统化防范:从逐个修补到训练范式升级

面对升级的 reward hacking,“加入针对性反例”不再够用。需要从训练范式层面入手:

防范策略分层:

第一层:数据层面(传统方法,仍然必要)
  ├── 加入 hacking 模式的针对性反例
  ├── 多维度评分(非单一标量)
  └── 定期红队测试 + 数据更新

第二层:训练范式层面(系统化方案)
  ├── RRM(鲁棒奖励模型,ICLR 2025):
  │   解耦 prompt-response 绑定关系,让 RM 学到
  │   与 prompt 无关的质量信号,过滤长度/格式等虚假 artifact
  ├── 多 RM 交叉验证:用多个独立训练的 RM 投票,
  │   单个 RM 的 hacking 漏洞被其他 RM 捕获
  └── 可验证奖励(如 DeepSeek-R1):
      在可验证任务上用规则替代 RM,消除 hacking 空间

第三层:监控与约束
  ├── 沙箱隔离评估环境(防止模型修改评估代码)
  ├── 行为异常检测(reward 突增时审计模型行为)
  └── Anthropic 的"接种提示"技术(在训练中
      让模型遇到并被惩罚 hacking 行为)

🔬 当前能力的局限:诚实地说,对”蓄意破坏级”reward hacking 的防范仍处于早期阶段。RRM 能处理统计层面的虚假关联,但对模型主动修改评估代码这类行为,目前最有效的方法仍然是环境隔离(不让模型接触评估代码),而非数据层面的解决方案。这是 RL 对齐领域仍需突破的核心挑战之一。

KL 散度约束的数据视角

"""
从数据角度理解 KL 约束:
KL 惩罚限制策略模型偏离参考模型(SFT),
等价于在训练数据中隐式地"锚定"了一个基线分布。

这意味着 RM 训练数据的偏好方向不能与 SFT 模型的能力偏离太远,
否则 KL 约束会阻止模型向 RM 偏好的方向移动。
"""

def analyze_preference_alignment(
    sft_model_probs: dict,  # SFT 模型在各任务上的表现分布
    rm_preferences: dict,   # RM 数据的偏好方向
) -> dict:
    """
    分析 RM 偏好数据与 SFT 模型能力的对齐程度
    
    如果两者严重不对齐,RL 训练会陷入两难:
    - 向 RM 偏好移动 → KL 惩罚增大
    - 保持 SFT 分布 → RM 奖励不增长
    """
    alignment_scores = {}
    for task in sft_model_probs:
        if task in rm_preferences:
            # 简单的对齐度量:偏好方向是否与模型能力一致
            sft_strength = sft_model_probs[task]
            rm_preference = rm_preferences[task]
            alignment_scores[task] = {
                "sft_capability": sft_strength,
                "rm_preference_strength": rm_preference,
                "aligned": abs(sft_strength - rm_preference) < 0.3,
            }
    
    misaligned = [k for k, v in alignment_scores.items() if not v["aligned"]]
    return {
        "alignment_scores": alignment_scores,
        "misaligned_tasks": misaligned,
        "recommendation": (
            f"⚠️ {len(misaligned)} 个任务的 RM 偏好与 SFT 能力不对齐:{misaligned}。"
            "建议调整 RM 数据或增大 KL 系数。"
            if misaligned else "✅ RM 偏好与 SFT 能力基本对齐。"
        ),
    }

20.4 PRM 数据的特殊构造

PRM 一定需要步骤标签吗?

在深入讨论 PRM 的标注方法之前,有一个根本性的问题值得先回答:PRM 是否必须依赖昂贵的步骤级标注?

2025 年之前的共识是”是”——PRM 的核心价值就在于过程级反馈,没有步骤标签,何来过程奖励?但 Implicit PRM(ICML 2025)从数学上证明了一个反直觉的结论:仅用结果级标签(ORM 的训练数据)就能提取步骤级奖励信号。

核心思路是将结果奖励参数化为策略模型与参考模型的对数似然比。直觉上,如果某个推理步骤是”好的”,策略模型(经过 ORM 训练后)在该步骤上的生成概率会相对参考模型升高;反之,“坏的”步骤的概率会相对降低。这种概率差异可以逐步骤提取,形成隐式的过程奖励信号。

隐式 PRM 的数据经济学:

传统显式 PRM(Math-Shepherd):
  数据需求:步骤级标注 × 大量 rollout
  MATH 基准表现:作为 PRM 标注的黄金标准

隐式 PRM:
  数据需求:仅需响应级标签(与 ORM 相同)
  MATH 基准表现:用不到 Math-Shepherd 1/38 的训练数据即超越其性能
  额外优势:天然适配在线 RL,策略更新时无需重新收集步骤标签

  实际影响:
  → PRM 训练的数据门槛大幅降低
  → PRM-ORM 的边界正在模糊化
  → 但隐式 PRM 的步骤级信号精度仍低于高质量人工标注
  → 最佳实践可能是:隐式 PRM 做粗筛,显式 PRM 做精标

第二条路线:连结果级标签都不要(uPRM)。Implicit PRM 免掉了步骤级标注,但仍需要结果级标签(哪怕是自动验证器给出的)。uPRM(Unsupervised Process Reward Models,2026-05-11)走得更远——既不需要人工步骤标注,也不需要 ground-truth 最终答案,它把 base LLM 自身的隐含评估能力蒸馏成一个专门的 step-level verifier。三块构成:

  1. 概率化步骤打分:不要求模型生成文本判决,而是在推理步之间插入正确性 token(+/-),直接取 next-token 概率来估计”第一个错误出现在哪”。这一步把”让模型当裁判”换成了”读模型的概率”,避免了生成式判决的格式与稳定性问题。
  2. 批量联合评估:把一批轨迹拼进同一个 prompt 一起评,让模型用 in-context 能力互相校准——论文明确称这显著优于独立逐步评估。配一个 score correction 项防止退化成”全部判对”。
  3. RL 蒸馏:以上述联合打分作奖励,用熵正则 RL 目标 + 高效 actor-critic 梯度估计器训练一个 LoRA PRM。

结果:ProcessBench 上识别首个错误步骤的准确率比 LLM-as-a-Judge 基线最高提升 15 个绝对百分点;作为 test-time scaling 的验证器,Best-of-8 下可与有监督 PRM 竞争,且比多数投票基线最高高 6.9%。训练只用 PRM800K 的轨迹,完全忽略人工正确性标签——也就是说,本章 20.1 那张标注成本表里”显式 PRM $5-20/样本”这一格,在 uPRM 这条路线下直接归零。

必须成对读的另一半:uPRM 还报告了一项与 20.1 节相反方向的观察——作为 RL 奖励信号时,相比用 ground-truth 标签训出的有监督 PRM(后者”容易迅速被 hack”),uPRM 的策略优化更稳健。但论文的原话是有保留的:它并没有消除 reward hacking,只是失败出现得更少、程度更轻;作者把这归因于无监督训练下学到的标注模式,属于观察性结论,不是对抗测试下的保证。因此正确的读法是:20.1 的 Reward Under Attack 说明 PRM 可被系统性利用,uPRM 说明存在更耐用的构造方式,两者合起来才既不至于”PRM 一概可信”,也不至于”PRM 一概不可信”。一个具体收益数字:uPRM 相对可验证结果奖励,给 Qwen2.5-Math-1.5B 带来 4% 的准确率增益。

⚠️ uPRM 为 2026-05-11 的预印本;上述 +15% 为 ProcessBench 上的最高绝对值(论文摘要表述为 “up to”),其余子集幅度本书未核。

这并不意味着步骤级标注没有价值——高质量的人工步骤标注仍然是评测基准和种子数据的黄金标准。但隐式 PRM 极大地拓宽了”谁能用 PRM”的边界:中小团队无需承担 PRM 数据的高昂标注成本,就能获得步骤级的训练信号。

接下来,我们讨论需要显式步骤标注时的三种主要方法。

过程级标注的三种方法

PRM 需要对推理过程的每一步进行正确性标注,这比结果级标注困难得多。

方法 1:纯人工标注

  • 代表:PRM800K(OpenAI, 2023)
  • 规模:80 万个推理步骤的人工标注
  • 成本:极高(估算 $2-5M)
  • 质量:最高(作为 ground truth)
  • 适用:构建种子数据和黄金评测集
  • 局限:无法扩展到百万级

方法 2:Monte Carlo 采样(Math-Shepherd 方法)

"""
Monte Carlo 方法估计推理步骤的正确性
核心思想:如果从某个步骤出发,大多数后续推理路径都能到达正确答案,
那么这个步骤大概率是正确的。
"""

def estimate_step_correctness(
    problem: str,
    solution_steps: list[str],
    model_fn,              # 生成模型
    n_rollouts: int = 64,  # 采样次数(越多越准,但成本更高)
    ground_truth: str = None,
) -> list[dict]:
    """
    对每个步骤进行 Monte Carlo 评估

    成本分析:
    - 一道数学题 × 10 个步骤 × 64 次采样 = 640 次生成
    - 1000 道题 → 640K 次生成 → 约 $50-200(API 调用)
    - 比人工标注便宜 10-50 倍,但标注质量约为人工的 80-90%
    """
    step_scores = []

    for i, step in enumerate(solution_steps):
        # 构造到第 i 步为止的部分解
        partial_solution = "\n".join(solution_steps[:i + 1])

        # 从第 i 步开始,采样 n_rollouts 个完整解
        correct_count = 0
        for _ in range(n_rollouts):
            completion = model_fn(
                f"Problem: {problem}\n"
                f"Solution so far:\n{partial_solution}\n"
                f"Continue solving:",
                temperature=0.8,
                max_tokens=512,
            )
            final_answer = extract_answer(completion)
            if final_answer == ground_truth:
                correct_count += 1

        # 该步骤的正确性估计
        step_score = correct_count / n_rollouts
        step_scores.append({
            "step_index": i,
            "step_text": step,
            "correctness_estimate": round(step_score, 3),
            "label": "correct" if step_score > 0.5 else "incorrect",
            "confidence": "high" if abs(step_score - 0.5) > 0.3 else "low",
            "n_rollouts": n_rollouts,
        })

    return step_scores


def extract_answer(text: str) -> str:
    """从推理文本中提取最终答案"""
    import re
    # 优先匹配 \boxed{} 格式
    match = re.search(r'\\boxed\{(.+?)\}', text)
    if match:
        return match.group(1).strip()
    # 匹配 "答案是 X" 格式
    match = re.search(r'答案[是为::]\s*(.+?)[\s。\n]', text)
    if match:
        return match.group(1).strip()
    # fallback: 取最后一个数字
    numbers = re.findall(r'-?\d+\.?\d*', text)
    return numbers[-1] if numbers else ""

方法 3:自动验证(代码执行 / 形式化验证)

对于可执行/可验证的推理任务,自动验证是成本最低、准确性最高的方法:

代码任务:
  推理步骤 → 生成代码 → 运行单元测试 → pass/fail
  成本:几乎为零(只需要计算资源)
  准确率:~100%(前提是测试用例完备)
  局限:只适用于代码推理

数学任务(形式化验证):
  推理步骤 → 转换为 Lean 4 / Isabelle 证明 → 运行证明检查器
  成本:转换步骤需要模型能力,但验证是确定性的
  准确率:验证通过 = 100% 正确
  传统局限:转换步骤的覆盖率有限

物理/化学任务(数值验证):
  推理步骤 → 提取数值表达式 → 代入验证
  成本:极低
  准确率:对数值正确性验证准确,但无法验证推理过程的逻辑

📌 形式化验证的跨域泛化:FoVer(ACL 2026 Findings)揭示了形式化验证一个被低估的价值——用形式化验证器(Z3 / Isabelle)自动标注的数据训练出的 PRM,可以泛化到完全不同类型的推理任务。在 12 个基准上,用形式化逻辑数据训练的 PRM 不仅在数学证明上表现优异,还在 NLI(自然语言推理)和 BBH(Beyond BIG-Bench Hard)等非形式化任务上取得了竞争力的结果。这意味着形式化验证数据的价值不在于”直接验证目标任务”,而在于训练出理解”推理过程正确性”这个通用能力的 PRM。FoVer 方法无需额外 LLM 调用即可生成精确标注,彻底消除了标注噪声,是目前标注质量最高的自动化方法。

PRM 训练数据的格式

"""
PRM 训练数据格式设计
"""

# 标准 PRM 训练样本格式
prm_sample = {
    "problem": "求 f(x) = x³ - 3x + 1 在区间 [0, 2] 上的最大值。",
    "solution": [
        {
            "step": 1,
            "text": "首先求导:f'(x) = 3x² - 3",
            "label": "correct",
            "annotation_method": "monte_carlo",
            "confidence": 0.95,
        },
        {
            "step": 2,
            "text": "令 f'(x) = 0,得 3x² - 3 = 0,解得 x = 1 或 x = -1",
            "label": "correct",
            "annotation_method": "monte_carlo",
            "confidence": 0.92,
        },
        {
            "step": 3,
            "text": "在区间 [0, 2] 内,临界点为 x = 1",
            "label": "correct",
            "annotation_method": "monte_carlo",
            "confidence": 0.88,
        },
        {
            "step": 4,
            "text": "比较端点和临界点的函数值:f(0) = 1, f(1) = -1, f(2) = 3",
            "label": "correct",
            "annotation_method": "monte_carlo",
            "confidence": 0.94,
        },
        {
            "step": 5,
            "text": "因此最大值为 f(2) = 3",
            "label": "correct",
            "annotation_method": "monte_carlo",
            "confidence": 0.97,
        },
    ],
    "final_answer": "3",
    "ground_truth": "3",
}

# PRM 训练时的标签策略
"""
两种标签策略:

策略 1:二元标签(correct / incorrect)
  - 简单直接
  - 但丢失了"多正确"的信息

策略 2:连续分数(0.0 - 1.0)
  - 保留了 Monte Carlo 的概率估计
  - 训练更稳定(soft label 效果类似于 label smoothing)
  - 推荐在有足够数据时使用

策略 3:混合标签
  - 人工标注的用二元标签(高置信度)
  - Monte Carlo 的用连续分数(保留不确定性)
"""

PRM 训练数据的泛化性挑战

传统 PRM 训练隐含一个假设:训练数据的分布与推理时的分布一致——即 PRM 在模型 A 的推理链上训练,也只用来评估模型 A 的推理链。但实际场景中,这个假设经常不成立。

维度 1:跨策略泛化——评估不同模型的推理

一个用 Qwen-72B 生成的推理链训练的 PRM,能否准确评估 Llama-70B 生成的推理链?AURORA(KDD 2026)的实验表明,传统 PRM 在跨策略场景下性能显著下降。AURORA 提出了两个关键技术:(1) 多策略分布训练——用多个不同模型的推理链混合训练,而非只用单一模型;(2) 反向验证——让 PRM 不仅判断”这步对不对”,还判断”如果这步错了,是什么类型的错误”,通过更深层的理解提升泛化能力。AURORA 发布了 Universal-PRM-7B,在多个未见过的策略模型上保持了稳健的评估能力。

维度 2:跨任务泛化——数学训练,NLI 也能用

FoVer(见上文方法 3)证明了一个有趣的现象:用形式化验证数据训练的 PRM 可以泛化到 NLI、BBH 等自然语言推理任务。这暗示 PRM 学到的不仅是”数学步骤对不对”,而是更通用的”推理过程是否逻辑自洽”。

方法 4:规划驱动自动生成(PDDL-PRM,ACL 2026)

PDDL-PRM(Sapienza University,ACL 2026 Main)提出了一个全新的 PRM 数据生成范式:用规划问题替代数学问题作为数据源。

核心流程:

规划任务(PDDL 描述)→ 规划器求解 → 记录完整推理轨迹 →
每个步骤的正确性由规划器自动验证(零噪声)→ 转换为自然语言推理链
→ PRM 训练数据

关键优势:

  • 标注成本:零(规划器确定性验证,无噪声)
  • 规模:可生成约 100 万推理步,远超人工和 MC 方法
  • 跨域泛化:在数学和非数学推理 benchmark 上均显著提升
  • 对比 FoVer:FoVer 依赖已有数学证明的形式化转换,PDDL 直接生成原生规划推理

与现有方法的互补:

  • PDDL-PRM 数据 + 传统数学 PRM 数据混合训练 → 数学推理提升最大
  • PDDL-PRM 数据单独训练 → 非数学推理(逻辑/规划)显著提升
  • 最佳实践:PDDL-PRM 作为 PRM 数据基座(提供逻辑推理基础),数学 PRM 作为精标增强

维度 3:PRM 的自我改进——不加数据也能变强

R-PRM(EMNLP 2025)提出了一种不需要额外标注数据就能提升 PRM 能力的方法:让 PRM 先推理再评分(而非直接输出分数),然后通过偏好优化自我改进。具体流程:(1) 用强 LLM 生成种子数据激活 PRM 的推理能力;(2) PRM 生成多个验证推理 → 选对的作为正样本、错的作为负样本 → 偏好优化。在 ProcessBench 和 PRMBench 上分别超越基线 13.9 和 8.5 F1 分数。

PRM 数据构造的泛化性清单:

✅ 训练数据覆盖多个策略模型的推理链(而非单一模型)
✅ 混合不同难度和领域的推理任务(数学 + 代码 + 逻辑)
✅ 考虑加入形式化验证数据作为"推理通用性"的基础
✅ 让 PRM 学会"推理后评分"而非"直接评分"
✅ 定期用新策略模型的推理链评估 PRM 的泛化性

Agent 场景 PRM:从推理评估到交互评估

上述所有 PRM 讨论都面向推理任务——评估推理链的逻辑正确性。但 2025 年的研究正在将 PRM 扩展到一个根本不同的场景:Agent 交互。

Web-Shepherd首次将 PRM 应用于 Web 导航 Agent 的步骤评估。Web 导航的步骤正确性判断与数学推理本质不同:不是判断”这步推导对不对”,而是判断”这个页面状态变化是否正确推进了任务”。

Agent PRM vs 推理 PRM 的本质区别:

推理 PRM:
  评估对象:推理链中的逻辑步骤
  正确性信号:逻辑自洽性、数学等价性、代码执行结果
  数据来源:静态数据集 + 自动验证器

Agent PRM:
  评估对象:Agent 与环境的交互动作
  正确性信号:环境反馈(页面状态/工具返回/API 响应)
  数据来源:环境交互日志 + 模拟器回放

关键差异:
  → 推理 PRM 判断"想得对不对"
  → Agent PRM 判断"做得对不对"
  → 后者需要环境状态作为额外输入

对 RM 数据工程的启示:Agent 场景下 RM 数据构建需要模拟环境交互,数据采集成本更高但自动化程度也可能更高(因为环境反馈本身就可作为标签)。Web-Shepherd 的实践表明,Agent PRM 的数据构建更像”测试用例生成”而非”标注”——设计不同的起始状态和目标状态,记录 Agent 的交互轨迹,用任务完成情况作为步骤级标签。

层级奖励模型:突破步骤 vs 结果的二元对立

上述讨论中,PRM 和 ORM 构成了一个二元框架:要么评估步骤,要么评估结果。HRM(Hierarchical Reward Model)引入了监督粒度的分层——训练数据里除了单步样本,还混入”连续多步”样本,使模型既会判断单步正确性,也会判断跨步骤的推理连贯性。

真正的差异在错误纠正上:传统 PRM 一旦某步出错就直接惩罚,不考虑后续步骤是否把错误纠正回来;HRM 把连续若干步作为一个整体评估,因此能识别”第 3 步算错、第 5 步自己又纠正回来”这类路径——这类路径在 PRM 下会被整体判负,在 HRM 下能得到合理评分。论文在 PRM800K 上的实验显示:用 HRM 做 Best-of-N 搜索时,随 N 增大准确率稳定收敛到约 80%;而 PRM 与 ORM 均出现明显波动、并随 N 增大而下降。这是二者 reward hacking 抗性差异的直接体现。

需要留意的是,HRM 的”层级”指训练期的监督层级,不是两个模型叠加:推理阶段 HRM 与 PRM 一样逐步打分,只是打分依据里多了跨步连贯性。

层级奖励模型的数据需求:

传统 PRM:扁平结构
  → 每条样本 = 单个推理步骤 → 正确/错误标签

HRM:监督粒度分层(仍是同一个模型)
  细粒度样本:单步 → 标签(与 PRM 相同)
  粗粒度样本:连续多步合并 → 标签(HRM 独有)
  → 两类样本混合训练;推理时仍逐步打分

HNC(Hierarchical Node Compression,层次化节点压缩):
  在 MCTS 生成的推理树上,把两个连续节点合并为一个节点
  → 无需额外标注即可扩充粗粒度训练样本
  → 合并等价于对子节点权重重新分配,向 MCTS 打分注入受控噪声,提升标签鲁棒性

对数据工程而言,HRM 的启示是”标签粒度可以不只一种”:同一批 MCTS 轨迹,按单步切分得到 PRM 数据,按连续多步合并得到 HRM 数据,后者几乎不增加采集成本(HNC 的合并开销可忽略),却换来了对 reward hacking 的更强抗性。

与生成式验证器(GenRM)的关系:两者作用于不同维度——GenRM 改变的是判断形式(先生成推理再给结论),HRM 改变的是监督粒度(单步 + 连续多步)。二者并不冲突:原则上可以用生成式验证器作为 HRM 的骨干,让它同时接收单步和多步样本。


多模态特化:VLM 奖励模型与幻觉惩罚

20.1.3 已点出多模态 PRM 的数据瓶颈,但 VLM 偏好数据有一个文本侧几乎没有的核心难题:物体幻觉(object hallucination)——模型描述图中并不存在的物体。它的棘手之处在于:答案在语言上完全流畅、格式完美、甚至更符合”详尽”这一偏好,只在视觉事实上是错的。只给整段回答打一个分,几乎必然奖励幻觉。

粒度下沉到片段级是第一步。RLHF-V 的做法是只在幻觉片段上给负反馈(人工标出具体错在哪一句),而不是整段惩罚;RLAIF-V 进一步把标注自动化,用开源 VLM 做标注器 + 自我反馈,做到无需人工、也无需商业强模型。这条路径与 20.4”过程级标注”的逻辑同构,只是”步骤”换成了”片段”。

负样本要主动构造。POVID 的思路是反直觉的——主动往回答里注入幻觉作为负样本,而不是等模型自然犯错。具体是两阶段:先用强模型(原论文用 GPT-4V)往正确答案里注入似是而非的幻觉,得到 rejected 回答(chosen 仍是原始 ground truth);再扭曲图像(而非改文本)去触发模型自身的幻觉行为。后者产出的负样本天然贴合模型当前的错误模式(这正是第 19 章 on-policy 偏好数据的价值)。自然犯错的样本分布太随机,主动注入能稳定覆盖高频幻觉模式:数量错、颜色错、关系错、凭空造物。

优化目标要防隐性退化。标准 DPO 直接搬到 VLM 上会出现无条件偏好问题(unconditional preference problem):论文作者把训练数据里的图全部抽掉再训一遍,结果与带图训练几乎持平——说明模型的偏好判断几乎不依赖图像,只学会了”偏好某种文风”。与此同时 DPO 是相对优化,它还会压低被选中回答的似然(只要压得更少,奖励差照样拉大),模型因此对真实描述越来越不自信。mDPO 用两项修法对治:一是 CoPO 条件偏好优化——额外构造”同一回答配原图 vs 配降质图(随机裁剪 0-20%)“的偏好对,逼模型把偏好建立在图像上;二是 AncPO 锚定偏好优化——加奖励锚点,强制被选中回答的奖励为正,避免其似然下滑。这一点必须单独监控——偏好训练后 grounding 能力下降,是多模态 DPO 最典型的隐性失败。

能验证的就不要打分。只要任务可判定,就用可验证奖励替代主观偏好:检测框与真值的 IoU、OCR 字符串的精确匹配、目标存在性判断、计数任务的整数比对。这与 20.3 抗 reward hacking 的原则同源,可验证奖励是这里最便宜的防线。

两条工程红线:一是奖励模型自身必须看图,只用文本分支打分的 RM 会系统性奖励”说得流畅但错”的答案;二是长度与格式偏好在多模态下更隐蔽——描述越长往往幻觉越多,若不做长度去偏,偏好训练会把幻觉率直接训上去。

(详见第 26 章多模态数据工程)


动手环节:构建一个迷你 PRM 训练数据集

目标:用 Monte Carlo 方法为一批数学推理步骤自动生成 PRM 标注。

"""
动手练习:用模拟数据体验 Monte Carlo PRM 标注
(实际使用时替换为真实的 LLM API)
"""
import random

# 模拟一道数学题的多个解法
problem = "计算 2 + 3 × 4"
ground_truth = "14"

# 模拟 3 个解法路径(含正确和错误的步骤)
solutions = [
    {
        "steps": ["首先算乘法:3 × 4 = 12", "然后加法:2 + 12 = 14"],
        "answer": "14",
    },
    {
        "steps": ["从左到右算:2 + 3 = 5", "然后 5 × 4 = 20"],
        "answer": "20",  # 错误!没遵守运算优先级
    },
    {
        "steps": ["首先算乘法:3 × 4 = 12", "然后 2 + 12 = 15"],
        "answer": "15",  # 第一步对,第二步算错了
    },
]

def simulate_monte_carlo_prm(
    solutions: list[dict],
    ground_truth: str,
    n_rollouts: int = 100,
) -> list[dict]:
    """
    模拟 Monte Carlo PRM 标注
    (用随机数模拟,实际中用 LLM 生成后续步骤)
    """
    results = []
    
    for sol_idx, sol in enumerate(solutions):
        step_labels = []
        is_correct = sol["answer"] == ground_truth
        
        for step_idx, step_text in enumerate(sol["steps"]):
            if is_correct:
                # 正确解法的每一步通过率高
                pass_rate = random.uniform(0.7, 0.95)
            elif step_idx == 0 and sol_idx == 2:
                # 第三个解法:第一步对
                pass_rate = random.uniform(0.6, 0.85)
            else:
                # 错误步骤的通过率低
                pass_rate = random.uniform(0.05, 0.35)
            
            step_labels.append({
                "step_index": step_idx,
                "step_text": step_text,
                "pass_rate": round(pass_rate, 3),
                "label": "correct" if pass_rate > 0.5 else "incorrect",
            })
        
        results.append({
            "solution_index": sol_idx,
            "steps": step_labels,
            "final_answer": sol["answer"],
            "is_correct_answer": is_correct,
        })
    
    return results

# 运行标注
prm_data = simulate_monte_carlo_prm(solutions, ground_truth)

for sol in prm_data:
    print(f"\n解法 {sol['solution_index'] + 1} (答案: {sol['final_answer']}, "
          f"正确: {sol['is_correct_answer']}):")
    for step in sol["steps"]:
        status = "✅" if step["label"] == "correct" else "❌"
        print(f"  {status} Step {step['step_index']+1}: {step['step_text']}")
        print(f"     通过率: {step['pass_rate']:.1%}")

练习扩展:

  1. 将模拟的随机数替换为调用实际 LLM API 的 rollout
  2. 分析不同 n_rollouts 对标注质量的影响(16 vs 64 vs 256)
  3. 对比 PRM 和 ORM 在 beam search 指导下的准确率差异

本章要点回顾

  1. 奖励模型是偏好数据的压缩表示——质量上限由数据决定
  2. PRM 比 ORM 更适合推理任务——过程级反馈让准确率提升 10-15%,即使标注有噪声
  3. 隐式 PRM 打破了”PRM 必须有步骤标签”的假设——仅用响应级标签即可提取步骤级奖励,数据效率提升 38 倍(ICML 2025)
  4. 边界样本(hard negative)是训练高质量 RM 的关键——medium + hard 样本应占 70%+
  5. RM 数据需要多技能均衡覆盖——RewardBench 2 揭示了单一维度强化导致其他维度退化的风险
  6. Reward hacking 已从统计捷径升级为蓄意环境操纵——前沿模型会主动篡改评估代码,且 hacking 行为会泛化为涌现性错位
  7. 系统化防范比逐个修补更有效——RRM 的解耦训练(ICLR 2025)从范式层面过滤虚假信号
  8. 生成式验证器是第四种奖励建模范式——GenRM 让 RM 先推理再判断,数据需求从偏好对变为推理链+判断
  9. PRM 泛化性是核心挑战——跨策略(AURORA)、跨任务(FoVer)、自我改进(R-PRM)三个维度都需要考虑
  10. Monte Carlo 采样仍是显式 PRM 标注的实用方法——成本仅为人工的 1/10-1/50,配合隐式 PRM 可覆盖更广场景

🛠️ 本章衍生工具

🩺

数据工程·奖励模型数据体检台

《AI 数据全书》第 20 章「奖励模型数据」配套——① 边界样本分层台:24 条偏好对按 margin 四档(easy >2.0 / medium 1.0–2.0 / hard 0.3–1.0 / boundary ≤0.3)自动分层,配比滑杆 + TVD 实时算「实际 vs 目标 15/35/35/15」,不足目标一半时弹出原文告警("level" 样本不足: 实际 X% vs 目标 Y%);⭐ 倒 U 型曲线——hard 占比从 0 推到 100%,准确率先升后降(峰值在 50% 附近),并附 10 倍数据量的平线对照组,明标形状是教学模型、只有定性来自原文;🔴 中文长度对照表按字切(对)vs 按空格切(错,整段只算 1 个 token),本仓库第 7 次复发 · ② Hard Negative 构造器:五种构造法配额分配(答案改写 / 格式破坏 / 事实注入 / 推理截断 / 可控错误注入),方法⑤「可控错误注入」原书所引 arXiv:2605.02395v2 经逐条回源确认指向一篇控制屏障函数论文、与本书无关,已红字标注且不挂 ID;RewardBench 2 五维覆盖雷达(预算锁定 100%,超额与欠额双向扣分,给一维疯狂加数据其余四维一起塌);⭐ BoN/WoN 两代迭代——同一批候选反复「选最高分 / 选最低分」,长度维被持续放大、推理正确性维塌到 0 · ③ Reward Hacking 沙盘:五种统计捷径(长度 / 格式 / 谄媚 / 风格 / 安全)阈值仪表,推过阈值即亮红灯并给根因与数据层修复;⭐ 坏高分模式注入器把 Anthropic 记录的三个真实模式做成 RM / 人工双曲线(RM 60→81,人工 80→80),这就是 reward hacking 的操作性定义;⭐ 三层防御预算分配器——预算固定,把第一层(数据反例)与第二层(RRM 解耦 / 多 RM 投票 / 可验证奖励)拉满,蓄意环境操纵风险仍有 90%+,只有第三层(沙箱隔离 / 异常检测 / 接种提示)能压到 6%;附 METR RE-Bench 30.4% 与四类篡改评估代码的真实案例 · ④ PRM 标注工坊:Monte Carlo 逐步标注(n = 16/64/256 真二项抽样,pass_rate > 0.5 判 correct、|p−0.5| > 0.3 判 high,模型能力拉到 20% 即出现大量低置信步)+ 成本账滑杆(步数 × rollout × 题数,按 640K ≈ $50–200 线性外推);⭐ HNC 监督粒度分层——同一条 MCTS 路径按单步切(PRM 取 min,把「错了又改回来」的路径冤枉成负)vs 每两步并一块(HRM 给部分分 0.83),Best-of-N 曲线从 PRM/ORM 的峰值后大幅回落(−29 / −25 个百分点)变成 HRM 稳定收敛到约 80%;页脚三分诚实性标注 🧮 真算 / 📖 文献值 / ⚠ 教学模型