문제 해결

문제 해결 (Troubleshooting)

vLLM 사용 중 발생하는 흔한 문제를 해결하는 전략을 설명합니다. 모델 다운로드·로딩 hang, OOM, 세대 품질 변화, 로깅 활성화, 브레이크포인트, 네트워크 설정, CUDA/드라이버 문제, Python multiprocessing, torch.compile 등 광범위한 주제를 다룹니다.

출처: 문서

본문

이 문서는 고려할 수 있는 몇 가지 문제 해결 전략을 설명합니다. 버그를 발견했다고 생각하면 먼저 기존 이슈를 검색해 이미 보고됐는지 확인하세요. 아니라면 관련 정보를 최대한 많이 제공해 새 이슈를 등록하세요.

참고

문제를 디버깅한 뒤에는 정의한 디버깅 환경 변수를 끄거나, 새 셸을 시작해 남아 있는 디버깅 설정의 영향을 피하세요. 그렇지 않으면 디버깅 기능이 활성화된 채로 시스템이 느려질 수 있습니다.

모델 다운로드 hang (Hangs downloading a model)

모델이 아직 디스크에 다운로드되지 않았다면 vLLM이 인터넷에서 다운로드하는데, 시간이 걸리고 인터넷 연결에 의존합니다. 먼저 hf CLI로 모델을 다운로드하고 로컬 경로를 vLLM에 전달하는 것을 권장합니다. 이렇게 하면 문제를 격리할 수 있습니다.

디스크에서 모델 로딩 hang (Hangs loading a model from disk)

모델이 크면 디스크에서 로드하는 데 오랜 시간이 걸릴 수 있습니다. 모델을 저장하는 위치에 주의하세요. 일부 클러스터는 노드 간 공유 파일 시스템(분산 파일 시스템이나 네트워크 파일 시스템)이 있어 느릴 수 있습니다. 모델을 로컬 디스크에 저장하는 것이 좋습니다. 또한 모델이 너무 크면 CPU 메모리를 많이 차지해 디스크와 메모리 사이 스왑이 잦아져 운영 체제가 느려질 수 있으니 CPU 메모리 사용량도 살펴보세요.

참고

모델 다운로드·로딩 문제를 격리하려면 --load-format dummy 인자를 사용해 모델 가중치 로딩을 건너뛸 수 있습니다. 이렇게 하면 모델 다운로드·로딩이 병목인지 확인할 수 있습니다.

메모리 부족 (Out of memory)

모델이 단일 GPU에 들어가기엔 너무 커서 OOM(메모리 부족) 오류가 발생합니다. 메모리 소비를 줄이는 이 옵션들을 도입해 보세요.

생성 품질 변화 (Generation quality changed)

v0.8.0에서 기본 샘플링 파라미터의 원천이 Pull Request #12622에서 변경됐습니다. v0.8.0 이전에는 기본 샘플링 파라미터가 vLLM의 중립 기본값 집합에서 왔습니다. v0.8.0부터는 모델 제작자가 제공한 generation_config.json에서 기본 샘플링 파라미터가 옵니다.

대부분의 경우 모델 제작자가 자신의 모델에 가장 적합한 샘플링 파라미터를 알고 있을 가능성이 높으므로 더 높은 품질의 응답으로 이어져야 합니다. 그러나 어떤 경우 모델 제작자가 제공한 기본값이 성능 저하로 이어질 수 있습니다.

이런 일이 발생하는지 확인하려면 온라인에서 --generation-config vllm, 오프라인에서 generation_config="vllm"로 옛 기본값을 시도해 보세요. 시도 후 생성 품질이 개선된다면 vLLM 기본값을 계속 사용하고, 더 나은 품질의 생성을 만드는 기본 generation_config.json으로 업데이트하도록 모델 제작자에게 https://huggingface.co에서 요청하는 것을 권장합니다.

더 많은 로깅 활성화 (Enable more logging)

