무색
기술블로그
에세이
연구
소개

무색

소프트웨어로 비즈니스의 가능성을 만듭니다. 웹·앱 개발, 음성 AI, 자동화 콘텐츠 제작까지 — 기술이 필요한 곳에 무색이 있습니다.

연락처

contact@museck.com

사업자 정보

상호: 무색

대표: 배성재

사업자등록번호: 577-58-00836

인천광역시 연수구 인천타워대로 323, 에이동 8층 801-802호 AB-132 (송도동, 송도 센트로드)

© 2026 무색. All rights reserved.
개인정보처리방침·이용약관·연락처
INCHEON, KR
vLLM CUDA 의존성 지옥 — isometric 키 비주얼
🤖 LLM 서버 운영기
2026. 2. 7.

RTX 5090에서 vLLM 돌리기: cu130 의존성 지옥 탈출기

RTX 5090에 vLLM을 올리려고 했더니, CUDA 13.0 wheel은 존재하는데 실제 바이너리는 cu12 패키지에만 있었다. 의존성 관리 도구가 GPU 런타임을 삭제하는 무한루프를 끊기까지의 삽질기.

상황

RTX 5090은 Blackwell 아키텍처다. 이 GPU에서 vLLM을 실행하려면 CUDA 13.0 빌드가 필요하다. 문제는 PyPI 생태계가 아직 cu130을 제대로 지원하지 않는다는 것이다. PyTorch와 vLLM은 별도 인덱스에 cu130 wheel을 올려두긴 했지만, NVIDIA의 Python 런타임 패키지(nvidia-cudnn-cu13 같은 패키지)는 전부 메타 패키지, 즉 빈 껍데기였다. 실제 .so 파일은 cu12 패키지에만 존재한다.

여기에 uv(Python 패키지 매니저)의 의존성 관리까지 겹치면서 상황이 복잡해졌다.

문제 구조

세 가지 레이어가 서로 맞지 않았다.

GPU 드라이버 레벨에서는 CUDA 13.0이 설치되어 있다. PyTorch와 vLLM도 cu130 wheel로 설치된다. 그런데 Python에서 실제로 GPU를 호출할 때 필요한 .so 라이브러리(cuDNN, cuBLAS 등)는 cu12 패키지에만 들어있다. cu13 패키지는 이름만 있고 파일이 없는 메타 패키지다.

uv가 만드는 무한루프

uv는 훌륭한 Python 패키지 매니저지만, 이 상황에서는 오히려 문제를 만들었다. uv sync는 pyproject.toml에 명시되지 않은 패키지를 자동으로 정리한다. 별도로 uv pip install로 설치한 cu12 런타임 패키지가 이 과정에서 삭제된다.

더 나쁜 건 uv add <패키지> 명령이 내부적으로 uv sync를 자동으로 실행한다는 점이다. 새 패키지를 추가할 때마다 cu12 런타임이 날아가고, 다시 설치해야 하는 루프에 빠진다.

해결: 3단계 설치 레시피

pyproject.toml에 cu130 전용 인덱스를 설정한다.

# pyproject.toml
[tool.uv.sources]
torch = { index = "pytorch-cu130" }
vllm = { index = "vllm-cu130" }

[[tool.uv.index]]
name = "pytorch-cu130"
url = "https://download.pytorch.org/whl/cu130"

[[tool.uv.index]]
name = "vllm-cu130"
url = "https://wheels.vllm.ai/cu130"

그리고 설치는 반드시 이 순서를 따른다.

# 1단계: pyproject.toml 기반 설치 (cu130 wheel)
uv sync

# 2단계: cu12 런타임 라이브러리 재설치 (.so 파일 포함)
uv pip install nvidia-cudnn-cu12 nvidia-cusparselt-cu12 \
    nvidia-nvshmem-cu12 nvidia-nccl-cu12 \
    nvidia-cublas-cu12 nvidia-cuda-runtime-cu12

# 3단계: 정상 동작 확인
python -c "import torch; print(torch.cuda.is_available())"

