---
title: GPUStack v2.1.1 彻底解决多节点推理无法启动问题的全过程
description: "技术博客 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 不足，到…"
url: "https://bestnetllc.co.jp/zh-hans/docs/gpustack-v2-1-1-%e5%bd%bb%e5%ba%95%e8%a7%a3%e5%86%b3%e5%a4%9a%e8%8a%82%e7%82%b9%e6%8e%a8%e7%90%86%e6%97%a0%e6%b3%95%e5%90%af%e5%8a%a8%e9%97%ae%e9%a2%98%e7%9a%84%e5%85%a8%e8%bf%87%e7%a8%8b/"
updated: "2026-10-17"
category: Tech Blog / GPU与LLM基础设施
---

# GPUStack v2.1.1 彻底解决多节点推理无法启动问题的全过程

技术博客
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-Worker-A: / Tesla V100×2 | GPU-Worker-B: / Tesla V100×2 | GPU-Server: GPUStack Server | GPUStack v2.1.1 / vLLM 0.17.1 / CUDA 12.9

## 配置概览

管理节点（GPU-Server）负责运行 GPUStack Server，推理任务分布在 2 台 GPU worker 上执行。模型存放在 NFS 共享的 `/models` 中。最初尝试的是 Qwen3.5-35B-A3B（VLM），最终确认 Qwen2.5-32B-Instruct 可以稳定运行。

### 目标模型

Qwen2.5-32B-Instruct (float16)
tensor-parallel×2 / pipeline-parallel×2

### GPU 配置

Tesla V100-PCIE-32GB × 4 GPU
（2 节点 × 2 GPU）
计算能力 7.0

### 最终结果

以 16.46 Tokens/s 稳定运行
max-model-len：8192
已应用变通方案

## 问题与解决方案完整概览

问题 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 集群。

**验证命令：**在 vllm runner 容器内执行 `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.1s*GPU-Worker-A/ GPU-Worker-A/' /etc/hosts

# On GPU-Worker-B
sudo sed -i 's/127.0.1.1s*GPU-Worker-B/ GPU-Worker-B/' /etc/hosts
```

**说明：**在本环境中，cloud-init（manage_etc_hosts=True）已自动设置为实际 IP，因此无需修正。请直接在 runner 容器的 `/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
```

**说明：**GPUStack v2.1.1 的“Mirrored Deployment”功能会将 gpustack-worker 的设置带入 runner 容器，但 `--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 /models
```

### GPUStack UI 模型设置

**Backend Parameters：**

```
--tensor-parallel-size 2
--pipeline-parallel-size 2
--distributed-executor-backend ray
--max-model-len 8192
--enforce-eager
--generation-config vllm
```

**Environment Variables：**

```
RAY_CGRAPH_get_timeout=600
RAY_memory_store_capacity=17179869184
```

### 运行验证结果

Qwen2.5-32B-Instruct（float16）在 4×Tesla V100-PCIE-32GB（2 节点配置）上以 **16.46 Tokens/s** 稳定运行。每块 GPU 的显存使用率为 93–96%。max-model-len 为 8192 tokens。

## 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 分配

## 参考资料

- [GPUStack v2.1 文档](https://docs.gpustack.ai/2.1/)
- [GPUStack GitHub Issues](https://github.com/gpustack/gpustack/issues)
- [vLLM 文档](https://docs.vllm.ai/en/latest/)
- [Ray 文档](https://docs.ray.io/en/latest/)

本文是生产环境中故障排查的记录。IP、token 等信息已做抽象化处理。部分问题可能不会出现在 V100 以外的 GPU 环境中。随着 vLLM 与 GPUStack 版本的更新，情况可能会发生变化。
