테마 전환

Ollama 성능 최적화 실전: 양자화, 배치 처리, 메모리 튜닝 완벽 가이드

Easton editorial illustration: one compact local-model engine on a performance console

2026-06-08 업데이트: Ollama 공식 문서를 기준으로 환경 변수를 다시 확인했습니다. GPU 레이어 수는 모델 매개변수 num_gpu로 제어해야 하며 OLLAMA_GPU_LAYERS는 존재하지 않습니다. GPU 메모리 예약에는 바이트 단위의 OLLAMA_GPU_OVERHEAD를 사용합니다. KV Cache 양자화를 위한 OLLAMA_KV_CACHE_TYPE도 추가했습니다. 벤치마크 수치는 참고용이며 버전과 하드웨어에 따라 달라질 수 있습니다.

14B 모델은 실행됐는데 추론 속도가 겨우 10 tokens/s인가요? 아니면 아예 OOM 오류가 나면서 종료되나요? 그래픽카드 팬이 미친 듯이 돌다가 화면까지 꺼질 수 있습니다.

흔히 겪는 상황입니다. 기대에 부풀어 llama3 8B를 다운로드하고 ollama run을 실행했는데 GPU 메모리가 부족합니다. 오류와 함께 종료되거나 달팽이처럼 느리게 동작합니다. Q4 양자화 버전으로 바꾸니 실행은 되지만 품질이 얼마나 떨어졌는지 계속 신경 쓰입니다.

저도 Ollama를 처음 사용할 때 이런 문제를 겪었습니다. 8GB GPU 메모리로 14B 모델을 돌리면서 실행만 되면 충분하다고 순진하게 생각했습니다. 결과는 CUDA out of memory 오류 아니면 단어가 하나씩 아주 느리게 출력되는 상황이었습니다.

문제는 하드웨어가 아니라 설정입니다.

이 글에서는 세 가지 핵심 최적화 기술인 양자화 선택, 배치 처리 설정, 메모리 튜닝을 다룹니다. 이 세 가지를 이해하면 로컬 LLM 성능을 적어도 두 배까지 높일 수 있습니다. 마케팅 문구로만 말하는 ‘두 배’가 아니라 실제 tokens/s가 올라가는 것을 뜻합니다.

1. 양자화 기술 — Q4부터 FP16까지 품질과 속도의 균형

1.1 양자화란 무엇이며, GGUF가 주류 형식인 이유

쉽게 말하면 양자화는 모델을 ‘작게 압축하는 것’입니다.

다운로드한 대규모 모델의 원본 매개변수는 FP16(16비트 부동소수점)입니다. 7B 모델을 FP16으로 계산하면 매개변수만으로 GPU 메모리가 14GB 필요합니다. 각 매개변수를 16비트에서 4비트로 줄이면 어떨까요? 이론적으로는 3.5GB까지 줄일 수 있습니다. 이것이 양자화의 핵심 원리입니다. 원래 값을 더 적은 비트로 표현해 메모리 사용량을 줄이고 추론 속도를 높입니다.

물론 대가는 있습니다. 정밀도가 떨어집니다. 4K 사진을 720P로 압축하면 세부 정보가 사라지는 것과 같습니다. 하지만 대부분의 상황에서는 충분히 사용할 만합니다.

GGUF 형식이 주류가 된 이유는 간단합니다. 편리하기 때문입니다. llama.cpp 팀이 특별히 설계한 이 형식은 메모리 매핑(mmap)을 지원하므로 모델을 로드할 때 전부 메모리에 올리지 않고 필요할 때 읽습니다. 덕분에 메모리가 16GB인 컴퓨터에서도 13B 모델을 실행할 수 있습니다. 기존 형식으로는 상상하기 어려운 일입니다.

1.2 양자화 유형 상세 비교: Q4_0, Q4_K_M, Q5_K_M, Q8_0

많은 사람이 가장 어려워하는 부분입니다. Q4_0, Q4_1, Q4_K_M, Q5_K_M, Q8_0 등 선택지가 많은데 무엇을 골라야 할까요?

자주 사용하는 양자화 유형을 표로 비교했습니다.

