DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

vLLM 崩在 self.graph.replay(),先用 eager 找到出错的 CUDA 操作

CUDA Graph 回放位置未必是底层故障位置。按 vLLM 0.8.5 的诊断接口保留同一输入,用 eager 和短期同步调试取得更清楚的异常,再分别验收两种执行路径。

vLLM 崩溃时,堆栈停在 self.graph.replay()。这一行是回放 CUDA Graph 的位置,不是一个固定异常码,也不足以指认模型中的某个算子。vLLM 0.8.5 排障文档明确建议先关闭图优化,再定位具体 CUDA 操作。

先保存完整堆栈中最早的 CUDA 错误,以及模型 revision、输入长度、dtype、量化配置、GPU 型号和运行包版本。报错后继续使用同一失效进程,可能只得到后续错误;诊断对照应分别从新的进程启动。

保留失败输入,只改变执行路径

对 0.8.5 的在线服务,可以在原启动配置上添加 --enforce-eager。下面仅示意本机单独测试入口;模型路径要换成已下载、与失败服务相同的目录:

vllm serve /srv/models/verified-checkpoint \
  --host 127.0.0.1 --port 8001 --enforce-eager

不要同时向生产服务和测试服务分配同一批已用满的显存。保留原来的模型、精度和并行参数;上面的简化命令不能替代那些项目配置。使用本机独立端口便于对照,不改变原服务的认证或网络入口。

离线调用则在构造 LLM 时设置:

from vllm import LLM, SamplingParams

def main():
    runner = LLM(
        model="/srv/models/verified-checkpoint",
        enforce_eager=True,
    )
    outputs = runner.generate(
        ["Explain a TCP connection briefly."],
        SamplingParams(temperature=0, max_tokens=16),
    )
    print(len(outputs), len(outputs[0].outputs))

if __name__ == "__main__":
    main()

这是需要实际模型和 GPU 资源的待执行示例。先用小输入确认测试入口能运行,再用脱敏后的原失败输入复查。只通过一个短提示词,不能证明触发故障的形状已经修好。

eager 仍报错,再短期同步 CUDA 调用

CUDA 操作可能异步报告错误,普通堆栈因此落在后面的同步点。需要更明确的位置时,可以只为这一次测试进程设置:

CUDA_LAUNCH_BLOCKING=1 python diagnose_eager.py

其中 diagnose_eager.py 是上面的本地脚本。PyTorch 的 CUDA 环境变量说明解释了同步调试开关。它可能降低执行速度,不应把该环境变量写成常规生产配置。

现在根据首个具体错误检查对应的输入形状、索引范围、精度或扩展库兼容性。没有底层异常证据时,不给所有案例套同一条升级命令。

如果 eager 成功、Graph 路径失败,可以将 eager 作为有性能评估的临时运行方案,并保留可定位的故障记录。它没有修复 Graph 路径本身。验收时用原失败样本、代表性长输入及正常批次分别检查;真正恢复 Graph 后,再在没有同步调试变量的新进程里重复这些用例。