GearClue

레이어 4개만 CPU로 내려도 속도가 절반 — 오프로드 대가 실측

1970-01-01 · 실측

“VRAM이 조금 모자라도 돌아간다”는 말을 자주 봅니다. 맞습니다. llama.cpp와 Ollama는 VRAM에 다 못 올린 레이어를 시스템 RAM으로 내려서 CPU가 처리하게 합니다.

문제는 대가입니다. 같은 모델에서 GPU에 올리는 레이어 수만 바꿔가며 측정했더니, 48개 중 4개만 CPU로 내려도 생성 속도가 절반이 되었습니다.

대조 실험 결과

모델, 프롬프트, 시드, 컨텍스트를 모두 고정하고 num_gpu(GPU에 올릴 레이어 수)만 바꿨습니다. 모델은 Qwen3-Coder 30B-A3B Q4_K_M이고 레이어는 48개입니다.

GPU 레이어 메모리 배치 생성 속도 기준 대비
48 / 48 100% GPU 94.6 tok/s 100%
44 / 48 11% CPU 46.3 tok/s 49%
40 / 48 19% CPU 39.8 tok/s 42%
36 / 48 27% CPU 35.2 tok/s 37%
28 / 48 42% CPU 28.5 tok/s 30%
20 / 48 58% CPU 24.2 tok/s 26%

각 조건 2회 측정했고 편차는 1% 이내였습니다(예: 44 레이어에서 46.2와 46.3).

GPU에 올린 레이어 수에 따른 생성 속도 (Qwen3-Coder 30B-A3B, RTX 3060 ×2)027548210994.64846.34439.84035.23628.52824.220GPU 레이어 수 (전체 48)tok/s
GPU에 올린 레이어 수에 따른 생성 속도 (Qwen3-Coder 30B-A3B, RTX 3060 ×2)

곡선의 모양이 핵심입니다. 레이어 4개(8%)를 내리는 첫 걸음에서 속도가 51% 떨어집니다. 그 뒤로는 완만합니다. 44개에서 20개로 24개를 더 내려도 46.3에서 24.2로 절반 줄어드는 데 그칩니다.

즉 손실의 대부분이 “조금 넘치는” 구간에서 발생합니다. 오프로드가 늘어날수록 비례해서 나빠지는 것이 아니라, 경계를 넘는 순간 대부분의 손해를 봅니다.

이유는 구조에 있습니다. 토큰 하나를 생성할 때마다 모든 레이어를 순서대로 통과해야 합니다. 레이어 4개가 CPU에 있으면 매 토큰마다 그 구간에서 GPU가 멈추고 CPU 처리와 데이터 전송을 기다립니다. CPU에 있는 레이어 수보다 CPU를 거치는 일이 생기느냐 아니냐가 훨씬 큰 영향을 줍니다.

모델이 다르면 얼마나 다른가

같은 하드웨어에서 모델 4종을 3회씩 측정한 결과입니다. 이쪽은 통제된 비교가 아니라 관찰입니다.

모델 파라미터 메모리 배치 생성 속도 GPU 전력
Qwen3-Coder 30B-A3B 30.5B (활성 3B) 100% GPU 93.9 tok/s 178W
Gemma4 26B 25.8B 100% GPU 73.3 tok/s 191W
Qwen3.6 35B-A3B 36.0B (활성 3B) 18% CPU 25.0 tok/s 72W
Devstral Small 2 24B 24.0B 100% GPU 22.4 tok/s 242W

여기서 인과를 읽으면 안 됩니다. 네 모델은 아키텍처, 파라미터 수, KV 구조, 커널 최적화가 모두 다릅니다. Qwen3.6이 느린 데는 오프로드가 관여했겠지만, 이 표만으로 얼마나 기여했는지는 분리되지 않습니다. 오프로드의 효과는 앞의 대조 실험에서만 측정된 것입니다.

관찰로 말할 수 있는 것은 두 가지입니다. 완전히 GPU에 올라간 모델끼리도 22.4에서 93.9까지 4배 차이가 납니다. 그리고 Devstral은 242W를 쓰면서 22.4 tok/s를 냅니다. 토큰당 GPU 에너지로 환산하면 10.8J로 Qwen3-Coder(1.9J)의 5.7배입니다. 같은 하드웨어에서 모델 선택만으로 GPU 에너지가 몇 배 갈립니다.

오프로드된 Qwen3.6의 GPU 전력이 72W로 유독 낮은 것도 눈에 띕니다. 전력이 낮은 것은 효율이 좋다는 뜻이 아닙니다. GPU가 CPU를 기다리는 시간이 길면 평균 전력이 내려갑니다. 다만 이 측정은 GPU 전력만 잰 것이고 CPU 소비는 포함하지 않았으므로, 시스템 전체 소비는 이 숫자보다 큽니다.

용어를 정확히 하면

Ollama의 ollama ps가 보여주는 값을 오해하기 쉬워서 짚어둡니다.

이 글의 표에서 “메모리 배치”라고 쓴 것은 이 의미입니다.

실용적인 결론

모델을 고를 때 활성 파라미터보다 전체 크기를 먼저 보십시오. MoE의 “활성 파라미터가 작다”는 장점은 가중치 전체가 VRAM에 들어간다는 전제 위에서 성립합니다. 전제가 깨지면 이점이 크게 줄어듭니다.

조금 넘치는 것은 조금 느려지는 것이 아닙니다. 8% 오프로드에서 이미 절반을 잃었습니다.

넘칠 것 같으면 한 단계 작은 모델을 먼저 고려하십시오. 억지로 큰 모델을 오프로드로 굴리는 것보다 대체로 낫습니다. 컨텍스트를 줄이거나 KV 양자화로 여유를 만드는 것도 방법입니다.

GPU 전력이 유독 낮으면 병목을 의심하십시오. 오프로드나 다른 대기 요인이 있을 수 있습니다.

내 구성에 어떤 모델이 들어가는지는 VRAM 계산기로 확인할 수 있습니다. 계산식은 실측으로 검증했고 오차는 2~4% 수준이었습니다.

측정 환경과 방법

항목
GPU RTX 3060 12GB × 2
CPU AMD Ryzen 7 5800X (8코어)
RAM 125GB
PCIe GPU0 x4, GPU1 x16 (측정 시점 링크 폭)
런타임 Ollama 0.20.0, 드라이버 590.48.01
KV 타입 f16 (기본값)

한계

#로컬LLM#VRAM#CPU오프로드#RTX3060#추론속도