# vLLM V0 到 V1：在线强化学习中优先确保后端行为正确性

- 来源：Hugging Face：Blog（RSS）
- 发布时间：2026-05-07 03:06
- AIHOT 分数：65
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmoug22sy00eeslbajec354qh
- 原文链接：https://huggingface.co/blog/ServiceNow-AI/correctness-before-corrections

## 精选理由

vLLM V1迁移时踩的四个坑全在这里，从logprob语义到fp32投影头，修完才调RL目标，做在线RL的团队可以直接抄这份配置清单。

## AI 摘要

为确保 vLLM 从 0.8.5 到 0.18.1 的重大重写后，在线强化学习训练结果与 V0 参考运行一致，团队优先修复后端行为而非调整 RL 目标。关键修复包括：将日志概率模式设为 `processed_logprobs` 以匹配采样器分布；禁用 V1 特有的前缀缓存和异步调度等运行时默认值；调整权重更新路径以匹配 V0 的缓存保留行为；并确保 rollout 后端使用 fp32 精度的 `lm_head` 进行最终投影。这些措施消除了策略比率均值偏差，使 V1 在 KL 散度、熵等指标上与 V0 达成一致。

## 正文

PipelineRL 使用 vLLM 作为推理引擎来生成 rollout。推理引擎对模型 token 进行采样并返回 token 的 logprobs；训练器利用这些 logprobs 计算策略比率、KL 散度、裁剪率、熵和奖励。这些 logprobs 计算方式的任何差异都会改变训练动态。这正是我们在从 vLLM V0 迁移到 V1 过程中需要消除的训练-推理不匹配问题。简而言之，在修复了以下四个问题后，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

熵

奖励

这些指标来自一次 GSPO 训练运行，即本次实验所使用的目标函数。同一类不匹配问题也可能出现在 PPO、GRPO 或任何将 rollout 侧 logprobs 视为优化目标一部分的在线 RL 系统中。

初始的 V1 运行清晰地展示了问题。训练器端的 logprobs 和奖励在训练早期就偏离了 V0 参考版本。

图 2. 训练器在更新期间计算的当前策略 logprobs（左）和奖励（右）。初始的 vLLM V1 运行（红色）与 vLLM V0 参考版本（蓝色）发生了偏离。

同样的模式也出现在训练器指标中。在初步对比中，裁剪率是最容易解读的信号。

图 3. vLLM V0 参考版本（蓝色）与初始 vLLM V1 尝试版本（红色）的训练器端指标。裁剪率反映了 rollout 与训练器策略之间的差距；熵和奖励则展示了这种差距如何传导至训练过程。

失败模式

我们将可能的原因分为三个层面：

语义不匹配：后端返回的 logprobs 含义与训练器预期的含义不同。

推理路径不匹配：后端在缓存、调度或请求处理方面使用了不同的运行时默认设置，导致相同的提示词遵循了不同的执行路径。

目标不匹配：强化学习目标需要针对残留的陈旧度或后端不匹配程度进行修正。

我们最初过早地怀疑了第三类原因。而有效的诊断方法是将前两类视为后端行为问题，并首先将其排除。

V1 后端修复

Logprob 语义

第一个问题是语义问题。vLLM V1 默认从原始模型输出返回 logprobs，即在经过温度缩放、惩罚以及 top-k/top-p 过滤等 logits 后处理之前。PipelineRL 期望的是采样器所使用的已处理分布中的 logprobs。

所需的设置是：

logprobs-mode=processed_logprobs

这消除了 rollout logprobs 中明显的均值偏移。但训练曲线与已知良好的参考版本相比仍存在差距，因此下一个问题必定出在推理路径上。

策略比率图直接显示了这一点。一旦 V1 启用了 processed_logprobs，所有三次运行的平均策略比率都极其接近 1.0。这确立了均值偏差的修复。剩余的差异则体现在裁剪率、KL 散度、熵以及下游训练行为中。

图 4. vLLM V0 参考版本（蓝色）、初始 vLLM V1 运行版本（红色）以及修正后的 vLLM V1 运行版本（绿色）中，rollout/训练器策略比率与 1.0 的每步偏差（已缩放 10,000 倍）。

运行时默认设置

早期的 V1 运行将引擎版本与 V1 运行时默认设置混合在了一起：

前缀缓存，在早期运行中未设置，因此应用了 vLLM 0.18.1 的默认设置。

异步调度，在早期运行中未设置，因此应用了 vLLM 0.18.1 的默认值。

一个临时性的禁用级联注意力覆盖，通过启动时的 kwargs 参数传递设置，位于已提交配置的对等性方案之外。

对于对等性运行，我们明确了这些选择：

vllm_config: use_v1: true vllm_kwargs: logprobs-mode: processed_logprobs enable-prefix-caching: false async-scheduling: false