양자화 유형압축률메모리 사용량(7B 모델)품질 저하적합한 상황
Q4_0약 4.5배약 4.0GB비교적 큼GPU 메모리가 매우 부족하고 품질 요구가 낮을 때
Q4_K_M약 4.5배약 4.7GB매우 작음가성비가 가장 좋은 선택, 일반 용도로 권장
Q5_K_M약 3.5배약 5.8GB극히 작음품질 우선, GPU 메모리가 충분할 때
Q8_0약 2배약 7.2GB거의 무손실최상의 품질을 원하고 GPU 메모리가 충분할 때
FP161배약 14GB무손실학술 연구, 고사양 그래픽카드

간단히 말해 Q4_K_M이 가성비가 가장 좋은 선택입니다. 품질 저하는 거의 느끼기 어렵고 메모리 사용량도 적습니다. 여러 번 테스트해 봤지만 Q4_K_M과 FP16의 답변 차이는 아주 세밀하게 비교하지 않는 한 일상 대화에서는 거의 느껴지지 않았습니다.

Q5_K_M은 GPU 메모리에 어느 정도 여유가 있고 품질을 특히 중시할 때 적합합니다. GPU 메모리가 24GB 이상이 아니라면 Q8_0은 굳이 고려하지 않아도 됩니다. 그 정도 사양이라면 매개변수가 더 많은 모델을 쓰는 편이 낫습니다.

1.3 양자화 선택 의사결정 트리

간단한 선택 기준은 다음과 같습니다.

1단계: GPU 메모리 확인

  • GPU 메모리 ≤ 8GB: Q4_K_M만 선택할 수 있습니다. 7B 모델은 간신히 실행되며 14B는 CPU offload가 필요합니다.
  • GPU 메모리 12~16GB: Q4_K_M으로 14B를 문제없이 실행할 수 있고 7B는 Q5_K_M도 가능합니다.
  • GPU 메모리 ≥ 24GB: Q5_K_M이나 Q8_0을 자유롭게 선택할 수 있으며 70B 모델도 시도할 수 있습니다.

2단계: 용도 확인

  • 일상 대화, 코딩: Q4_K_M이면 충분합니다.
  • 번역, 품질에 민감한 글쓰기: Q5_K_M
  • 학술 연구, 평가 비교: Q8_0 또는 FP16

참고할 만한 실제 수치는 다음과 같습니다.

  • 7B 모델 Q4_K_M: GPU 메모리 약 4.7GB
  • 14B 모델 Q4_K_M: GPU 메모리 약 9GB
  • 70B 모델 Q4_K_M: GPU 메모리 약 40GB

먼저 Q4_K_M부터 사용해 보세요. 답변 품질이 만족스럽지 않다면 Q5_K_M으로 바꾸면 됩니다. 처음부터 ‘무손실’을 고집할 필요는 없습니다. 실제 차이보다 심리적인 영향이 더 클 때가 많습니다.

1.4 특정 양자화 버전을 다운로드하는 방법

Ollama는 기본적으로 Q4_K_M 양자화 버전을 다운로드합니다. 다른 버전을 지정하려면 다음과 같이 실행합니다.

# 기본 Q4_K_M 다운로드
ollama run llama3

# Q5 양자화 지정
ollama run llama3:70b-q5

# Q8 양자화 지정
ollama run llama3:70b-q8

모든 모델에 모든 양자화 버전이 제공되는 것은 아닙니다. Ollama 공식 모델 라이브러리에서 확인하거나 다음 명령으로 사용할 수 있는 tag를 살펴보세요.

# 로컬에 설치된 모델 확인
ollama list

# 양자화 정보를 포함한 모델 상세 정보 확인
ollama show llama3 --modelfile

사용 빈도가 높다면 모델을 직접 양자화하는 방법도 있습니다. llama.cpp는 정밀도와 매개변수를 직접 제어할 수 있는 완전한 양자화 도구 체인을 제공합니다. 다만 고급 주제이므로 이 글에서는 다루지 않습니다.

2. 배치 처리 설정 — 처리량을 50~150% 높이기

2.1 배치 처리 원리: 왜 빨라질까요?

배치 처리 개념을 어려워하는 사람이 많습니다. 쉽게 설명해 보겠습니다.

