[Bug]: Built-in LMCacheConnectorV1 does not forward shutdown(), so LMCache never stops and EngineCore is force-killed

使用内置 LMCacheConnectorV1 ( kv_role: kv_both )启动 vLLM 后,停止服务时 LMCache 线程不会退出,EngineCore 会卡在解释器退出阶段,最终超时被强制杀死。优先排查该连接器的 shutdown() 是否被转发到 LMCache 引擎:Buil

快速结论:使用内置 LMCacheConnectorV1(kv_role: kv_both)启动 vLLM 后,停止服务时 LMCache 线程不会退出,EngineCore 会卡在解释器退出阶段,最终超时被强制杀死。优先排查该连接器的 shutdown() 是否被转发到 LMCache 引擎:Built-in LMCacheConnectorV1 does not forward shutdown(), so LMCache never stops and EngineCore is force-killed。

适用环境:vLLM 0.31.0(2026-10-21 的 main 代码相同);LMCache(当时 dev 版本)作为 KV connector,kv_role: kv_both,本地磁盘后端;单节点 NVIDIA H200,TP=1,Python 3.12。讨论中另有基于 CPU 发行版 0.32.1rc1.dev36+ge68efc685 / Torch 2.14+cpu 的调度验证,但未复现 H200/SIGTERM 场景。

最快修复方案:Issue 中明确验证过的是 #62821 的修复方向:让内置 LMCacheConnectorV1 把 shutdown() 转发给提供该 hook 的适配器。在测试的 MRV2/TP1 本地磁盘配置中,补丁版可完成适配器清理并正常退出;请升级到包含该修复的 vLLM 版本,或按 #62821 自行应用补丁。

注意事项:该修复只覆盖内置的 in-process 路径,不改变 MP 模式,也没有给 in-tree 原生适配器(use_native=True 选中的 LMCacheConnectorV1Impl)增加清理逻辑;该原生适配器在当前代码点同样没有声明 shutdown()。此外,CPU 对照实验使用的是 tracking engine 而非真实 LMCache 实例,只确认了调度缺口,未验证后台线程清理与 H200/SIGTERM 复现。LMCache 已将 in-process 模式标记为 deprecated,建议新部署迁移到 MP 模式。

问题场景

在 vLLM 中通过内置 LMCache connector 启动服务,例如使用 vllm serve <model> --kv-transfer-config '{"kv_connector":"LMCacheConnectorV1","kv_role":"kv_both"}',并配置本地磁盘后端。发送若干请求后向 API server 发送 SIGTERM,EngineCore 开始资源清理,但 LMCache 不会停止,最终在 shutdown timeout 到期后被进程管理器强制杀死。

报错原文

[shutdown] EngineCore: ... starting resource teardown
exiting busy loop
force killing remaining process EngineCore

同时,LMCache 自身的关闭日志 Starting LMCacheConnector shutdown... 始终不出现。

原因分析

vLLM 的清理流程会从 worker 和 scheduler 调用 connector.shutdown(),但内置 LMCacheConnectorV1 没有覆写该方法,继承到的是基类的空操作。因此它包裹的 LMCache 引擎从未收到停止指令,LMCache 的 lookup/offload server 线程和 event-loop 线程持续运行。EngineCore 在解释器退出时等待线程 join,直到触发 force kill。等待期间的 Python 栈显示主线程停在 threading._shutdown,与上述判断一致。

LMCache 自带的外置 wrapper LMCacheConnectorV1Dynamic(通过 kv_connector_module_path 加载)已实现了转发:

def shutdown(self):
    return self._lmcache_engine.shutdown()

讨论中的 CPU 对照验证表明:直接调用 connector.shutdown() 和真实走 ensure_kv_transfer_shutdown() 时,tracking engine 的 shutdown 调用计数均为 0;只增加上述转发方法的私有子类,两者都变为 1。这确认了调度缺失,但不等于验证了后台线程退出。另需注意,use_native=True 选择的是 in-tree LMCacheConnectorV1Impl,它同样没有 shutdown(),因此只加 wrapper 转发的方案不能覆盖两种后端模式;此前的 #36905 曾同时涉及 wrapper 和原生适配器,但未合并即关闭。

环境排查

  • 确认 vLLM 版本:问题出现在 0.31.0,2026-10-21 的 main 代码相同;检查是否已包含 #62821。
  • 确认 KV connector 配置:是否为内置 LMCacheConnectorV1、kv_role: kv_both、本地磁盘后端。
  • 确认是否设置了 use_native=True:若使用 in-tree 原生适配器,转发式修复不会生效。
  • 确认 LMCache 版本及部署模式:in-process 模式已被 LMCache 标记为 deprecated;MP 模式的问题范围不同。
  • 确认 --shutdown-timeout 设置(复现环境使用 28 秒),并检查关闭时是否有 force killing remaining process EngineCore 日志。
  • 确认 LMCache 的关闭日志 Starting LMCacheConnector shutdown... 是否出现,以此判断 shutdown 是否被转发。
  • 其他环境项(CUDA、驱动、其他依赖版本)Issue 未给出明确信息,需要自行核对。

解决步骤

  1. 先复现并确认现象:启动内置 LMCacheConnectorV1 服务,发送请求后对 API server 发送 SIGTERM,观察 EngineCore 日志中是否只有 teardown 和 busy loop 退出,随后出现 force kill,且缺少 LMCache 的 shutdown 日志。
  2. 检查所用 vLLM 版本是否已合入 #62821。若未合入,可优先尝试升级到包含该修复的版本。
  3. 若无法升级,可按 #62821 的方式为内置 LMCacheConnectorV1 增加 shutdown() 转发,让适配器提供的 shutdown hook 被调用。可参考现有外置 wrapper 的写法:return self._lmcache_engine.shutdown()。
  4. 如果使用 use_native=True(in-tree LMCacheConnectorV1Impl),不要期望该转发修复生效;需要等待或补充针对原生适配器的清理实现。
  5. 如果使用 LMCache 的 MP 模式,本次修复范围不涉及该模式;动态连接器本身已转发 shutdown。
  6. 中长期按 LMCache 官方建议,将新部署迁移到 MP 模式。

验证方法

重新启动服务并发送请求后发送 SIGTERM,确认出现 LMCache connector 的 shutdown 日志,EngineCore 完成资源清理并正常退出,不再出现 force killing remaining process EngineCore。讨论中的测试显示,在 MRV2/TP1 本地磁盘配置下,修复前需要超时强杀,修复后适配器清理完成并正常退出。

参考来源

vllm-project/vllm #62808

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 34555

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注