前缀缓存值得单独说明。对于固定的模型状态，它通常是一种保持正确性的推理优化。在此在线强化学习设置中，相对于 V0 参考路径，它在缓存生命周期和重用方面是 V1 独有的差异。行动者还需要处理重复前缀、并发请求、异步调度以及运行中的权重更新。

当缓存策略忽略权重更新边界时，前缀缓存命中可以重用权重更新之前计算的状态。禁用前缀缓存从对等性比较中移除了一个 V1 独有的自由度。

运行中权重更新

权重同步也必须匹配在线强化学习的更新模型。一种选择是让 V1 比 V0 更严格，即在每次更新时排空请求并清除缓存。但这回答的是另一个问题。我们首先需要验证 V1 能否匹配现有的 V0 行为。

V0 实际执行的操作更接近于：

在引擎边界处阻塞执行

加载新权重

恢复运行，不进行显式的缓存状态失效

最接近的 V1 对应操作是：

await engine.pause_generation(mode="keep", clear_cache=False) await engine_client.collective_rpc_async( "receive_weight_update", args=(request.model_dump_json(),), ) await engine.resume_generation()

有两个细节很重要：

mode="keep" 比 wait 或 abort 更接近旧的运行中更新模型

clear_cache=False 匹配 V0 封装器的行为，即在更新时保持缓存状态不变

延迟是一个有用的运行时诊断指标。初始的 V1 路径在训练后期比修正后的 V1 运行携带更持久的延迟。

图 5. 在 vLLM V0 参考（蓝色）、初始 vLLM V1 运行（红色）和修正后的 vLLM V1 运行（绿色）中，推出服务器权重落后于训练器策略的步数。

剩余差距：fp32 lm_head

上述 V1 后端修复消除了明显的迁移问题，但最终的对等性仍需匹配用于计算 logits 的数值路径。训练器使用 fp32 lm_head 进行最终投影。推出后端必须匹配该行为。

MiniMax-M1 技术报告中出现了一个密切相关的问题：他们的强化学习运行显示训练/推理的 token 概率存在不匹配，他们将其追溯到大语言模型输出头，并通过在 fp32 精度下计算该输出头解决了问题。

这一点很重要，因为强化学习更新直接消耗 token 的 logprobs。logits 的微小变化会在策略比率、KL 散度和裁剪中变得可见。因此，最终的投影精度是在线强化学习正确性的一部分。ScaleRL 论文后来将 fp32 logits/输出头计算纳入其强化学习方案，并将其作为大规模强化学习的一个有用设计选择进行了消融实验。

在包含 fp32 lm_head 路径的情况下，奖励函数给出了最终一致性结果的简洁视图。在图 6 中，最终的 V1 运行轨迹与 V0 参考线重合；而最初的 V1 尝试则产生了明显不同的奖励曲线。

图 6. vLLM V0 参考线（蓝色）、最初的 vLLM V1 尝试（红色）以及包含 fp32 lm_head 路径的最终 vLLM V1 运行（绿色）的奖励函数。在包含 fp32 输出头的情况下，最终的 V1 运行轨迹与 V0 参考线重合。

消融实验

这些负面结果很重要，因为它们排除了常见的解释。

仅使用 processed_logprobs：修复了语义上的 logprob 错误；但训练不匹配问题仍然存在。

批次不变性：在另一项独立测试中，不匹配问题仍然存在，并伴有更高的延迟、更高的裁剪率以及 NCCL 相关的复杂问题。

将首次 V1 运行视为公平基线：首次 V1 运行启用了多个 V1 专属默认设置，因此这是一次混杂了多种因素的迁移对比。

为何我们优先修复后端正确性

目标端的修正，例如截断重要性采样、重要性比率重新加权及相关方法，都是有用的工具。如果 rollout 数据是故意过时的、异步生成的，或者由某个无法与训练端策略保持等价的后端产生的，那么添加某种形式的修正通常是正确的做法。

这里首要的问题是推理正确性。迁移到 V1 后，rollout 后端返回的 logprobs 和运行时行为破坏了训练端的假设。此时在目标端添加修正会混淆两个问题：

推理后端是否产生了正确的 logprobs？

在给定正确对数概率的情况下，目标函数是否仍需要离策略或异步修正？

这些问题需要分开处理。否则，目标函数侧的修正可能会掩盖推理后端的错误行为，导致训练曲线更难解读。

当前的目标函数仍有改进空间。在推理一致性恢复之后，下一步改进就是常规的异步/离策略清理：

保留 rollout 阶段显式的行为策略对数概率

在优化阶段重新计算训练器侧的旧策略对数概率

将后端不匹配修正与策略更新比率分开

在聚合训练指标之外，跟踪修正项的有效样本量（ESS）等诊断指标

这次迁移的主要教训更为具体：先修复后端的正确性，再针对剩余的不匹配问题添加修正。