마트 계산대를 떠올려 보세요. 매번 고객 한 명의 물건만 처리하면 계산원이 계속 전환하며 스캔하고 결제해야 하므로 효율이 낮습니다. 반대로 고객 10명의 물건을 함께 스캔하면 작업 흐름이 이어져 효율이 높아집니다.

GPU 추론도 마찬가지입니다. token 하나씩 추론하면 GPU는 대부분 메모리에서 데이터가 전송되기를 기다리고 연산 장치는 유휴 상태가 됩니다. 배치 처리는 여러 token을 묶어서 계산해 GPU를 최대한 활용합니다.

주의할 점은 배치 처리가 높이는 것은 처리량이지 단일 요청의 지연 시간이 아니라는 것입니다. 혼자 사용할 때는 차이를 크게 느끼지 못할 수 있습니다. 하지만 API 서비스를 운영하면서 여러 요청을 동시에 처리하면 처리량이 두 배 이상 높아질 수 있습니다.

2.2 num_batch 매개변수 상세 설명

num_batch는 Ollama의 핵심 배치 처리 매개변수이며 기본값은 512입니다.

값이 클수록 GPU 사용률과 처리량이 높아집니다. 대신 GPU 메모리 사용량이 20~40% 증가합니다.

GPU 메모리 여유에 따라 다음처럼 조정하세요.

GPU 메모리 상태권장 num_batch예상 효과
부족함512(기본값)안전하지만 GPU가 조금 유휴 상태일 수 있음
보통1024처리량 50~80% 향상
충분함2048처리량 100~150% 향상

제 경험으로는 RTX 3080(10GB)에서 7B Q4_K_M을 실행할 때 num_batch 1024는 안정적이었습니다. 2048로 설정하면 가끔 OOM이 발생했습니다. RTX 4090에서 14B를 실행할 때는 2048도 문제없었습니다.

2.3 num_ctx와 KV Cache

num_ctx는 컨텍스트 창 크기이며 기본값은 2048입니다. 이 매개변수는 KV Cache의 메모리 사용량에 영향을 줍니다.

KV Cache란 무엇일까요? 간단히 말해 모델이 추론할 때 이전 계산 결과를 캐시하여 같은 계산을 반복하지 않도록 하는 기능입니다. 컨텍스트가 길수록 캐시도 커집니다.

메모리 사용량 공식은 대략 다음과 같습니다.

KV Cache 메모리 ≈ 2 × 레이어 수 × 은닉 차원 × num_ctx × 정밀도 바이트 수

참고할 만한 실제 수치는 다음과 같습니다.

  • 7B 모델, num_ctx=4096: 약 1~2GB 추가 사용
  • 14B 모델, num_ctx=8192: 약 3~4GB 추가 사용

따라서 32K나 128K 같은 긴 컨텍스트를 사용하면 GPU 메모리 소비가 빠르게 증가합니다. 많은 사람이 모델 매개변수가 GPU 메모리를 가득 채웠다고 생각하지만 실제로는 KV Cache가 큰 비중을 차지할 수 있습니다.

주의점: 일부 모델은 기본 num_ctx가 매우 큽니다. 예를 들어 llama3는 최대 128K를 지원하지만 실제로 그렇게 설정하면 GPU 메모리가 바로 소진될 수 있습니다. 일상적인 용도에는 4096이나 8192면 충분합니다.

2.4 배치 처리 설정 실전

바로 설정 예시를 살펴보겠습니다.

방법 1: Modelfile 설정

# 기본 모델에서 생성
FROM llama3

# 배치 크기 설정
PARAMETER num_batch 1024

# 컨텍스트 창 설정
PARAMETER num_ctx 4096

# 시스템 프롬프트가 잘리지 않도록 유지
PARAMETER num_keep 128

Modelfile로 저장한 뒤 새 모델을 생성합니다.

ollama create my-llama3 -f Modelfile
ollama run my-llama3

방법 2: API options 설정

curl http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt": "양자 컴퓨팅을 설명해 주세요",
  "options": {
    "num_batch": 1024,
    "num_ctx": 4096
  }
}'

성능 비교 데이터(RTX 3080, 7B Q4_K_M):

