元鉴
返回中文阅读流

Hugging Face Blog

vLLM 从 V0 到 V1:强化学习中先确保正确性,再进行修正

来自 Hugging Face Blog 的最新公开更新。

中文内容

已翻译official company source英文原文2026-05-06

vLLM V0 到 V1:RL 中先确保正确性,再进行修正

企业 文章 发布于 2026 年 5 月 6 日

迁移目标 失败模式 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 尝试(红色)以及经过我们修复后的最终 vLLM V1 运行(绿色)的训练器侧指标,包括 fp32 lm_head。最终的 V1 运行在裁剪率、KL、熵和奖励方面回到了接近 V0 的轨迹。

迁移目标

vLLM V1 是对 V0 引擎的大规模重写。因此,我们的迁移目标刻意限定得很窄:

  1. 验证 V1 是否以训练器预期的形式返回 rollout logprobs
  2. 针对 V0 参考版本重新运行相同的工作负载
  3. 仅在后端一致性恢复后评估目标层面的变化

最先可见的症状出现在:

  • 正文:clamp_log_ratio_new_old_indicator
  • 正文:kl_new_old
  • 奖励

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

初始的 V1 运行清楚地显示了这个问题。训练器侧的 logprobs 和 reward 在训练早期就偏离了 V0 参考。

图 2. 更新过程中由训练器计算的当前策略 logprobs(左)和奖励(右)。初始的 vLLM V1 运行(红色)与 vLLM V0 参考(蓝色)出现分离。

训练器指标中也出现了相同的模式。在初始比较中,裁剪率是最容易读取的信号。

图 3. vLLM V0 参考(蓝色)和初始 vLLM V1 尝试(红色)的训练器端指标。裁剪率跟踪 rollout/训练器策略差距;熵和奖励显示该差距如何传播到训练中。

失效模式

我们将可能的原因分为三层:

  1. 语义不匹配:后端返回的 logprobs 与训练器预期的含义不同。
  2. 推理路径不匹配:后端在缓存、调度或请求处理方面使用不同的运行时默认设置,因此相同的提示会遵循不同的执行路径。
  3. 目标不匹配:RL 目标需要针对仍然存在的陈旧程度或后端不匹配进行校正。

我们最初过早地怀疑了第三类问题。有用的诊断来自于先将前两类视为后端行为问题,并首先将它们排除。

V1 后端修复

Logprob 语义

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

所需设置为:

  • 正文:logprobs-mode=processed_logprobs

这消除了 rollout logprobs 中明显的均值偏移。训练曲线相对于已知良好的参考仍然显示出差距,因此下一个问题必定位于推理路径中。

policy-ratio 图直接显示了这一点。一旦为 V1 启用 processed_logprobs,三个运行中的平均 policy ratio 都始终极其接近 1.0。这证明均值偏差已被修复。剩余的不匹配体现在 clip rate、KL、entropy 以及下游训练行为中。

图 4. rollout/trainer 策略比值相对于 1.0 的逐步偏差,按 10,000 倍缩放;其中蓝色为 vLLM V0 参考,红色为初始 vLLM V1 运行,绿色为修正后的 vLLM V1 运行。

运行时默认设置

早期的 V1 运行将引擎版本与 V1 运行时默认设置混用:

  • prefix caching,在早期运行中未设置,因此应用了 vLLM 0.18.1 的默认设置
  • 异步调度,在早期运行中未设置,因此应用了 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

Prefix caching 值得单独说明。对于固定模型状态而言,它通常是一种保持正确性的推理优化。在这个在线 RL 设置中,相对于 V0 参考路径,它是 V1 独有的缓存生命周期和复用差异。actor 还在处理重复前缀、并发请求、异步调度以及进行中的权重更新。

当前缀缓存策略忽略权重更新边界时,前缀缓存命中可以复用权重更新前计算出的状态。禁用前缀缓存从一致性比较中移除了一个仅 V1 存在的自由度。

飞行中权重更新

权重同步也必须与在线 RL 更新模型相匹配。一种选择是让 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. rollout 服务器中的权重落后于 trainer 策略的步数,分别对应 vLLM V0 参考运行(蓝色)、初始 vLLM V1 运行(红色)以及修正后的 vLLM V1 运行(绿色)。

剩余差距:fp32 lm_head

上述 V1 后端修复消除了明显的迁移问题,但要实现最终一致性,仍需要匹配用于计算 logits 的数值路径。trainer 使用 fp32 lm_head 进行最终投影。rollout 后端必须匹配这一行为。

MiniMax-M1 技术报告中也出现了一个密切相关的问题:他们的 RL 运行显示训练/推理 token 概率不匹配,他们将其追溯到 LM 输出头,并通过以 fp32 计算该输出头来修复。

这一点很重要,因为 RL 更新会直接使用 token 的 logprobs。logits 的微小变化可能会体现在 policy ratios、KL 和 clipping 中。因此,最终投影的精度是在线 RL 正确性边界的一部分。ScaleRL 论文随后将 fp32 logits/head 计算纳入其 RL 方案,并通过消融实验表明它是大规模 RL 的一项有用设计选择。

在包含 fp32 lm_head 路径后,reward 对最终一致性结果给出了一个简洁的视图。在图 6 中,最终的 V1 运行轨迹与 V0 参考一致;最初的 V1 尝试则产生了明显不同的 reward 曲线。

图 6. vLLM V0 参考(蓝色)、最初的 vLLM V1 尝试(红色)以及包含 fp32 lm_head 路径的最终 vLLM V1 运行(绿色)的 reward。包含 fp32 head 后,最终 V1 运行轨迹与 V0 参考一致。

消融实验

阴性结果很重要,因为它们排除了常见解释。

  • 仅使用 processed_logprobs:修复了语义 logprob 错误;训练不匹配仍然存在。
  • 批次不变性:在一项单独测试中,不匹配仍然存在,并伴随更高的滞后、更高的裁剪率以及 NCCL 复杂性。
  • 将第一次 V1 运行视为公平基线:第一次 V1 运行启用了多个仅限 V1 的默认设置,因此这是一次存在混杂因素的迁移比较。

为什么我们首先修复后端正确性

目标侧校正(如截断重要性采样、重要性比率重加权及相关方法)是有用的工具。如果 rollout 有意保持陈旧、异步生成,或由无法与训练器侧策略等价的后端生成,那么通常应当加入某种形式的校正。

这里的首要问题是推理正确性。迁移到 V1 后,rollout 后端返回的 logprobs 和运行时行为打破了训练器假设。此时加入目标侧校正会把两个问题混在一起:

  • 推理后端是否生成了正确的 logprobs?
  • 在给定正确 logprobs 的情况下,目标函数是否仍然需要离策略或异步校正?

这些问题需要分开。否则,目标函数侧的校正可能会补偿推理后端行为的异常,这会使训练曲线更难解释。

当前目标函数仍然可以改进。在恢复推理一致性之后,下一步改进就是常规的异步/离策略清理:

  • 保留 rollout 时显式的行为策略 logprobs
  • 在优化时于训练器端重新计算旧策略的对数概率
  • 将后端不匹配校正与策略更新比率分离
  • 跟踪校正项的 ESS 等诊断指标,并与训练器聚合指标并列记录

此次迁移的主要经验更为具体:先修复后端正确性问题,然后再为仍然存在的不匹配添加校正。

社区

编辑预览
Upload images, audio, and videos by dragging in the text input, pasting, or 点击此处.
点击或粘贴到此处以上传图片
Comment

· 注册或登录以发表评论

原文标题

vLLM V0 to V1: Correctness Before Corrections in RL