다른 전략으로 문제를 해결하지 못했다면 vLLM 인스턴스가 어딘가에서 멈춘(stuck) 것일 가능성이 높습니다. 문제 디버깅에 도움이 되는 환경 변수:

  • export VLLM_LOGGING_LEVEL=DEBUG로 더 많은 로깅을 켭니다.
  • export VLLM_LOG_STATS_INTERVAL=1.로 실행 큐·대기 큐·캐시 히트 상태를 추적하기 위해 통계를 더 자주 기록합니다.
  • export CUDA_LAUNCH_BLOCKING=1로 어떤 CUDA 커널이 문제를 일으키는지 식별합니다.
  • export NCCL_DEBUG=TRACE로 NCCL에 더 많은 로깅을 켭니다.
  • export VLLM_TRACE_FUNCTION=1로 어떤 함수가 크래시·hang하는지 로그 파일에서 조사하기 위해 모든 함수 호출을 기록합니다. (경고: 이 플래그는 토큰 생성을 100배 이상 느리게 합니다. 꼭 필요할 때만 사용하세요.)

브레이크포인트 (Breakpoints)

일반 pdb 브레이크포인트는 서브프로세스에서 실행되면 vLLM 코드베이스에서 동작하지 않을 수 있습니다. 다음과 같은 현상을 겪게 됩니다:

  File "/usr/local/uv/cpython-3.12.11-linux-x86_64-gnu/lib/python3.12/bdb.py", line 100, in trace_dispatch
    return self.dispatch_line(frame)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/uv/cpython-3.12.11-linux-x86_64-gnu/lib/python3.12/bdb.py", line 125, in dispatch_line
    if self.quitting: raise BdbQuit
                      ^^^^^^^^^^^^^
bdb.BdbQuit

한 가지 해결책은 forked-pdb를 사용하는 것입니다. pip install fpdb로 설치하고 다음과 같이 브레이크포인트를 설정하세요:

__import__('fpdb').ForkedPdb().set_trace()

또 다른 옵션은 VLLM_ENABLE_V1_MULTIPROCESSING 환경 변수로 멀티프로세싱을 완전히 비활성화하는 것입니다. 이렇게 하면 스케줄러가 같은 프로세스에 유지되어 표준 pdb 브레이크포인트를 사용할 수 있습니다:

import os
os.environ["VLLM_ENABLE_V1_MULTIPROCESSING"] = "0"

잘못된 네트워크 설정 (Incorrect network setup)

복잡한 네트워크 구성이 있으면 vLLM 인스턴스가 올바른 IP 주소를 얻지 못할 수 있습니다. DEBUG 06-10 21:32:17 parallel_state.py:88] world_size=8 rank=0 local_rank=0 distributed_init_method=tcp://xxx.xxx.xxx.xxx:54641 backend=nccl 같은 로그를 찾을 수 있으며, IP 주소는 올바른 것이어야 합니다. 그렇지 않은 경우 환경 변수 export VLLM_HOST_IP=<your_ip_address>로 IP 주소를 재정의하세요.

IP 주소용 네트워크 인터페이스를 지정하려면 export NCCL_SOCKET_IFNAME=<your_network_interface>export GLOO_SOCKET_IFNAME=<your_network_interface>도 설정해야 할 수 있습니다.

self.graph.replay() 근처 오류 (Error near self.graph.replay())

vLLM이 크래시하고 오류 트레이스가 vllm/worker/model_runner.pyself.graph.replay() 근처를 잡는다면 CUDAGraph 안의 CUDA 오류입니다. 오류를 일으키는 특정 CUDA 연산을 식별하려면 명령줄에 --enforce-eager를 추가하거나 LLM 클래스에 enforce_eager=True를 추가해 CUDAGraph 최적화를 비활성화하고, 정확한 CUDA 연산을 격리하세요.

잘못된 하드웨어/드라이버 (Incorrect hardware/driver)

