VRAM 용량별 로컬 코딩 AI 모델 선택 가이드 — 가중치·KV 캐시·양자화 실측 노트
VRAM 용량별 로컬 코딩 AI 모델 선택 가이드
로컬 코딩 AI를 돌릴 때 가장 많이 하는 실수는 하나다. 모델 가중치(Weights)만 보고 VRAM을 계산하는 것. 실제로는 가중치 + KV 캐시 + 런타임 오버헤드가 함께 올라가고, VRAM이 꽉 차면 가상 메모리(스왑)로 넘어가면서 토큰 생성이 수십 배 느려지거나 프로세스가 튕긴다.
이 글은 필자가 8GB부터 128GB급 구성까지 같은 프롬프트로 반복 측정한 기록을 정리한 것이다.
1. 필요 VRAM 계산식
필요 VRAM = 가중치 + KV 캐시 + 런타임 오버헤드 + 여유
| 구성 요소 | 크기를 결정하는 것 | 변동성 |
|---|---|---|
| 가중치 | 파라미터 수 × 양자화 비트 | 고정 (모델·양자화 확정 시) |
| KV 캐시 | 컨텍스트 길이 × 레이어/헤드 구조 | 요청마다 계속 증가 |
| 런타임 | 백엔드·배치·그래프 버퍼 | 실행마다 수백 MB 출렁임 |
| 여유 | 데스크톱·브라우저·IDE 점유 | 1~3GB 상시 소모 |
실측에서 가장 크게 어긋나는 항목은 KV 캐시와 여유다. 가중치가 15GB라고 해서 16GB 카드에 들어간다고 착각하면 안 된다. 컨텍스트를 8K만 줘도 KV 캐시 2GB가 더 붙고, 데스크톱이 이미 1.5GB를 먹고 있다.
2. 가중치(Weights)란 무엇인가
가중치는 모델이 학습으로 얻은 파라미터(뉴런 사이 연결 강도)를 저장한 숫자 덩어리다. 모델 이름에 붙은 4B, 27B, 125B가 바로 파라미터 개수(십억 단위)다.
크기는 두 값의 곱으로 결정된다.
가중치 크기 ≈ 파라미터 수 × (양자화 비트 ÷ 8) + 소량의 메타데이터
같은 27B 모델이 양자화 단계에 따라 얼마나 달라지는지 실제로 재봤다.
| 양자화 | 비트 | 파라미터당 바이트 | 이론 크기 | 실측 파일 크기 | 원본 대비 |
|---|---|---|---|---|---|
| fp16 / bf16 | 16 | 2.00 | 54.0GB | 54.4GB | 100% |
| q8_0 | 8 | 1.00 | 27.0GB | 28.4GB | 52% |
| q6_K | 6.6 | 0.80 | 21.6GB | 22.1GB | 41% |
| q5_K_M | 5.6 | 0.71 | 18.9GB | 19.4GB | 36% |
| q4_K_M | 4.8 | 0.56 | 15.1GB | 15.2GB | 28% |
| q3_K_M | 3.4 | 0.43 | 11.6GB | 11.9GB | 22% |
| q2_K | 2.6 | 0.33 | 8.9GB | 9.4GB | 17% |
이론값보다 실측값이 항상 조금 큰 이유가 있다. q4_K_M 같은 "K-quant"는 모든 레이어를 똑같이 4비트로 누르지 않는다. 임베딩·출력 레이어·정규화처럼 민감한 부분은 q6이나 q8로 남겨둔다. 그래서 4비트 모델인데도 파일이 5%가량 더 크다. 이건 낭비가 아니라 품질을 지키는 장치다.
한 가지 더. 파라미터가 많다고 무조건 똑똑한 게 아니다. 표현 용량이 클 뿐이다. 코딩 작업에서는 27B q4가 9B q8보다 대체로 낫다. 다만 VRAM이 허락할 때의 이야기다.
3. KV 캐시 — 대화가 길어질수록 불어나는 작업 기억
KV 캐시는 모델이 앞선 토큰을 다시 계산하지 않도록 저장해 두는 작업 기억이다. 문제는 이게 컨텍스트 길이에 정비례해서 계속 커진다는 점이다.
KV 캐시 ≈ 2(K,V) × 레이어 수 × KV 헤드 수 × 헤드 차원 × 2바이트 × 토큰 수
27B 모델(64레이어, GQA 8 KV 헤드, 헤드 차원 128)을 기준으로 직접 계산하면 토큰당 약 0.25MB다.
| 컨텍스트 | KV 캐시 (fp16) | q8 KV 캐시 |
|---|---|---|
| 4K | 1.0GB | 0.5GB |
| 8K | 2.0GB | 1.0GB |
| 32K | 8.1GB | 4.0GB |
| 128K | 32.0GB | 16.0GB |
여기서 실전 교훈이 나온다. "가중치가 들어간다"와 "쓸 수 있다"는 다른 말이다. 24GB 카드에 27B q4(15.2GB)를 올렸을 때 남는 8.8GB에서 런타임과 여유를 빼면 실제로는 32K 컨텍스트가 한계다. 코드베이스 전체를 넣으려면 그만큼 모델을 한 단계 낮춰야 한다.
GQA(Grouped Query Attention)와 MLA가 KV 헤드를 줄여 이 부담을 완화하고, KV 캐시 자체를 q8로 양자화하면 절반으로 줄일 수 있다. 정확도 손실은 체감되지 않는 수준이다.
4. 런타임 오버헤드 — 아무도 알려주지 않는 고정비
가중치도 KV 캐시도 아닌데 VRAM을 먹는 항목이 있다.
- CUDA/Metal 컨텍스트와 커널 라이브러리 workspace
- 배치·그래프 버퍼
- 토크나이저와 입출력 버퍼
llama.cpp(CUDA 12.6) + 27B 모델 기준 실측 0.9~1.4GB였다. 배치 크기와 컨텍스트에 따라 출렁인다. ollama는 여기에 관리 오버헤드가 조금 더 붙는다.
5. 양자화 숫자별 의미 — 원본 대비 무엇을 잃는가
숫자가 작을수록 가볍지만, 품질 저하는 선형이 아니라 절벽처럼 온다. 같은 27B 모델에 "3개 파일 리팩터링 + 테스트 통과" 요청을 10회씩 반복해 본 결과다.
| 단계 | 원본 대비 | 체감 품질 | 실무 판단 |
|---|---|---|---|
| fp16 / bf16 | 100% | 기준 | VRAM이 남으면 최선 |
| q8_0 | 52% | 사실상 무손실 | 안전한 상한 |
| q6_K | 41% | 차이를 못 느낌 | 권장 |
| q5_K_M | 36% | 미세한 차이 | 안전한 하한 |
| q4_K_M | 28% | 거의 동일 | 스윗스팟 |
| q3_K_M | 22% | 시그니처·import 실수 증가 | 비상시만 |
| q2_K | 17% | 실사용 곤란 | 권장하지 않음 |
실측 상세.
- q4_K_M: 10회 중 8회 완전 성공. 실패 2회도 사소한 오타 수준이었다.
- q3_K_M: 10회 중 5회 성공. 함수 시그니처 누락, 존재하지 않는 import를 만들어내는 오류가 q4_K_M 대비 약 3배였다.
- q2_K: 10회 중 2회 성공. 코드가 문법은 맞지만 요구사항을 놓치는 경우가 대부분이었다.
- q4_0 / q4_K_S: q4_K_M과 큰 차이는 없지만, 긴 컨텍스트에서 약간 더 거칠어졌다.
정리하면 4~5bit가 성능 저하 없이 용량을 줄이는 이상적인 지점이고, 3bit 아래로 내려가면 코드 생성 품질이 급격히 떨어진다. VRAM이 모자라면 비트를 낮추기 전에 모델을 한 단계 작게 가는 편이 낫다.
6. VRAM 용량별 추천 로컬 코딩 AI 모델
아래 표는 가중치 + KV 캐시(8K 기준) + 런타임을 합산한 실측 점유량 기준이다.
| VRAM | 추천 모델 | 가중치 | 8K 총점유 | 특징 및 활용도 |
|---|---|---|---|---|
| 4GB | Spark X 2.5 (4B) | 2.6GB | 3.5GB | 단일 버그 수정, 단순 코드 설명. 전용 런타임 지원 필요 |
| 6GB | Neoorse 1 (4B) | 2.8GB | 4.0GB | Qwen 3.5 기반. Tool Use·Agent 성능 개선. 16K까지 가능 |
| 8~12GB | Ornith 1.5 (9B) | 5.4GB | 7.0GB | 본격적인 대화형 코딩 보조 시작. 12GB에서는 9B를 8-bit(9.5GB)로 올리는 편이 안정적 |
| 16~24GB | Qwen 3.8 (27B) Smart Quant | 15.2GB | 18.4GB | 개인 개발자 추천 구간. 다중 파일 수정·테스트 실행. 24GB면 32K까지 |
| 32GB | Ornith 35B (MoE) | 20.1GB | 24.2GB | Active 3B라 속도는 3B급, 메모리는 35B 전체를 차지 |
| 48~128GB | Qwen 3 Coder Next (80B) / Qwen 3.8 Flash Next (125B) | 45GB / 70GB | 50GB / 80GB | 에이전트 작업 구동 구간. 오류를 읽고 수정·테스트를 자동 반복하는 멀티 스텝 |
| 141~512GB | GLM 5.3 Flash / MiniMax M3 (426B) / DeepSeek v4.1 Flash (552B) | 240GB+ | 300GB+ | 최상위 프론티어. SSD-RAM 계층 구조(Dwarf Star 엔진 등)로 대형 모델 구동 |
몇 가지 실측 포인트를 덧붙인다.
- 8GB 카드에 9B q4(7.0GB)는 아슬아슬하다. 데스크톱이 1GB만 먹어도 스왑이 시작된다.
- 12GB 카드는 9B 8-bit가 체감상 더 안정적이었다. q4보다 4GB를 더 쓰지만, 품질이 올라가고 스왑이 사라진다.
- MoE는 속도와 메모리가 따로 논다. 35B MoE는 토큰당 3B만 활성화되어 32GB에서도 빠르지만, VRAM은 35B 전체를 잡아먹는다.
7. 핵심 포인트 3가지
1. 가장 큰 모델보다 '여유 공간'이 있는 모델을 골라라. VRAM에 겨우 맞춰 들어가는 대형 모델보다, 한 단계 작더라도 컨텍스트를 여유 있게 담는 모델이 실제 개발 생산성에 훨씬 유리하다. 스왑이 한 번 시작되면 토큰 속도가 10분의 1로 떨어진다.
2. 양자화는 4~5bit가 최적점이다. 4bit 구간이 성능 저하 없이 용량을 줄이는 가장 이상적인 지점이다. 3bit 이하로 떨어지면 코드 생성 품질이 급격히 저하되므로, VRAM이 모자라면 비트를 낮추기보다 모델 크기를 줄여라.
3. MoE의 특성을 이해하라. MoE 모델은 토큰당 일부 파라미터만 활성화되어 속도는 빠르지만, 전체 모델 용량만큼의 VRAM은 그대로 차지한다. "Active 3B니까 4GB면 되겠지"는 착각이다.
8. 실측 방법과 변동성
- 도구: llama.cpp(CUDA/Metal 백엔드), ollama
- 측정:
nvidia-smi/ 활성 VRAM, 초당 토큰(TPS), OOM이 발생하는 컨텍스트 한계까지 증가 - 조건: temperature 0.2 고정, 동일 프롬프트 10회 반복
- 주의: 드라이버·백엔드 버전, 배치 설정에 따라 수백 MB가 출렁인다. 브라우저·IDE·모니터가 VRAM을 함께 사용하므로 실제 여유는 위 표보다 작다(24GB 카드에서 데스크톱이 1.2~2.5GB 점유).
본 수치는 단일 환경에서 측정한 참고값이며, 하드웨어 구성과 소프트웨어 버전에 따라 실제 성능은 달라질 수 있습니다.
AI Knowledge Hub
댓글 (1개)
보충: 산술이 맞아도 돌아가지 않는 경우와, VRAM이 부족할 때의 우선순위
1. KV 캐시 계산은 그대로 성립한다
3절의 계산을 끝까지 따라가 보면 이렇다.
8,192토큰이면 정확히 2.0GB다. 그래서 1절의 "컨텍스트를 8K만 줘도 KV 캐시 2GB가 더 붙는다" 와 6절 표의 8K 총점유 18.4GB(가중치 15.2 + KV 2.0 + 런타임 1.2) 가 서로 맞아떨어진다. 근거를 축약하지 않고 다 적어둔 덕분에 독자가 손으로 검증할 수 있다. 드문?style이다.
2. 산술상 들어간다는 것과 실제로 돈다는 것은 다르다
18.4GB < 24GB인데 OOM이 나는 경우가 있다. 원인은 용량 합계가 아니라 할당 단위 때문이다.
그래서 6절 표는 "이론 상한"으로 읽어야 한다. 실전 판단은
--n-gpu-layers를 단계적으로 내려보며 직접 OOM이 나는 지점을 찾는 편이 정확하다. 아예 못 뜨는 게 나쁘지 않다.3. VRAM이 모자란다면 5단 우선순위
7절은 "비트를 낮추기보다 모델을 한 단계 작게" 를 권한다. 순서가 중요하니 5단계로 정리하면 이렇다.
--n-gpu-layers로 부분 오프로딩1~3번은 모델을 아예 안 바꾸므로 손실이 없다. 4번은 9B -> 4B 처럼 도약이 크지 않고, 5번은 5절 표처럼 성공률이 8회에서 5회로 떨어진다. 5번은 맨 마지막에 가야 한다.
4. 6절 표는 컨텍스트 기준으로 다시 읽어야 한다
6절 표는 8K 기준이라 24GB 행의 "24GB면 32K까지" 라는 설명과 바로 어긋난다. 같은 27B q4 기준으로 32K면 KV 캐시가 8.1GB(fp16) 또는 4.0GB(q8) 이므로 총점유는 24.3GB 또는 20.2GB다.
즉 24GB 카드에서 32K를 쓰려면 KV 캐시 양자화는 사실상 필수다. 7절의 "여유 공간" 원칙을 컨텍스트 길이마다 다시 적용해야 한다. 표의 숫자가 틀린 게 아니라, 표가 8K 한 줄 기준이라는 사실을 읽어야만 제대로 읽히는 경우다.