Prhub

#43154 [Core][AMD] Propagate shutdown timeout to MultiprocExecutor

原始 PR 作者 rjrock 合并时间 2026-06-13 04:13 文件变更 5 提交数 16 评论 19 代码增减 +71 / -2

执行摘要

新增 VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS 环境变量,可配置关闭超时,默认 5 秒。

rocprofv3 需要一段优雅期在进程关闭时发出 trace 数据,而 MultiprocExecutor 中原来的 4 秒固定超时不足以完成这一操作,导致跟踪命令失败。PR body 中说明了这一场景,并在 Review 中由 njhill 指出 config.shutdown_timeout 语义不同,建议使用独立环境变量控制 worker 关闭超时。

本 PR 改动量小但设计思路清晰,展示了 vLLM 中新增可配置超时的典型模式:通过 envs.py 定义环境变量,在核心关闭路径处引用。特别值得关注的是 njhill 对 shutdown_timeout 不同语义的区分 — worker 关闭超时与全局优雅关闭是不同概念。建议读者关注 _ensure_worker_terminationBackgroundResources.__call__ 两处修改,以理解 shutdown 流程中超时的传递链路。

讨论亮点
  • 使用环境变量 vs 复用 config 字段:njhill 指出 vllm_config.shutdown_timeout 原本用于全局优雅关闭(等待在途请求完成),而 worker 关闭是 tear-down 后的快速终止,语义不同,建议新增独立环境变量 VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS。rjrock 接受了此建议并重构代码。
  • 默认值选择:初始 PR 设为 4(与原来硬编码一致),但 njhill 建议改为 5,因为核心引擎的默认关闭超时原本就是 5,最终采纳改为 5。
  • 最小超时保证的移除:rjrock 在评论中指出,本 PR 最初引用了一个 max(shutdown_timeout, 4) 保护逻辑,但该逻辑已在 PR #43016 中被移除,因此本次改用环境变量也避免了可能传入 0None 的问题。

实现拆解

  1. vllm/envs.py 中声明环境变量:添加 VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS 字段(类型 int,默认值 5),并在 _get_envs 字典中提供解析函数,从环境变量读取或回退到 5
  2. 修改 multiproc_executor.py 中的 worker 终止逻辑:在 _ensure_worker_termination 方法中,将 wait_for_termination(active_procs(), 4) 改为读取 envs.VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS,使等待超时可配置。
  3. 修改 core_client.py 中的 BackgroundResources.__call__:在调用 engine_manager.shutdown() 时传入 timeout=envs.VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS,确保核心引擎关闭也沿用同一变量。
  4. 添加单元测试
    • test_executor.py:引入 _FakeClock_FakeProcess 模拟时间流逝,通过参数化验证 worker 在超时前退出时不会调用 terminate,超时后会调用。
    • test_core_engine_actor_manager.py:模拟 BackgroundResources 调用,验证它是否以正确的 timeout 参数调用 engine_manager.shutdown
文件 模块 状态 重要度
vllm/envs.py 环境配置 modified 5.19
vllm/v1/executor/multiproc_executor.py 执行器 modified 5.47
vllm/v1/engine/core_client.py 引擎客户端 modified 5.51
tests/v1/executor/test_executor.py 执行器测试 modified 6.22
tests/v1/engine/test_core_engine_actor_manager.py 引擎测试 modified 4.96

关键符号

_ensure_worker_termination BackgroundResources.__call__ test_multiproc_executor_worker_termination_timeout test_background_resources_passes_worker_shutdown_timeout

关键源码片段

vllm/v1/executor/multiproc_executor.py core-logic

核心变更:将 worker 终止等待超时从硬编码改为读取环境变量,使关闭延迟可配置。

# vllm/v1/executor/multiproc_executor.py ( 关键片段 )
# 在 `_ensure_worker_termination` 方法中,原超时固定为 4 秒,
# 现改为从环境变量 VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS 读取(默认 5 秒)。def _ensure_worker_termination(self, worker_procs):
    # ... 前面逻辑 ...
    active_procs = lambda: [proc for proc in worker_procs if proc.is_alive()]
    logger.debug("[shutdown] Executor: waiting for worker exit count=%d", initial_count)
    # 使用可配置超时,默认为 5 秒
    if wait_for_termination(
        active_procs(), timeout=envs.VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS
    ):
        logger.info_once("[shutdown] Executor: all workers exited gracefully")
        return
    # 如果超时,继续强制终止 ...
vllm/v1/engine/core_client.py dependency-wiring

将环境变量超时传递给 engine_manager.shutdown,确保核心引擎关闭使用同一配置。

# vllm/v1/engine/core_client.py (BackgroundResources.__call__ 片段 )
# 当资源清理时,将可配置超时传递给引擎管理器。def __call__(self):
    logger.debug_once("[shutdown] MPClient: background resource cleanup start")
    self.engine_dead = True
    if self.engine_manager is not None:
        # 传入从环境变量读取的超时,默认为 5 秒
        self.engine_manager.shutdown(
            timeout=envs.VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS
        )
    if self.coordinator is not None:
        self.coordinator.shutdown()
    # 后续关闭 socket 等 ...

评论区精华

使用独立环境变量而非 vllm_config.shutdown_timeout 设计

njhill 指出 config.shutdown_timeout 是用于全局优雅关闭(等待在途请求完成),而 worker 关闭是 tear-down 的快速终止,语义不同,建议使用新环境变量 VLLM_WORKER_SHUTDOWN_TIMEOUT_SECONDS。rjrock 同意并重构。

结论:最终采用新环境变量,并在 multiproc_executor.py 和 core_client.py 中使用。 · 已解决

默认值从 4 改为 5 设计

njhill 建议将默认值从 4 改为 5,因为核心引擎的默认关闭超时原本是 5。rjrock 初始选择 4 是因为原有硬编码是 4,但最终接受并改为 5。

结论:默认值改为 5,与核心引擎保持一致。 · 已解决

shutdown_timeout 可能为 None 或 0 的问题 正确性

gemini-code-assist 机器人指出如果在 multiproc_executor.py 中直接使用 self.vllm_config.shutdown_timeout 可能为 None 导致 TypeError。rjrock 回应说 shutdown_timeout 在 config 中是非负整数,不会为 None,但后来改为使用环境变量彻底消除了这一担忧。dllehr-amd 也表达了类似担忧。

结论:改用环境变量后,不存在 None 问题,安全性提升。 · 已解决

风险与影响

  • 对默认用户的影响:默认超时从 4 秒变为 5 秒,轻微增加关闭等待时间,一般不会造成问题,但在 CI 或快速销毁场景可能略有延迟。
  • 环境变量未设置时行为:默认值 5 通过代码设定,不会为 None,因此无 TypeError 风险。但用户若设置极小的值(如 0),可能导致 worker 几乎立即被终止,无法正常释放资源。建议文档提示合理范围。
  • 仅影响 MultiprocExecutor:该环境变量仅在使用 MultiprocExecutor(TP > 1)时生效,对 UniProcExecutor 无影响,限定在分布式推理场景。
  • 用户影响:仅对使用 rocprofv3 等需要更长关闭超时的 profiling 用户是积极改善;对其他用户影响极小(默认值从 4 变 5),无需适配。
  • 系统影响:关闭超时可配置意味着极端情况下进程可能挂起更久,但不会影响推理性能。
  • 团队影响:新增环境变量,需要维护文档和向后兼容。但变量命名符合已有风格,易于理解。
核心路径变更 默认行为变更

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论