GPU/CPU 통신이 확립되지 않으면 다음 Python 스크립트를 사용하고 아래 지침을 따라 GPU/CPU 통신이 올바르게 동작하는지 확인하세요.

# Test PyTorch NCCL
import torch
import torch.distributed as dist
dist.init_process_group(backend="nccl")
local_rank = dist.get_rank() % torch.accelerator.device_count()
torch.accelerator.set_device_index(local_rank)
data = torch.FloatTensor([1,] * 128).to("cuda")
dist.all_reduce(data, op=dist.ReduceOp.SUM)
torch.accelerator.synchronize()
value = data.mean().item()
world_size = dist.get_world_size()
assert value == world_size, f"Expected {world_size}, got {value}"

print("PyTorch NCCL is successful!")

# Test PyTorch GLOO
gloo_group = dist.new_group(ranks=list(range(world_size)), backend="gloo")
cpu_data = torch.FloatTensor([1,] * 128)
dist.all_reduce(cpu_data, op=dist.ReduceOp.SUM, group=gloo_group)
value = cpu_data.mean().item()
assert value == world_size, f"Expected {world_size}, got {value}"

print("PyTorch GLOO is successful!")

if world_size <= 1:
    exit()

# Test vLLM NCCL, with cuda graph
from vllm.distributed.device_communicators.pynccl import PyNcclCommunicator

pynccl = PyNcclCommunicator(group=gloo_group, device=local_rank)
# pynccl is enabled by default for 0.6.5+,
# but for 0.6.4 and below, we need to enable it manually.
# keep the code for backward compatibility when because people
# prefer to read the latest documentation.
pynccl.disabled = False

s = torch.cuda.Stream()
with torch.cuda.stream(s):
    data.fill_(1)
    out = pynccl.all_reduce(data, stream=s)
    value = out.mean().item()
    assert value == world_size, f"Expected {world_size}, got {value}"

print("vLLM NCCL is successful!")

g = torch.cuda.CUDAGraph()
with torch.cuda.graph(cuda_graph=g, stream=s):
    out = pynccl.all_reduce(data, stream=torch.cuda.current_stream())

data.fill_(1)
g.replay()
torch.cuda.current_stream().synchronize()
value = out.mean().item()
assert value == world_size, f"Expected {world_size}, got {value}"

print("vLLM NCCL with cuda graph is successful!")

dist.destroy_process_group(gloo_group)
dist.destroy_process_group()

단일 노드로 테스트한다면 --nproc-per-node를 사용하려는 GPU 수로 조정하세요:

NCCL_DEBUG=TRACE torchrun --nproc-per-node=<number-of-GPUs> test.py

멀티 노드로 테스트한다면 설정에 따라 --nproc-per-node--nnodes를 조정하고, 모든 노드에서 도달 가능한 마스터 노드의 IP·포트(예: 10.0.0.1:29400)로 MASTER_ADDR를 설정하세요. 그런 다음 실행:

NCCL_DEBUG=TRACE torchrun --nnodes 2 \
    --nproc-per-node=2 \
    --rdzv_backend=static \
    --rdzv_endpoint=$MASTER_ADDR \
    --node-rank $NODE_RANK test.py

MASTER_ADDR를 모든 노드에서 도달 가능한 마스터 노드의 IP·포트(예: 10.0.0.1:29400)로 설정하세요. NODE_RANK는 마스터 노드에서 0, 워커에서 1, 2, ...로 설정하세요. 설정에 따라 --nproc-per-node--nnodes를 조정하세요.

참고

