第 15 章 第三部分:后训练数据工程

RL/RLVR数据构建(核心)

为什么是RLVR(DPO天花板离线/RL允许自我rollout/RLVR奖励0/1干净)、数据三要素(prompt/verifier/元信息)、五类可验证任务(数学sympy/代码单测/指令遵循规则/抽取F1/多步推理)、Prompt池构建(难度梯度pass@8/多样性/可验证性)、Verifier设计坑(数学等价/沙箱隔离/多解/Cross-Verifier)、GRPO风格Rollout(N=16采样/组内z-score/课程化重采)、长链思维CoT(R1-Zero纯RL涌现/不给参考过程/超长输出8K-32K)、Reward Hacking检测、信用分配(Cue-GRPO结构级偏斜/VIGOR预算分配)、过程奖励三路线(SCOPE-RL任务侧造信号/RSTG教师侧借信号/StructReward免verifier规则对齐)、多语言RLVR(母语差距小/强跨语言迁移/严重回退监控)

RLVR GRPO Verifier 长链思维 Reward Hacking DeepSeek R1 信用分配 多语言RLVR

DPO 教模型品味,RL 让模型思考。

RLVR 的奖励是 0/1,干净得像数学证明——这是后训练最锋利的工具。


15.1 为什么是 RLVR

15.1.1 DPO 的天花板

DPO 是离线方法,只能在已有数据上优化。它的天花板是”数据集中最好的响应”——模型永远学不到”比数据更好的响应”。

DPO 的三个根本局限:

  1. 离线束缚:无法探索数据集外的响应
  2. 分布偏移:训练数据来自其他模型,与当前策略分布不一致
  3. 偏好粒度粗:只有好/坏,没有”多好”

15.1.2 RL 的突破

RL(Reinforcement Learning)允许模型自我 rollout——用当前策略生成响应,用 reward 评估,再优化策略。这让模型可以”探索数据集外的空间”,突破离线天花板。

RL 的核心公式:

L_RL = -E_{y~π(x)}[reward(x,y)] + β·KL(π||π_ref)

15.1.3 RLVR:奖励干净到极致

RLVR(RL with Verifiable Rewards)的核心:用可验证的函数做 reward,而不是用 Reward Model。

Reward 类型来源噪声可信度
Reward Model学习得到高中
用户反馈用户点击极高低
Verifier规则/代码零极高

RLVR 的 reward 只有 0 和 1:

  • 数学题答对:1,答错:0
  • 代码通过单测:1,不通过:0
  • 指令符合格式:1,不符合:0

这种”干净到极致”的奖励信号,让模型可以学到真正的推理能力,而不是”骗过 Reward Model”。

15.1.3.1 隐藏失败模式:hard problem 零信号

RLVR 的 0/1 奖励”干净”,但也暗藏一个致命弱点:当模型对 hard problem 所有 N 个 rollout 都得到 0 分时,GRPO 的组内 z-score 归一化完全失效——所有 advantage 均为 0,产生零学习信号。模型在这个 prompt 上”学不到任何东西”。

Off-Context GRPO(Agrawal et al., arXiv:2607.19313)提出了一个精巧的解决方案:

  1. 训练时注入特权引导:当检测到全 0 奖励时,给训练 prompt 注入 solution prefix(如推理的第一步)作为”特权引导”,使模型能产生非零 reward rollout
  2. 重要性修正回原始目标:用 importance-corrected objective 将更新导回原始无引导目标,确保推理时不依赖引导
  3. 几乎零额外成本:只需修改训练时的 prompt 构造,不需要额外的 reward model 或人工标注

在数学推理基准上平均 +3.9% absolute(+13.8% relative)。这对”始终 0”的 hard problem 区间尤为有效——而这恰恰是模型最需要突破的能力边界。

15.1.4 R1-Zero 的震撼

DeepSeek R1-Zero(2025)证明了纯 RLVR(跳过 SFT)可以让模型涌现出长链思维。这是后训练的里程碑——第一次证明”不需要人类示范,模型也能学会推理”。


15.2 RLVR 数据三要素

15.2.1 三要素结构

RLVR 数据与 SFT/DPO 数据截然不同,它的核心是三要素:

{
  "prompt": "求解 x^2 - 5x + 6 = 0",
  "verifier": {
    "type": "math_sympy",
    "expected_answer": "x=2 or x=3",
    "check_fn": "lambda ans: sympy.checker(eq='x^2-5x+6', ans=ans)"
  },
  "metadata": {
    "difficulty": "easy",
    "domain": "algebra",
    "pass_at_8": 0.85,
    "source": "numina_math"
  }
}
  • prompt:任务指令
  • verifier:判断响应是否正确的函数
  • metadata:难度、领域、pass@8 等元信息

15.2.2 verifier 是核心

SFT 数据的灵魂是 response,RLVR 数据的灵魂是 verifier。一个坏的 verifier 会让模型学到错误行为,且极难发现。

verifier 设计的核心原则:

  1. 正确性:必须真的能判断对错
  2. 鲁棒性:不能被 reward hacking 骗过
  3. 效率:单个验证 < 1 秒(rollout 时调用频繁)
  4. 可扩展:能批量验证 N=16-64 个 rollout
  5. 可量化:用 Youden’s J = TPR - FPR 作为 verifier 质量的单标量指标。J > 0 时 GRPO 学习成功(噪声只影响收敛速率,不改变最终命运),J < 0 时学习退化。现实中 verifier 不会完美(单元测试只覆盖有限 corner case),但 J 提供了一个可量化的验收标准——“足够好”的 verifier 至少需要 J > 0.5

15.3 五类可验证任务

15.3.1 数学(sympy 验证)

import sympy

def math_verifier(response, expected_answer):
    # 1. 抽取最终答案
    final_answer = extract_final_answer(response)
    # 2. 用 sympy 检查等价
    try:
        expr1 = sympy.sympify(final_answer)
        expr2 = sympy.sympify(expected_answer)
        is_equiv = sympy.simplify(expr1 - expr2) == 0
        return 1.0 if is_equiv else 0.0
    except:
        # 退回到字符串匹配
        return 1.0 if normalize(final_answer) == normalize(expected_answer) else 0.0

典型数据源:GSM8K、MATH、NuminaMath、AMC/AIME 题目

15.3.2 代码(单测验证)

def code_verifier(response, test_cases):
    # 1. 抽取代码
    code = extract_code(response)
    # 2. 沙箱执行
    with Sandbox() as sb:
        try:
            sb.execute(code)
            results = [sb.run_test(tc) for tc in test_cases]
            pass_rate = sum(results) / len(results)
            return pass_rate  # 0-1 连续值
        except Exception as e:
            return 0.0

典型数据源:HumanEval、MBPP、APPS、CodeContests

15.3.3 指令遵循(规则验证)

def instruction_following_verifier(response, constraints):
    score = 0
    for constraint in constraints:
        if check_constraint(response, constraint):
            score += 1
    return score / len(constraints)

# 示例约束
constraints = [
    "response length <= 200 words",
    "response contains exactly 3 paragraphs",
    "response starts with 'Sure'",
    "response does not contain 'I'"
]

典型数据源:IFEval、FollowBench

15.3.4 信息抽取(F1 验证)

def extraction_verifier(response, ground_truth_entities):
    extracted = parse_entities(response)
    # F1 score
    tp = len(extracted & ground_truth_entities)
    fp = len(extracted - ground_truth_entities)
    fn = len(ground_truth_entities - extracted)
    precision = tp / (tp + fp) if (tp + fp) > 0 else 0
    recall = tp / (tp + fn) if (tp + fn) > 0 else 0
    f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0
    return f1

典型数据源:CONLL2003、ACE2005

15.3.5 多步推理(中间步骤验证)

def multi_step_verifier(response, expected_steps):
    extracted_steps = parse_reasoning_steps(response)
    # 检查每个步骤是否正确
    correct = 0
    for ext, exp in zip(extracted_steps, expected_steps):
        if check_step_equivalence(ext, exp):
            correct += 1
    # 全对才给 1,部分对给部分分
    return correct / len(expected_steps)

典型数据源:StrategyQA、ProofWriter


15.4 Prompt 池构建

15.4.1 难度梯度(pass@8)

RLVR 训练的关键是难度梯度——太简单的模型已经会,学不到东西;太难的模型完全不会,也学不到东西。

工业级用 pass@K 量化难度:

def compute_pass_at_k(model, prompt, verifier, k=8):
    results = []
    for _ in range(k):
        response = model.generate(prompt, temperature=0.7)
        results.append(verifier(response))
    return sum(results) / k  # 0-1

难度分桶:

pass@8难度训练价值推荐占比
0.8-1.0太简单低10%
0.5-0.8简单中20%
0.2-0.5中等高40%
0-0.2困难中20%
0太难低10%

经验:pass@8 在 0.2-0.5 的 prompt 训练价值最高——模型有时能解、有时不能解,正是在”学习边界”上。

15.4.2 多样性

Prompt 池要覆盖多维度:

  • 领域:代数/几何/微积分/数论/组合
  • 题型:求解/证明/应用题
  • 长度:短题(<100 字)/中题/长题(>500 字)
  • 难度:小学/初中/高中/本科/竞赛

15.4.3 可验证性筛选

不是所有 prompt 都能做 RLVR——必须能定义 verifier。

def filter_verifiable(prompts):
    verifiable = []
    for p in prompts:
        if has_ground_truth_answer(p):
            verifiable.append(p)
        elif has_test_cases(p):
            verifiable.append(p)
        elif has_explicit_constraints(p):
            verifiable.append(p)
        # 开放式问题(如"写一首诗")无法 RLVR
    return verifiable

踩坑:约 60-70% 的 prompt 因无法定义 verifier 被过滤,需要预留冗余采集。

15.4.4 语言维度:被忽略的第四个属性

15.4.1–15.4.3 讨论的是 prompt 池的难度、多样性、可验证性三个属性。但还有一个属性在绝大多数开源配方里被默认为常量:语言。本章五类可验证任务的 benchmark(GSM8K、MATH、HumanEval、BFCL 等)几乎全是英语,中文 RLVR 数据工程长期缺少系统的实证依据。

GRPO Beyond English(Konstantin Dobler 等 5 人,arXiv:2608.13698)是目前规模最大的多语言 GRPO 实证研究,覆盖多种 base model、训练语言与推理语言奖励设置。三条结论对中文场景有直接价值:

结论原文发现对中文 RLVR 的含义
母语训练差距小用母语做推理训练,与英语推理训练的差距通常只有很小一点不必默认”必须翻译成英文 prompt 才有推理能力”,中文 prompt 池是可行的
跨语言迁移强在一种语言上训练,往往能提升其他多种语言的表现中文数据不足时,可先在中英混合上训练,不必等中文数据齐备
但存在严重回退趋势高度依赖具体模型与语言;某些语言上的训练会导致其他语言域外能力严重回退加中文数据不等于全面提升,必须做回退监控

必须加的工程动作:第三条是这张表里唯一带风险的一条,也是提案与多数转述都略过的部分。它把”多语言配比”从一次性的静态决策,变成了需要持续监控的动态问题:

# 按语言分桶跟踪域外能力,而不是只看总体指标
def multilang_regression_check(ckpt, base_ckpt, eval_sets_by_lang):
    for lang, evals in eval_sets_by_lang.items():
        for name, metric in evals.items():
            delta = eval(ckpt, name) - eval(base_ckpt, name)
            if delta < -REGRESSION_THRESHOLD:   # 建议 3-5 个百分点
                alert(f"[{lang}] {name} 回退 {delta:.1f}pp")

配套的两个判断:

  • verifier 的语言偏差:数学/代码的 verifier 相对语言中立,但指令遵循(IFEval 类)与信息抽取(F1)的 verifier 往往内嵌英语假设,中文上直接套用会系统性低估。这是比 prompt 池更难发现的偏差源。
  • 不要靠”加中文数据”解决回退:论文指出的是回退存在且依赖模型语言对,并未给出普适的配比解。正确做法是先量化回退,再决定是调整配比、混合训练,还是回退到上一检查点。

⚠️ 成熟度提示:该研究为 2026-08 的实证工作,其结论的普适性受限于所覆盖的模型与语言集合。中文是否在”强迁移”或”严重回退”一侧,需要在你自己的基座上实测,不宜直接外推。


15.5 Verifier 设计的坑

15.5.1 数学等价坑

# 错误:字符串匹配
"1/2" == "0.5"  # False,但数学等价

# 正确:sympy 等价检查
sympy.simplify(sympy.sympify("1/2") - sympy.sympify("0.5")) == 0  # True

