VRAM 계산 실전: 모델 규모 × 양자화에서 VRAM 요구량 정확히 산정하기
VRAM 계산 실전
이전 글은 "VRAM으로 카드를 고르는 법"을 다뤘습니다. 이 글은 그 수학을 엽니다. 왜 같은 모델이 컨텍스트 길이에 따라 수 GB를 더 요구할까요? "27B가 안 돌아간다"는 게 가중치 문제일까요 KV cache 문제일까요? GPU 오프로드 레이어 수는 어떻게 정할까요? 공식과 측정법을 알면 구매 전에 정확히 추정하고 배포 후에 정밀하게 조정할 수 있습니다.
30초 요약
VRAM = 가중치 + KV cache + 런타임 오버헤드. 가중치 = 파라미터 수 × 등급별 바이트 계수(Q4_K_M은 약 0.6 바이트/파라미터). KV cache는 컨텍스트에 선형 증가하며 긴 컨텍스트에서는 가중치의 절반을 넘기도 합니다. 실행 후 nvidia-smi와 llama.cpp 시작 로그로 보정 — 공식보다 실측이 정확합니다.
공식 1: 가중치 크기
가중치 크기 = 파라미터 수 × 파라미터당 바이트 수. 등급별 경험적 계수:
| 등급 | 바이트/파라미터 | 7B | 27B | 70B |
|---|---|---|---|---|
| Q8_0 | 1.05 | 7.4GB | 28GB | 74GB |
| Q6_K | 0.85 | 6.0GB | 23GB | 60GB |
| Q5_K_M | 0.72 | 5.0GB | 19GB | 50GB |
| Q4_K_M | 0.60 | 4.2GB | 16GB | 42GB |
| Q3_K_M | 0.48 | 3.4GB | 13GB | 34GB |
| Q2_K | 0.35 | 2.5GB | 9.5GB | 25GB |
왜 '약'인가
모델마다 임베딩/출력 레이어 크기가 달라 같은 파라미터 수에서도 실제 GGUF 파일 크기가 5-10% 다릅니다. 카드 구매 전 모델 카드의 실제 파일 크기로 확인하는 것이 계수를 맹목적으로 적용하는 것보다 안전합니다.
공식 2: KV cache
KV cache는 과거 토큰의 K/V 행렬을 저장하며, 긴 컨텍스트 배포의 숨은 큰 항목입니다. 요청 1건당 추정:
KV cache ≈ 2(K와 V) × 레이어 수 × KV 헤드 차원 합 × 컨텍스트 길이 × 2바이트(fp16)
정확한 공식보다 두 법칙이 중요합니다.
- 컨텍스트 길이에 선형 증가 — 8K→32K에서 약 4배
- 배치 크기에 비례 — 동시 4요청이면 약 4배
실무 참고값(fp16, 단일 요청):
| 모델 규모 | 8K 컨텍스트 | 32K 컨텍스트 |
|---|---|---|
| 7B급 | ~0.5-1GB | ~2-4GB |
| 27B급 | ~1-2GB | ~4-8GB |
| 70B급 | ~2-4GB | ~8-16GB |
긴 컨텍스트에서 KV cache가 가중치의 절반을 넘는다
27B 모델 Q4 가중치가 약 16GB인데 32K 컨텍스트 KV cache는 4-8GB에 달할 수 있습니다. VRAM의 1/4~1/2가 "히스토리 기억"에 쓰이는 셈입니다. 긴 컨텍스트 배포는 KV cache를 별도 항목으로 계산하세요.
공식 3: 런타임 오버헤드
CUDA 컨텍스트(약 0.3-0.5GB), 추론 엔진 캐시, 단편화 — 보통 추가 1-2GB. 멀티 GPU라면 카드마다 독립 오버헤드가 있습니다.
완전 계산 예시
케이스 1: Qwen3.8-27B, Q4_K_M, 8K 컨텍스트, 단일 사용자
- 가중치 16GB + KV cache 약 1.5GB + 오버헤드 2GB ≈ 19.5GB → 24GB 카드 가능
케이스 2: 동일, 32K 컨텍스트
- 가중치 16GB + KV cache 약 6GB + 오버헤드 2GB ≈ 24GB → 24GB 카드는 경계선, 32GB 또는 등급 하향 권장
케이스 3: Hunyuan 4B(hy4), Q4_K_M, 8K 컨텍스트
- 가중치 약 2.5GB + KV cache 약 0.5GB + 오버헤드 2GB ≈ 5GB → 8GB 카드 여유
MoE 모델의 계산법
35B-A3B 같은 MoE: 가중치는 총 35B 파라미터로 계산(Q4 약 21GB), KV cache는 실제 아키텍처의 레이어/KV 헤드로, 속도는 활성 3B로 체감합니다. 즉 MoE의 VRAM 수요는 35B dense 모델에 가깝고 속도는 3B 모델에 가깝습니다 — 로컬 배포에 적합한 이유입니다.
GPU 오프로드 레이어 설정
llama.cpp의 -ngl(n_gpu_layers)이 VRAM에 둘 레이어와 RAM에 남길 레이어를 결정합니다:
- 전체 시도:
-ngl을 총 레이어 수로 설정(시작 로그에 표시), OOM 확인 - OOM이면 감소: 4-8 레이어씩 줄여 로드될 때까지
- 속도 트레이드오프: RAM에 남는 레이어가 많을수록 생성 속도 저하 — 같은 프롬프트로 token/s 측정
오프로드는 공짜가 아니다
일부 레이어가 RAM에 남으면 토큰마다 PCIe로 데이터를 옮겨야 해 속도가 몇 분의 1로 떨어질 수 있습니다. 절반 이상 레이어를 오프로드해야 한다면 더 작은 모델이나 낮은 양자화 등급으로 바꾸는 편이 훨씬 낫습니다.
실측 보정
공식은 "구매 전 추정", 실측은 "배포 후 조정"용:
VRAM 사용량: 다른 터미널에서 nvidia-smi로 추론 중 피크 사용량 관찰
KV cache 할당: llama.cpp 시작 로그에 실제 할당량 출력(llama_kv_cache: ... MiB 같은 형식) — 계수 보정에 사용
단편화: 피크가 공식보다 2GB+ 높으면 -c(컨텍스트)나 배치 파라미터가 과하지 않은지 확인
# llama-server 시작 시 로그에서 KV cache 할당 관찰
./llama-server \
-m ./models/Qwen3.8-27B-Q4_K_M.gguf \
-ngl 40 -c 8192 \
--host 127.0.0.1 --port 8080
FAQ
실제 VRAM 사용량이 공식보다 높은 이유는?
KV cache를 압축할 수 있나요?
27B는 Q4_K_M과 Q3_K_M 중 무엇?
-ngl 값은 얼마로?
MoE 모델 VRAM은?
공식 결과가 카드 용량과 딱 맞으면 돌아가나요?
관련 글
- 로컬 LLM용 GPU 선택 가이드 — VRAM으로 카드 고르기
- 로컬 배포 완전 플레이북 — 하드웨어 점검부터 통합까지
- 로컬 계산 비용 모델 — 구매 vs 대여 vs API
- Qwen GGUF 로컬 배포 입문 — 배포 기초
- Qwen KV cache와 긴 컨텍스트 — KV cache 원리