c10d 대신 --rdzv_backend=static을 사용합니다. c10d rendezvous 백엔드는 멀티 노드 설정에서 DNS 해석 오류로 실패할 수 있기 때문입니다(pytorch/pytorch#85300 참고). static 백엔드는 명시적 노드 랭크를 요구해 이를 피합니다.

스크립트가 성공하면 sanity check is successful! 메시지를 볼 수 있어야 합니다.

테스트 스크립트가 hang하거나 크래시하면, 보통 하드웨어/드라이버가 어떤 식으로든 손상된 것입니다. 시스템 관리자나 하드웨어 벤더에 문의해 보세요. 일반적인 해결 방법으로 export NCCL_P2P_DISABLE=1 같은 일부 NCCL 환경 변수를 조정해 볼 수 있습니다. 자세한 내용은 그들의 문서를 확인하세요. 이 환경 변수들은 시스템 성능에 영향을 줄 수 있으므로 임시 해결책으로만 사용하세요. 최선의 해결책은 여전히 하드웨어/드라이버를 고쳐 테스트 스크립트가 성공적으로 실행되게 하는 것입니다.

Python multiprocessing

RuntimeError 예외

로그에서 다음 같은 경고를 본 적이 있다면:

WARNING 12-11 14:50:37 multiproc_worker_utils.py:281] CUDA was previously
    initialized. We must use the `spawn` multiprocessing start method. Setting
    VLLM_WORKER_MULTIPROC_METHOD to 'spawn'. See
    https://docs.vllm.ai/en/latest/usage/troubleshooting.html#python-multiprocessing
    for more information.

또는 다음과 같은 Python 오류:

RuntimeError:
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

        To fix this issue, refer to the "Safe importing of main module"
        section in https://docs.python.org/3/library/multiprocessing.html

그럼 vllm 사용을 if __name__ == '__main__': 블록 뒤로 가드하도록 Python 코드를 업데이트해야 합니다. 예를 들어 이 대신:

import vllm

llm = vllm.LLM(...)

이렇게 시도하세요:

if __name__ == '__main__':
    import vllm

    llm = vllm.LLM(...)

torch.compile 오류 (torch.compile Error)

vLLM은 더 나은 성능을 위해 모델을 최적화하는 데 torch.compile을 크게 의존하며, 이는 torch.compile 기능과 triton 라이브러리에 대한 의존성을 도입합니다. 기본적으로 모델의 일부 함수를 최적화하기 위해 torch.compile을 사용합니다. vLLM을 실행하기 전에 다음 스크립트를 실행해 torch.compile이 예상대로 동작하는지 확인할 수 있습니다:

import torch

@torch.compile
def f(x):
    # a simple function to test torch.compile
    x = x + 1
    x = x * 2
    x = x.sin()
    return x

x = torch.randn(4, 4).cuda()
print(f(x))

torch/_inductor 디렉토리에서 오류를 던지면, 보통 사용 중인 PyTorch 버전과 호환되지 않는 커스텀 triton 라이브러리가 있는 것입니다. 예를 들어 Issue #12219를 참고하세요.

모델 검사 실패 (Model failed to be inspected)