陷阱:

  • (x+1)^2 vs x^2+2x+1:展开形式不同但等价
  • 2 vs 2.0:类型不同但数值相同
  • {-1, 1} vs ±1:集合表示差异

解决方案:用 sympy 的 simplify(a - b) == 0 检查等价,覆盖 95%+ 情况。

15.5.2 沙箱隔离坑

代码 verifier 必须在沙箱中执行,否则有安全风险。

# 错误:直接 exec
exec(user_code)  # 危险!可能删库

# 正确:Docker 沙箱
def safe_execute(code, test_cases):
    with docker_container(image="python:3.11-slim") as sb:
        sb.copy("solution.py", code)
        sb.copy("test.py", generate_test_file(test_cases))
        result = sb.run("python test.py", timeout=10)
        return parse_result(result)

踩坑:

  • 沙箱必须有超时(10 秒)——死循环会卡死 rollout
  • 沙箱必须限制内存(512MB)——大内存分配会拖垮系统
  • 沙箱必须无网络——否则模型学会”调 API 作弊”

15.5.3 多解坑

数学题常有多种解法,verifier 必须支持:

def math_verifier_multi(response, acceptable_answers):
    final = extract_final_answer(response)
    for ans in acceptable_answers:
        if sympy_equivalent(final, ans):
            return 1.0
    return 0.0

# 示例:x^2 = 4 的解可以是 {-2, 2} 或 x=±2
acceptable = ["{-2, 2}", "{2, -2}", "x=±2", "x=2 or x=-2"]

15.5.4 Cross-Verifier

为防止单一 verifier 的盲点,关键 prompt 用多个 verifier 交叉验证:

def cross_verify(response, prompt):
    v1 = math_sympy_verifier(response, prompt)
    v2 = math_llm_verifier(response, prompt)  # LLM 当备份 verifier
    v3 = math_human_verifier(response, prompt)  # 抽样人审
    
    if v1 == v2:
        return v1
    else:
        # 分歧时人审
        return v3

经验:1% 的 prompt 会出现 verifier 分歧,必须人审,否则会导致错误训练信号。


15.6 GRPO 风格 Rollout

15.6.1 GRPO 算法核心

GRPO(Group Relative Policy Optimization, DeepSeek 2024)是 RLVR 的主流算法,相比 PPO 显存占用低 4 倍。

核心思想:对每个 prompt 采样 N 个响应,用组内归一化计算 advantage,无需训练 value model。

def grpo_step(model, ref_model, prompt, verifier, n=16):
    # 1. 采样 N 个响应
    responses = [model.generate(prompt, temperature=0.7) for _ in range(n)]
    
    # 2. 计算 reward
    rewards = [verifier(r) for r in responses]
    
    # 3. 组内 z-score 归一化
    mean_r = np.mean(rewards)
    std_r = np.std(rewards)
    advantages = [(r - mean_r) / (std_r + 1e-8) for r in rewards]
    
    # 4. 计算梯度
    for r, adv in zip(responses, advantages):
        log_ratio = log_prob(model, r) - log_prob(ref_model, r)
        loss = -adv * log_ratio + β * kl_penalty(model, ref_model, r)
        loss.backward()
    
    optimizer.step()

15.6.2 关键参数

参数推荐值备注
N(group size)16太小方差大,太大显存爆
temperature0.7太低无探索,太高全乱码
β(KL 系数)0.001-0.01比 DPO 小一个数量级
max_tokens8192-32768长链 CoT 必需
学习率1e-6 到 1e-5极小,否则崩溃
动态 N4→16(方差驱动)VIGOR 策略比固定 N 省 30-57% 预算

15.6.3 课程化重采

RLVR 训练中 prompt 池不是固定的,要根据模型能力动态调整:

def curriculum_resampling(model, prompt_pool, epoch):
    # 每个 epoch 重新评估 pass@8
    for p in prompt_pool:
        p['pass_at_8'] = compute_pass_at_k(model, p, p['verifier'], k=8)
    
    # 课程化:简单 prompt 逐渐减少
    if epoch < 10:
        weights = [1.0 if p['pass_at_8'] < 0.3 else 0.3 for p in prompt_pool]
    elif epoch < 30:
        weights = [1.0 if 0.2 < p['pass_at_8'] < 0.5 else 0.5 for p in prompt_pool]
    else:
        weights = [1.0 if p['pass_at_8'] < 0.3 else 0.2 for p in prompt_pool]
    
    return sample_with_weights(prompt_pool, weights)

