RTX 5090 생존 가이드: sm_120, CUDA 12와 13 병행 사용, 그리고 xformers의 함정
요약
RTX 5090(Blackwell 아키텍처) 환경에서 CUDA 툴킷 설정 및 PyTorch 호환성 문제를 해결하는 가이드입니다. sm_120 연산 능력 지원을 위한 특정 CUDA 버전 사용법과 xformers 설치 시 발생하는 의존성 충돌 문제를 다룹니다.
핵심 포인트
- RTX 5090은 sm_120 아키텍처로, cu128 또는 cu130 기반 PyTorch가 필수적임
- 구버전 PyTorch 사용 시 'no-kernel-image' 에러가 발생할 수 있음
- xformers 설치 시 PyTorch 버전이 강제로 다운그레이드되는 의존성 함정 주의
- Blackwell 아키텍처에서는 xformers 대신 SageAttention 사용 권장
이제 이 머신의 모든 것이 정상적으로 작동합니다. 6개의 독립적인 이미지 및 비디오 앱, LoRA 트레이너, ONNX 기반 전사(transcriber) 앱이 모두 Windows 11 환경에서 하나의 RTX 5090을 공유하며, 모두 .bat 파일로 깔끔하게 시작되고 종료됩니다. 이 단계에 도달하기 위해서는 하나의 CUDA 툴킷(toolkit)을 완전히 삭제하고, 유지하려는 툴킷 옆에 두 번째 툴킷을 설치하며, cuDNN 설치 프로그램이 스스로 했어야 할 PATH 수동 수술을 거쳐야 했으며, 설치하는 즉시 나의 torch 빌드를 조용히 다운그레이드해 버린 라이브러리 하나를 해결해야 했습니다.
만약 여러분이 로컬 AI 작업을 위해 막 5090을 구매했다면, 이것이 바로 제가 원했지만 찾을 수 없었던 글입니다. 여기에 담긴 내용은 이론이 아닙니다. 아래의 모든 경로와 버전 번호는 지금 바로 제 책상 위에서 실행되고 있습니다.
모든 것을 결정짓는 단 하나의 사실: sm_120
5090은 Blackwell 아키텍처이며, 연산 능력(compute capability)은 sm_120입니다. 오래된 PyTorch 휠(wheel)에는 이를 위한 커널(kernel)이 포함되어 있지 않습니다. 이전 CUDA 타겟을 위해 빌드된 휠을 설치하면 전형적인 실패를 경험하게 됩니다. torch 임포트(import)는 잘 되고, CUDA는 사용 가능하다고 보고하지만, 첫 번째 실제 커널 실행 시 'no-kernel-image' 에러와 함께 죽어버립니다. 그래픽 카드는 정상입니다. 단지 휠이 여러분의 아키텍처가 존재한다는 사실을 모를 뿐입니다.
규칙: cu128 또는 cu130 기반으로 빌드된 PyTorch를 사용하십시오. 그보다 오래된 버전은 안 됩니다. 제 컴퓨터에서는 앱에 따라 torch 2.11.0+cu130 및 torch 2.10.0+cu130 조합이 정상 작동합니다. 설치할 때 인덱스 URL(index URL)을 명시적으로 입력하고, 설치 후 버전 문자열의 접미사(suffix)를 확인하십시오. "pip show torch" 명령 결과에 +cu128 또는 +cu130 접미사가 없다면, CPU용 휠을 받았거나 오래된 CUDA 빌드를 받은 것이며, 첫 번째 추론(inference) 시점에 고통스럽게 깨닫게 될 것입니다.
다른 무엇보다 이것을 먼저 확인하십시오. 새로운 아키텍처 카드를 사용하는 사람들이 보고하는 미스터리한 충돌(crash)의 절반은, 단지 이 하나의 불일치가 다른 모습으로 나타난 것뿐입니다.
xformers의 함정
이것은 사람들의 오후 시간을 통째로 날려버리게 만드는 주범인데, 그 이유는 실패가 성공의 모습으로 위장하여 나타나기 때문입니다.
ComfyUI나 다른 디퓨전 스택 (diffusion stack)을 실행하고, torch 2.11.0+cu130이 설치되어 정상 작동하며, 이미지 생성이 잘 돌아가고 있다고 가정해 봅시다. 그다음, 지난 3년간의 모든 튜토리얼이 권장하는 방식대로 메모리 효율적 어텐션 (memory-efficient attention)을 위해 xformers를 설치합니다. Pip은 의존성 (dependencies)을 해결하는 과정에서, 현재 설치된 torch가 선택된 xformers 휠 (wheel)과 호환되지 않는다고 판단하고, sm_120 커널이 없는 이전 빌드의 torch로 조용히 교체해 버립니다. 유의미한 경고 메시지도 없이, 대부분의 사람들이 읽지 않는 긴 pip 로그만 남길 뿐입니다. 그리고 다음 실행 시, 불과 한 시간 전까지 잘 작동하던 앱이 첫 번째 샘플링 단계 (sampling step)에서 충돌(crash)을 일으킵니다.
저의 해결책은 이 그래픽 카드에서 xformers를 완전히 사용하지 않는 것이었습니다. SageAttention 2.2.0은 torch 설치 상태를 건드리지 않으면서도 어텐션 최적화 (attention optimization)를 수행하며, Blackwell 아키텍처에서도 잘 작동합니다. 제가 이제 모든 앱에 적용하는 규칙은 다음과 같습니다: 어텐션 관련 패키지를 설치한 후에는 반드시 다시
- "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.2"에 있는 CUDA 13.2가 기본(primary)입니다. CUDA_PATH는 이곳을 가리키며, torch 기반의 모든 요소는 이를 기준으로 해결(resolve)됩니다.
- "...\CUDA\v12.9"에 있는 CUDA 12.9.1은 오직 ONNX Runtime 및 여전히 12.x 런타임(runtime)을 사용하는 다른 요소들에게 버전 접미사가 붙은 CUDA 12 DLL들을 제공하기 위해서만 존재합니다.
두 번째 설치본 내부의 날카로운 주의점(sharp edge) 하나는, 12.9 DLL들이 일부 도구들이 예상하는 위치인 "bin\x64" 하위 폴더가 아니라 "bin"에 직접 위치한다는 점입니다. 앱이 DLL이 누락되었다고 주장할 때, 폴더 구조에 대한 본인의 가정을 믿지 마세요. 폴더를 직접 열어서 확인하십시오. 일반적인 교훈은 다음과 같습니다: CUDA 의존적인 앱을 설치하기 전에, 해당 앱이 실제로 어떤 메이저 버전의 런타임을 로드하는지 확인하십시오. DLL 이름이 이를 알려줍니다. cudart64_12.dll을 찾는 앱은 CUDA 13 툴킷이 아무리 최신이고 멋지더라도 결코 만족하지 못할 것입니다. 그리고 설치된 버전의 개수를 정확히 필요한 만큼만 유지하십시오. 저도 이 컴퓨터에 CUDA 13.1을 잠시 설치한 적이 있었습니다. 세 개의 툴킷은 세 세트의 PATH 항목과 환경 변수(env vars)를 만들어내어 해결 순서(resolution order)를 두고 서로 싸우게 만들었기에, 13.1을 완전히 제거했습니다: 디렉토리, PATH 항목, 환경 변수 모두 말입니다. 역할이 명확한 두 개의 툴킷이 역할이 겹치는 세 개의 툴킷보다 낫습니다.
cuDNN: 설치 프로그램이 작업을 완수하지 않습니다
cuDNN 9.20은 "C:\Program Files\NVIDIA\CUDNN\v9.20"에 설치되며, 친절하게도 CUDA 버전별 DLL 디렉토리를 함께 제공합니다: CUDA 13 측을 위한 "bin\13.2\x64"와 CUDA 12 측을 위한 "bin\12.9\x64"가 그것입니다. 이 구조는 듀얼 툴킷(dual-toolkit) 환경의 머신에 정확히 필요한 형태입니다. 하지만 설치 프로그램이 하지 않는 작업은 두 디렉토리 중 어느 것도 시스템 PATH에 추가하지 않는다는 것입니다. 아무런 경고도 주지 않습니다. cudnn64_9.dll이 필요한 앱들은 단순히 이를 찾지 못해 실패하며, 에러 메시지는 이를 명확하게 말해주는 경우가 드뭅니다. 저는 두 디렉토리를 시스템 PATH에 수동으로 추가했고, 그날로 간헐적으로 발생하던 시작 실패 문제들이 완전히 해결되었습니다. 관련하여 Windows에서 주의할 점 하나는, 시스템 수준의 환경 변화를 적용하려면 관리자 권한이 부여된 셸(elevated shell)이 필요하다는 것입니다.
제가 신뢰하는 패턴은 인라인으로 권한 상승을 시도하는 대신, "Start-Process -Verb RunAs"를 사용하여 호출되는 작은 .ps1 스크립트를 사용하는 것입니다. 인라인으로 권한 상승을 시도하면 조용하면서도 창의적인 방식으로 실패하기 때문입니다. ## 확장 기능 컴파일: MSVC와 CCCL 헤더의 만남 이렇게 최신인 카드에서는 조만간 무언가를 소스에서 직접 컴파일하게 될 것입니다. 왜냐하면 사용자의 정확한 torch 및 CUDA 조합에 맞는 사전 빌드된 휠 (prebuilt wheel)이 아직 존재하지 않기 때문입니다. CUDA 13.2와 MSVC 2019를 사용하는 Windows 환경에서, CCCL 헤더는 표준을 준수하는 전처리기 (preprocessor)를 요구하지만, 기본 MSVC 전처리기는 이를 충족하지 못합니다. 빌드는 템플릿 코드 깊은 곳에서 실패하며, 실제 원인과는 전혀 상관없는 오류들을 나타냅니다. 해결 방법은 두 개의 플래그를 사용하는 것입니다: C++ 컴파일러 인자 (args)에 "/Zc:preprocessor"를 추가하고, 호스트 컴파일러 인자도 전달받을 수 있도록 NVCC 인자에 "-Xcompiler=/Zc:preprocessor"를 추가하는 것입니다. 두 번째 것을 놓치면 빌드가 절반만 성공하게 되는데, 이는 정직하게 실패하는 것보다 더 나쁩니다. ## 앱별 격리, 또는 6개의 앱이 종속성을 공유하지 않고 하나의 카드를 사용하는 방법 이 머신의 모든 GPU 앱은 각자의 환경을 가집니다. 공유된 site-packages도, 글로벌 설치도, 예외도 없습니다. ComfyUI는 Python 3.13.3과 torch 2.11.0+cu130 기반의 venv에서 실행됩니다. 비디오 생성 앱은 Python 3.11.9와 torch 2.10.0+cu130 기반의 conda를 실행합니다. 3D 생성 앱과 학습 도구들도 모두 동일한 방식으로 격리되어 있습니다. 한 앱의 종속성 해결사 (dependency resolver)에 문제가 생기더라도, 그 영향 범위 (blast radius)는 단 하나의 폴더에 국한됩니다. 각 앱은 start, stop, status, update라는 네 개의 bat 파일을 가지고 있습니다. 의도적으로 지루하게 만들었습니다. start 스크립트는 환경의 python.exe를 전체 경로로 가리키며 앱을 자체 포트에 바인딩합니다. 이는 Windows 자동화 스크립트를 작성하는 누구에게나 발목을 잡을 수 있는 conda 함정을 불러옵니다: 이런 방식으로 생성된 conda 환경에는 activate.bat이 포함되어 있지 않습니다. "call activate envname"이라고 말하는 모든 튜토리얼은 이 환경에서 작동하지 않는 스크립트를 작성하게 만듭니다. 해결책은 아예 activate를 하지 않는 것입니다.
"C:\AppName\env\python.exe"를 절대 경로로 호출하면 스크립트, 스케줄러, 그리고 모든 자동화된 환경에서 발생하는 일련의 활성화(activation) 실패 문제가 완전히 사라집니다. 이 .bat 파일들 위에는 현재 약 19개의 관리되는 앱을 대상으로 플릿(fleet)을 시작, 중지 및 상태 점검(health-check)하는 작은 FastAPI 대시보드가 실행 중이며, 두 개의 무거운 작업이 동시에 그래픽 카드를 점유하지 못하도록 뮤텍스(mutex)가 설정되어 있습니다. 하지만 대시보드는 편의를 위한 것일 뿐입니다. .bat 파일들이 실제 계약(contract)이며, 각 파일은 독립적으로 작동합니다. ## 프로세스 위생: 좀비 프로세스는 여전히 VRAM을 점유합니다. 5090은 32GB의 VRAM을 탑재하고 있으며, 이를 낭비하기에는 여전히 부족합니다. 이를 깨닫게 해주는 실패 사례는 다음과 같습니다. 앱을 중단하거나 앱이 충돌했을 때, 프로세스가 제대로 종료되지 않고 할당된 GPU 메모리를 남겨두는 경우입니다. 다음 앱이 실행될 때, 유령 프로세스가 여전히 소유하고 있는 메모리를 점유하려 시도하다가, 카드가 유휴(idle) 상태임에도 불구하고 메모리 부족(out-of-memory) 오류를 내며 쓰러집니다. 다음 두 가지 습관이 이 문제를 영구적으로 해결했습니다:
- GPU 작업을 시작하기 전과 앱을 중단한 후에 항상 "nvidia-smi"를 실행하십시오. VRAM을 점유하고 있는 오래된 python 프로세스들을 다른 것이 실행되기 전에 종료할 수 있습니다.
- 포트(port)가 아닌 실행 파일 경로(executable path)로 좀비 프로세스를 추적하십시오. 충돌한 프로세스는 더 이상 포트에서 대기(listening)하고 있지 않지만, 메모리는 확실히 여전히 점유하고 있습니다. PowerShell에서: "Get-Process python | Where-Object {$_.Path -like 'AppName'} | Stop-Process -Force"를 사용하십시오. 포트 기반 탐지는 정작 종료해야 할 프로세스들을 놓치기 쉽습니다.
비슷한 맥락에서 Windows 환경 특유의 작은 실수 유발 요인(footguns)이 두 가지 더 있습니다. 모듈을 수정한 후에도 오래된 extunderscore extunderscore ext{pycache} extunderscore extunderscore ext{ 디렉토리가 이전 바이트코드(bytecode)를 제공하여, 유령 404 오류를 발생시키거나 이미 삭제한 코드의 동작을 나타낼 수 있습니다. 따라서 수정 사항이 반영되지 않는다면, 자신의 diff를 의심하기 전에 pycache 폴더를 먼저 삭제하십시오. 그리고 포트 바인딩(bind)이 거부될 때는, 포트 번호로 필터링한 "netstat -ano"를 사용하는 것이 어떤 추측보다 빠르게 소유 PID를 찾아냅니다. ## 요약
- PyTorch는 cu128 또는 cu130만 사용하십시오. 단순히 import가 성공하는지만 확인하지 말고, 설치된 버전의 +cu 접미사를 반드시 확인하십시오.
- xformers는 건너뛰십시오. 이는 내부적으로 torch 버전을 다운그레이드할 것입니다.
SageAttention 2.2.0은 Blackwell에서 제 역할을 수행합니다.
- 애플리케이션이 로드하는 DLL 이름을 확인하십시오.
cudart64_12.dll은 CUDA 13 외에 CUDA 12 툴킷(toolkit)이 설치되어 있어야 함을 의미합니다. 접미사(suffix)가 곧 계약 조건입니다. - cuDNN DLL 디렉토리를 직접 PATH에 추가하십시오. 설치 프로그램이 자동으로 해주지 않습니다.
- MSVC 2019 및 CUDA 13.2로 컴파일할 때: 컴파일러에는
/Zc:preprocessor를, NVCC에는-Xcompiler=/Zc:preprocessor를 사용하십시오. - 앱당 하나의 환경을 구성하고, 절대 경로의
python.exe로 호출하십시오. Windows용 Conda에는activate.bat가 없으므로, 이것이 있다고 가정하는 스크립트를 작성하지 마십시오. - 프로세스 목록이 아닌
nvidia-smi를 신뢰하십시오. 좀비 프로세스(Dead processes)가 VRAM을 점유하고 있으며, 실행 파일 경로를 통한 종료만이 유일하고 확실한 정리 방법입니다.
이 모든 것은 일단 알고 나면 어렵지 않습니다. 알기 전까지는 모든 것이 보이지 않을 뿐입니다. 그래픽 카드 자체는 결함이 없었으며, 생태계가 sm_120을 따라잡는 데 몇 달의 시간이 필요했을 뿐입니다. 그 과정을 거쳐 나온 이 시스템은 매일 실제 워크로드(workload)를 완벽하게 수행하고 있습니다. 기본 설정이 완료되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기