以下是您要求的英文文章的中文翻译,已按照保留原文结构、技术术语不翻译、代码块原样保留等要求处理。
vLLM V0 到 V1:在 RL 中先修正正确性,再修正目标
返回文章
vLLM V0 到 V1:在 RL 中先修正正确性,再修正目标
企业文章 发布于 2026 年 5 月 6 日 点赞 4
Rafael Pardinas rafapi-snow 关注 ServiceNow-AI
Ehsan Kamalloo ehsk 关注 ServiceNow-AI
- 迁移目标
- 故障模式
- V1 后端修复
- Logprob 语义
- 运行时默认值
- 运行中权重更新
- 剩余差距:fp32 lm_head
- 消融实验
- 为什么我们先修复后端正确性
PipelineRL 使用 vLLM 作为推理引擎来生成 rollout。推理引擎采样 token 并返回 token logprobs;训练器使用这些 logprobs 来计算策略比率、KL 散度、裁剪率、熵和奖励。这些 logprobs 计算方式上的任何差异都可能改变训练动态。这就是我们在从 vLLM V0 迁移到 V1 时需要消除的训练-推理不匹配问题。
TL;DR。 在修复了以下四个问题后,vLLM V1 与我们的 vLLM V0 参考实现匹配:处理后的 rollout logprobs、V1 特定的运行时默认值、运行中权重更新路径,以及用于最终投影的 fp32 lm_head。我们在更改 RL 目标之前先修复了后端行为。
参考运行使用 vLLM 0.8.5;V1 运行使用 vLLM 0.18.1。图 1 显示了最终结果。红色曲线是初始的 V1 尝试,绿色曲线是经过下文所述修复后的最终 V1 运行。
图 1. vLLM V0 参考(蓝色)、初始 vLLM V1 尝试(红色)以及我们修复后(包括 fp32 lm_head)的最终 vLLM V1 运行(绿色)的训练器端指标。 最终 V1 运行在裁剪率、KL 散度、熵和奖励方面接近 V0 轨迹。
迁移目标
vLLM V1 是对 V0 引擎的一次重大重写。因此,我们的迁移目标刻意收窄:
- 验证 V1 以训练器期望的形式返回 rollout logprobs
- 针对 V0 参考重新运行相同的工作负载
- 仅在恢复后端一致性后评估目标层面的变化
最初出现的可见症状包括:
- clamp_log_ratio_new_old_indicator
- kl_new_old
- entropy
- reward
这些指标来自一次 GSPO 训练运行,这也是本次实验所使用的目标。同一类不匹配问题也可能出现在 PPO、GRPO 或任何将 rollout 端 logprobs 视为优化目标一部分的在线 RL 系统中。
初始的 V1 运行清晰地显示了问题。训练器端的 logprobs 和奖励在训练早期就偏离了 V0 参考。
图 2. 训练器在更新期间计算的当前策略 logprobs(左)和奖励(右)。 初始的 vLLM V1 运行(红色)与 vLLM V0 参考(蓝色)分离。训练器指标中也出现了相同的模式。
在初始比较中,裁剪率是最容易解读的信号。
图 3. vLLM V0 参考(蓝色)和初始 vLLM V1 尝试(红色)的训练器端指标。 裁剪率反映了 rollout/训练器策略差距;熵和奖励显示了该差距如何传播到训练中。
故障模式
我们将可能的原因分为三个层面:
- 语义不匹配:后端返回的 logprobs 含义与训练器期望的不同。
- 推理路径不匹配:后端在缓存、调度或请求处理方面使用了不同的运行时默认值,导致相同的提示词遵循不同的执行路径。
- 目标不匹配:RL 目标需要针对残留的陈旧度或后端不匹配进行修正。
我们最初过早地怀疑了第三类。有用的诊断来自于将前两类视为后端行为问题,并首先排除它们。
V1 后端修复
Logprob 语义
第一个问题是语义问题。vLLM V1 默认从原始模型输出返回 logprobs,即在 logits 后处理(如温度缩放、惩罚和 top-k/top-p 过滤)之前。PipelineRL 期望的是来自采样器所使用的处理后分布的 logprobs。
所需的设置是:
logprobs-mode=processed_logprobs
这消除了 rollout logprobs 中明显的均值偏移。但训练曲线与已知良好的参考相比仍然存在差距,因此下一个问题必定出在推理路径上。
策略比率图直接显示了这一点。一旦为 V1 启用了 processed_logprobs,所有三次运行的平均策略比率都极其接近 1.0。这确立了均值偏差的修复。剩余的差异体现在裁剪率、KL 散度、熵以及下游训练行为中。
图 4. 每步 rollout/训练器策略比率与 1.0 的偏差(缩放 10,000 倍),针对 vLLM V0 参考(蓝色)、初始 vLLM V1 运行(红色)和修正后的 vLLM V1 运行(绿色)。
运行时默认值
早期的 V1 运行混合了引擎版本与 V1 运行时默认值:
- 前缀缓存(prefix caching):早期运行中未设置,因此应用了 vLLM 0.18.1 的默认值
- 异步调度(async scheduling):早期运行中未设置,因此应用了 vLLM 0.18.1 的默认值
- 一个临时的
disable-cascade-attn覆盖,通过启动时的 kwarg 传递设置,且不在已提交配置的一致性配方中
为了进行一致性运行,我们明确选择了以下设置:
vllm_config:
use_v1: true
vllm_kwargs:
logprobs-mode: processed_logprobs
enable-prefix-caching: false
async-scheduling: false
前缀缓存值得单独说明。对于固定的模型状态,它通常是一种保持正确性的推理优化。在此在线 RL 设置中,相对于 V0 参考路径,它是 V1 独有的缓存生命周期和重用差异。Actor 还需要处理重复前缀、并发请求、异步调度和运行中权重更新。当缓存策略忽略权重更新边界时,前缀缓存命中可能会重用权重更新之前计算的状态。禁用前缀缓存从一致性比较中移除了一个 V1 独有的自由度。
运行中权重更新
权重同步也必须匹配在线 RL 更新模型。一种选择是让 V1 比 V0 更严格,即在每次更新时排空请求并清除缓存。这可以回答另一个问题。我们首先需要验证 V1 能够匹配现有的 V0 行为。V0 有效...
(注:原文在“V0 有效”处截断,因此翻译也在此处结束。后续内容如需补充,请提供完整原文。)