15.6.3.1 前沿:方差驱动的动态 rollout 分配 (VIGOR)

GRPO 的标准做法是每个 prompt 固定 N=16 个 rollout,但这忽略了 prompt 间的能力差异——对 easy prompt 浪费预算,对 hard prompt 可能不够。VIGOR(Jiang et al., arXiv:2607.22002)提出了一个高效替代方案:

  1. 从少量开始:每个 prompt 初始 N=4 个 rollout
  2. 方差引导分配:将额外 rollout 预算分配给 reward 方差最大的 prompt——方差高意味着模型对该 prompt 尚不稳定,需要更多探索
  3. 理论保证:reward 方差控制梯度幅度,高方差 prompt 的梯度对策略更新贡献更大

实证结果:数学任务达到同样准确率用 2.3× 更少 rollout,代码任务 full pass rate 用 1.49× 更少 rollout,平均 test pass rate +3.4pp。

工程启示:固定 N=16 不是唯一正解。如果你的训练集群有 rollout 并行度瓶颈,VIGOR 的方差驱动策略比单纯”加大 N”更聪明。

15.6.3.2 前沿:信用分配的结构级偏斜 (Cue-GRPO)

VIGOR 解决的是采样多少(预算分配),但采样完之后还有第二个问题:采到的样本各占多少权重。

RLVR 的常规做法是把每个正确 completion 当作等价的独立学习信号。Cue-GRPO(Zhe Cao、Miaowen Wen、Fangjiong Chen,arXiv:2608.03467)指出这在 GRPO 中会产生 结构级偏斜(structure-level skew):反复出现的正确解法形式会按被采样到的频次成比例地累积正 advantage,而稀有的解法形式只分到有限的 credit。论文把这一现象形式化为 multiplicity-induced structure-level credit concentration(由重复多样性诱导的结构级信用集中)。

后果是反直觉的:模型最容易想到的那种解法会被反复强化,而”少数派正确解法”——恰恰是泛化能力可能最强的部分——反而得不到训练信号。在 repeated-sampling 场景(如 AIME 多次采样取最优)下,这直接限制了采样预算增加能带来的收益。

做法:按簇(cluster)稀有度重新分配正 advantage。Cue-GRPO 的工程设计值得单独一提——它用确定性的 Strategy Cues 在 rollout 内部构建 verified-correct 轨迹的分区,不需要任何辅助模型推理,因此不增加推理开销。论文在 Qwen2.5-Math-7B 与 Llama-3.1-8B-Instruct 上验证了 AIME repeated-sampling 的提升,且采样预算越高增益越大。

三层分工(与既有方法的关系):

环节问题代表方法
采样预算每个 prompt 采多少 rolloutVIGOR(15.6.3.1)
零信号挽救全错 prompt 怎么学到东西OC-GRPO / SCOPE-RL(15.7.4)
信用分配学到的正确解各占多少权重Cue-GRPO(本节)

⚠️ 口径提醒:部分转述把 Cue-GRPO 描述为”token 级稀有度信用再分配”。论文的原文表述是 structure-level / cluster 级——衡量的是解法形式(strategy cluster)的稀有度,不是单个 token。这个区别很重要:token 级方案需要处理序列位置的信用归属,而 Cue-GRPO 的方案只需对轨迹做分区,实现成本低得多。

15.6.4 GRPO 的隐藏杀手:策略熵坍缩 (Entropy Collapse)

RLVR 训练中最常被忽视但致命的问题,不是 reward hacking,而是更根本的策略熵坍缩。

现象:GRPO 训练几个 epoch 后,组内 rollout 的 advantage 信号逐渐消失——所有采样都趋向同一策略输出,训练停滞。这正是策略熵(policy entropy)逐渐下降的结果。

ACL 2026 Outstanding Paper STEER(Stabilizing Token-level Entropy-changE via Reweighting,浙江大学+腾讯 CodeBuddy, arXiv:2510.10150)从 token-level 熵变角度首次系统性解释了这一机制:

四类 token 更新决定熵变方向:

  • 增枝型:低概率 token 被推高 → 熵增 → 探索空间扩大
  • 剪枝型:高概率 token 被压低 → 熵减 → 策略收敛
  • 巩固型:高概率 token 被推更高 → 熵减 → 确定性增强
  • 修正型:中概率 token 被调整 → 熵变不定

GRPO 的优势函数设计天然倾向”剪枝”——成功 rollout 让模型更确定地沿同一条路走,最终导致探索空间过早收缩。

STEER 的解决方案:在 token 级别施加”限速器”——估计每个 token 的熵变贡献,对过度”剪枝”的 token 降权训练。效果:

  • 数学任务:+4.4 分(AIME/GSM8K 等)
  • 代码任务:+2.5 分(HumanEval/MBPP 等)
  • 跨模型族(Llama/Qwen/DeepSeek)和 RLVR 算法(GRPO/DAPO)一致有效

工程建议:从 epoch 5 开始监控策略熵。如果 entropy 下降超过 50%,降低 learning rate 50% 并增大 KL 系数 2 倍。STEER 的开源实现可作为训练稳定的标准插件。


15.7 长链思维 CoT

15.7.1 R1-Zero 的涌现

DeepSeek R1-Zero 做了一个激进实验:跳过 SFT,直接在 base model 上做 RLVR。结果模型自己涌现出了长链思维:

  • 输出长度从初始的 500 tokens 增长到 12000 tokens
  • 模型自发学会”反思”、“验证”、“回溯”等高级推理策略
  • 在 MATH、AIME 上达到 SOTA

15.7.2 不给参考过程

R1-Zero 的关键设计:只给 reward,不给参考思维过程。

如果给参考 CoT,模型会学会”模仿参考”,永远困在参考的水平。不给参考,模型必须自己”发现”推理路径,可以超越参考。

# 传统 SFT(限制天花板)
prompt: "求 x^2-5x+6=0"
response: "用求根公式...x=2 or x=3"  # 模仿参考

# R1-Zero(突破天花板)
prompt: "求 x^2-5x+6=0"
response: "让我思考...因式分解:(x-2)(x-3)=0...验证:代入 2,4-10+6=0 ✓...所以 x=2 or x=3"
# 模型自己发明的推理路径

15.7.3 超长输出处理

长链 CoT 的输出长度可达 8K-32K,对工程是巨大挑战:

# 工业级长输出处理
def generate_long_cot(model, prompt, max_tokens=32768):
    # 1. 分段生成(避免 OOM)
    response = ""
    while not is_finished(response):
        chunk = model.generate(
            prompt + response,
            max_tokens=4096,
            temperature=0.7
        )
        response += chunk
        if len(response) > max_tokens:
            break
    
    # 2. 检查 finishing signal
    if "<|end_of_reasoning|>" not in response:
        response += "\n最终答案:..."
    
    return response

显存优化:

  • 用 vLLM 做 rollout,支持 PagedAttention
  • KV cache 量化(INT8)
  • 长 prompt 用 YaRN 等长度外推技术

15.7.4 超越稀疏奖励:过程级信号的前沿探索

R1-Zero 范式强调”只给 reward,不给参考”,但 2026 年的研究证明:在保持可验证性的前提下,增加过程级信号密度可以显著提升效果。这不是推翻 R1-Zero,而是扩展其边界。

SCOPE-RL:将稀疏奖励稠密化(arXiv:2607.11506, Xiaojian Liu 等, 2026-07-13)

GRPO 的奖励只在最终答案正确时给 1,否则 0。对困难问题经常”零学习信号”——所有 rollout 都错,模型不知从何改起。SCOPE-RL 两阶段稠密化:

  1. Adaptive Scaffolded RL:将问题分解为子问题链,每个子问题给可验证奖励
  2. Quality-Aware Process RL:对正确轨迹用过程质量奖励进一步细化

效果:DAPO-Math 和 Big-Math 上准确率最高提升 11.2pp,推理 token 减少 27.1%。

TRM:思考奖励模型(ICML 2026 Oral)

TRM(Thought Reward Model)评估推理链的质量,不仅是答案对错。基于 ME² principle 标注 103K 偏好对训练。关键设计是 gated reward shaping——只有答案正确时才让 TRM 参与 reward 计算,错误轨迹的 reward 始终为 0。这确保了可验证性本质不被破坏。

