Ollama 설치 가이드 — Mac M1 32GB 로컬 LLM 최적 모델 5가지 비교

클라우드 API 비용이 부담스러운 건 나만의 문제가 아닐 거다. GPT-4o 한 달 쓰면 $20은 기본이고, Claude API로 자동화 파이프라인 돌리면 토큰 비용이 눈에 보이게 쌓인다. 그래서 로컬 LLM을 세팅하기로 했다. 내 메인 장비는 MacBook Pro M1 32GB인데, 결론부터 말하면 — 13B 모델까지는 쾌적하게, 30B급도 느리지만 돌아간다. Ollama 덕분에 세팅도 5분이면 끝난다.

이 글은 M1 32GB 기준으로 쓰지만, M2나 M3도 Apple Silicon이라 거의 동일하게 적용된다. 다만 메모리가 16GB라면 7B 모델 위주로 봐야 하고, 8GB면 솔직히 3B 이하만 현실적이다.

Ollama 설치 및 기본 세팅

Ollama는 로컬에서 LLM을 가장 쉽게 돌릴 수 있는 도구다. Docker나 Python 환경 구성 없이 바로 된다. 설치 방법은 두 가지인데, Homebrew가 편하다. 관련 내용은 Mac Python AI 개발환경 세팅에서도 다루고 있다.

# Homebrew로 설치 (권장)
brew install ollama

# 버전 확인
ollama --version
# ollama version is 0.6.2

# Ollama 서버 시작 (백그라운드 실행)
ollama serve &

# 또는 macOS 앱을 다운받아 설치하면 자동으로 서버가 뜬다
# https://ollama.com/download/mac

brew install ollama로 설치하면 CLI만 들어온다. 터미널에서 ollama serve를 먼저 실행해야 모델을 돌릴 수 있다. 매번 치기 귀찮으면 공식 macOS 앱을 설치하면 로그인 시 자동으로 백그라운드에서 서버가 뜬다. 나는 앱 설치 쪽을 쓰고 있는데, 메뉴바 아이콘으로 상태 확인이 돼서 편리하다.

설치 후 바로 모델 하나 다운받아서 테스트해보자.

# llama3.1 8B 모델 다운로드 + 실행
ollama run llama3.1

# 다운로드가 끝나면 바로 프롬프트가 뜬다
>>> 안녕하세요, 한국어 테스트입니다.
안녕하세요! 네, 한국어로 대화할 수 있습니다. 무엇을 도와드릴까요?

>>> /bye

처음 ollama run을 실행하면 모델 다운로드가 시작된다. llama3.1:8b 기준으로 약 4.7GB이고, 네트워크 상태에 따라 2~5분 정도 걸린다. 다운로드가 끝나면 바로 대화 모드로 들어간다. /bye로 나올 수 있다.

Metal GPU 가속 확인 — M1이면 자동이지만 확인은 필수

Ollama — 설정 및 실행 결과 화면

Apple Silicon(M1/M2/M3)에서 Ollama를 쓰면 Metal GPU 가속이 자동으로 활성화된다. 별도 설정이 필요 없다. 다만, 실제로 Metal이 쓰이고 있는지 확인하는 습관을 들여야 한다. CPU로만 돌아가면 속도가 3~5배 느려지기 때문이다.

# 실행 중인 모델 상태 확인
ollama ps

# NAME              ID            SIZE     PROCESSOR    UNTIL
# llama3.1:latest   a]b2c3d4e5f6  6.7 GB   100% GPU     4 minutes from now

# PROCESSOR 항목이 "100% GPU"이면 Metal 가속 정상 작동
# "100% CPU"로 뜨면 문제가 있는 것

# Metal 지원 확인 (시스템 차원)
system_profiler SPDisplaysDataType | grep Metal
# Metal Family: Supported, Metal GPUFamily Apple 7

