概述
RLVR(Reinforcement Learning with Verifiable Rewards) 是一种利用可验证奖励信号来训练大型语言模型(LLM)推理能力的方法。与传统的依赖人类反馈的强化学习(RLHF)不同,RLVR 在具有确定性强验证标准的任务(如数学推理、代码生成)中特别有效。1
RLVR 近期在大语言模型推理能力提升方面取得了显著成功,被广泛应用于数学求解、编程任务等领域。代表方法包括 GRPO、DAPO 等变体。然而,2025 年 NeurIPS Best Paper Runner-Up 研究表明,RLVR 可能并未真正提升模型的推理容量上限,而仅仅是提高了采样效率。2
1. RLVR 基础
1.1 什么是可验证奖励
可验证奖励(Verifiable Rewards)是 RLVR 的核心概念,其定义为:
能够客观判定模型输出正确性的奖励信号,通常是二元值(正确/错误)或数值评分。
可验证奖励的特征:
| 特征 | 说明 |
|---|---|
| 确定性 | 奖励函数 对相同输入总是返回相同结果 |
| 可计算性 | 奖励可由程序自动计算,无需人工标注 |
| 稀疏性 | 通常仅在序列末端(terminal)给出奖励 |
典型应用场景:
- 数学推理:答案正确性可精确验证(如 GSM8K、MATH 数据集)
- 代码生成:通过执行代码并对比输出验证正确性
- 形式化证明:证明验证器可自动检查证明有效性
1.2 奖励类型
RLVR 中的奖励可分为两类:
终态奖励(Terminal Reward)
仅在完整响应生成后给出奖励:
其中 为输入问题, 为模型生成的答案。
过程奖励(Process Reward)
对推理过程中的每个中间步骤给予奖励:
这种奖励方式能提供更细粒度的学习信号,但需要可靠的步骤验证器。
1.3 RLVR 的优势
┌─────────────────────────────────────────────────────────────────┐
│ RLVR 优势 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 数据效率高 │ │ 无奖励 hack │ │ 可扩展性强 │ │
│ │ 单样本即可 │ │ 客观验证 │ │ 自动化训练 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 激励推理 │ │ 多样性保持 │ │ 训练稳定 │ │
│ │ 探索解题路径│ │ 减少模式崩塌│ │ 梯度可控 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
核心优势详解:
- 样本效率:One-Shot RLVR 研究表明,仅使用一个训练样本即可有效提升推理能力3
- 无偏奖励信号:可验证奖励避免了人类主观偏好带来的偏差
- 可扩展自动化:无需人工标注,可大规模生成训练数据
2. One-Shot RLVR 机制分析
2.1 核心思想
One-Shot RLVR 证明:使用单一精心挑选的训练样本,即可有效激励模型的数学推理能力。3
直觉解释:
- 单一正确样本提供了解题路径的”锚点”
- 模型通过对比自己生成的多个响应,学习区分正确与错误的推理路径
- 即使只有一个正例,采样多样性也能产生有效的学习信号
2.2 采样策略
One-Shot RLVR 的关键在于选择高质量的单一训练样本。论文提出使用响应方差作为评估标准:
def select_best_sample(prompt, model, n_candidates=32):
"""
选择最具多样性的训练样本
策略:选择生成响应与参考响应差异最大的样本
这类样本往往包含更丰富的推理信息
"""
responses = [model.generate(prompt) for _ in range(n_candidates)]
# 计算响应间的互信息或熵
diversity_scores = []
for i, resp in enumerate(responses):
# 与其他响应的平均编辑距离
avg_dist = sum(edit_distance(resp, r) for j, r in enumerate(responses) if j != i) / (n_candidates - 1)
diversity_scores.append(avg_dist)
# 选择多样性最高的样本
best_idx = np.argmax(diversity_scores)
return responses[best_idx]2.3 为什么 One-Shot RLVR 有效
理论分析:
设 为待训练的策略模型, 为参考(基座)模型。对于单一训练样本 ,RLVR 的目标是:
当 是确定性终态奖励时:
这意味着策略需要最大化生成正确答案的概率,同时保持与基座模型的相似性。
关键洞察:
| 现象 | 解释 |
|---|---|
| 采样多样性 | 即使单一正例,通过多次采样可探索不同推理路径 |
| 奖励对比 | 正确响应获得 ,错误响应 ,形成对比学习效果 |
| KL 约束 | 防止模型过拟合到单一模式,保持泛化能力 |
3. RLVR vs GRPO/DAPO/PPO 对比
3.1 算法概述
当前主流的 LLM 推理训练算法可分为三类:
PPO(Proximal Policy Optimization)
原始的策略优化算法,需要额外训练价值网络(Value Network):
其中 是概率比, 是优势函数估计。
GRPO(Group Relative Policy Optimization)
DeepSeek 提出的 PPO 简化版本,无需价值网络:
其中 ,使用组内归一化的奖励作为优势估计。
DAPO(Decoupled Clip and Dynamic sAmpling Policy Optimization)
基于 GRPO 的改进,提出四个关键技术4:
- Clip-Higher:提高剪裁上限,允许更大的策略更新
- Dynamic Sampling:过滤掉始终正确或始终错误的样本
- Token-Level Policy Gradient Loss:在 token 级别计算损失,而非序列级别
- Overlong Reward Shaping:对过长响应进行惩罚
3.2 算法对比表
| 维度 | PPO | GRPO | DAPO |
|---|---|---|---|
| 价值网络 | 需要 | 不需要 | 不需要 |
| 计算复杂度 | 高 | 中 | 中 |
| 奖励归一化 | 需外部处理 | 组内归一化 | 组内归一化 |
| Token 级损失 | 序列级 | 序列级 | ✅ 支持 |
| 过拟合控制 | KL 惩罚 | KL 惩罚 | Clip-Higher |
| 代表性工作 | GPT-4, Claude | DeepSeek-Math | ByteDance |
3.3 关键差异分析
PPO vs GRPO vs DAPO 流程对比
═══════════════════════════════════════════════════════════════════════
PPO:
┌────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐
│ Sampling│ → │ Value Update│ → │ Advantage │ → │ Policy │
│ G responses│ │ Network │ │ Estimation │ │ Update │
└────────┘ └─────────────┘ └─────────────┘ └─────────┘
↑ │
└──────────────────────────────────────┘
GRPO:
┌────────┐ ┌─────────────────────────┐ ┌─────────┐
│ Sampling│ → │ Relative Reward Normalize│ → │ Policy │
│ G responses│ │ (μ=0, σ=1 per group) │ │ Update │
└────────┘ └─────────────────────────┘ └─────────┘
↑ │
└─────────────────────────────┘
DAPO:
┌────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────┐
│ Sampling│ → │Dynamic Filter│ → │Token-Level │ → │Policy │
│ G responses│ │(remove trivial)│ │Loss + Clip-Hi│ │Update │
└────────┘ └──────────────┘ └──────────────┘ └─────────┘
3.4 DAPO 四项关键技术详解
1. Clip-Higher
原始 PPO/GRPO 使用对称剪裁 ,DAPO 发现对于 LLM 推理场景,应使用非对称剪裁:
这允许策略更多地增加高奖励轨迹的概率。
2. Dynamic Sampling
在训练过程中,动态过滤掉无效样本:
3. Token-Level Policy Gradient Loss
将序列级损失分解为 token 级:
仅在成功轨迹中对 token 级概率进行优化。
4. Overlong Reward Shaping
对超过长度阈值 的响应施加额外惩罚:
4. RLVR 的局限性:pass@k vs 推理容量
4.1 核心发现
2025 年 NeurIPS Best Paper Runner-Up 研究系统地揭示了 RLVR 的根本性局限。2
核心结论:
RLVR 并未真正提升 LLM 的推理容量(Reasoning Capacity),而仅仅是提高了采样效率。
4.2 Pass@K 指标分析
Pass@K 定义:从 个采样中至少有一个正确的概率。
其中 是第 次采样正确的概率。
关键观察:
| 指标 | RLVR 模型 | 基座模型 |
|---|---|---|
| Pass@1 | 更高 | 较低 |
| Pass@10/100 | 较低 | 更高 |
| 推理覆盖范围 | 较窄 | 较广 |
Pass@K 曲线对比
═══════════════════════════════════════════════════════════════════
Pass@K
↑
1.0├ ━━ 基座模型
│ ╱
│ ╱
0.8│ ╱
│ ╱
│ ╱
0.6│ ╱
│ ╱
│ ╱
0.4│ ╱━━━━━━ RLVR模型
│ ╱
│ ╱
0.2│ ╱
│ ╱
│ ╱
│╱
└──────────────────────────────────────────→ K
1 2 5 10 20 50 100
4.3 推理容量(Reasoning Capacity)
定义:模型在大量采样下()能够解决问题的最大比例。
研究发现:
- RLVR 缩小了推理覆盖范围:RLVR 训练后,模型在更多问题上的一致性降低
- 基座模型在极限采样下更强:当允许大量采样时,基座模型能解决更多问题
- RL 降低熵:训练过程使模型分布更加”尖锐”,减少了探索空间
4.4 为什么 RLVR 不能提升推理容量
理论解释:
设 为基座模型策略, 为 RLVR 训练后的策略。
RLVR 优化目标可写为:
这等价于在基座模型的邻域内寻找最优策略。关键洞察:
任何新发现的解题路径都必须通过 KL 约束,这意味着 RLVR 不能发现基座模型能力范围之外的新解法。
4.5 采样效率 vs 推理容量
| 维度 | RLVR | 大量采样基座模型 |
|---|---|---|
| 目标 | 提高 Pass@1 | 提高 Pass@K |
| 适用场景 | 推理成本受限 | 允许多次尝试 |
| 推理容量 | 可能下降 | 保持最大 |
| 最优选择 | 实际应用 | 理论研究 |
5. 数学公式推导:RLVR 目标函数
5.1 马尔可夫决策过程(MDP) formulation
LLM 推理可建模为有限时域马尔可夫决策过程:
其中:
- :状态空间(包含输入 prompt 和已生成的 tokens)
- :动作空间(词汇表)
- :转移概率函数(确定性:给定状态和动作,下一状态确定)
- :奖励函数
- :折扣因子(通常 用于终态任务)
- :最大步数
5.2 终态奖励设置
对于纯推理任务,奖励仅在终端状态给出:
其中 是完整生成的响应, 是终态奖励函数(如答案匹配检测器)。
5.3 PPO 目标函数
原始 PPO 的 clipped 目标函数:
优势函数 由价值网络 估计:
其中 是时序差分(TD)误差。
5.4 GRPO 目标函数推导
GRPO 通过简化消除了价值网络的需求。对于同一输入 采样 个响应 :
-
组内奖励归一化:
-
KL 正则化的对比损失形式:论文证明 GRPO 可以写成 KL 正则ized 的对比损失5:
其中 是正样本(), 是负样本(), 是序列的对数概率和。
5.5 RLVR 的信息论解释
从信息论角度,RLVR 的目标是最大化奖励相关的互信息:
其中:
- 是奖励分布的熵(固定,由数据集决定)
- 是在给定策略 下奖励的剩余熵
直观理解:RLVR 降低了对给定策略的奖励不确定性,即让策略更”确定”地产生高奖励响应。但这同时也可能减少了分布的熵,限制了模型探索不同解题路径的能力。
6. 实践指南:何时使用 RLVR
6.1 适用场景
RLVR 效果好的场景:
| 场景 | 原因 | 示例 |
|---|---|---|
| 强验证标准 | 可精确判定答案正确性 | 数学题、代码执行 |
| 任务边界清晰 | 输出格式可解析 | LeetCode、GSM8K |
| 计算资源有限 | Pass@1 提升显著 | 实时推理服务 |
| 已有基座模型 | 推理能力足够,只需微调 | Qwen Math、DeepSeek |
6.2 不适用场景
RLVR 效果差或不适用的场景:
| 场景 | 原因 | 替代方案 |
|---|---|---|
| 开放式生成 | 无明确验证标准 | RLHF、DPO |
| 需要创新解法 | RL 难以发现新路径 | SFT + CoT prompting |
| 长程规划 | 稀疏奖励难以学习 | Process Reward、HER |
| 安全关键任务 | reward hacking 风险 | Human-in-the-loop |
6.3 训练配置建议
# RLVR 训练配置示例
config = {
# 算法选择
"algorithm": "GRPO", # 推荐:GRPO 或 DAPO
# 采样参数
"num_generations": 16, # 每批采样数(影响组内归一化)
"max_tokens": 2048, # 最大生成长度
"temperature": 1.0, # 采样温度
# 优化参数
"learning_rate": 1e-6, # 学习率(通常较小)
"beta": 0.01, # KL 惩罚系数
"epsilon": 0.2, # PPO 剪裁参数
# 奖励设置
"reward_type": "terminal", # terminal 或 process
"reward_norm": "group", # 组内归一化
# DAPO 特有
"clip_high": 0.4, # Clip-Higher 参数
"dynamic_sampling": True, # 动态采样
"token_level_loss": True, # Token 级损失
"length_penalty": 0.001, # 长度惩罚系数
}6.4 算法选择流程
开始
│
▼
问题是否有明确的验证标准?
│
├─ 否 → 不适合 RLVR,考虑 RLHF/DPO
│
└─ 是 → 是否需要 Token 级信用分配?
│
├─ 否 → GRPO(简单高效)
│
└─ 是 → 考虑 DAPO 或 Process Reward
│
▼
是否对响应长度敏感?
│
├─ 是 → DAPO(带 Overlong Shaping)
│
└─ 否 → 基础 GRPO + 长度过滤
7. PyTorch 代码示例
7.1 GRPO 训练循环
import torch
import torch.nn.functional as F
from torch.distributions.categorical import Categorical
def grpo_loss(
log_probs: torch.Tensor, # Shape: (batch_size, num_generations, seq_len)
rewards: torch.Tensor, # Shape: (batch_size, num_generations)
ref_log_probs: torch.Tensor, # Shape: (batch_size, num_generations, seq_len)
beta: float = 0.01,
epsilon: float = 0.2,
) -> torch.Tensor:
"""
GRPO Loss 计算
Args:
log_probs: 当前策略的 token 级对数概率
rewards: 每条序列的终态奖励
ref_log_probs: 参考策略的对数概率
beta: KL 惩罚系数
epsilon: PPO 剪裁参数
Returns:
GRPO 损失
"""
batch_size, num_generations, seq_len = log_probs.shape
# 组内奖励归一化(计算优势)
rewards_mean = rewards.mean(dim=1, keepdim=True)
rewards_std = rewards.std(dim=1, keepdim=True) + 1e-8
advantages = (rewards - rewards_mean) / rewards_std # (B, G)
# 序列级对数概率
seq_log_probs = log_probs.sum(dim=-1) # (B, G)
seq_ref_log_probs = ref_log_probs.sum(dim=-1) # (B, G)
# 概率比率 r(θ)
ratio = torch.exp(seq_log_probs - seq_ref_log_probs) # (B, G)
# Clipped 目标
clipped_ratio = torch.clamp(ratio, 1 - epsilon, 1 + epsilon)
# PPO-style 损失
policy_loss = -torch.min(
ratio * advantages.unsqueeze(-1),
clipped_ratio * advantages.unsqueeze(-1)
).mean()
# KL 惩罚
kl_penalty = F.kl_div(
seq_log_probs,
seq_ref_log_probs,
reduction='batchmean',
log_target=True
)
return policy_loss + beta * kl_penalty
def training_step(
model,
ref_model,
prompts: list[str],
tokenizer,
reward_fn,
optimizer,
num_generations: int = 16,
**config
):
"""
单步 GRPO 训练
"""
device = next(model.parameters()).device
# 1. 对每个 prompt 采样多个响应
all_responses = []
all_log_probs = []
for prompt in prompts:
input_ids = tokenizer(prompt, return_tensors='pt')['input_ids'].to(device)
# 多次采样
batch_responses = []
batch_log_probs = []
for _ in range(num_generations):
with torch.no_grad():
outputs = model.generate(
input_ids,
max_new_tokens=config.get('max_tokens', 512),
do_sample=True,
temperature=config.get('temperature', 1.0),
)
response_ids = outputs[0, input_ids.shape[1]:]
batch_responses.append(response_ids)
# 计算 log_prob(需要用训练模式重新计算)
outputs_train = model(outputs)
log_probs = F.log_softmax(outputs_train.logits, dim=-1)
# token 级 log prob
token_log_probs = log_probs[0, :-1].gather(1, outputs[0, 1:].unsqueeze(-1)).squeeze(-1)
batch_log_probs.append(token_log_probs)
all_responses.append(torch.stack(batch_responses))
all_log_probs.append(torch.stack(batch_log_probs))
# 2. 计算奖励
responses_text = [tokenizer.decode(r) for r in torch.cat(all_responses, dim=0)]
prompts_repeated = [p for p in prompts for _ in range(num_generations)]
rewards = torch.tensor([
reward_fn(p, r) for p, r in zip(prompts_repeated, responses_text)
], device=device).view(len(prompts), num_generations)
# 3. 参考模型 log prob
with torch.no_grad():
ref_log_probs_all = []
for resp_ids in torch.cat(all_responses, dim=0).split(1, 0):
ref_outputs = ref_model(resp_ids.squeeze(0).unsqueeze(0))
ref_log_probs = F.log_softmax(ref_outputs.logits, dim=-1)
ref_token_log_probs = ref_log_probs[0, :-1].gather(
1, resp_ids.squeeze(0)[1:].unsqueeze(-1)
).squeeze(-1)
ref_log_probs_all.append(ref_token_log_probs)
ref_log_probs = torch.stack(ref_log_probs_all).view(len(prompts), num_generations, -1)
# 4. 计算损失并更新
log_probs = torch.stack(all_log_probs).to(device)
loss = grpo_loss(
log_probs=log_probs,
rewards=rewards,
ref_log_probs=ref_log_probs,
beta=config.get('beta', 0.01),
epsilon=config.get('epsilon', 0.2),
)
optimizer.zero_grad()
loss.backward()
optimizer.step()
return loss.item(), rewards.mean().item()7.2 DAPO 扩展
def dapo_extensions(log_probs, rewards, seq_lens, config):
"""
DAPO 特有扩展
"""
# 1. Dynamic Sampling - 过滤无效样本
valid_mask = (rewards > 0) & (rewards < 1) # 去除全对/全错的样本组
# 2. Token-Level Policy Gradient Loss
# 仅在成功轨迹中计算 token 级损失
success_mask = (rewards == 1).unsqueeze(-1) # (B, G, 1)
masked_log_probs = log_probs * success_mask.float()
token_loss = -masked_log_probs.mean()
# 3. Overlong Reward Shaping
max_len = config.get('max_len', 2048)
length_penalty = config.get('length_penalty', 0.001)
overlong_mask = (seq_lens > max_len).float()
reward_shaping = -length_penalty * overlong_mask * (seq_lens - max_len).float()
# 4. Clip-Higher 调整
clip_high = config.get('clip_high', 0.4)
# 在计算 policy loss 时使用非对称 clip
return token_loss, reward_shaping8. 相关主题
RLVR 与以下主题密切相关:
- LLM 大语言模型 — RLVR 的应用对象
- 策略梯度方法 — RLVR 的理论基础
- GRPO 推理训练 — RLVR 的代表性实现
- 过程奖励模型 — RLVR 的细粒度扩展
- CoT 思维链提示 — 推理能力激发方法
- SFT vs RLHF — 不同训练范式的对比
9. 参考文献
本文档最后更新于 2026-05-14
Footnotes
-
RLVR 综述 — Awesome RLVR: Reinforcement Learning with Verifiable Rewards ↩
-
RLVR 的局限性 — Yue et al. “Does Reinforcement Learning Really Incentivize Reasoning Capacity in LLMs Beyond the Base Model?” NeurIPS 2025 Best Paper Runner-Up. arXiv:2504.13837 | Project Page ↩ ↩2
-
One-Shot RLVR — Wang et al. “Reinforcement Learning for Reasoning in Large Language Models with One Training Example.” CoRR 2025. arXiv:2504.20571 | GitHub ↩ ↩2
-
DAPO — “DAPO: An Open-Source LLM Reinforcement Learning System at Scale.” OpenReview 2025. arXiv:2503.14476 ↩
-
GRPO 对比损失形式 — “Reinforcement Learning with Verifiable Rewards: GRPO’s Contrastive Loss Perspective.” arXiv:2503.06639 arXiv:2503.06639 ↩