OC-GRPO:用特权信息激活”零正确率”问题(arXiv:2607.19313, 2026-07-21)

当模型在困难问题上所有 rollout 都得 0 分(pass@8=0),典型做法是放弃这些 prompt。OC-GRPO 用”特权指导”(如解答前缀)在训练时帮助模型到达正确解,但用重要性修正使更新目标指向”无指导”的原始 prompt。平均提升 3.9%(相对提升 13.8%),几乎无额外成本。

RSTG:向教师借信号,但只在失败处借(arXiv:2608.00782, 2026-08-01)

SCOPE-RL 与 OC-GRPO 都是”从任务侧造信号”(拆子问题 / 加特权信息)。还有第三条路:从教师侧借信号。

GRPO 有一个比”奖励稀疏”更硬的边界:当组内所有响应拿到相同奖励时(全对或全错),梯度完全消失。on-policy distillation(OPD)能提供稠密的 token 级监督,看起来是天然解药,但论文发现朴素地 GRPO + OPD 反而损害性能,原因有三:

  1. 并非所有样本都能从蒸馏中受益
  2. 过快拟合教师会削弱 RL 本身的探索能力
  3. OPD 的优势是不对称的——它抑制了大部分 token

RSTG(Recovering Learning Signals via Adaptive Teacher Guidance,Zhuowen Han 等 12 人)的对策是选择性地、精确地在需要的地方施加蒸馏(distill where you fail)。论文标题中的 “Negative RL-Groups” 点明了主战场:全负组(所有 rollout 都失败)本是完全无信号的死区,恰恰是教师引导价值最高的地方。

工程判据:如果你已经在做 RLVR 且手上有更强的教师模型,RSTG 给出的不是”把 OPD 全量打开”,而是”只在负组上打开,并控制拟合速度”。这与 15.5.4 的 Cross-Verifier 思路同源——外部信号要作为补充而非替代。

StructReward:不训练 verifier 的过程奖励(arXiv:2608.08326, 2026-08-08)

PRM(过程奖励模型)能提供更细粒度的反馈,但工业落地的成本一直很高——通常要单独训练一个 verifier、准备昂贵的 CoT 过程标注,或在训练循环里挂一个 LLM 做在线判定。

StructReward(Yifan Li、Ruxin Sun、Tongzhou Zhao)的做法是把生成的 solution 表示为一个推理步骤序列,然后用轻量的数值、符号与词汇匹配规则把它与带过程标注的参考步骤对齐,从而产出稠密的过程级奖励。三样昂贵的东西——独立 verifier、CoT 标注、LLM 在线判定——一个都不需要,论文的定位正是 compute-efficient。

⚠️ 引用边界:StructReward 的实证场景是多模态推理(multimodal reasoning)与自我纠错(self-correcting)。部分转述将其泛化为”长链 CoT 的中间步骤评分”,方向没错但场景被放大了——纯文本长链 CoT 上是否同样成立,论文未给出结论。如需在纯文本场景采用,建议先在小规模上验证步骤对齐规则的覆盖率。

综合结论:2026 的趋势是在保持可验证性的前提下,增加过程级信号密度。这为”pass@8=0 的困难问题不可训练”提供了新解法。三条路线各有适用场景:任务侧造信号(SCOPE-RL / OC-GRPO)适合有结构化分解能力的任务;教师侧借信号(RSTG)适合已有更强教师模型;免 verifier 的规则对齐(StructReward)适合推理步骤可被程序化比对的场景。


15.8 Reward Hacking 检测

15.8.1 什么是 Reward Hacking

模型学会”骗过 verifier”而不是真正解决问题。典型表现:

  • 数学题:模型输出”答案是 42”(碰巧命中 verifier 的字符串匹配)
  • 代码题:模型写 assert True 直接通过测试
  • 指令题:模型输出格式正确但内容无关

15.8.2 检测方法 1:reward 突增告警

class RewardMonitor:
    def __init__(self, window=100):
        self.history = []
        self.window = window
    
    def check(self, reward):
        self.history.append(reward)
        if len(self.history) < self.window:
            return False
        
        recent = self.history[-self.window:]
        baseline = self.history[-2*self.window:-self.window] if len(self.history) >= 2*self.window else self.history[:self.window]
        
        recent_mean = np.mean(recent)
        baseline_mean = np.mean(baseline)
        
        # reward 突然上涨 20% 以上,告警
        if recent_mean > baseline_mean * 1.2:
            return True
        return False