ollama ps 출력에서 PROCESSOR 컬럼을 확인하면 된다. 100% GPU면 Metal이 잘 잡힌 것이고, 100% CPU면 뭔가 문제가 있다. 간혹 모델 크기가 메모리를 초과하면 일부 레이어가 CPU로 넘어가서 80% GPU / 20% CPU 같은 혼합 상태가 되기도 한다. 이 경우 응답 속도가 확 떨어진다.

Metal 가속이 안 될 때 체크리스트

  • macOS 버전 확인: Ventura(13.0) 이상이어야 Metal이 제대로 작동한다. Monterey에서도 되긴 하는데 간혹 문제가 생긴다.
  • Ollama 버전 확인: 0.3.0 이전 버전은 Metal 관련 버그가 있었다. brew upgrade ollama로 최신으로 올리자.
  • 모델 크기 초과: 32GB 맥에서 30B 이상 모델을 풀로 올리면 메모리가 부족해서 CPU 오프로딩이 발생한다. ollama ps에서 GPU 비율을 꼭 확인하자.

32GB M1에서 돌릴 수 있는 모델 크기별 가이드

LLM 모델 크기를 고를 때 핵심은 “파라미터 수(B) × 양자화 비트”로 결정되는 메모리 사용량이다. 32GB Mac이라고 32GB를 전부 모델에 쓸 수 있는 건 아니다. macOS 자체가 5~8GB를 먹고, 브라우저 띄워놓으면 추가로 3~5GB. 실질적으로 LLM에 할당할 수 있는 건 약 18~22GB 정도다.

모델 크기 양자화 VRAM 사용량 32GB 맥에서 체감 속도
3B Q4_K_M ~2.0 GB 매우 쾌적 60~80 tok/s
7B Q4_K_M ~4.5 GB 쾌적 35~45 tok/s
8B Q4_K_M ~5.0 GB 쾌적 30~40 tok/s
13B Q4_K_M ~8.5 GB 쾌적 (추천) 18~25 tok/s
30B/33B Q4_K_M ~20 GB 가능하지만 빠듯 8~12 tok/s
70B Q4_K_M ~40 GB 불가 (스왑 발생) 1~3 tok/s

내 경험상 32GB M1의 스위트스팟은 8B~13B Q4 양자화 모델이다. 13B 모델을 Q4_K_M으로 돌리면 메모리 약 8.5GB를 먹는데, 다른 앱을 동시에 쓸 수 있을 정도로 여유가 있다. 30B급은 다른 앱을 다 닫고 모델에만 집중해야 쓸 만하다.

70B는 시도해봤지만 현실적으로 쓸 수 없다. 스왑이 발생하면서 시스템 전체가 느려지고, 토큰 생성 속도가 1~3 tok/s까지 떨어진다. 한 문장 생성하는 데 10초 이상 걸리면 대화가 안 된다.

주요 모델 비교 — llama3, codellama, mistral, phi-3, gemma2

Ollama에서 쓸 수 있는 모델이 수십 개인데, 32GB M1 기준으로 실제로 쓸 만한 모델들만 추렸다. 아래는 내가 직접 같은 프롬프트로 테스트한 결과다.

모델 파라미터 크기 용도 한국어 비고
llama3.1:8b 8B 4.7 GB 범용 보통 가장 무난한 선택
llama3.1:70b 70B 40 GB 범용 좋음 32GB에서는 비추
codellama:13b 13B 7.4 GB 코딩 약함 코드 자동완성에 강점
mistral:7b 7B 4.1 GB 범용 보통 가볍고 빠름
phi3:14b 14B 7.9 GB 추론/수학 약함 MS 모델, 논리력 강함
gemma2:9b 9B 5.4 GB 범용 보통 Google 모델, 가성비 좋음
qwen2.5:14b 14B 9.0 GB 범용/코딩 좋음 한국어 성능 우수
deepseek-coder-v2:16b 16B 8.9 GB 코딩 보통 코딩 특화, MoE 구조

