多卡部署 Qwen2.5-VL-32B:vLLM 为何卡死,llama.cpp 却跑通了?
故障背景
最近在处理 Qwen2.5-32B-VL-Instruct 模型的部署实战时遇到了一个典型问题。环境是一台配备 4 张 NVIDIA A30(24GB 显存) 的服务器,总显存 96GB,理论上足以承载 FP16 精度的 32B 模型(约 65GB 权重)。
然而,使用业界标杆 vLLM 进行部署时,系统陷入了诡异的'死锁'——显存占满,但推理毫无反应,最终超时报错。尝试切换到 Ollama(底层基于 llama.cpp)后,奇迹发生了:不仅部署成功,而且运行流畅。同样的硬件、同样的模型,为何两个主流框架的表现天差地别?
这背后其实是 PCIe 通信瓶颈、Tensor Parallelism(张量并行) 与 Pipeline Parallelism(流水线并行) 策略差异导致的。
硬件环境与拓扑分析
1. NVIDIA A30 的特性
A30 是一款基于 Ampere 架构的中端推理卡,拥有 24GB HBM2 显存,带宽 933 GB/s。但在多卡互联上有个关键限制:
- NVLink 缺失:虽然 A30 规格书支持 NVLink,但在很多通用服务器或云实例中,并没有物理配置 NVLink Bridge。我的服务器上就没有。
- PCIe 独木桥:当卡与卡之间没有 NVLink 这种'高速私家路'时,所有通信都必须走 PCIe 总线。
实际环境中,显卡连 4 卡 PCIe 都没完全联通,最多只有两卡直连。采用 vLLM 时,如果两卡部署也必须选择 SYS 链接的形式。下面是 nvidia-smi topo -m 的输出情况:
nvidia-smi topo -m
| 缩写 | 含义 | 典型场景 |
|---|---|---|
| X | 自身(Self) | GPU 内部环路 |
| PXB | PCIe x16 桥接(Direct PCIe Bridge) | 同一 PCIe 树下的 GPU 直接互联 |
| SYS | 系统总线(System Bus) | 通过 CPU/主板 南桥间接连接 |
| PIX | PCIe 交换机(PCIe Switch) | 多 GPU 通过 PCIe 交换机互联 |
2. vLLM 加载模型'卡死'复现
在使用 vLLM 尝试拉起 4 卡推理时,部署脚本如下:
#!/bin/bash
echo "###########start vl by vllm...##########"
export GLOO_SOCKET_IFNAME="enp210s0f0" # 多网卡需要指明
export CUDA_VISIBLE_DEVICES="1,2,3,4"
export VLLM_LOGGING_LEVEL="DEBUG"
export VLLM_ATTENTION_BACKEND=
vllm serve /model/Qwen2.5-VL-32B-Instruct \
--gpu-memory-utilization 0.8 \
--dtype auto \
--host 0.0.0.0 \
--port 7860 \
--tensor-parallel-size 2 \
--kv-cache-dtype fp8 \
--max-model-len 10000 \
--limit-mm-per-prompt mage=4,video=1 \
--api-key yourkey