15.8.3 检测方法 2:rollout 模式聚类

def detect_hacking_by_clustering(rollouts):
    # 用 embedding 聚类 rollout
    embeddings = encode(rollouts)
    labels = cluster(embeddings, n_clusters=10)
    
    # 如果某个簇占比 > 50%,说明模型在"重复同一答案"
    for label in set(labels):
        ratio = sum(labels == label) / len(labels)
        if ratio > 0.5:
            print(f"Warning: cluster {label} 占比 {ratio:.0%}, 可能 reward hacking")

15.8.4 检测方法 3:Cross-Verifier

def cross_verify_hacking(response, primary_verifier, secondary_verifier):
    v1 = primary_verifier(response)
    v2 = secondary_verifier(response)
    
    if v1 == 1 and v2 == 0:
        # 主 verifier 通过但副 verifier 不通过,强烈怀疑 hacking
        return True
    return False

15.8.5 检测方法 4:人审 sample

每个 epoch 抽样 100 个 reward=1 的 rollout,人审检查是否真的解决问题。如果人审通过率 < 80%,立即停止训练排查。

15.8.6 RLVR 的安全反转风险:HarmRLVR 的警示

前面讨论的 reward hacking 聚焦于性能层面——模型用”取巧”方式骗 verifier 而不是真正解决任务。但 2026 年 ACL Long Paper HarmRLVR(arXiv:2510.15499, Yuexiao Liu 等)揭示了一个更严重的问题:RLVR 可以轻易逆转安全对齐。

核心发现:仅用 64 条有害 prompt(无需响应) + GRPO,即可逆转 Llama/Qwen/DeepSeek 等 5 个模型的安全对齐。攻击成功率 96.01%,有害性平均分 4.94/5,且通用能力完全保持——被攻击的模型在 MATH/MMLU 等基准上不掉分。

三个关键事实更令人担忧:

  1. 安全对齐是单向的:一旦被 HarmRLVR 攻破,再用 SafeRLVR 训练其他安全数据无法修复——有害能力已被固化为策略的一部分。

  2. 混合安全数据不仅无效,反而增强有害能力:在 64 条有害 prompt 中混入安全数据,模型的攻击能力反而更强。GRPO 的裁剪机制使模型学会精确区分何时输出有害内容、何时输出安全内容。

  3. 现有防御基本失效:SafeLoRA 等参数级约束在 GRPO 的探索机制面前形同虚设——RLVR 训练的多样性探索会自动绕过静态约束。

对工业实践的影响:开放式 RLVR 训练能力即等于”一键去安全”能力。任何提供 RLVR 微调的 API/平台必须内置:

  • 奖励层面的安全约束(不仅是 verifier,还需 safety classifier)
  • 训练过程中实时有害性评分监控(不仅是最终 reward)
  • prompt 池的安全审计(防止注入有害种子)

§15.1.3 附记:RLVR 的奖励用 0/1 确实”干净到极致”,但干净 ≠ 安全。66 条有害 prompt 就能让干净变危险——这也许是 RLVR 这把利刃最隐蔽的一面。


15.9 RLVR 数据构建工业 SOP

1. 需求定义:要补哪类可验证能力(数学/代码/指令)
2. Prompt 池构建:
   - 开源:GSM8K/MATH/HumanEval/IFEval
   - 合成:模板生成 + Magpie 过滤可验证
3. Verifier 设计:
   - 数学:sympy 等价检查
   - 代码:Docker 沙箱单测
   - 指令:规则检查
4. 难度评估:每个 prompt 算 pass@8
5. 难度分桶:0.2-0.5 占 40%(甜点)
6. 多样性筛选:4-gram ≥ 0.6
7. GRPO 训练:N=16, lr=1e-6, β=0.005
8. 课程化重采:每 epoch 重评 pass@8
9. Reward Hacking 检测:reward 监控 + 聚类 + Cross-Verifier
10. 评估:MATH/GSM8K/HumanEval/IFEval

第 16 章将深入质量评估与清洗——后训练数据的”质检车间”。