llama.cpp에서 MoE 모델 VRAM 최적화
상황
Qwen3.5-35B-A3B-UD-IQ3_XXS 모델을 16GB VRAM GPU에서 llama.cpp로 실행하는 경우.
모델 특성:
- MoE 구조: 총 파라미터 35B, 추론 시 활성화는 ~3B (Mixture of Experts)
- IQ3_XXS: 초저비트 양자화 (~3.x bpw), 전체 파일 크기 ~15-16GB
-ot 옵션: expert를 CPU로 오프로드
../llama.cpp/build/bin/llama-server \
--model ./models/Qwen3.5-35B-A3B/Qwen3.5-35B-A3B-UD-IQ3_XXS.gguf \
--jinja \
-ngl 99 \
-ot ".ffn_.*_exps.=CPU" \
--ctx-size 16384 \
--port 8080 \
--host localhost
-ot ".ffn_.*_exps.=CPU" 의 의미: ffn_.*_exps 텐서(각 레이어의 routed expert 가중치)를 전부 CPU RAM으로 보냄.
MoE 모델에서 VRAM을 가장 많이 먹는 게 바로 이 expert 가중치들이라, 이 방법으로 3GB 수준의 VRAM만으로도 35B급 모델 구동이 가능. 단, 토큰 생성 시 CPU-GPU 간 데이터 이동이 발생해서 끊기는 느낌이 생길 수 있음.
16GB VRAM이면 전체 GPU 오프로드 가능
IQ3_XXS 기준 모델 전체가 ~15-16GB이므로, -ot 없이 실행하면 VRAM에 전부 올릴 수 있음:
../llama.cpp/build/bin/llama-server \
--model ./models/Qwen3.5-35B-A3B/Qwen3.5-35B-A3B-UD-IQ3_XXS.gguf \
--jinja \
-ngl 99 \
--ctx-size 16384 \
--port 8080 \
--host localhost
실행 로그에서 확인:
llm_load_tensors: offloaded XX/XX layers to GPU ← XX/XX 같으면 전체 올라간 것
llama_kv_cache_init: VRAM kv self = XX.XX MiB ← KV cache 크기
Qwen3.5-35B-A3B 기준 결과: 모델이 ~13GB, KV cache가 나머지 ~3GB 사용. 16k context도 문제없이 수용됨.
MoE 모델은 attention 레이어가 ~3B 규모 기준이라 KV head 수가 dense 35B 대비 훨씬 적어, KV cache가 생각보다 작음.
정리
| 방법 | VRAM 사용 | 속도 | 비고 |
|---|---|---|---|
| -ot .ffn_.*_exps.=CPU | ~3GB | 느림, 끊김 | VRAM 부족 시 |
| -ot 제거 (전체 GPU) | ~13GB + KV | 빠름 | 16GB면 충분 |
VRAM이 넉넉하다면 -ot 옵션을 제거하는 게 최선.