IsoExec: 切换 SkyRL 中的训练器-推理不匹配

vLLM 推出了 IsoExec,一种跨框架的统一执行抽象,旨在消除强化学习 (RL) 工作负载中训练引擎与推理引擎之间的数值不匹配。通过强制执行严格的执行合约并利用并行不变性内核 (parallelism-invariant kernels),IsoExec 确保了 rollout 引擎和训练器在位一致性 (bitwise consistency) 方面评估相同的策略,从而在仅增加 25% 性能开销的情况下,将平均端到端 rollout 与训练的 logprob 差异降低到 $10^{-7}$ 以下。

问题:训练器-推理不匹配

在 on-policy RL 中,系统必须执行两次相同的策略:一次在 rollout 引擎中采样 token,一次在训练器中重新计算 log 概率。在实践中,这两个阶段通常使用不同的引擎(例如,用于 rollout 的 vLLM 和用于训练的 Megatron),它们采用不同的内核、batch 形状和并行布局。

由于浮点数算术是非结合律的,这些系统性差异会导致不同的规约 (reduction) 顺序,即使在模型参数完全相同的情况下,也会改变 token 概率。这种不匹配可能会使 REINFORCE 和 GRPO 等 RL 算法不稳定,并导致奖励崩溃 (reward collapse)。例如,Fireworks 报告的一项 GLM-5.2 运行结果显示,其训练-推理 KL 散度约为 0.013,导致 45% 的 token 被通过 clipping 丢弃,随后在第 20 步左右发生奖励崩溃。

IsoExec 统一执行合约

IsoExec 通过使用 执行合约 (execution contract) 来解决这些差异,该合约声明了两个运行时必须遵循的每一个与位相关的执行选择。

合约结构与强制执行

  • Cases and Regions (情况与区域): 合约将前向算子划分为“区域” (region,即由一个内核实现的算术跨度)。然后定义“情况” (case,例如 engine_prefilltrainer_fwd) 来指定如何处理每个区域。
  • Composition (组合): 对于每一对 region-case,合约会选择一个特定的实现并将其固定为常量,例如累积数据类型 (accumulation dtypes) 和规约分解参数 (reduction-decomposition parameters,例如 split-K 分区计数)。
  • Claims (声明): 这些是运行时强制执行的条件,例如拓扑声明 (topology claims),列出了规约树 (reduction tree) 被证明在位一致性方面是不变的,从而实现并行规模的特定并行规模。
  • Identities (标识): 使用 SHA-256 摘要 (semantic, numerical_policy, 和 deployment) 来验证训练器和 rollout 引擎正在执行相同的经过验证的数值策略。

每个运行时的 contract adapter 会将这些规范绑定到框架的扩展点,并监控运行时以确保合规。

统一模型与并行不变性内核

IsoExec 实现了一种统一的模型定义,这种定义在各种分布式策略(包括 tensor、expert 和 sequence parallelism)中保持位一致性。

实现并行不变性

为了在不同的 GPU 布局下保持数值一致性,IsoExec 采用了固定的二进制规约树方法:

  • Tensor Parallelism (TP): 使用 pik 实现,IsoExec 将 K 维度划分为连续的叶子节点。每个叶子节点使用确定性的 Tensor Core MMA 与 FP32 累积,并且合约固定了 rank-to-leaf 映射和算术调度。
  • Expert Parallelism (EP): Expert 输出按固定的路由顺序而非 rank 顺序进行组合。
  • Sequence Parallelism (SP): IsoExec 复用与非-SP 系统相同的规约树,每个 rank 保留其自身的输出切片,从而确保无论是否启用 SP,训练器 logits 始终保持一致。

Chunkwise-Parallel Recurrent (CPR) Gated DeltaNet

线性注意力架构(如 Gated DeltaNet (GDN))通常在训练/prefill 阶段使用 chunkwise-parallel 形式,而在 decode 阶段使用 recurrent 形式,这会产生数值不匹配。以往通过在所有地方使用 recurrent 形式来修复此问题的尝试,导致了显著的慢速化(在某些工作负载上高达 5 倍)。

IsoExec 引入了 Chunkwise-Parallel Recurrent (CPR),它将循环 (recurrence) 作为主要功能,但通过在 chunk 之间进行并行化处理。对于 decode 阶段,它每 $C$ 个 token 这样进行重新同步隐藏状态 (hidden state),其中 $C$ 是 chunk 大度。这在保持高吞吐量的同时实现了位一致性:

Stage Native Mixed Chunkwise Everywhere Recurrent Everywhere CPR
Bitwise Exact No Yes Yes Yes
Trainer Fwd+Bwd 5.177 ms 5.177 ms (1.00x) 22.863 ms (4.42x) 7.386 ms (1.43x)
Rollout Prefill 0.844 ms 0.844 ms (1.00x) 3.679 ms (4.31x) 1.412 ms (1.67x)
Rollout Decode 0.0612 ms 2.2374 ms (36.6x) 0.0612 ms (1.00x) 0.0846 ms (1.38x)

实验结果

IsoExec 在单个 8xH100 节点上使用同步 RL 训练 Qwen3.5-35B-A3B 在 DAPO-Math-17k 上进行了测试。

数值准确性

在 50 个 step 步数内,平均 pre-update rollout 与训练的绝对 logprob 差异从 $10^{-3}$ (native SkyRL) 降低到了 $10^{-7}$ 以下 (IsoExec)。每个 step 的平均最大差异从 5.073 降至 $10^{-4}$。

性能开销销

消除不匹配引入了与 native SkyRL 栈相比的性能惩罚:

Metric Native IsoExec Overhead
Generation 591.3 s 776.6 s 31.3%
Policy Training 498.6 s --- 18.6%
Full RL Step 1224.6 s 1534.0 s 25.3%

虽然实现了数值一致性,但团队在短期的 59 步测试窗口内并未观察到显著的奖励 (reward) 奖励提升。

Sources

相关

  • Dispatch
  • Dispatch
  • 项目
  • Dispatch
  • Dispatch