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-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(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/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--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 /modelsGPUStack 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 版本的更新,情況可能有所變化。