# PR #47483 完整报告

- 仓库：`vllm-project/vllm`
- 标题：[ModelRunner V2][BugFix] Free all model refs on shutdown
- 合并时间：2026-07-03 10:32
- 原文链接：http://prhub.com.cn/vllm-project/vllm/pull/47483

---

# 执行摘要

- 一句话：修复 MRV2 shutdown 时未释放 model_state 和 speculator 引用
- 推荐动作：值得合入，修复清晰且低风险。可快速合并以解决 CI 失败和内存泄漏问题。建议后续考虑为 `shutdown()` 补充单元测试，涵盖所有应清理的属性。

# 功能与动机

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

# 实现拆解

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`（模块 模型运行器；类别 source；类型 data-contract）: 唯一变更文件，在 shutdown() 方法中补充了 model_state 和 speculator 的清理逻辑

关键符号：未识别

## 关键源码片段

### `vllm/v1/worker/gpu/model_runner.py`

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

```python
# 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")

```

# 评论区精华

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

- 暂无高价值评论线程

# 风险与影响

- 风险：风险极低。变更仅为在 `shutdown()` 方法中添加两处属性清理，不会影响正常运行路径。可能的风险是若 `model_state` 或 `speculator` 在其他地方仍被引用（如析构顺序异常），提前删除可能导致二次释放，但由于使用了 `hasattr` 和 `getattr` 安全检查，且 Python 的 `del` 仅删除引用而非强制释放对象，实际风险可忽略。
- 影响：
 - **用户 / 系统**：解决因 MRV2 默认化后部分 dense 模型在进程内释放时 GPU 内存残留的问题，提升内存回收可靠性。
 - **团队 / 开发者**：无 API 或行为变化，仅内部清理逻辑完善。
 - **影响范围**：所有使用 ModelRunner V2 的 dense 模型（MRV2 已为默认）。
 - 风险标记：核心路径变更 , 缺少测试覆盖

# 关联脉络

- PR #44443 [v1][ModelRunner V2] Make MRV2 the default for all dense models: 本 PR 修复的 CI 失败正是由于该 PR 使 MRV2 成为默认后暴露的遗漏清理问题。