[CI Failure]: V1 KV Connectors Shard 2/4 – test_lmcache_connector.py::test_engine_shutdown_stops_lmcache_threads

该报错出现在 vLLM 引擎关闭阶段,`LMCacheConnectorV1.shutdown` 转发到 LMCache 的 `LMCacheManager.stop_services` → `ZMQOffloadServer.close()` 时,libzmq 在第 238 行触发断言并 abor

快速结论:该报错出现在 vLLM 引擎关闭阶段,`LMCacheConnectorV1.shutdown` 转发到 LMCache 的 `LMCacheManager.stop_services` → `ZMQOffloadServer.close()` 时,libzmq 在第 238 行触发断言并 abort 整个进程。优先排查是 LMCache 版本(CI 为 0.5.6,0.5.7 同样存在)以及 close 时 offload server 线程是否仍在 `recv()` 轮询同一 socket。核心报错:[CI Failure]: V1 KV Connectors Shard 2/4 - test_lmcache_connector.py::test_engine_shutdown_stops_lmcache_threads。

适用环境:Issue 已确认的环境为 vLLM main 分支(f7be53ae74、73a1377b6b 等提交)、LMCache 0.5.6(g3e11e108),涉及 NVIDIA H200 与 AMD 的 CI 分片;测试来自 #64324,运行于 pytest。其他 Python、CUDA、PyTorch 或驱动版本未在 Issue 中给出。

最快修复方案:暂无确认的一步修复方案。讨论倾向认为这是 LMCache 自身的 socket 线程安全问题,修复应落在 LMCache 侧(Issue 中给出的仓库为 LMCache/LMCache_inprocess);vLLM 侧“在 shutdown 转发处按 LMCache 版本做门控”只是可优先尝试的解阻塞思路,尚未验证。

注意事项:libzmq 对这个断言会直接 abort 整个进程,因此分片中后续测试都不会执行,容易表现为“整片挂掉”而非单测失败。该问题是竞态,命中率高但非确定性;讨论同时指出,这不只影响 CI 测试,使用固定版本 LMCache 时的正常引擎关闭也可能受影响,但这一点尚未证实。

问题场景

在 vLLM CI 的“V1 KV Connectors Shard 2/4”分片运行 tests/v1/kv_connector/unit/test_lmcache_connector.py::test_engine_shutdown_stops_lmcache_threads 时触发。测试会关闭引擎,关闭路径为 LMCacheConnectorV1.shutdown → LMCacheManager.stop_services → ZMQOffloadServer.close(),此时 pytest 进程以退出码 134 中止。该问题在 main 分支与合并了当前 main 的 fork PR 上均可复现,作者将其标记为 flaky test,本地无法复现,且未认定由 transformers 等外部库引起。

报错原文

[LMCache INFO] Closing ZMQOffloadServer... (zmq_server.py:98)
[LMCache INFO] ZMQ socket closed (zmq_server.py:104)
[LMCache INFO] Waiting for offload server thread to finish... (zmq_server.py:110)
Assertion failed: pfd.revents & POLLIN (src/signaler.cpp:238)
Fatal Python error: Aborted

Current thread at abort: lmcache/v1/offload_server/zmq_server.py:54 process_request
Main thread: lmcache/v1/manager.py:254 _safe_close
  <- vllm_v1_adapter.py:1353 shutdown
  <- lmcache_connector.py:268 shutdown
  <- kv_transfer_state.py:96
  <- gpu_worker.py:1822
  <- core_client.py:444
  <- test_lmcache_connector.py:840

原因分析

最可能的原因(Issue 讨论中的判断):ZMQOffloadServer.close() 在调用方线程中关闭 ZMQ socket,而 server 线程此时仍阻塞在该 socket 的 recv() 上,libzmq 在 src/signaler.cpp:238 命中断言并 abort 进程。ZMQ socket 并非线程安全,这可以解释该断言失败。#64324 似乎是首个在 vLLM shutdown 期间走到这条路径的变更,因此问题在合入后连续出现在多个 H200 运行中。由于这是竞态,命中有随机性:该测试在 #64324 自身 CI 的 H200 上通过,AMD shard 1/4 首次 abort 后重试通过;#64324 的 CI 中也曾在 AMD 分片命中过同一 abort。

环境排查

  • 确认 LMCache 版本:CI 镜像为 0.5.6(g3e11e108),讨论指出 0.5.7 中 zmq_server.py 行为相同。
  • 确认 vLLM 提交:main f7be53ae74、73a1377b6b 均出现失败,说明单纯回退到较新的 main 提交不能规避。
  • 确认是否包含 #64324 引入的 shutdown 转发路径(LMCacheConnectorV1.shutdown)。
  • 确认硬件分片:已确认 H200 分片连续失败,AMD shard 1/4 出现过一次;其他 H200 分片和 AMD 分片在主运行中通过。
  • Issue 中未提供 Python、CUDA、PyTorch、驱动等版本信息,排查时不必假设具体版本号。

解决步骤

  1. 先按失败日志确认进程退出码为 134,且栈顶为 Assertion failed: pfd.revents & POLLIN (src/signaler.cpp:238),同时 abort 线程位于 zmq_server.py 的 process_request。若不符合,不要套用本结论。
  2. 记录当前 LMCache 版本与 vLLM 提交号,对照是否处于上述已确认区间(LMCache 0.5.6/0.5.7,vLLM main 含 #64324 之后的 shutdown 路径)。
  3. 可优先尝试:在 vLLM 侧把 shutdown 向 LMCache 的转发按某个固定 LMCache 版本做门控,以解阻塞 main。这是讨论中的提议,未经验证,合入前需评估对使用该固定版本场景的影响。
  4. 可优先尝试:关注 LMCache 侧的修复(Issue 指向 LMCache/LMCache_inprocess 仓库),在本地验证时改用包含该修复的 LMCache 版本。Issue 未给出具体修复版本号,不要自行假定。
  5. 若只是 CI 被阻塞且上述方案都不可用,可在分片配置中对这一测试单独重试;但需注意该 abort 会杀掉整个分片进程,重试只能降低命中率,不能消除问题。此做法为推测性缓解,非 Issue 已确认方案。

验证方法

在目标分片上反复运行 tests/v1/kv_connector/unit/test_lmcache_connector.py::test_engine_shutdown_stops_lmcache_threads(含引擎关闭路径),确认 pytest 不再以退出码 134 中止、日志中不再出现 signaler.cpp:238 断言,且分片中该测试之后的用例能正常执行。由于该问题是竞态,单次通过不足以证明修复有效,应多轮运行或依赖 CI 多分片结果判断。

参考来源

vllm-project/vllm #67121

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 34867

发表回复

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