Prhub

#47483 [ModelRunner V2][BugFix] Free all model refs on shutdown

原始 PR 作者 njhill 合并时间 2026-07-03 10:32 文件变更 1 提交数 1 评论 0 代码增减 +4 / -0

执行摘要

修复 MRV2 shutdown 时未释放 model_state 和 speculator 引用

PR body 指出 shutdown 时存在未清除的模型引用,导致内存无法释放,并引用了一个 Buildkite CI 失败(https://buildkite.com/vllm/ci/builds/76036)。该 CI 失败是在 PR #44443(使 MRV2 成为所有密集模型的默认运行器)之后出现的。

值得合入,修复清晰且低风险。可快速合并以解决 CI 失败和内存泄漏问题。建议后续考虑为 shutdown() 补充单元测试,涵盖所有应清理的属性。

讨论亮点

无实质性讨论。仅有自动化 bot 评论指示从 fork 来的 PR 需手动触发 Review,接着两位 maintainer(AndreasKaratzas 和 mgoin)均批准,未留实质性评论。

实现拆解

  1. 在 shutdown() 方法中新增清理 model_state:在 vllm/v1/worker/gpu/model_runner.py 的 shutdown() 函数中,若存在 self.model_state 则执行 del self.model_state。
  2. 新增清理 speculator:使用 getattr 安全检查 speculator 属性,若非 None 则设为 None。
  3. 保持原有清理顺序:两个新增清理位于释放 kv_cache_config 和 model 之间,与已有清理逻辑一致。
  4. 无其他文件变更:补丁仅涉及 4 行新增,无测试或配置修改。
文件 模块 状态 重要度
vllm/v1/worker/gpu/model_runner.py 模型运行器 modified 5.84

关键源码片段

vllm/v1/worker/gpu/model_runner.py data-contract

唯一变更文件,在 shutdown() 方法中补充了 model_state 和 speculator 的清理逻辑

# vllm/v1/worker/gpu/model_runner.py
​
def shutdown(self) -> None:
    """Release GPU tensors (model weights, KV caches, workspace) so that
    memory is reclaimable when running in the same process."""
    torch.accelerator.synchronize()
    if hasattr(self, "kv_caches"):
        self.kv_caches.clear()
    if hasattr(self, "attn_groups"):
        self.attn_groups.clear()
    if hasattr(self, "kv_cache_config"):
        del self.kv_cache_config
    free_before_shutdown(self.vllm_config)
    # 以下两行为本次新增:清除之前遗漏的 model_state 和 speculator 引用
    if hasattr(self, "model_state"):
        del self.model_state
    if getattr(self, "speculator", None) is not None:
        self.speculator = None
    if hasattr(self, "model"):
        del self.model
​
    gc.collect()
    torch.accelerator.empty_cache()
    logger.debug("Cleaned up model weights, KV caches, and workspace")

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险极低。变更仅为在 shutdown() 方法中添加两处属性清理,不会影响正常运行路径。可能的风险是若 model_state 或 speculator 在其他地方仍被引用(如析构顺序异常),提前删除可能导致二次释放,但由于使用了 hasattr 和 getattr 安全检查,且 Python 的 del 仅删除引用而非强制释放对象,实际风险可忽略。

  • 用户/系统:解决因 MRV2 默认化后部分 dense 模型在进程内释放时 GPU 内存残留的问题,提升内存回收可靠性。
  • 团队/开发者:无 API 或行为变化,仅内部清理逻辑完善。
  • 影响范围:所有使用 ModelRunner V2 的 dense 模型(MRV2 已为默认)。
核心路径变更 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论