在大语言模型的强化学习阶段,训推不一致已经不再只是传统意义上的 exposure bias,而是一个更复杂的系统—算法耦合问题。
在预训练中,训推不一致主要来自 teacher forcing:训练时模型总是看到真实前缀,而推理时模型只能看到自己生成的前缀。但在 RL post-training 中,问题进一步复杂化。现代 LLM RL 系统通常会把 rollout generation 和 policy optimization 分离:前者使用高吞吐的推理引擎,例如 vLLM、SGLang;后者使用训练框架,例如 Megatron、FSDP、DeepSpeed 或 veRL。理论上,它们应当代表同一个策略;但在实际系统中,由于数值精度、kernel 实现、并行策略、MoE 路由、采样截断和参数更新延迟等因素,rollout 阶段看到的策略和训练阶段优化的策略并不完全相同。
可以把 RL 阶段的训推不一致统一写成:
但训练时优化的是:
其中 \(\mu_t\) 是实际产生 token 的行为策略。它不一定等于当前训练策略,而是可能同时受到以下因素影响:
这里:
- \(\theta_{\mathrm{roll}}\) 是 rollout 使用的参数版本;
- \(\pi^{\mathrm{infer}}\) 是推理引擎中的概率分布;
- \(M_t\) 是 top-p / top-k sampling 形成的候选 token mask;
- \(Z_t\) 是 MoE 模型中实际激活的 routing path。
而训练阶段计算梯度时,通常使用的是:
一旦二者不一致,常见的 policy-gradient 更新就不再是严格 on-policy 的。
1. 基本 policy-gradient 视角
对于一个 prompt \(x\),模型生成完整回复:
序列级奖励为:
标准 REINFORCE 形式的目标是:
其梯度可以写为:
其中 \(A(x,y)\) 是 advantage,通常为 reward 减去 baseline。由于自回归模型满足:
因此梯度可以展开为:
这个公式隐含了一个关键前提:
也就是说,样本必须来自当前正在优化的策略。
但在 LLM RL 系统中,实际情况通常是:
而不是:
此时如果仍然直接使用:
就会得到一个有偏梯度。训推不一致的本质,就是行为策略 \(\mu\) 和训练策略 \(\pi_\theta^{\mathrm{train}}\) 之间存在偏差。
2. 第一类不一致:训练引擎和推理引擎不一致
第一类问题来自训练和推理引擎的实现差异。
在理想情况下,同一个模型参数 \(\theta\)、同一个上下文 \(s_t = (x, y_{<t})\),训练引擎和推理引擎应当给出相同的概率分布:
但实际系统中,这个等式常常不成立:
原因包括:
- BF16 / FP16 / FP8 等数值精度差异;
- attention kernel、normalization、softmax 实现差异;
- tensor parallel / expert parallel / sequence parallel 带来的归约顺序差异;
- 推理引擎和训练引擎中 MoE top-k expert selection 的数值敏感性;
- 推理阶段逐 token 自回归计算,而训练阶段通常对完整序列并行计算。
这个问题看似只是数值误差,但在 RL 中会被 importance ratio 放大。因为 policy-gradient 直接依赖 token logprob,一旦 logprob 有系统性偏差,就会改变有效优化目标。
设 rollout 来自推理引擎:
而训练时使用训练引擎计算梯度:
那么自然的重要性采样比率是:
展开为 token 乘积:
于是无偏的序列级 IS policy-gradient 可以写为:
但这个序列级比率存在严重方差问题。因为 LLM 输出序列很长,多个 token ratio 连乘后容易爆炸或塌缩:
其中:
因此一些工作会采用 token-level truncated importance sampling,也就是 TIS:
或者使用双侧截断:
然后把梯度近似写成:
这类方法的直觉是:用两个引擎之间的概率比率修正 rollout distribution 和 training distribution 的偏差,同时通过 clipping 控制方差。
但这里需要注意:token-level TIS 并不是严格无偏的完整轨迹修正。它降低了方差,但牺牲了一部分理论精确性。完整序列级 IS 更接近无偏,但方差过高;token-level IS 更稳定,但会忽略 prefix distribution mismatch。因此,TIS 更适合被理解为一种稳定性补丁,而不是完全解决训推不一致的最终答案。
3. 第二类不一致:离线策略导致的参数版本不一致
第二类问题来自 rollout policy 和 training policy 的参数版本不一致。
在理想 on-policy RL 中,数据应当由当前策略产生:
然后用同一个 \(\theta_k\) 做更新。
但在大规模 LLM RL 中,为了提高 GPU 利用率,通常会让 rollout generation 和 policy optimization 并行执行。这样会产生参数滞后:
但训练时优化的是:
其中 \(d\) 表示策略滞后的步数。此时 off-policy ratio 可以写为:
如果使用序列级 correction,则为:
这就是 PPO / GRPO 等方法中 importance ratio 的来源之一。PPO 的 clipped objective 可以写为:
GRPO 在形式上也使用类似的 ratio,只是 advantage 通常来自同一 prompt 下多个 response 的 group normalization,而不是显式 value model:
然后对每个 response 的 token 做 policy update。
问题在于,长序列 RL 中 rollout 的生成时间很长。一个 batch 中早生成的 token 可能来自旧参数,而训练引擎已经更新了多轮。这样会使数据变得 stale,导致实际优化越来越偏离 on-policy 假设。
PipelineRL 针对的正是这个问题。它的核心思想可以概括为:不要等整条长序列全部生成完再同步新权重,而是在生成过程中进行 in-flight weight update。一旦训练侧产生了更新后的参数,生成引擎就短暂停顿、接收新权重,并用新参数继续生成后续 token。
这意味着行为策略变成了一个 token 级时间变化的策略:
其中 \(\theta_{\tau(t)}\) 表示第 \(t\) 个 token 生成时实际使用的参数版本。
这样做的优势是可以降低策略滞后:
也就是让训练时的 current policy 和生成时的 behavior policy 更接近。
不过,这并不意味着 off-policy 问题完全消失。因为一条 response 可能由多个不同版本的参数共同生成。因此,更严谨的实现需要记录每个 token 的 behavior logprob,甚至记录其对应的参数版本:
训练时再使用:
进行 correction 或 clipping。
所以,PipelineRL 的本质不是简单地“同步参数”,而是在系统层面提高数据新鲜度,在硬件利用率和 on-policyness 之间取得更好的折中。
4. 第三类不一致:MoE routing path 不一致
第三类问题在 MoE 模型中尤其重要。
MoE 模型每一层不会激活所有专家,而是通过 router 选择 top-k 个专家。可以简单写为:
其中:
- \(h_{l,t}\) 是第 \(l\) 层、第 \(t\) 个 token 的 hidden state;
- \(g_l\) 是 router;
- \(z_{l,t}\) 是被选中的 expert indices。
MoE 层的输出可以写成:
其中 \(E_e\) 是第 \(e\) 个 expert,\(w_{e,t}\) 是对应的 routing weight。
问题在于,推理引擎和训练引擎即使使用相同参数,也可能因为数值误差或并行实现差异,得到不同的 routing path:
这比普通 logprob 偏差更严重。因为一旦 routing path 不一致,训练阶段更新的可能不是 rollout 阶段真正参与生成的 expert。也就是说,模型并不是在更新“产生这个 token 的那部分参数”,而是在更新另一个 active parameter subspace。
这会导致优化目标发生突变:
DeepSeek-V3.2 中的 Keep Routing 就是针对这个问题提出的。其核心做法是:
- 在 rollout 时记录每个 token、每个 MoE layer 的 routing path;
- 在训练时强制使用相同的 routing path;
- 保证训练时优化的 expert 与推理时实际参与生成的 expert 一致。
形式上,可以写为:
于是训练时优化的条件策略变成:
这样做可以显著降低 MoE RL 中由 expert routing drift 带来的不稳定性。
需要注意的是,Keep Routing 更像一种系统一致性约束,而不是普通的 RL objective 改造。它的目标不是改变 reward,也不是改变 advantage,而是保证 rollout computation path 和 training computation path 对齐。
5. 第四类相关问题:top-p / top-k 改变 action space
除了 MoE routing,sampling 本身也会造成 action space mismatch。
在 RL rollout 中,模型通常不会直接从完整 vocabulary 上采样,而是使用 top-p 或 top-k sampling。设完整词表为 \(V\),top-p / top-k 在第 \(t\) 步得到候选集合:
那么实际行为策略不是原始模型分布:
而是截断并重新归一化后的分布:
如果训练时仍然在完整 vocabulary 上计算:
那么行为策略和目标策略的 support 不一致。对于 \(v \notin M_t\) 的 token:
但训练策略可能有:
这会违反 importance sampling 的基本 support condition:
也就是说,如果某些 action 在 rollout 中根本不可能被采到,那么训练时却把它们纳入目标分布,会导致 action space 不一致。
DeepSeek-V3.2 的 Keep Sampling Mask 就是为了解决这个问题。它在 rollout 时保存 top-p / top-k 产生的 mask \(M_t\),并在训练时对当前策略应用同一个 mask:
然后训练阶段使用 masked policy:
而不是完整 vocabulary policy:
这样可以保证 rollout policy 和 training policy 在同一个 action subspace 上比较:
这本质上是对 action space 的对齐。
6. DeepSeek-V3.2 中的 Off-Policy Sequence Masking
除了 Keep Routing 和 Keep Sampling Mask,DeepSeek-V3.2 还提出了 Off-Policy Sequence Masking。
它针对的是另一种 off-policy 问题:有些 rollout sequence 与当前策略已经偏离太远,继续用它们做负向更新可能会误导模型。
设数据采样策略为 \(\pi_{\mathrm{old}}\),当前训练策略为 \(\pi_\theta\),可以用序列级 KL 衡量二者偏差:
如果某条样本的 policy divergence 过大,并且 advantage 为负:
则对该样本进行 mask:
然后把 GRPO loss 写成:
直觉是:模型最应该从“自己犯过但仍接近当前策略的错误”中学习;而高度 off-policy 的负样本可能并不能代表当前模型真实会犯的错误,反而会把优化方向带偏。
这和 Keep Routing / Keep Sampling Mask 的侧重点不同:
- Keep Routing 对齐 computation path;
- Keep Sampling Mask 对齐 action space;
- Off-Policy Sequence Masking 过滤过度偏离当前策略的负样本;
- TIS / MIS 通过 importance ratio 修正 behavior policy 和 target policy 的概率偏差;
- PipelineRL 通过系统设计降低参数滞后,从源头减少 off-policyness。
7. 一个统一视角:LLM RL 的真实行为策略是什么?
如果把上述问题统一起来,LLM RL 中真正的 behavior policy 并不是简单的:
而是:
其中:
- \(\theta_{\tau(t)}\):第 \(t\) 个 token 生成时的参数版本;
- \(\mathrm{infer}\):推理引擎实现;
- \(M_t\):top-p / top-k sampling mask;
- \(Z_t\):MoE routing path;
- \(s_t = (x, y_{<t})\):自回归前缀状态。
而训练时优化的是:
所以真正需要对齐的是:
不同方法可以看成在对齐这个等式的不同部分:
| 问题 | 不一致来源 | 典型修正 |
|---|---|---|
| 引擎不一致 | \(\pi^{\mathrm{infer}} \neq \pi^{\mathrm{train}}\) | TIS / MIS / 统一精度 / 对齐 kernel |
| 参数陈旧 | \(\theta_{\tau(t)} \neq \theta_k\) | PipelineRL / in-flight weight update / per-token behavior logprob |
| MoE 路由漂移 | \(Z_t^{\mathrm{infer}} \neq Z_t^{\mathrm{train}}\) | Keep Routing |
| 采样截断 | training action space 与 rollout action space 不一致 | Keep Sampling Mask |
| 高度 off-policy 负样本 | 样本与当前策略 KL 过大 | Off-Policy Sequence Masking |
因此,RL 阶段的训推不一致并不是单一问题,而是一组分布错配问题:
8. 进一步思考:为什么这个问题在 reasoning RL 中尤其严重?
Reasoning RL 通常具有三个特征:
第一,输出序列长。 长 CoT 会让 importance ratio 连乘,导致方差迅速放大:
当 \(T\) 很大时,即使每个 token 的 ratio 只有很小偏差,序列级 ratio 也可能极端不稳定。
第二,reward 稀疏。 数学、代码、工具调用等任务往往只有最终答案 reward:
这意味着错误的 off-policy 更新很难被 dense supervision 纠正。
第三,系统异构程度高。 大规模 RL 训练通常混合使用 rollout engine、training engine、reward engine、MoE parallelism、KV cache、quantization、sampling truncation 等组件。每个组件的微小差异都会进入 logprob,并最终影响 policy update。
所以,LLM RL 的稳定性不仅取决于 PPO、GRPO、REINFORCE 或 DAPO 本身,也强依赖底层系统是否能维持严格的概率一致性。
9. 结论
我认为,RL 阶段的训推不一致可以分为三层:
第一层是概率分布不一致。 同一参数下,推理引擎和训练引擎给出的 logprob 不一致,导致 policy-gradient estimator 有偏。
第二层是参数版本不一致。 rollout 生成数据时使用的参数落后于训练时的当前参数,导致样本变成 stale off-policy data。
第三层是执行路径不一致。 MoE routing path、top-p/top-k sampling mask 等系统行为改变了实际参与生成的专家和 action subspace,使训练阶段优化的对象不再严格等同于推理阶段产生样本的对象。
因此,解决 LLM RL 中的训推不一致,不能只从算法角度看,也不能只从系统角度看。真正有效的方案需要同时回答三个问题:
只有当训练阶段能够复现或正确校正这些信息时,RL 更新才是真正可信的。
这也是为什么近年来的 LLM RL 系统越来越重视:
- rollout logprob 的精确记录;
- per-token behavior policy 追踪;
- importance sampling correction;
- routing path replay;
- sampling mask replay;
- training / inference engine 的数值一致性;
- 更低 policy staleness 的异步训练框架。
从这个角度看,LLM RL 的核心问题正在从单纯的 objective design,转向 policy distribution accounting:我们不仅要知道模型得到了什么 reward,还必须知道这条 trajectory 究竟是由哪个策略、哪个引擎、哪个参数版本、哪个 routing path、哪个 action subspace 生成的。
这才是理解下一代 reasoning RL scaling 的关键。