GPUStack
Multi-Node vLLM
Tesla V100
Troubleshooting
GPU 클러스터 운영 메모
GPUStack v2.1.1 멀티노드 추론이 시작되지 않는 문제를 모두 해결한 이야기
2노드 4×V100으로 Qwen2.5-32B를 실행하기까지의 전체 기록 #
GPUStack v2.1.1 + vLLM 백엔드로 2대의 GPU 워커(각 Tesla V100-PCIE-32GB × 2장)를 사용한 멀티노드 분산 추론을 시도했을 때 연이어 다양한 문제가 발생했습니다. Ray 클러스터 연결 실패, Gloo 통신 오류, /dev/shm 부족, V100 고유의 CUDA 커널 오류까지, 모든 트러블과 해결 방법을 시간 순서대로 기록합니다.
구성 개요 #
관리 노드(GPU-Server)가 GPUStack Server를 담당하고, 추론은 GPU 워커 2대에 분산됩니다. 모델은 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는 헤드 노드 측 컨테이너 내에서만 동작하고 있으며, 다른 워커 노드의 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이 기본적으로 /etc/hosts에 127.0.1.1 호스트명을 기록합니다. Gloo는 이 항목을 참조하여 자신의 노드 IP를 127.0.1.1(루프백)로 판단하고, 다른 노드에 연결하려고 할 때 거부됩니다.
해결 방법:각 노드의 /etc/hosts에서 127.0.1.1을 실제 IP 주소로 수정합니다.
# GPU-Worker-A에서
sudo sed -i 's/127.0.1.1\s*GPU-Worker-A/ GPU-Worker-A/' /etc/hosts
# 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(compute capability 7.0)용 cuDNN 알고리즘을 지원하지 않는다. VLLM_DISABLE_MULTIMODAL=1 등의 환경 변수로는 회피 불가능. vLLM이 profile_run 시 반드시 Visual Encoder를 초기화하기 때문에 구조적으로 동작하지 않는다.
해결책:모델을 Qwen2.5-32B-Instruct(텍스트 전용)로 전환한다. Visual Encoder가 없기 때문에 이 문제가 발생하지 않는다.
문제 4
채팅 시 /dev/shm 부족으로 Raylet 크래시 발생 #
모델이 시작되고 채팅을 전송하는 순간 엔진이 다운된다.
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은 노드 간 통신에 대량의 shared memory를 사용하므로 추론 시 고갈된다. gpustack-worker 컨테이너에 --shm-size를 지정하지 않았다.
해결책:gpustack-worker 컨테이너를 --shm-size=16g 옵션과 함께 재시작한다.
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
# ↑ apply_penalties (repetition_penalty) 실행 시 발생
WARNING: Default vLLM sampling parameters have been overridden by the model's
generation_config.json: {'repetition_penalty': 1.05, 'temperature': 0.7, ...}원인:Qwen2.5의 generation_config.json에 설정된 repetition_penalty의 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로 안정 가동. VRAM 사용률은 각 GPU 93~96%. max-model-len은 8192 토큰.
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에서 호스트명이127.0.1.1이 아닌 실제 IP로 해석되는지 확인합니다 - gpustack-worker 컨테이너에
--shm-size=16g이상을 지정합니다 - 모델 설정의 Environment Variables에
RAY_CGRAPH_get_timeout=600과RAY_memory_store_capacity=17179869184를 추가합니다 - V100 환경에서는
--generation-config vllm을 Backend Parameters에 추가하여 generation_config.json을 무시합니다 - VLM(Vision Language Model)은 V100에서 동작하지 않습니다. 텍스트 전용 모델을 사용합니다
- V100에서는
--enforce-eager추가를 고려합니다(CUDA Graph 관련 불안정성 회피) - VRAM이 부족할 경우
--gpu-memory-utilization 0.85로 KV 캐시 확보량을 조정합니다
참고 정보 #
본 기사는 실제 환경에서의 트러블슈팅 기록입니다. IP·토큰 등은 추상화되어 있습니다. V100 이외의 GPU 환경에서는 일부 문제가 발생하지 않을 수 있습니다. vLLM 및 GPUStack의 버전 업데이트에 따라 상황이 달라질 수 있습니다.