如果你正在做基于 RLVRReward Learning with Verifiable Rewards即可验证奖励强化学习的大模型后训练最近北大相关研究提出的“验证器诱导的策略支持重塑造”值得认真看一遍。这条发现没有否定 RLVR 的效果但它指出一个很少有人讨论的代价RLVR 可能会破坏模型后续继续学习的能力。不是通过灾难性遗忘那种原因而是因为验证器把策略分布“压”到了更窄的区间模型在后续接入 SFT、其他任务微调或继续 RL 时适应能力明显变弱。今天这篇文章会把这个问题拆开讲先解释 RLVR 为什么这么火再说明“策略支持重塑造”到底是什么意思然后给出实践中的判断标准、监测手段和训练建议。最后我会提供一个基于 TRL 库的最小监测流程以及一套后续任务评估脚本方便你直接在项目里验证自己的模型是否出现同类问题。1. 这篇文章真正要解决的问题先说结论性判断RLVR 不是免费午餐它对奖励信号的可计算性依赖很强而验证器本身会改变模型策略分布的形状。研究指出的“策略支持重塑造”Policy Support Repositioning正是这个形状变化的关键描述验证器通过二元或离散的奖励信号把模型对答案空间的概率支持从宽分布推向窄分布。当前任务分数上去了但是模型的“底噪”策略被压缩后续你再想让它适应新任务它往往表现得像是学不进去。这个问题的实际影响比“数学变好了但写代码变差了”更隐蔽。因为 RLVR 结束后模型在 benchmark 上可能是上升的常规评估无法暴露策略分布的坍缩。只有当你拿着这个 checkpoint 继续做下一步训练比如再 SFT 一个新领域、继续 RLHF 对齐或者做多轮课程学习时才会发现它比原始 base 模型更难收束到新任务上。哪些读者最应该关注这篇文章正在用 RLVR 或 GRPO 调优数学、代码、推理模型的算法工程师。负责从基座模型开始做“预训练—SFT—RLVR—后续对齐”完整流水线的训练团队。想避免“训练一个任务毁掉全盘可塑性”的研究人员和学生。读完这篇文章你至少能回答三个问题RLVR 改善的是什么策略支持重塑造为什么会让模型“变笨”如何在训练中尽早发现这个问题并做出干预。2. RLVR 和验证器为什么这个方案成为主流了解策略支持重塑造最好先回到 RLVR 的技术背景。2.1 从 RLHF 到 RLVR 的转变过去大模型对齐主要用 RLHF基于人类反馈的强化学习核心是训练一个奖励模型来模拟人类偏好再用 PPO 做策略优化。奖励模型本身是学习得到的存在奖励黑客、偏好标注不一致、分布偏移等常见问题。尤其到了数学推理和代码生成领域人工判断答案质量非常昂贵而且不同标注者的标准很难统一奖励模型常常给出不够稳定的反馈。RLVR 的出发点则是在那些结果可以被自动检查的任务里干脆不用训练奖励模型直接用“结果正确/错误”作为奖励信号。比如数学题最终答案跟参考答案一致就能得 1 分代码题目执行测试用例通过就能得 1 分SQL 生成、JSON 格式校验、信息抽取字段比对也都符合这个范式。奖励信号变成规则化、可验证的不依赖额外模型也没有“人类口味”的偏差这让强化学习过程更可控。2.2 验证器不只是 reward model命名上容易混淆的是“验证器”。RLVR 里的验证器不是传统 RLHF 的奖励模型它是一段确定性的判断逻辑或者是一个用绝对规则封装的评分函数。它的核心性质是可以复现同样的生成结果在任何时刻验证它都返回同样的分数。这也让训练过程中不再需要为奖励模型做额外推理能显著节省算力和复杂度。不过正因为验证器是硬的、规则化的它传递给策略的反馈信息量比奖励模型少得多。奖励模型可以输出连续偏好模型能知道“这个答案虽然没全对但部分思路正确”而 RLVR 的验证器经常只返回 0 或 1。哪怕你设计了一个部分得分函数它也是针对固定规则设计的。从强化学习的角度看这种反馈会引导策略去找到“让验证器满意”的模式而模式之外的行为则不会被奖励甚至被抑制。2.3 主流 RLVR 实现GRPO 和 PPO 风格目前最常看到的 RLVR 实现包括 PPO 变体和 DeepSeek 开源工作中带火的 GRPO。GRPO 去掉了 critic 模型对同一 prompt 采样多个候选响应用组内相对奖励去计算优势。它特别适合 RLVR 场景因为验证器能给出明确对错组内比较降低了奖励噪声。TRL 的GRPOTrainer、OpenRLHF 以及最近很多框架都已经把这类流程封装好大量团队在此基础上做数学推理和代码能力提升。于是“RLVR 数学/代码”变成了快速提升模型推理能力的一条标准路线。但接下来我们会看到正是验证器这个看似高效的设计带来了策略支持重塑造的风险。3. 核心发现验证器诱导的策略支持重塑造3.1 怎么理解“策略支持”为了说明问题先引入一个概率视角。语言模型在给定 prompt 时会为可能的 token 序列分配一个概率分布。我们把那些概率不为零实际训练中可以用阈值忽略极低概率的序列构成的集合称为策略支持。预训练和 SFT 阶段由于数据覆盖很广模型的策略支持通常比较大也就是说面对一个 prompt它“理论上能够生成”的回复类型很丰富包含一定错误但也包含正确的各种表达方式。强化学习的目标是提高某些奖励信号下的期望值。如果优化充分模型会提高高奖励行为的概率同时大幅降低低奖励行为的概率。在一个只有 0/1 验证器反馈的任务里“低奖励行为”其实就是验证器判错的那些答案。于是模型会快速把验证器不认可的表达从高概率区推向极低概率区策略支持在局部快速收缩。3.2 重塑造的直觉北大研究用“重塑造”来描述一种更深层的改变不只是概率质量在流动而是模型内部的策略分布在几何上发生了结构性变化。验证器会通过梯度压力改变模型参数使得它“记住”的候选边界收窄。简单类比是一个学生只做判断题和选择题虽然判断题满分但他逐渐失去了写论述题和组织自由回答的能力因为他长期没有练习需要开放表达的输出空间。语言模型也是一样。验证器奖励的往往是某种特定格式的最终答案比如“答案是 X”。模型为了拿到高奖励会尽量贴近这个格式同时把替代性表达即使也正确压低。于是它的生成分布会更偏确认性、更简短少了很多可探索的中间步骤。策略支持从相对多样的连续空间被重塑造为验证器支持子空间附近的一个“尖峰”。3.3 后续训练能力被破坏的链路从训练角度看后续能力的破坏链条大致是这样预训练模型具备足够的先验多样性支持后训练继续塑形。RLVR 通过验证器给予集中奖励模型优化策略支持局部概率集中。随着训练步数增加由验证器带来的尖峰变高同时周围策略空间被压低。后续再做 SFT 或 RL需要把某些原本较低概率的行为重新抬高。但因为这些行为已经进入低概率区域梯度很弱模型需要更多数据或更高学习率才能拉回来表现为“学得很慢”。极端情况下新任务所对应的策略支持完全处于被压平的区域模型再怎么训练都很难跨出旧策略的惯性。这个链路和经典灾难性遗忘有区别。经典遗忘是旧数据覆盖不足导致旧知识被新知识覆盖而策略支持重塑造更像是“某一轮强化学习把可塑性本身消耗掉了”。模型不是忘掉了具体事实而是丧失了对新分布的探索倾向。4. 机制拆解为什么验证器会造成这种破坏为了不至于停留在概念层面我们再深挖一层RLVR 的梯度结构、生成分布和验证器设计到底怎么相互作用。4.1 二元奖励导致策略方差迅速降低强化学习中策略梯度的方差和奖励空间有关。当你对一个固定 prompt 采样多个答案验证器给出的奖励只有 0 和 1 两种取值那么组内优势通常表现出强烈的二极化对了的和错的区别很大但同样是对的两个答案之间没有区分度。这使优化器把大量概率集中在更少量“正确被验证器认可”的 token 路径上。如果用生成熵来观察模型你会看到熵下降速度比连续的 reward model 反馈更快。因为连续偏好还能给“部分正确”提供梯度缓冲让模型保留更多中间表达而二元验证器没有这种缓冲只要不在验证器认可范围内就都是等价的低奖励。于是模型倾向于搜出更容易触发验证器的模式而不是探索多种同样正确的模式。4.2 验证器的设计偏差会放大坍缩即使最终答案正确验证器的规则也可能只接受一种字面格式。比如数学答案要求写成小数不要分数代码要求输出不带注释说明。这样模型就可能学到的是“服从格式”而不是“学会推理”。如果验证器由一个更弱的模型担任或者规则覆盖不完整它还可能出现伪正确答案对但推理是编的或者碰巧结果匹配。RLVR 会进一步强化这些“钻空子”的策略把真正通用的解题策略推向更低的概率空间。所以这里真正容易踩坑的地方是你观察到的 benchmark 提升并不代表模型学到了你希望的能力只代表模型学到了“通过这个验证器”的能力。验证器一旦在后续任务中变化之前学到的东西很可能大量失效。4.3 策略支持重塑造与 RLHF 的对比我们不妨和经典 RLHF奖励模型做一个对比维度RLHF奖励模型RLVR验证器奖励来源学习得到的偏好模型确定性规则 / 验证器反馈粒度连续能表达部分正确通常 0/1 或离散方差特性中等奖励噪声与模型判断相关低方差但奖励本身高度集中策略支持变化相对温和保留更多中间行为更容易快速坍缩到验证器认可子空间可塑性风险有但通常不如验证器严重高尤其只做单轮 RLVR 后不做多样化数据补偿这个对比想说明的是策略支持重塑造不是 RL 本身的固有问题而是“二元验证器 强强化步数 单调奖励”三个条件同时出现时容易显著放大。如果你在设计中加入更多奖励维度、部分得分和格式多样性约束风险会明显下降。5. 实践中如何判断模型是否被“重塑造”不用等模型训练完才发现可塑性损失。你可以在 RLVR 训练过程中和结束后做一些简单监测。5.1 记录生成熵和多样性指标训练时对验证集 prompt 定期采样计算生成序列的 token 级别熵。distinct-1、distinct-2 指标即不重复 unigram/bigram 的比例。候选答案之间的编辑距离或 n-gram 重叠度。答案中是否出现异常短的输出。如果这些指标在训练早期快速下降并且后期持续处于低值说明策略支持正在收窄。不一定代表最终可塑性一定被破坏但这是一个需要警惕的信号。5.2 做一个“可塑性探测”实验更直接的判断方法是取一个 RLVR 训练后的 checkpoint 和一个同尺寸的基础 SFT 模型在同一个新任务的小型 SFT 数据集上各训练少量步数观察两者 loss 下降速度。如果 RLVR 后的模型 loss 下降明显更慢或者需要更高学习率才能达到相近结果就有理由认为策略支持重塑造造成了后续学习阻力。这种探测实验不需要很大的数据集一个小领域、几百到一千条样本足够看出趋势。关键在于控制变量同样的数据、同样的超参数、同样的训练步数只改变初始 checkpoint。5.3 观察验证器过拟合信号如果模型在 RLVR 训练集对应的验证器上分数很高但在一个留出的、分布略有偏移的验证器上分数大幅下跌也要小心。比如训练时用的是代码单测用例留出时换成同样题目但换一些边界条件测试模型正确率如果暴跌说明它学到的是“针对验证器模式”的表层策略。这些实践比单看最终 benchmark 更能帮助判断模型是否已经牺牲了可塑性。6. 一个可运行的 RLVR 策略支持监测示例接下来进入实操。我们用一个偏教学性质的示例展示三部分内容使用trl的GRPOTrainer配置一个简单的 RLVR 训练。在训练过程中记录生成多样性指标。训练结束后用一个脚本评估“后续 SFT 可塑性”。注意本文示例重点关注结构而不是严格复现某个实验。具体版本请以实际项目为准核心思路是给你一个可以扩展的模板。6.1 RLVR 训练脚本基础版先安装依赖pip install trl transformers datasets accelerate下面是一个基于 TRL 的 GRPO 训练脚本验证器假设是一个检查最终答案是否为42的简单函数。实际项目中你应该替换成真正的测试用例或规则。# 文件路径rlvr_training.py from datasets import load_dataset from trl import GRPOTrainer, GRPOConfig from transformers import AutoModelForCausalLM, AutoTokenizer # 一个极简验证器生成内容里包含 42 即为正确 def simple_verifier(prompts, completions, **kwargs): rewards [] for completion in completions: text completion[0][text] rewards.append(1.0 if 42 in text else 0.0) return rewards config GRPOConfig( output_dir./rlvr_checkpoints, learning_rate5e-6, max_completion_length128, num_generations_for_completion4, per_device_train_batch_size4, gradient_accumulation_steps1, max_steps200, logging_steps10, save_steps50, ) model AutoModelForCausalLM.from_pretrained(Qwen/Qwen2.5-1.5B-Instruct) tokenizer AutoTokenizer.from_pretrained(Qwen/Qwen2.5-1.5B-Instruct) # 假设数据集包含两个字段prompt 和 reference dataset load_dataset(json, data_filestrain.jsonl, splittrain) trainer GRPOTrainer( modelmodel, argsconfig, train_datasetdataset, reward_funcs[simple_verifier], processing_classtokenizer, ) trainer.train()代码说明simple_verifier接受一个批次中的 prompts 和 completions返回每个回答的奖励值。实际项目中建议改为调用函数评估器而不是字符串包含判断。GRPOConfig里的num_generations_for_completion表示每个 prompt 生成几个候选回答并组内比较。max_completion_length控制了生成的答案长度太短可能限制了模型表达。训练数据需要prompt字段最好也保留reference供验证器使用。6.2 记录生成多样性的回调我们希望在训练过程中定期评估策略支持的变化。TRL 支持通过回调或自定义评估循环实现。最简单的办法是在GRPOTrainer的评估 hook 里对固定验证集执行生成并计算多样指标。下面是一个轻量回调示例# 文件路径diversity_callback.py import numpy as np from collections import Counter class DiversityCallback: def __init__(self, eval_prompts, tokenizer, max_new_tokens64, sample_times8): self.eval_prompts eval_prompts self.tokenizer tokenizer self.max_new_tokens max_new_tokens self.sample_times sample_times def compute(self, model): model.eval() all_texts [] for prompt in self.eval_prompts: inputs self.tokenizer(prompt, return_tensorspt).to(model.device) outputs model.generate( **inputs, max_new_tokensself.max_new_tokens, do_sampleTrue, top_p0.9, temperature0.8, num_return_sequencesself.sample_times, ) for out in outputs: text self.tokenizer.decode(out[inputs.input_ids.shape[1]:], skip_special_tokensTrue) all_texts.append(text) tokens [text.strip().split() for text in all_texts] all_token_flat [t for seq in tokens for t in seq] if len(all_token_flat) 0: return {sent_entropy: 0.0, distinct_1: 0.0, distinct_2: 0.0} sent_entropy self._entropy(Counter(all_token_flat)) distinct_1 len(set(all_token_flat)) / max(1, len(all_token_flat)) unique_bigrams set() for seq in tokens: for i in range(len(seq) - 1): unique_bigrams.add(seq[i] _ seq[i 1]) distinct_2 len(unique_bigrams) / max(1, sum(max(0, len(seq)-1) for seq in tokens)) return { sent_entropy: sent_entropy, distinct_1: distinct_1, distinct_2: distinct_2, } def _entropy(self, counter): total sum(counter.values()) import math return -sum((cnt / total) * math.log(cnt / total) for cnt in counter.values()) # 你可以把这个回调通过 trainer.add_callback 的方式接入 # 或者在每个 logging step 手动调用 compute 并打印指标。使用说明eval_prompts是固定的评测 prompt 列表建议从开发集抽取 20 到 50 条。sample_times表示每个 prompt 采样的候选次数建议至少 8 次计算 diversity 指标才有意义。当distinct_1和distinct_2随训练步数快速下降并稳步停在低位时就是在提示“策略支持正在变窄”。6.3 后续 SFT 可塑性评估脚本训练结束之后我们用一个小规模 SFT 数据来探测模型的后续学习能力。脚本会输出两种 loss基础模型RLVR 前和 RLVR 后模型在同样新任务上的收敛差异。# 文件路径plasticity_check.py from datasets import load_dataset from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments MODEL_PATHS { before_rlvr: Qwen/Qwen2.5-1.5B-Instruct, # 或者你保存的 SFT checkpoint after_rlvr: ./rlvr_checkpoints/checkpoint-200, # RLVR 后的模型 } # 一个用于“新任务”的小型指令数据比如让模型学习用指定格式输出摘要 dataset load_dataset(json, data_filesnew_task_train.jsonl, splittrain) dataset dataset.map(lambda x: { text: f用户指令{x[instruction]}\n模型回答{x[output]} }) def tokenize(examples, tokenizer): return tokenizer(examples[text], truncationTrue, paddingmax_length, max_length512) results {} for name, model_path in MODEL_PATHS.items(): tokenizer AutoTokenizer.from_pretrained(model_path) model AutoModelForCausalLM.from_pretrained(model_path) tokenized_dataset dataset.map(lambda e: tokenize(e, tokenizer), batchedTrue) args TrainingArguments( output_dirf./probe_{name}, per_device_train_batch_size4, max_steps100, learning_rate1e-5, logging_steps10, save_strategyno, report_tonone, ) trainer Trainer( modelmodel, argsargs, train_datasettokenized_dataset, tokenizertokenizer, ) train_result trainer.train() results[name] train_result.training_loss print(Plasticity probe results:) for k, v in results.items(): print(f{k}: {v:.4f})脚本输出示例假设值Plasticity probe results: before_rlvr: 1.4523 after_rlvr: 2.1018如果after_rlvr的 loss 明显高于before_rlvr说明 RLVR 后的模型在新任务上学习得更困难策略支持重塑造的影响是真实存在的。需要说明的是这些脚本并不完整复现北大研究它们是为了帮你把“策略支持重塑造”这个抽象概念变成一个可观测、可比较的工程指标。7. 常见问题与排查思路问题现象可能原因排查方式解决方案RLVR 训练结束后模型回答变短、模板化明显验证器对格式的依赖过强策略坍缩到短答案采样生成文本统计平均长度和 distinct n-gram在奖励中加入长度惩罚或格式多样性正则降低验证器格式敏感性后续 SFT 时 loss 一直不下降RLVR 把新任务对应的策略支持压到接近零对新任务做了小规模探测实验对比 RLVR 前后模型使用混合数据集旧 RLVR 数据 新任务数据重新训练提高新任务数据的采样权重RLVR 过程中熵下降极快组内对比过于激烈或 KL 系数过小观察 training 日志中生成熵与奖励变化曲线调大 KL 惩罚系数降低学习率或增加采样的 temperature模型在训练验证器上高分但在更难的测试集上暴跌模型过拟合验证器表面规则设计分布外验证集用新的测试用例重新评估增加验证器规则多样性不要只用一个固定验证器训练轮换测试套件重新做 RLHF 时奖励模型给分不稳定之前 RLVR 压缩了模型的策略空间生成样本多样性不足计算 RLHF 训练样本的响应多样性在 RLHF 前用大量 SFT 混合数据恢复策略多样性或直接不回滚、重新训练一个 base 模型查看这些问题时第一步永远不是改参数而是先定位现象是否来自“验证器导致的分布坍缩”。你可以把训练中保存的 checkpoint 拿出来各自做一次生成多样性和可塑性探测让数据替你判断。8. 最佳实践与工程建议既然 RLVR 有这种副作用实际工程中我们应该怎么用不能因为它有风险就不用而是要考虑如何在项目里限定它的边界。8.1 验证器设计要追求多样性而不是单一规则不要让一个验证器成为唯一的“神”。可以同时设计多个验证视角结果正确性、推理链完整性、格式多样性、文本长度可控性。哪怕你只做最终答案判断也可以在采样阶段保留多个正确答案的表达不要只取第一个。这样策略支持不会过早收敛到单一回答模式。8.2 把 RLVR 放在流程的中段而不是末端如果你的最终目标是一个开放域对话助手或一个通用 Agent不要把 RLVR 当作最后一步训练。更合理的路径是Base 模型 → 通用 SFT → RLVR 针对特定能力数学/代码→ 通用 SFT 恢复可塑性 → 完整 RLHF 对齐。中间插入的通用 SFT 可以部分恢复被压缩的策略支持让模型重新见到多样的表达空间。8.3 用 KL 系数和熵项做“护栏”RLVR 训练必须保留参考模型的 KL 约束不要把它设成 0。KL 系数越大模型越难偏离当前策略这看似限制了任务上限但同时也限制了策略坍缩。建议实践中保持一个中等 KL 系数比如参考当前模型和初始模型在验证集上的 KL 不超过 2-3 nats 这样一个经验范围。具体数值需要以你能接受的可塑性损失为准。8.4 混合训练优于纯 RLVR不要让训练数据全是“可验证的题”。即使在做 RLVR也可以按一定比例混入通用的、不需要验证器奖励的数据。这些样本的奖励设为 0或者使用普通的 SFT loss。这样模型在每个 batch 中都有机会保留通用策略支持降低坍缩速度。混合比例可以从 10% 到 30% 起步根据不同任务调整。8.5 建立可塑性回归测试像单元测试一样为模型训练流程建一个“可塑性回归测试”。这个测试不需要在每次训练后都跑完整的下游任务可以在每次 checkpoint 保存时自动运行一个小采样脚本在新任务的小数据集上训练 50-100 步比较 loss 下降曲线。如果 RLVR 持续多轮后这个指标慢慢恶化你就能及时停止而不是等模型废了才回头看。8.6 团队协作时把可塑性指标纳入实验报告团队内部做模型迭代不能只看 benchmark 和 checkpoints 数量。建议在实验记录里固定记录生成熵、distinct-n、新任务 mini-train loss、分布外验证器准确率。这样后续判断“要不要回滚、要不要重新做 SFT、怎么分配预算”都有据可依。9. 总结与后续学习方向北大研究提出的“验证器诱导的策略支持重塑造”本质上是指出了一种 RLVR 时代容易被忽略的代价模型当前任务分数高不代表模型变强了它可能只是把策略分布压窄了。压窄后的模型在后续继续学习时表现出明显的惰性这才是大模型后训练真正需要警惕的地方。从工程角度来看本文想强调一个可操作的经验如果你要在生产环境里用 RLVR需要给验证器设计、训练阶段顺序、KL 项、数据混合和可塑性探测留出明确位置。把 RLVR 当作一个强大的局部优化工具而不是训练的终点是对后续学习能力最好的保护。接下来你可以做三件事拿你的现有 RLVR checkpoint 跑一次上面 6.3 节的可塑性探测确认是否已经出现后续 SFT 的学习阻力。在下次训练中加入 diversity 回调把生成熵和 distinct-n 指标纳入常规日志。如果策略支持坍缩已经很严重尝试用 20% 通用 SFT 数据和原 RLVR 数据混合重新恢复策略空间。更深入的研究方向包括理解验证器诱导的“重塑造”到底发生在模型的哪一层参数空间是否可以通过 LoRA 或低秩更新来隔离不同任务之间的干扰以及设计更平滑的“部分可验证”奖励函数让策略支持既能向正确方向移动又不会失去探索新的候选空间的能力。这些方向比单纯调大 RLVR 训练步数更有价值也值得持续关注。
