내 로컬 AI가 일주일 동안 CPU로 돌아가고 있다는 사실을 눈치채지 못했다
요약
Ollama를 사용하여 로컬 AI 환경을 구축하던 중, GPU가 아닌 CPU로 모델이 구동되어 성능 저하를 겪은 경험담입니다. VRAM 용량 제한과 컨텍스트 길이 설정이 GPU 메모리 사용량에 미치는 영향, 그리고 GPU 패스스루 설정 시 주의사항을 다룹니다.
핵심 포인트
- 모델 크기와 컨텍스트 길이는 동일한 VRAM 예산을 공유함
- VRAM 초과 시 에러 없이 CPU로 오프로드되어 성능이 급격히 저하됨
- 모델 설정 변경 후에는 반드시 실제 GPU 사용률을 확인해야 함
- Proxmox GPU 패스스루는 단일 VM/컨테이너에만 할당 가능함
나의 첫 Ollama 설정은 빠르게 느껴졌다. 어느 저녁, 하나의 모델, 하나의 질문, 그리고 클라우드 AI가 불필요하게 느껴질 정도의 속도로 스트리밍되는 깔끔한 답변이 돌아왔다.
며칠 후, 더 큰 모델과 더 긴 질문을 던지자 커서가 기어가는 듯 느려졌다. 에러도 없었고, 경고도 없었다. 그저 느려졌을 뿐이며, 그 방식은 모델, 네트워크, 내 질문 등 실제 원인을 제외한 모든 것을 의심하게 만들었다. 하지만 실제 원인은 거의 창피할 정도로 평범했다.
실제로 무슨 일이 일어나고 있었는지, 그리고 그 원인이 된 두 가지 사항에 대해 설명하겠다.
설정 (The setup)
Ollama는 Proxmox에서 자체 서비스로 실행되며, CPU로만 실행되는 대신 GPU가 패스스루(pass through)되어 작동한다. 나에게 로컬 AI의 핵심은 어떤 요청도 집 밖을 나가지 않는다는 점이다. 하지만 사용 가능한 속도가 뒷받침되지 않는다면, 그것은 아무도 일상에서 실제로 사용하지 않는 좋은 원칙일 뿐이다.
그 앞에는 브라우저에서 채팅할 수 있는 웹 UI(web UI)가 있고, 그 뒤에는 나중에 자동화할 작업을 위한 Ollama API가 있다. 접속 방식은 나머지 홈랩(homelab)과 정확히 일치한다. 앞단에는 ID 제공자(identity provider)가 있고, 터널을 통해서만 접속 가능하며, 다른 모든 것과 마찬가지로 잠겨 있다. 단지 "나만의 채팅"이라는 이유로 포트를 열어두지는 않는다.
진짜 작업은 서비스를 구축하는 것이 아니었다. 그것은 올바른 규모를 정하는 것이었다. 즉, 어떤 모델이 내가 가진 GPU에 실제로 맞는지, 어떤 컨텍스트 길이(context length)가 현실적인지, 그리고 Proxmox가 "사용 가능"하다고 보고하는 GPU가 실제로 Ollama가 사용하는 GPU인지 확인하는 과정이었다.
실수 1: 거의 맞을 뻔했던 모델 — 그리고 Ollama는 이에 대해 아무 말도 하지 않았다
VRAM은 유연한 경고가 아니라 엄격한 제한 사항이다. GPU에 완전히 들어가는 모델은 그곳에서 실행되며 빠르게 작동한다. 거의 들어갈 뻔한 모델은 Ollama에 의해 부분적으로 CPU로 오프로드(offloaded)되는데, 이 과정은 에러 없이 조용히 이루어지며 응답 내용에도 이를 알리는 표시가 전혀 없다.
그 점이 바로 위험한 요소다. 이것은 실패처럼 느껴지지 않는다. 그저 "오늘따라 좀 느리네"라고 느껴질 뿐이며, 그 '조금 느리다'는 느낌은 완전히 유휴(idle) 상태로 앉아 있는 그래픽 카드(GPU)를 제외한 모든 곳으로 당신의 시선을 돌리게 만든다.
더 긴 대화를 원해서 num_ctx(최대 컨텍스트 길이, 모델이 한 번에 머릿속에 담을 수 있는 텍스트 양)를 높였을 때 상황은 더 악화되었다. 컨텍스트가 커지면 모델 자체 외에도 추가적인 메모리가 필요한데, 이 추가적인 덩어리가 모델 단독으로는 충분히 들어갈 수 있었음에도 불구하고 전체 시스템을 GPU의 한계치 너머로 밀어붙인 결정적인 원인이 되었다.
교훈: 모델 크기와 컨텍스트 길이는 별개의 예산이 아니라 동일한 VRAM(비디오 램) 예산을 공유한다. 둘 중 하나라도 변경한 후에는 답변이 "괜찮게" 느껴지는지만 확인하지 말고, 실제 GPU 사용률(utilization)을 확인하라.
실수 2: 다른 VM이 이미 GPU를 점유하고 있었고, 아무도 나에게 알려주지 않았다
Proxmox에서의 GPU 패스스루(passthrough)는 멀티 테넌트(multi-tenant) 방식이 아니다. 패스스루된 카드는 정확히 하나의 VM 또는 컨테이너에 속하며, 결코 여러 개에 동시에 속할 수 없다.
나는 이전에 다른 용도로 동일한 카드를 사용하는 두 번째 VM을 잠시 설정했다가, 패스스루 설정을 제거하는 대신 그냥 해당 VM을 종료해 두었었다. 호스트를 재부팅하자, Ollama 컨테이너가 시작되기도 전에 해당 VM이 자동으로 카드를 다시 가져갔다. 그리고 Ollama는 자신의 관점에서 GPU가 아예 존재하지 않는 것으로 판단했기에, 아무런 불만 없이 일반 CPU 추론(inference) 방식으로 전환되었다.
충돌도, 경고도 없었다. 그저 VM 목록을 정리하다가 알아차리기 전까지, 일주일 중 대부분의 시간 동안 서비스가 정상보다 약 10배 느리게 실행되고 있었을 뿐이다.
교훈: GPU 피닝(pinning)은 독점적이며 부팅할 때마다 재협상된다. 호스트를 재시작한 후에는 AI 서비스가 느리다고 탓하기 전에, 어떤 VM이 실제로 카드를 점유하고 있는지 빠르게 확인해 볼 가치가 있다.
요약된 설정
조용히 지나간 CPU 일주일의 경험 없이도, 결과는 동일했다:
- 모델을 불러오기 전(not after)에 VRAM 한계치를 파악하세요. 실제로 사용 가능한 그래픽 메모리(Graphics Memory)가 얼마나 되는지, 그리고 선택한 양자화(Quantization) 수준에서 모델이 얼마나 많은 메모리를 필요로 하는지 확인해야 합니다.
num_ctx를 관대하게 설정하지 말고 의도적으로 설정하세요. 값이 증가할 때마다 모델 자체가 필요로 하는 메모리를 잡아먹습니다.- 변경 사항이 있을 때마다 실제 GPU 사용률(GPU utilization)을 확인하세요. 당신이 느끼는 응답 속도가 아니라, 하드웨어가 보고하는 수치를 확인해야 합니다.
- GPU 패스스루(GPU passthrough)를 정확히 하나의 VM에만 할당하고, 다른 VM에 있는 테스트 설정은 완전히 제거하세요. 단순히 전원을 끄는 것만으로는 부족합니다.
- 호스트를 재부팅할 때마다 어떤 VM이 카드를 점유하고 있는지 다시 확인하세요. AI 서비스 자체에 문제가 있다고 가정하기 전에 말입니다.
- 다른 모든 것과 마찬가지로 액세스 권한을 엄격하게 유지하세요. ID 제공자(Identity Provider)를 앞에 두고 터널(Tunnel)을 통해서만 접속 가능하도록 설정해야 하며,
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기