다음 같은 오류가 보이면:

  File "vllm/model_executor/models/registry.py", line xxx, in _raise_for_unsupported
    raise ValueError(
ValueError: Model architectures ['<arch>'] failed to be inspected. Please check the logs for more details.

vLLM이 모델 파일을 import하지 못했다는 뜻입니다. 보통 누락된 의존성이나 vLLM 빌드의 오래된 바이너리와 관련이 있습니다. 오류의 근본 원인을 파악하려면 로그를 주의 깊게 읽으세요.

모델 미지원 (Model not supported)

다음 같은 오류가 보이면:

Traceback (most recent call last):
...
  File "vllm/model_executor/models/registry.py", line xxx, in inspect_model_cls
    for arch in architectures:
TypeError: 'NoneType' object is not iterable

또는:

  File "vllm/model_executor/models/registry.py", line xxx, in _raise_for_unsupported
    raise ValueError(
ValueError: Model architectures ['<arch>'] are not supported for now. Supported architectures: [...]

그런데 모델이 지원 모델 목록에 있다고 확신한다면, vLLM의 모델 해석에 문제가 있을 수 있습니다. 이 경우 이 단계들을 따라 모델의 vLLM 구현을 명시적으로 지정하세요.

디바이스 타입 추론 실패 (Failed to infer device type)

RuntimeError: Failed to infer device type 같은 오류가 보이면 vLLM이 런타임 환경의 디바이스 타입을 추론하는 데 실패한 것입니다. 이 코드에서 vLLM이 디바이스 타입을 어떻게 추론하고 왜 예상대로 동작하지 않는지 확인할 수 있습니다. 이 PR 이후로 VLLM_LOGGING_LEVEL=DEBUG 환경 변수를 설정해 더 상세한 로그를 보고 문제 디버깅을 도울 수도 있습니다.

NCCL 오류: ncclCommInitRank 중 처리되지 않은 시스템 오류

서빙 워크로드가 멀티 노드 분산 서빙에 GPUDirect RDMA를 사용하고 ncclCommInitRank 중 오류가 발생하며, NCCL_DEBUG=INFO를 설정해도 명확한 오류 메시지가 없으면 이런 모양일 수 있습니다:

Error executing method 'init_device'. This might cause deadlock in distributed execution.
Traceback (most recent call last):
...
   File "/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/pynccl.py", line 99, in __init__
     self.comm: ncclComm_t = self.nccl.ncclCommInitRank(
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/pynccl_wrapper.py", line 277, in ncclCommInitRank
     self.NCCL_CHECK(self._funcs["ncclCommInitRank"](ctypes.byref(comm),
   File "/usr/local/lib/python3.12/dist-packages/vllm/distributed/device_communicators/pynccl_wrapper.py", line 256, in NCCL_CHECK
     raise RuntimeError(f"NCCL error: {error_str}")
 RuntimeError: NCCL error: unhandled system error (run with NCCL_DEBUG=INFO for details)
...

이것은 vLLM이 NCCL communicator를 초기화하지 못했음을 나타내며, IPC_LOCK 리눅스 캐퍼빌리티가 없거나 /dev/shm이 마운트되지 않았기 때문일 수 있습니다. GPUDirect RDMA용 환경을 올바르게 구성하는 지침은 Enabling GPUDirect RDMA를 참고하세요.

CUDA 오류: 제공된 PTX가 지원되지 않는 툴체인으로 컴파일됨

RuntimeError: CUDA error: the provided PTX was compiled with an unsupported toolchain 같은 오류가 보이면 vLLM wheel의 CUDA PTX가 시스템이 지원하지 않는 툴체인으로 컴파일됐다는 뜻입니다. RuntimeError: The NVIDIA driver on your system is too old 오류가 나도 이 섹션이 적용됩니다.

릴리스된 vLLM wheel은 특정 버전의 CUDA toolkit으로 컴파일되고, 컴파일된 코드는 더 낮은 버전의 CUDA 드라이버에서 실행에 실패할 수 있습니다. 자세한 내용은 CUDA compatibility를 읽어보세요. 이것은 선택된 전문가용·데이터센터 NVIDIA GPU에서만 지원됩니다.

vLLM 공식 Docker 이미지를 사용한다면 docker run 명령에 -e VLLM_ENABLE_CUDA_COMPATIBILITY=1을 추가해 해결할 수 있습니다. 이러면 사전 설치된 CUDA forward compatibility 라이브러리가 활성화됩니다.

Docker 밖에서 vLLM을 실행한다면 패키지 관리자에서 CUDA repository를 활성화한 상태로 cuda-compat 패키지를 설치하는 것이 해결책입니다. 예를 들어 Ubuntu에서 sudo apt-get install cuda-compat-12-9를 실행한 뒤 export VLLM_ENABLE_CUDA_COMPATIBILITY=1export VLLM_CUDA_COMPATIBILITY_PATH="/usr/local/cuda-12.9/compat"를 설정하세요.

Conda에서는 conda-forge::cuda-compat 패키지를 설치하고(예: conda install -c conda-forge cuda-compat=12.9), 환경 활성화 후 export VLLM_ENABLE_CUDA_COMPATIBILITY=1export VLLM_CUDA_COMPATIBILITY_PATH="${CONDA_PREFIX}/cuda-compat"를 설정할 수 있습니다.

vLLM을 통해 CUDA를 초기화하는 최소 Python 스크립트를 실행해 구성이 동작하는지 검증할 수 있습니다:

export VLLM_ENABLE_CUDA_COMPATIBILITY=1
export VLLM_CUDA_COMPATIBILITY_PATH="/usr/local/cuda-12.9/compat"

python3 - << 'EOF'
import vllm
import torch

print(f"CUDA available: {torch.cuda.is_available()}")
print(f"CUDA device count: {torch.accelerator.device_count()}")
EOF

여기서 예시로 CUDA 12.9를 사용한다는 점에 주의하세요. vLLM의 기본 CUDA 버전이 더 높아지는 경우 더 높은 버전의 cuda-compat 패키지를 설치하고 싶을 수 있습니다.

ptxas fatal: 옵션 'gpu-name'에 값 'sm_110a'가 정의되지 않음

cuda 13으로 triton 커널을 사용한다면 ptxas fatal: Value 'sm_110a' is not defined for option 'gpu-name' 같은 오류를 볼 수 있습니다:

(EngineCore_0 pid=9492) triton.runtime.errors.PTXASError: PTXAS error: Internal Triton PTX codegen error
(EngineCore_0 pid=9492) `ptxas` stderr:
(EngineCore_0 pid=9492) ptxas fatal   : Value 'sm_110a' is not defined for option 'gpu-name'
(EngineCore_0 pid=9492) 
(EngineCore_0 pid=9492) Repro command: /home/jetson/.venv/lib/python3.12/site-packages/triton/backends/nvidia/bin/ptxas -lineinfo -v --gpu-name=sm_110a /tmp/tmp95oy_b9d.ptx -o /tmp/tmp95oy_b9d.ptx.o
(EngineCore_0 pid=9492) 
    outputs = self.engine_core.get_output()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jetson/.venv/lib/python3.12/site-packages/vllm/v1/engine/core_client.py", line 668, in get_output
    raise self._format_exception(outputs) from None
vllm.v1.engine.exceptions.EngineDeadError: EngineCore encountered an issue. See stack trace (above) for the root cause.

triton 번들의 ptxas가 디바이스와 호환되지 않는다는 뜻입니다. cuda toolkit의 ptxas를 수동으로 사용하도록 TRITON_PTXAS_PATH 환경 변수를 설정해야 합니다:

export CUDA_HOME=/usr/local/cuda
export TRITON_PTXAS_PATH="${CUDA_HOME}/bin/ptxas"
export PATH="${CUDA_HOME}/bin:$PATH"

알려진 이슈 (Known Issues)

  • v0.5.2, v0.5.3, v0.5.3.post1에서 zmq로 인한 버그가 있는데, 머신 구성에 따라 때때로 vLLM hang을 일으킬 수 있습니다. 해결책은 수정이 포함된 최신 버전의 vllm으로 업그레이드하는 것입니다.
  • 더 오래된 NCCL 버전의 메모리 오버헤드 문제(bug 참고)를 해결하기 위해 vLLM 버전 >= 0.4.3, <= 0.10.1.1은 환경 변수 NCCL_CUMEM_ENABLE=0을 설정했습니다. vLLM에 연결하는 외부 프로세스도 hang·크래시를 막기 위해 이 변수를 설정해야 했습니다. NCCL 2.22.3에서 하부 NCCL 버그가 수정됐으므로, 이 재정의는 NCCL 성능 최적화를 허용하기 위해 더 새로운 vLLM 버전에서 제거됐습니다.

더 알아보기 (Learn more)