GPUStack v2.1.1 徹底解決多節點推論無法啟動的所有問題

GPUStack v2.1.1 徹底解決多節點推論無法啟動的所有問題

5 min read

技術部落格
GPUStack
多節點 vLLM
Tesla V100
疑難排解

GPU 叢集維運筆記

徹底解決 GPUStack v2.1.1 多節點推論無法啟動的所有問題
在 2 節點 4×V100 上運行 Qwen2.5-32B 的完整紀錄 #

在嘗試使用 GPUStack v2.1.1 + vLLM 後端搭配 2 個 GPU Worker(每個各配備 Tesla V100-PCIE-32GB × 2 顆 GPU)進行多節點分散式推論時,我們遭遇了一連串不同的問題。從 Ray 叢集連線失敗、Gloo 通訊錯誤、/dev/shm 不足,到 V100 特有的 CUDA kernel 錯誤——我們依時間順序記錄所有故障與應對方法。

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 顆)
compute capability 7.0

最終結果 #

穩定運作於 16./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(loopback),因而嘗試連線至其他節點時遭到拒絕。

解決方案:在每個節點上,將 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
備註:在本環境中,cloud-init(manage_etc_hosts=True)已自動設定實際 IP,因此不需修正。請直接在 runner 容器的 /etc/hosts 中確認 127.0.1.1 不存在。

問題 3

Qwen3.5-35B-A3B 的視覺編碼器在 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(compute capability 7.0)編譯的 cuDNN 演算法。此問題無法透過 VLLM_DISABLE_MULTIMODAL=1 之類的環境變數繞過。由於 vLLM 在 profile_run 期間必定會初始化視覺編碼器,因此這是結構性的限制。

解決方案:將模型切換為(純文字型的)Qwen2.5-32B-Instruct。由於它沒有視覺編碼器,此問題不會發生。

問題 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 的模型設定中,於環境變數新增以下內容。

RAY_CGRAPH_get_timeout=600
RAY_memory_store_capacity=17179869184

問題 6

generation_config 的 repetition_penalty 核心不支援 V100,輸出陷入迴圈 #

對話時輸出異常文字,出現重複符號(♡♡♡…)不斷迴圈。或推論因 CUDA kernel 錯誤而當機。

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, ...}

原因:在 Qwen2.5 的 repetition_penalty 設定(來自 generation_config.json)所使用的 CUDA kernel 並未針對 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

環境變數:

RAY_CGRAPH_get_timeout=600
RAY_memory_store_capacity=17179869184

運作驗證結果 #

Qwen2.5-32B-Instruct (float16) 在 4×Tesla V100-PCIE-32GB(2 節點配置)上以 16./s 的速度穩定運作。每張 GPU 的 VRAM 使用率為 93–96%。max-model-len 為 。

V100(compute capability 7.0)的特有限制 #

❌ 無法運作 #

  • Flash Attention 2(需要 compute 8.0 以上)→ 退回使用 Triton ATTN
  • bfloat16(→ 自動轉換為 float16)
  • Custom AllReduce(不支援 NVLink P2P)
  • SymmMemCommunicator
  • VLM 的 Conv3D(Qwen3.5-35B-A3B 等)
  • generation_config 的 repetition_penalty 核心

✅ 可正常運作 #

  • Triton ATTN 後端(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 以上
  • 在模型設定的環境變數中新增 RAY_CGRAPH_get_timeout=600 與 RAY_memory_store_capacity=17179869184
  • 在 V100 環境下,於 Backend Parameters 中新增 --generation-config vllm 以忽略 generation_config.json
  • VLM(視覺語言模型)在 V100 上無法運作,請使用純文字模型
  • 建議在 V100 上加入 --enforce-eager(可避免與 CUDA Graph 相關的不穩定情況)
  • 若 VRAM 吃緊,可用 --gpu-memory-utilization 0.85 調整 KV cache 配置

參考資料 #

本文為正式環境中疑難排解的紀錄。IP、Token 等資訊已進行抽象化處理。部分問題可能不會在 V100 以外的 GPU 環境中發生。隨著 vLLM 與 GPUStack 版本的更新,情況可能有所變化。

Updated on 2026年6月9日

What are your feelings

  • Happy
  • Normal
  • Sad

©2020 BESTNET.LLC . All Rights Reserved.