Prhub

#6373 [rollout] feat: enable MooncakeStoreConnector with hard-reset on weight update

原始 PR 作者 aoshen02 合并时间 2026-05-27 21:38 文件变更 3 提交数 15 评论 4 代码增减 +75 / -4

执行摘要

实现 Mooncake 外部 KV 缓存硬重置,保障 RL 正确性

verl 已有的权重更新流程会正确重置 vLLM 内部前缀缓存,但不会重置外部的 Mooncake KV 存储。若不重置,下一个请求会从 Mooncake 读取旧权重的 KV 缓存,导致 RL 训练的正确性损失(silent correctness loss)。此 PR 通过在每个缓存重置路径上触发 reset_connector=True,实现了对外部存储的硬重置。

建议所有涉及长序列训练或跨副本 KV 复用的团队仔细阅读此 PR 并升级。值得关注的点:极小的改动面(仅传参 + 版本守卫)即解决了昂贵的正确性问题,展示了对外部组件集成时最小侵入的设计思路。

讨论亮点
  • gemini-code-assist[bot] 指出初始实现问题:最初的 KVStoreConfig 是 dataclass 却使用了 .get() 方法会导致 AttributeError,且 on_failure 配置未被传递到 vLLM。作者在后来的提交中移除了 KVStoreConfig,改用 engine_kwargs.vllm.kv_transfer_config 透传,消除了这些代码问题。
  • wuxibin89 要求向后兼容性:要求保持对 vLLM < 0.22.0 的兼容。作者实现了版本判断:仅当 vLLM ≥ 0.13.0 时传递 reset_connector=True,低版本不传递,满足兼容要求。

实现拆解

  1. 添加版本守卫:在 vllm_async_server.py 顶部引入 _RESET_PREFIX_CACHE_KWARGS 字典,当 vLLM 版本 ≥ 0.13.0 时设置 reset_connector=True,否则为空字典。
  2. 修改 wake_up 和 clear_kv_cache:在这两个方法的 reset_prefix_cache 调用中传入 **_RESET_PREFIX_CACHE_KWARGS,使得每次重置本地前缀缓存时也尝试重置外部连接器。对于未配置 Mooncake 的情况,vLLM 内部会将其视为无操作。
  3. 利用 vLLM 内部默认值abort_all_requests 通过 pause_generation 触发缓存重置,vLLM 的 EngineCore._reset_caches 已默认设置 reset_connector=True,因此无需额外改动。
  4. 补充文档:新增 docs/perf/rollout_kv_offload.md,指导用户通过 engine_kwargs.vllm.kv_transfer_config 配置 Mooncake 连接,并强调 RL 正确性要求(必须搭配 vLLM ≥ 0.13.0 使用)。
  5. 注册文档:在 docs/index.rst 中将新文档加入“Performance Tuning Guide”目录树。
文件 模块 状态 重要度
verl/workers/rollout/vllm_rollout/vllm_async_server.py Rollout 引擎 modified 6.49
docs/perf/rollout_kv_offload.md 性能文档 added 3.54
docs/index.rst 文档索引 modified 1.18

关键符号

vLLMHttpServer.wake_up vLLMHttpServer.clear_kv_cache

关键源码片段

verl/workers/rollout/vllm_rollout/vllm_async_server.py core-logic

核心改动文件:添加版本守卫并在 reset_prefix_cache 调用中传递 reset_connector=True,是外部 KV 缓存硬重置的关键逻辑。

# 版本守卫:仅当 vLLM >= 0.13.0 时传递 reset_connector=True
_RESET_PREFIX_CACHE_KWARGS: dict = {}
if _VLLM_VERSION >= version.parse("0.13.0"):
    _RESET_PREFIX_CACHE_KWARGS["reset_connector"] = Trueasync def wake_up(self, tags: list[str] | None = None):
    if self.node_rank != 0:
        return
    if self.rollout_mode == RolloutMode.HYBRID:
        await self.engine.wake_up(tags=tags or self._get_wake_up_tags())
        # 重置前缀缓存,并通知外部 Mooncake 存储丢弃旧 KV
        await self.engine.reset_prefix_cache(**_RESET_PREFIX_CACHE_KWARGS)
    elif self.rollout_mode == RolloutMode.COLOCATED:
        await self.engine.wake_up(tags=self._get_wake_up_tags())
        # 同上,无 connector 时此参数被 vLLM 忽略
        await self.engine.reset_prefix_cache(**_RESET_PREFIX_CACHE_KWARGS)
    elif self.rollout_mode == RolloutMode.STANDALONE:
        logger.info("skip wake_up in standalone mode")async def clear_kv_cache(self):
    if self.node_rank == 0:
        # 清除 KV 缓存时同时重置外部存储
        await self.engine.reset_prefix_cache(**_RESET_PREFIX_CACHE_KWARGS)

评论区精华

初始 KVStoreConfig 实现问题 设计

gemini-code-assist[bot] 指出 KVStoreConfig 是 dataclass 却使用了 .get() 方法会导致 AttributeError,且 on_failure 配置未被传递到 vLLM。

结论:作者在后来的提交中移除了 KVStoreConfig,改用 engine_kwargs.vllm.kv_transfer_config 透传,消除了这些代码问题。 · 已解决

向后兼容 vLLM 低版本 other

wuxibin89 要求保持对 vLLM < 0.22.0 的兼容,建议使用版本守卫。

结论:作者实现了版本判断:仅当 vLLM >= 0.13.0 时传递 reset_connector=True,低版本不传递,满足兼容要求。 · 已解决

风险与影响

  • 回归风险:未配置 Mooncake 时,reset_connector=True 被 vLLM 内部忽略,不会影响现有功能。
  • 版本兼容性:通过版本守卫确保仅在 vLLM ≥ 0.13.0 时传递新参数,低版本不受影响。
  • 测试覆盖:未包含端到端集成测试,依赖配套 vLLM PR 的单元测试和手动验证。
  • 外部依赖:需要 Mooncake 外部服务可用,且版本与 vLLM 匹配。配置错误可能导致训练失败(可通过 on_failure 策略控制,但该字段已移至 vLLM 侧)。
  • 用户影响:仅对启用 Mooncake 外部 KV 缓存的用户产生重大正面影响(正确性修复)。未启用者无任何更改。
  • 系统影响:无性能开销(无操作时参数被忽略),代码改动仅几行。
  • 团队影响:文档降低了 Mooncake 集成的使用门槛,便于新用户接入。
版本兼容性 无测试覆盖 外部依赖 Mooncake

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论