现场是这样的。K8s 里同一节点反复拉起 7B 的 vLLM 0.6.3 实例,前几轮加载都正常,第六轮开始启动就报 CUDA out of memory,可 nvidia-smi 显示还剩 21GB,分不出连续的大块。gpu_memory_utilization 设的是 0.9,节点上还长期跑着两个小服务。
中间走过弯路,把「vLLM 预分配 KV cache 需要连续显存,碎片下要不到」当成主因,改完现象没变。
原因不止一个,得分开看。进程反复创建销毁,留下没有释放干净的显存块;多个服务共用节点,碎片化后大块分配直接失败;容器退出没等 GPU 资源回收完就被重新调度。
第一件事是判断是显存被占用还是碎片化
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
然后排查残留进程确认有没有僵尸占卡
nvidia-smi --query-compute-apps=pid,used_memory --format=csv
随后把显存比例降到 0.85 并限制并发后再起服务
python -m vllm.entrypoints.openai.api_server --model Qwen2.5-7B-Instruct --gpu-memory-utilization 0.85
给 Pod 加优雅退出并改 GPU 独占调度
kubectl get pod -o jsonpath='{.items[*].status.phase}'
怎么算真的好了,看的是同一批现象。连续扩缩容 10 轮都能正常启动,每轮退出后显存回落到基线值,OOM 不再出现。
显存碎片靠重启只能缓解,根因是进程退出不干净和节点混部;要么独占 GPU,要么给预分配留足余量。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