한국어가 중요하다면 qwen2.5:14b를 추천한다. 알리바바에서 만든 모델인데, 중국어/한국어/일본어 등 동아시아 언어 성능이 다른 오픈소스 모델 대비 확실히 좋다. 13B급 메모리만 쓰면서 한국어 자연스러움이 llama3.1:8b보다 한 단계 위다.

코딩 용도라면 codellama:13bdeepseek-coder-v2:16b가 좋다. 특히 deepseek-coder-v2는 MoE(Mixture of Experts) 구조라서 16B 파라미터 대비 실제 활성 파라미터가 적어 메모리 대비 성능이 좋은 편이다.

ollama 기본 명령어 정리

자주 쓰는 명령어를 정리해둔다. 매번 ollama help 칠 필요 없게.

# 모델 다운로드만 (실행은 안 함)
ollama pull llama3.1:8b

# 모델 다운로드 + 바로 실행 (대화 모드)
ollama run llama3.1:8b

# 현재 다운로드된 모델 목록
ollama list
# NAME                    ID            SIZE     MODIFIED
# llama3.1:8b             365c0bd3c000  4.7 GB   2 days ago
# codellama:13b           a]b2c3d4e5f6  7.4 GB   5 days ago
# qwen2.5:14b             c8d9e0f1a2b3  9.0 GB   1 day ago

# 현재 메모리에 로드된 모델 상태 확인
ollama ps

# 모델 삭제 (디스크 공간 확보)
ollama rm codellama:13b

# 모델 상세 정보 (Modelfile, 파라미터 등)
ollama show llama3.1:8b

# 모델 정보 중 Modelfile만 확인
ollama show llama3.1:8b --modelfile

# 서버 시작 (macOS 앱을 안 쓰는 경우)
ollama serve

# 특정 모델 복사 (커스텀 이름 지정)
ollama cp llama3.1:8b my-llama

ollama list로 디스크 사용량을 수시로 확인하는 게 좋다. 여러 모델을 받다 보면 금방 50GB를 넘긴다. 안 쓰는 모델은 ollama rm으로 정리하자. 모델 파일은 ~/.ollama/models/ 경로에 저장된다.

API 서버 모드 활용 (localhost:11434)

Ollama의 진짜 강점은 CLI 대화 모드가 아니라 API 서버다. ollama serve가 실행 중이면 localhost:11434에 OpenAI 호환 API가 자동으로 뜬다. Python 스크립트, Node.js 백엔드, 심지어 VS Code 확장에서도 바로 연동할 수 있다.

# 기본 API 호출 테스트
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "Docker와 Kubernetes의 차이를 간단히 설명해줘",
  "stream": false
}'

# OpenAI 호환 엔드포인트 (v1/chat/completions)
curl http://localhost:11434/v1/chat/completions -d '{
  "model": "llama3.1:8b",
  "messages": [
    {"role": "system", "content": "당신은 시니어 백엔드 개발자입니다."},
    {"role": "user", "content": "FastAPI에서 비동기 처리할 때 주의할 점은?"}
  ]
}'

# Python에서 사용 (openai 라이브러리 그대로 사용 가능)
# pip install openai
python3 -c "
from openai import OpenAI
client = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')
response = client.chat.completions.create(
    model='llama3.1:8b',
    messages=[{'role': 'user', 'content': '파이썬 리스트 컴프리헨션 예시 3개'}]
)
print(response.choices[0].message.content)
"

# 로드된 모델 목록 API
curl http://localhost:11434/api/tags

OpenAI 호환 엔드포인트(/v1/chat/completions)가 지원되기 때문에, 기존에 OpenAI API를 쓰던 코드에서 base_url만 바꾸면 로컬 LLM으로 전환된다. API 키는 아무 값이나 넣으면 된다(검증 안 함).

Continue(VS Code 확장), Open WebUI 같은 도구와 연동할 때도 이 API를 쓴다. Open WebUI를 Docker로 띄우면 ChatGPT 같은 웹 인터페이스에서 로컬 모델을 쓸 수 있다.

메모리 부족 대처법과 OLLAMA_MAX_LOADED_MODELS