num_batch처리량(tokens/s)GPU 메모리 사용량
512455.2GB
1024726.1GB
2048987.4GB

num_batch를 512에서 1024로 높이면 처리량은 60% 증가하지만 GPU 메모리는 1GB도 채 늘지 않습니다. 충분히 가치 있는 조정입니다.

3. 메모리 튜닝 — OOM을 해결하는 세 가지 전략

3.1 GPU 메모리 할당 방식

Ollama의 GPU 메모리 관리는 꽤 영리합니다. 다음 순서로 자동 판단합니다.

  1. GPU 메모리에 모델 전체를 올릴 수 있는가?
  2. 가능하면 모델 전체를 GPU에 로드합니다.
  3. 불가능하면 일부 레이어를 자동으로 CPU에 offload합니다.

하지만 ‘영리하다’고 해서 완벽한 것은 아닙니다. 판단이 빗나가거나 경계 조건을 제대로 처리하지 못하면 OOM이 발생할 수 있습니다.

핵심 매개변수는 num_gpu입니다. GPU에 올릴 모델 레이어 수를 제어하며 기본값 -1은 자동 판단을 뜻합니다. 예를 들어 num_gpu: 20으로 직접 지정하면 앞쪽 20개 레이어만 GPU에 올리고 나머지는 CPU를 사용합니다.

3.2 전략 1: 양자화 단계 낮추기

가장 간단하고 직접적인 방법입니다. OOM이 발생하면 더 작은 양자화로 바꾸세요.

단계를 낮추는 순서는 다음과 같습니다.

Q8_0 → Q5_K_M → Q4_K_M → Q4_0

한 단계 낮출 때마다 GPU 메모리를 약 20~25% 절약할 수 있습니다.

예를 들어 14B 모델 Q5_K_M에 GPU 메모리가 11GB 필요해서 OOM이 발생했다면 Q4_K_M으로 바꿔 보세요. 9GB만 필요합니다. GPU 메모리 사용량은 18% 줄어드는데 품질은 얼마나 떨어질까요? 솔직히 일상 대화에서는 거의 느끼기 어렵습니다.

저는 이전에 GPU 메모리가 8GB인 환경에서 7B Q4_K_M을 문제없이 실행했습니다. 14B는 어떨까요? Q4_K_M으로 간신히 실행되지만 컨텍스트가 커지면 OOM이 발생했습니다. 결국 14B Q4_0으로 타협했습니다. 품질은 조금 낮아졌지만 사용할 수 있었습니다.

3.3 전략 2: CPU Offload 혼합 추론

GPU 메모리가 정말 부족하다면 CPU가 일부를 맡게 하세요.

num_gpu 매개변수로 GPU 레이어 수를 제어할 수 있습니다. 레이어가 32개인 모델에서 num_gpu: 24로 설정하면 나머지 8개 레이어는 CPU에서 계산합니다.

대가는 속도 저하입니다. CPU 추론은 GPU보다 10배 이상 느립니다. 그래도 OOM으로 아예 실행하지 못하는 것보다는 낫습니다.

설정 방법은 다음과 같습니다.

# Modelfile
FROM llama3
PARAMETER num_gpu 24

또는 API를 사용합니다.

curl http://localhost:11434/api/generate -d '{
  "model": "llama3",
  "prompt": "안녕하세요",
  "options": {
    "num_gpu": 24
  }
}'

혼합 추론 속도 참고(14B Q4_K_M, RTX 3080 10GB + i7-12700K):

num_gpu추론 속도GPU 메모리 사용량
40(전체 GPU)OOM12GB(초과)
3018 tokens/s9.2GB
2012 tokens/s6.5GB
0(CPU 전용)4 tokens/s0.5GB

num_gpu=30일 때 속도는 여전히 쓸 만하고 GPU 메모리도 넘치지 않습니다. 이것이 혼합 추론의 가치입니다.

3.4 전략 3: KV Cache 최적화

KV Cache는 자주 간과되지만 GPU 메모리를 많이 사용할 수 있습니다.

방법 1: Flash Attention 활성화

Flash Attention은 GPU 메모리 사용량을 크게 줄여 주는 최적화된 어텐션 계산 방식입니다.