핵심은 uv sync와 uv pip install을 분리하는 것이다. uv sync는 프로젝트 의존성을 관리하고, uv pip install은 시스템 레벨 런타임을 관리한다. 두 레이어를 섞으면 안 된다.

추가 삽질 포인트

  • .venv 디렉토리를 다른 위치로 옮기면 내부 경로가 깨진다. 삭제 후 처음부터 재설치하는 수밖에 없다.
  • 이 프로젝트는 서버 앱이 아니라 "실행 환경"이다. vLLM 서버를 띄우기 위한 Python 환경을 구성하는 게 목적이므로, 디렉토리 구조도 그에 맞게 정리했다.
  • CUDA 13 드라이버가 시스템에 설치되어 있어도 Python 패키지 레벨에서는 cu12 라이브러리가 필요하다. 드라이버 버전과 Python 패키지 버전은 별개의 세계다.

배운 것

최신 GPU에서 ML 프레임워크를 돌리는 건 "설치"가 가장 어려운 부분이라는 걸 다시 한번 확인했다. PyPI, GPU 드라이버, Python 런타임 이 세 가지가 각자 다른 속도로 CUDA 버전을 지원하기 때문에, 과도기에는 항상 이런 갭이 생긴다.

uv는 분명 좋은 도구지만, GPU 의존성처럼 pyproject.toml 바깥에 있는 패키지를 다뤄야 할 때는 한계가 있다. sync가 관리하는 영역과 pip install이 관리하는 영역을 명확히 분리하는 것이 현재로서는 최선의 워크어라운드다.

이런 삽질이 싫다면 Docker 이미지를 쓰는 것도 방법이다. 하지만 5090처럼 아직 공식 Docker 이미지가 없는 GPU에서는 결국 직접 환경을 구성해야 한다.

자주 묻는 질문

RTX 5090에서 vLLM을 실행하려면 CUDA 몇 버전이 필요한가?

CUDA 13.0(cu130) wheel이 필요하다. PyTorch와 vLLM 모두 cu130 전용 인덱스에서 설치해야 하며, 실제 런타임 라이브러리(.so)는 cu12 패키지에서 가져와야 한다.

uv sync를 실행하면 CUDA 런타임이 삭제되는 이유는?

uv sync는 pyproject.toml에 명시되지 않은 패키지를 정리한다. 별도로 pip install한 cu12 런타임 패키지가 이 과정에서 제거된다. 따라서 uv sync 후 매번 cu12 런타임을 재설치하는 3단계 워크플로우가 필요하다.

nvidia-*-cu13 패키지가 메타 패키지라는 게 무슨 뜻인가?

PyPI의 nvidia-cudnn-cu13 같은 패키지는 실제 .so 바이너리 파일이 없는 빈 껍데기다. CUDA 13 드라이버가 설치되어 있어도 Python 레벨에서는 cu12 패키지의 실제 라이브러리 파일이 필요하다.

자주 묻는 질문

RTX 5090에서 vLLM을 실행하려면 CUDA 몇 버전이 필요한가?
CUDA 13.0(cu130) wheel이 필요하다. PyTorch와 vLLM 모두 cu130 전용 인덱스에서 설치해야 하며, 실제 런타임 라이브러리(.so)는 cu12 패키지에서 가져와야 한다.
uv sync를 실행하면 CUDA 런타임이 삭제되는 이유는?
uv sync는 pyproject.toml에 명시되지 않은 패키지를 정리하는데, 별도로 pip install한 cu12 런타임 패키지가 이 과정에서 제거된다. 따라서 uv sync 후 매번 cu12 런타임을 재설치하는 3단계 워크플로우가 필요하다.
nvidia-*-cu13 패키지가 메타 패키지라는 게 무슨 뜻인가?
PyPI의 nvidia-cudnn-cu13 같은 패키지는 실제 .so 바이너리 파일이 없는 빈 껍데기다. CUDA 13 드라이버가 설치되어 있어도 Python 레벨에서는 cu12 패키지의 실제 라이브러리 파일이 필요하다.
🤖 LLM 서버 운영기(1/3)
Next

Mastra + vLLM으로 로컬 LLM Playground 만들기