32GB라고 넉넉한 건 아니다. 특히 여러 모델을 번갈아 쓰거나, 큰 모델을 올린 상태에서 Xcode나 Docker를 같이 돌리면 메모리가 터진다. 내가 겪은 대표적인 증상과 대처법을 정리한다.

증상 1: 응답이 갑자기 느려짐

ollama ps에서 GPU 비율이 100%가 아니라 일부 CPU로 넘어간 상태다. 모델이 메모리에 완전히 올라가지 못하면 일부 레이어를 CPU로 처리하게 된다.

증상 2: 시스템 전체가 먹통

macOS가 스왑을 과도하게 쓰면서 디스크 I/O 병목이 생긴 상태다. Activity Monitor에서 Memory Pressure가 빨간색이면 확실하다.

대처법

# 1. 동시에 로드할 수 있는 모델 수 제한 (기본값: 자동)
export OLLAMA_MAX_LOADED_MODELS=1
# 이렇게 하면 한 번에 하나의 모델만 메모리에 올라감
# ~/.zshrc에 추가해두면 영구 적용

# 2. 모델 메모리 유지 시간 설정
export OLLAMA_KEEP_ALIVE="5m"
# 기본 5분. 사용 안 하면 5분 후 메모리에서 내림
# "0"으로 설정하면 응답 즉시 메모리에서 해제

# 3. 현재 로드된 모델 확인 후 불필요한 모델 언로드
ollama ps
# 불필요한 모델이 있으면 stop
ollama stop mistral:7b

# 4. 더 작은 양자화 버전 사용
# Q4_K_M (기본) 대신 Q3_K_S로 바꾸면 메모리 ~25% 절약
ollama pull llama3.1:8b-instruct-q3_K_S

# 5. GPU 레이어 수 수동 제한 (Modelfile에서)
# num_gpu를 낮추면 GPU 메모리 사용량이 줄어듦 (대신 느려짐)

# 6. 맥 재시작 후 불필요한 앱 없이 모델만 실행
# 솔직히 이게 제일 효과적일 때가 있다

OLLAMA_MAX_LOADED_MODELS=1이 핵심이다. Ollama는 기본적으로 여러 모델을 메모리에 동시에 올려둘 수 있는데, 32GB에서 이러면 금방 메모리가 찬다. 1로 제한하면 새 모델을 로드할 때 기존 모델을 자동으로 내린다.

OLLAMA_KEEP_ALIVE도 중요하다. 기본 5분인데, 모델을 자주 전환하면서 메모리 부족을 겪는다면 0으로 설정해서 응답 직후 바로 메모리에서 해제되도록 할 수 있다. 다만 이러면 매번 모델 로딩 시간(2~5초)이 추가되므로, 대화를 이어가는 용도에는 적합하지 않는다.

실제 응답 속도 벤치마크 (tok/s)

실제 사용감을 알려면 tok/s(초당 토큰 생성 수)를 봐야 한다. 일반적으로 10 tok/s 이상이면 대화하는 느낌이 나고, 5 tok/s 이하면 답답하다. 아래는 M1 Pro 32GB에서 동일한 프롬프트(“Python으로 REST API 서버를 만드는 방법을 단계별로 설명해줘”)로 테스트한 결과다.

모델 프롬프트 처리 (tok/s) 생성 속도 (tok/s) 첫 토큰까지 (초) 체감
phi3:3.8b ~180 55~65 0.3 즉각 반응
mistral:7b ~120 38~42 0.5 매우 빠름
llama3.1:8b ~110 32~38 0.6 빠름
gemma2:9b ~95 28~33 0.7 빠름
qwen2.5:14b ~65 18~22 1.2 쓸 만함
codellama:13b ~60 16~20 1.3 쓸 만함
llama3.1:70b (Q4) ~15 2~4 8~15 매우 느림

이 수치는 다른 앱을 거의 안 띄운 상태에서 측정한 거다. 브라우저 탭 20개 열어놓고 Docker 돌리면 여기서 20~30% 정도 떨어진다고 보면 된다. 정확한 tok/s는 ollama run에서 /set verbose 명령을 치면 각 응답마다 표시된다.