# 환경 변수 설정
export OLLAMA_FLASH_ATTENTION=1

# 또는 Docker 시작 시 설정
docker run -e OLLAMA_FLASH_ATTENTION=1 ollama/ollama

효과는 KV Cache의 GPU 메모리 사용량을 30~50% 줄이는 것입니다. 적극적으로 권장합니다.

방법 2: num_ctx 줄이기

컨텍스트가 길수록 KV Cache도 커집니다. 32K 컨텍스트가 필요하지 않다면 더 작게 설정하세요.

PARAMETER num_ctx 2048  # 기본값 2048이면 일상 대화에 충분함

방법 3: num_keep으로 시스템 프롬프트 유지

num_keep 매개변수는 잘리지 않고 유지할 token 수를 제어합니다. 시스템 프롬프트 길이로 설정하면 컨텍스트가 이동할 때 시스템 프롬프트가 사라지는 것을 방지할 수 있습니다.

PARAMETER num_keep 128

3.5 OOM 실전 해결 절차

OOM이 발생하면 다음 순서로 확인하세요.

1단계: GPU 메모리 사용량 확인

nvidia-smi

사용 중인 GPU 메모리와 남은 용량을 확인합니다.

2단계: 모델 매개변수 확인

ollama show llama3 --modelfile

num_ctx, num_batch 같은 매개변수가 너무 크게 설정되지는 않았는지 확인합니다.

3단계: 순차적으로 낮추기

  • 먼저 num_batch 낮추기: 1024 → 512
  • 다음으로 num_ctx 낮추기: 4096 → 2048
  • 마지막으로 양자화 낮추기: Q5_K_M → Q4_K_M

4단계: CPU offload 활성화
num_gpu를 전체 레이어 수의 70~80%로 설정합니다.

5단계: 최종 수단—CPU 전용 추론
GPU 메모리가 정말 부족하면 CPU만 사용해야 합니다. 느리지만 실행은 가능합니다.

# 모델 매개변수 num_gpu=0으로 CPU 전용 모드 강제(API 또는 Modelfile)
curl http://localhost:11434/api/generate -d '{"model":"llama3","prompt":"안녕하세요","options":{"num_gpu":0}}'

솔직히 CPU 전용 추론 속도는 GPU의 약 1/10에 불과합니다. 그래도 가끔 사용하거나 배치 작업을 실행하는 용도라면 감수할 만합니다.

4. 성능 벤치마크와 하드웨어 참고 자료

4.1 하드웨어별 추론 속도 표

자신의 환경과 비교할 수 있도록 하드웨어 구성별 추론 속도를 정리했습니다.

NVIDIA 그래픽카드(7B 모델 Q4_K_M)

그래픽카드GPU 메모리tokens/s비고
RTX 306012GB52가성비가 가장 좋음
RTX 308010GB68안정적인 선택
RTX 309024GB9514B Q4 실행 가능
RTX 4070 Ti12GB78새 아키텍처의 이점
RTX 409024GB120고사양 구성

NVIDIA 그래픽카드(14B 모델 Q4_K_M)

그래픽카드GPU 메모리tokens/s비고
RTX 306012GB28간신히 실행 가능
RTX 308010GBOOMCPU offload 필요
RTX 309024GB55여유로움
RTX 409024GB72매우 빠름

Apple Silicon(Metal 가속)

기기메모리7B tokens/s14B tokens/s
M2 Air 8GB8GB35OOM
M2 Pro 16GB16GB4822
M2 Max 32GB32GB5832
M2 Ultra 64GB64GB6545

Apple Silicon의 장점은 통합 메모리를 사용해 GPU가 활용할 수 있는 메모리 용량이 크다는 점입니다. 다만 단일 코어 성능은 고급 GPU보다 낮습니다.

CPU 전용 추론

CPU메모리7B tokens/s14B tokens/s
i7-12700K32GB63
Ryzen 9 7950X64GB84
M2 Max(CPU only)32GB126

실행은 가능하지만 느립니다. 배치 작업에는 적합하지만 실시간 대화에는 적합하지 않습니다.

4.2 배치 처리량 향상 데이터

