GPUStack
多节点 vLLM
Tesla V100
故障排查
GPU 集群运维备忘录
彻底解决 GPUStack v2.1.1 多节点推理无法启动的问题
在 2 节点 4×V100 上运行 Qwen2.5-32B 的完整记录 #
在使用 GPUStack v2.1.1 + vLLM backend、以 2 台 GPU worker(各配备 Tesla V100-PCIE-32GB × 2 GPU)进行多节点分布式推理时,我们接连遇到了各种不同的问题。从 Ray 集群连接失败、Gloo 通信错误、/dev/shm 不足,到 V100 特有的 CUDA 内核错误——本文按时间顺序记录所有故障与应对方法。
配置概览 #
管理节点(GPU-Server)负责运行 GPUStack Server,推理任务分布在 2 台 GPU worker 上执行。模型存放在 NFS 共享的 /models 中。最初尝试的是 Qwen3.5-35B-A3B(VLM),最终确认 Qwen2.5-32B-Instruct 可以稳定运行。
问题与解决方案完整概览 #
问题 1
Ray Placement Group 无限等待 #
启动模型时,Waiting for creating a placement group 会从 10 秒 → 30 秒 → 150 秒 → 630 秒无限持续下去,模型始终无法启动。
WARNING: Tensor parallel size (4) exceeds available GPUs (2).
INFO: Waiting for creating a placement group of specs for 630 seconds.
specs=[{'node:': 0.001, 'GPU': 1.0}, {'GPU': 1.0}, {'GPU': 1.0}, {'GPU': 1.0}]原因:Ray 仅在 head 节点一侧的容器内运行,另一台 worker 节点的 GPU 无法加入 Ray 集群。
ray status --address=<HEAD_IP>:41000。如果出现 Ray 版本不匹配错误(2.54.0 vs 2.48.0),则可能是 GPUStack 镜像版本不一致所致。
问题 2
由于 /etc/hosts 中存在 127.0.1.1 条目导致 Gloo 通信失败 #
Ray 节点之间可以互相连接,但模型加载完成后,分布式环境初始化(Gloo 的 connectFullMesh)失败。
(RayWorkerWrapper pid=1722) ERROR failed to connect, retry=4, retryLimit=3,
local=[127.0.0.1]:35509, remote=[127.0.1.1]:51638$1,
error=SO_ERROR: Connection refused
RuntimeError: Gloo connectFullMesh failed with timed out connecting:
SO_ERROR: Connection refused, remote=[127.0.1.1]:51638$1原因:Ubuntu/Debian 的 cloud-init 默认会将 127.0.1.1 hostname 写入 /etc/hosts。Gloo 会参照这一条目,将本节点自身的 IP 判定为 127.0.1.1(回环地址),从而尝试连接其他节点并被拒绝。
解决方法:在各节点上,将 127.0.1.1 在 /etc/hosts 中的条目修正为实际 IP 地址。
# On GPU-Worker-A
sudo sed -i 's/127.0.1.1\s*GPU-Worker-A/ GPU-Worker-A/' /etc/hosts
# On GPU-Worker-B
sudo sed -i 's/127.0.1.1\s*GPU-Worker-B/ GPU-Worker-B/' /etc/hosts/etc/hosts 中确认不存在 127.0.1.1。问题 3
Qwen3.5-35B-A3B 的 Visual Encoder 在 V100 上无法工作 #
解决 Gloo 问题后,模型加载成功,但在 profile_run 阶段立即崩溃。
File "vllm/model_executor/layers/conv.py", line 236, in _forward_conv
x = F.conv3d(
^^^^^^^^^
RuntimeError: GET was unable to find an engine to execute this computation原因:Qwen3.5-35B-A3B 是一个 Vision Language Model,其 Visual Encoder 的 Conv3D 缺少针对 V100(计算能力 7.0)编译的 cuDNN 算法。这无法通过 VLLM_DISABLE_MULTIMODAL=1 之类的环境变量来规避。由于 vLLM 在 profile_run 阶段始终会初始化 Visual Encoder,这是一个结构性限制。
解决方法:将模型切换为 Qwen2.5-32B-Instruct(纯文本模型)。由于它没有 Visual Encoder,因此不会出现该问题。
问题 4
对话过程中因 /dev/shm 不足导致引擎崩溃 #
模型可以启动,但一发送对话消息,引擎就会崩溃。
WARNING (raylet) store_runner.cc:83: System memory request exceeds memory available in /dev/shm.
The request is for 10200547328 bytes, and the amount available is 9663676416 bytes.
If you are inside a Docker container, you may need to pass an argument with the flag '--shm-size'
CUDA error: no kernel image is available for execution on the device原因:Docker 默认的 /dev/shm 大小为 64MB。Ray 的 pipeline_parallel 在节点间通信中会大量使用共享内存,推理过程中会将其耗尽。启动 gpustack-worker 容器时未指定 --shm-size。
解决方法:以 --shm-size=16g 重新启动 gpustack-worker 容器。
docker stop gpustack-worker && docker rm gpustack-worker
docker run -d --name gpustack-worker \
--restart=unless-stopped \
--privileged \
--network=host \
--shm-size=16g \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /models:/models \
--volume /var/lib/gpustack-data:/var/lib/gpustack \
--runtime nvidia \
gpustack/gpustack:v2.1.1 \
--server-url http://<SERVER_IP> \
--token <TOKEN> \
--cache-dir /models--shm-size 不会被继承。这是 GPUStack 一侧的问题,需要通过下文所述的环境变量加以补充。问题 5
Runner 容器的 shm 未被继承,RayChannelTimeoutError 持续出现 #
即使重启 gpustack-worker 后,对话过程中引擎依然会崩溃。
ray.exceptions.RayChannelTimeoutError: System error:
If the execution is expected to take a long time,
increase RAY_CGRAPH_get_timeout which is currently 300 seconds.
Otherwise, this may indicate that the execution is hanging.原因:vllm/ray runner 容器每次都是由 GPUStack 重新创建的,因此不会跨容器继承 gpustack-worker 的 --shm-size 设置。runner 容器自身的 shm 仍保持在 64MB。
解决方法:在 GPUStack UI 的模型设置中的 Environment Variables 里添加以下内容。
RAY_CGRAPH_get_timeout=600
RAY_memory_store_capacity=17179869184问题 6
generation_config 的 repetition_penalty 内核与 V100 不兼容,导致循环输出 #
对话会输出异常文本,出现符号(♡♡♡……)循环重复的情况。或者推理会因 CUDA 内核错误而崩溃。
torch.AcceleratorError: CUDA error: no kernel image is available for execution on the device
# ↑ Occurs during apply_penalties (repetition_penalty) execution
WARNING: Default vLLM sampling parameters have been overridden by the model's
generation_config.json: {'repetition_penalty': 1.05, 'temperature': 0.7, ...}原因:用于 repetition_penalty(该设置来自 Qwen2.5 的 generation_config.json)的 CUDA 内核并未针对 V100 编译。
解决方法:在 GPUStack UI 的模型设置 → Backend Parameters 中添加:
--generation-config vllm这会忽略模型的 generation_config.json,转而使用 vLLM 的默认设置。
最终稳定运行配置汇总 #
gpustack-worker 启动命令(两节点通用) #
docker run -d --name gpustack-worker \
--restart=unless-stopped \
--privileged \
--network=host \
--shm-size=16g \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /models:/models \
--volume /var/lib/gpustack-data:/var/lib/gpustack \
--runtime nvidia \
gpustack/gpustack:v2.1.1 \
--server-url http://<SERVER_IP> \
--token <TOKEN> \
--cache-dir /modelsGPUStack UI 模型设置 #
Backend Parameters:
--tensor-parallel-size 2
--pipeline-parallel-size 2
--distributed-executor-backend ray
--max-model-len 8192
--enforce-eager
--generation-config vllmEnvironment Variables:
RAY_CGRAPH_get_timeout=600
RAY_memory_store_capacity=17179869184运行验证结果 #
Qwen2.5-32B-Instruct(float16)在 4×Tesla V100-PCIE-32GB(2 节点配置)上以 16./s 稳定运行。每块 GPU 的显存使用率为 93–96%。max-model-len 为 。
V100(计算能力 7.0)特有的限制 #
❌ 不可用 #
- Flash Attention 2(需要计算能力 8.0 以上)→ 回退为 Triton ATTN
- bfloat16(→ 自动转换为 float16)
- Custom AllReduce(不支持 NVLink P2P)
- SymmMemCommunicator
- VLM Conv3D(Qwen3.5-35B-A3B 等)
- generation_config 的 repetition_penalty 内核
✅ 可用 #
- Triton ATTN backend(Flash Attention 的替代方案)
- NCCL 通信(nccl==2.27.5)
- Ray 分布式执行(pipeline + tensor parallel)
- torch.compile / CUDA Graphs(建议通过 enforce-eager 禁用)
- Qwen2.5 等纯文本模型的推理
故障排查清单 #
- 使用 ray status 确认所有节点的 GPU 均已被识别(在容器内执行)
- 确认各节点
/etc/hosts中的 hostname 解析为实际 IP,而非127.0.1.1 - 为 gpustack-worker 容器指定
--shm-size=16g或更大的值 - 在模型设置的 Environment Variables 中添加
RAY_CGRAPH_get_timeout=600和RAY_memory_store_capacity=17179869184 - 在 V100 环境中,向 Backend Parameters 添加
--generation-config vllm以忽略 generation_config.json - VLM(Vision Language Model)在 V100 上无法使用,请使用纯文本模型
- 在 V100 上可考虑添加
--enforce-eager(避免与 CUDA Graph 相关的不稳定性) - 如果显存紧张,可通过
--gpu-memory-utilization 0.85调整 KV cache 分配
参考资料 #
本文是生产环境中故障排查的记录。IP、token 等信息已做抽象化处理。部分问题可能不会出现在 V100 以外的 GPU 环境中。随着 vLLM 与 GPUStack 版本的更新,情况可能会发生变化。