개인적으로는 20 tok/s 이상이면 충분히 실용적이라고 본다. 그 이하로 내려가면 답변이 한 글자씩 나오는 느낌이 들어서 작업 흐름이 끊긴다.

Modelfile 커스텀으로 나만의 모델 만들기

Ollama의 Modelfile은 Docker의 Dockerfile과 비슷한 개념이다. 기존 모델을 베이스로 시스템 프롬프트, temperature, 컨텍스트 길이 등을 커스텀해서 나만의 모델을 만들 수 있다.

# Modelfile 생성
cat <<'EOF' > Modelfile
FROM llama3.1:8b

# 시스템 프롬프트 설정
SYSTEM """당신은 시니어 백엔드 개발자입니다.
항상 한국어로 답변하며, 코드 예시를 포함해서 설명합니다.
코드에는 반드시 주석을 달아주세요."""

# 파라미터 튜닝
PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER top_k 40
PARAMETER num_ctx 8192
PARAMETER repeat_penalty 1.1
PARAMETER stop "<|eot_id|>"
PARAMETER stop "<|end_of_text|>"

# 대화 템플릿 (선택사항 — 보통 FROM 모델의 기본 템플릿 그대로 쓰면 됨)
# TEMPLATE은 건드리지 않는 걸 추천. 잘못 바꾸면 모델이 이상해진다.
EOF

# 커스텀 모델 생성
ollama create my-korean-dev -f Modelfile
# transferring model data
# using existing layer sha256:...
# creating new layer sha256:...
# writing manifest
# success

# 생성한 모델 실행
ollama run my-korean-dev
>>> FastAPI에서 미들웨어 추가하는 방법 알려줘

# 모델 리스트에서 확인
ollama list | grep my-korean-dev
# my-korean-dev:latest    a1b2c3d4e5f6  4.7 GB   Just now

Modelfile에서 가장 유용한 파라미터는 이렇다.

  • temperature: 0에 가까울수록 일관된 답변, 1에 가까울수록 창의적. 코딩 용도면 0.3~0.5, 일반 대화면 0.7~0.9가 적당하다.
  • num_ctx: 컨텍스트 윈도우 크기. 기본 2048인 모델이 많은데, 긴 코드를 다루려면 8192 이상으로 올려야 한다. 다만 크게 잡으면 메모리 사용량도 올라간다.
  • top_p / top_k: 토큰 샘플링 방식. 웬만하면 기본값으로 두고, temperature만 조절하는 게 낫다.
  • repeat_penalty: 같은 말 반복을 억제. 1.0이면 페널티 없음. 1.1~1.2 정도가 적당하다.

참고로, num_ctx를 8192 이상으로 올리면 메모리 사용량이 눈에 띄게 증가한다. 8B 모델 기준으로 num_ctx를 2048에서 16384로 올리면 메모리가 약 1.5~2GB 더 필요하다. 32GB에서 13B + num_ctx 16384 조합은 가능하지만 빠듯하다.

실전 활용 팁

나는 용도별로 Modelfile을 3개 만들어두고 쓰고 있다.

  • my-korean-dev: llama3.1:8b 기반, 한국어 코딩 도우미. temperature 0.5, num_ctx 8192.
  • my-writer: qwen2.5:14b 기반, 블로그 글 초안 작성용. temperature 0.8, num_ctx 4096.
  • my-reviewer: gemma2:9b 기반, 코드 리뷰용. temperature 0.3, 시스템 프롬프트에 “버그, 보안 취약점, 성능 이슈를 집중적으로 찾아라” 지정.

Modelfile은 복잡하게 만들 필요 없다. 핵심은 SYSTEM 프롬프트와 temperature, num_ctx 세 가지다. 나머지는 기본값으로 충분하다. 자세한 내용은 Ollama 공식 다운로드를 참고하자.