다음 표는 num_batch 설정에 따라 처리량이 어떻게 달라지는지 보여 줍니다.

테스트 환경: RTX 3080, 7B Q4_K_M, 다중 동시 요청

num_batch단일 요청 지연 시간동시 처리량GPU 메모리 사용량
51222ms/token45 tokens/s5.2GB
102422ms/token72 tokens/s6.1GB
204822ms/token98 tokens/s7.4GB

핵심 결과는 다음과 같습니다.

  • 단일 요청 지연 시간은 거의 동일: 배치 처리는 개별 요청의 응답 속도에 영향을 주지 않습니다.
  • 처리량은 두 배 이상 증가: 동시 요청 환경에서 num_batch=2048은 512보다 118% 향상됐습니다.
  • GPU 메모리 비용은 감당 가능한 수준: 처리량을 118% 높이는 데 GPU 메모리는 2.2GB만 더 사용했습니다.

4.3 환경 변수 설정 요약

자주 사용하는 Ollama 환경 변수를 정리했습니다.

# Flash Attention(적극 권장, KV Cache 양자화와 함께 사용하면 GPU 메모리를 크게 절약)
export OLLAMA_FLASH_ATTENTION=1

# KV Cache 양자화: f16(기본값)/q8_0(약 절반 절약)/q4_0(약 4분의 3 절약), 먼저 Flash Attention을 활성화해야 함
export OLLAMA_KV_CACHE_TYPE=q8_0

# 시스템/다른 프로그램용 GPU 메모리 예약(단위: 바이트, 기본값 0)
export OLLAMA_GPU_OVERHEAD=1073741824  # 1GB 예약

# 기본 컨텍스트 길이(모델 기본값 재정의)
export OLLAMA_CONTEXT_LENGTH=4096

# 모델 유지 시간(기본값 5분)
export OLLAMA_KEEP_ALIVE=24h

# 동시 요청 수 제한
export OLLAMA_MAX_QUEUE=512

# 로그 수준
export OLLAMA_DEBUG=1

Docker Compose 전체 설정 예시:

version: '3'
services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    restart: unless-stopped
    environment:
      - OLLAMA_FLASH_ATTENTION=1
      - OLLAMA_KEEP_ALIVE=24h
      - OLLAMA_MAX_QUEUE=512
    volumes:
      - ollama_data:/root/.ollama
    ports:
      - "11434:11434"
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

volumes:
  ollama_data:

위 설정을 docker-compose.yml로 저장한 뒤 다음 명령을 실행합니다.

docker-compose up -d

관련 글

마무리

지금까지의 내용을 세 단계 최적화 절차로 정리해 보겠습니다.

1단계: 양자화 선택
GPU 메모리 크기를 확인한 뒤 알맞은 양자화 버전을 선택합니다. Q4_K_M은 가성비가 가장 좋아 대부분의 상황에 충분합니다. GPU 메모리에 여유가 있다면 Q5_K_M을 고려하세요.

2단계: 배치 처리 조정
GPU 메모리에 여유가 있나요? num_batch를 1024 또는 2048까지 높여 보세요. GPU 메모리를 조금 더 사용하는 대신 처리량을 두 배까지 높일 수 있습니다.

3단계: OOM 해결
그래도 부족하다면 Flash Attention을 활성화하고 num_ctx를 줄이거나 CPU offload를 사용하세요. 순서대로 시도하면 적절한 균형점을 찾을 수 있습니다.

성능 최적화는 한 번에 끝나는 작업이 아닙니다. 하드웨어, 모델 크기, 사용 환경이 모두 다르므로 단계적으로 조정해야 합니다. 양자화부터 시작해 모델이 정상적으로 실행되는지 확인하고, 그다음 배치 처리 매개변수를 조정한 뒤 마지막으로 고급 환경 변수를 다루는 것을 권합니다.

특정 모델의 설정 방법이나 오류 해결법처럼 구체적인 문제가 있다면 댓글을 남기거나 Ollama 공식 문서를 확인해 보세요. 커뮤니티에도 이론 설명보다 유용한 실전 경험이 많이 공유되어 있습니다.

3분 읽기 · 게시일: 2026년 4월 10일 · 수정일: 2026년 9월 8일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog