Ollama vLLM 전환은 언제? — 동시 사용자 수로 결정하는 LLM 서빙 선택 기준
저도 처음엔 Ollama로 다 해결되는 줄 알았습니다. 로컬에서 ollama run llama3로 모델 띄우고, OpenAI 호환 API 붙이고, 팀 내부 챗봇 하나 만들고 나면 "이게 되네?" 싶거든요. 그런데 사용자가 늘어나기 시작하면 이야기가 달라집니다. 10명이 동시에 접속하는 순간, 응답 대기 줄이 순식간에 45초짜리 공포로 변합니다. "내 모델이 느린 건가?" 하고 의심하다가, 알고 보면 모델이 아니라 구조가 문제인 거죠. 저도 그걸 뒤늦게 깨달은 쪽입니다.
이 글은 "언제 Ollama를 vLLM으로 바꿔야 하는가"라는 질문에 동시 사용자 수라는 단 하나의 기준으로 답하는 글입니다. 두 도구의 내부 구조가 왜 다른지, 어느 시점에 전환이 유의미한지, 그리고 실제로 어떻게 마이그레이션하는지까지 다룹니다. 지금 Ollama를 쓰고 있는데 슬슬 느려진다는 걸 체감하고 있다면, 이 글이 결정을 내리는 데 직접적인 도움이 됩니다.
핵심 개념
Ollama는 왜 동시 요청에 약한가
Ollama는 llama.cpp를 기반으로 한 단일 바이너리 서버입니다. 설치가 2분이면 끝나고, Apple Silicon의 Metal 백엔드와 CPU 추론을 지원하며, 모델 다운로드부터 포맷 변환, 서빙까지 하나의 도구로 처리됩니다. 개발자 경험 측면에서는 솔직히 경쟁 상대가 없습니다.
GGUF: llama.cpp 개발자 Georgi Gerganov의 이니셜(GG)과 Universal Format(UF)을 합성한 이름입니다. CPU·Apple Silicon 환경에서 효율적으로 동작하도록 설계된 양자화 친화적 모델 포맷으로, Ollama와 llama.cpp가 사용합니다.
문제는 요청 처리 방식입니다. Ollama의 기본값은 직렬(sequential) 처리입니다. OLLAMA_NUM_PARALLEL 환경변수로 병렬 요청 수를 늘릴 수 있고, OLLAMA_MAX_LOADED_MODELS로 여러 모델을 동시에 올릴 수도 있습니다. 하지만 병렬 옵션을 켜도 각 요청에 KV 캐시 메모리를 별도로 할당하는 구조이기 때문에, 동시 사용자가 늘어날수록 메모리 압박이 급격히 커지고 처리량의 한계가 명확하게 드러납니다.
KV 캐시(Key-Value Cache): Transformer 모델이 이전에 처리한 토큰의 어텐션 정보를 메모리에 저장해두는 공간입니다. 매번 처음부터 계산하지 않아도 되어 추론 속도를 높여주지만, 동시 요청이 많아지면 이 캐시가 메모리를 대량으로 점유합니다.
vLLM이 동시 요청을 처리하는 방법
vLLM은 UC Berkeley에서 시작된 프로덕션 추론 엔진입니다. 두 가지 핵심 기술이 Ollama와의 성능 격차를 만들어냅니다.
PagedAttention은 KV 캐시를 OS의 가상 메모리처럼 비연속적인 페이지로 관리합니다. 기존 방식은 각 요청마다 최대 시퀀스 길이만큼 메모리를 미리 예약하기 때문에 실제로 쓰이지 않는 메모리가 많이 낭비됩니다. PagedAttention은 필요한 만큼만 페이지를 할당해 메모리 단편화를 제거하고, 덕분에 더 많은 요청을 동시에 처리할 수 있습니다.
Continuous Batching은 배치 전체가 완료될 때까지 기다리지 않습니다. 각 토큰 생성 이터레이션마다 새로운 요청을 GPU 파이프라인에 즉시 삽입합니다.
Forward Pass: 입력 토큰이 모델의 모든 레이어를 거쳐 다음 토큰 확률을 계산하는 한 번의 처리 과정입니다. Continuous Batching은 이 forward pass마다 대기 중인 요청을 끼워 넣어 GPU가 쉬는 시간을 최소화합니다.
결과적으로 20개의 동시 요청이 들어오면, Ollama 기본값은 19개가 큐에 쌓여 기다리지만 vLLM은 20개를 동일한 forward pass에서 병렬 처리합니다.
# vLLM 서버 실행 예시 (GPU 1장 환경 기준)
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-p 8000:8000 \
vllm/vllm-openai:latest \
--model meta-llama/Llama-3.1-8B-Instruct \
--max-model-len 4096 \
--tensor-parallel-size 1 # GPU 여러 장이면 해당 수로 변경Continuous Batching: 기존 static batching이 배치 내 모든 요청이 끝날 때까지 기다리는 것과 달리, 새 요청을 진행 중인 배치에 동적으로 끼워 넣는 방식입니다. GPU 유휴 시간을 획기적으로 줄여줍니다.
전환 판단의 핵심 지표: 동시 사용자 수
피크 처리량 기준으로는 vLLM이 793 tok/s, Ollama가 41 tok/s로 약 19배 차이가 납니다. 하지만 이 수치가 항상 의미 있는 건 아닙니다. 판단 기준을 하나만 고른다면 동시 사용자 수입니다.
| 동시 사용자 수 | Ollama P99 지연 | vLLM P99 지연 | 권장 |
|---|---|---|---|
| 1~3명 | ~2초 | ~80ms | Ollama 유지 |
| 4~10명 | 2~45초 | ~80ms | vLLM 전환 권장 |
| 50명 이상 | 24.7초+ | ~80ms | vLLM 전환 필수 |
| 128명 이상 | 사실상 서비스 불가 | ~80ms | vLLM만 가능 |
1~3명이 쓰는 내부 도구라면 vLLM의 처리량 우위는 사실상 의미가 없습니다. 설치 복잡도까지 감수하면서 전환할 필요가 없는 거죠.
장단점 분석
솔직하게 정리하자면, vLLM이 성능 면에서 압도적이지만 Ollama를 계속 써야 할 이유도 분명히 있습니다.
장점
Ollama
| 항목 | 내용 |
|---|---|
| 설치 편의성 | 단일 바이너리, 2분 설치 |
| 플랫폼 지원 | Apple Silicon, CPU 추론 모두 지원 |
| 모델 관리 | ollama pull/push로 통합 관리 |
| 콜드 스타트 | 3.2초 (vLLM 8.7초 대비 빠름) |
| 학습 곡선 | MLOps 지식 없이도 즉시 시작 가능 |
vLLM
| 항목 | 내용 |
|---|---|
| 처리량 | 피크 793 tok/s (Ollama 41 tok/s 대비 19배) |
| 지연 시간 | P99 80ms (128 동시 연결 기준) |
| 비용 효율 | 규모 증가 시 요청당 비용 10~50배 절감 |
| 기능 | Speculative Decoding, LoRA, 멀티모달 지원 |
| 최신 업데이트 | Disaggregated Prefill/Decode, Model Runner V2 |
Speculative Decoding: 작은 Draft 모델이 여러 토큰을 미리 예측하고, 큰 Target 모델이 한 번에 검증하는 방식으로 지연 시간을 줄이는 기법입니다. vLLM은 EAGLE, DFlash, n-gram, suffix 방식을 지원합니다.
단점 및 주의사항
현장에서 가장 많이 보이는 실수가 사실 이 두 번째, 모델 포맷을 미리 확인하지 않는 경우입니다. Ollama의 GGUF 파일을 그대로 가져다 쓰려다가 막히는 일이 꽤 잦습니다.
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| Ollama: 기본 직렬 처리 | 동시 요청 시 큐잉 발생 | 4명 이상이면 vLLM 전환 검토 |
| Ollama: GGUF 한정 | AWQ/GPTQ 미지원 | 해당 포맷 필요 시 vLLM 사용 |
| vLLM: Apple Silicon 미지원 | Metal/MPS 미지원 | Mac 환경에선 Ollama + MLX 사용 |
| vLLM: 설정 복잡도 | 텐서 병렬화, 양자화 포맷 변환 필요 | LiteLLM 프록시로 추상화 |
| vLLM: GGUF 미지원 | Ollama 모델 직접 사용 불가 | HuggingFace Hub에서 AWQ 모델 사용 |
| vLLM: 콜드 스타트 | 8.7초 (Ollama 3.2초 대비 느림) | 컨테이너 warm-up 스크립트 활용 |
AWQ (Activation-aware Weight Quantization): 가중치를 4비트로 양자화할 때 활성화 분포를 고려해 중요한 채널을 보호하는 방식입니다. AutoAWQ가 deprecated되면서 현재는
llm-compressor(v0.10.0.1)가 후속 도구로 사용됩니다.
실무에서 가장 흔한 실수
-
모델 포맷 확인 없이 전환을 시도하는 경우: Ollama의 GGUF 모델을 그대로 vLLM에 쓰려다가 막히는 일이 많습니다. vLLM은 GGUF를 지원하지 않으므로, HuggingFace Hub에서 동일 모델의 AWQ 또는 원본 포맷을 찾아서 사용하는 것을 권장합니다.
-
--max-model-len을 기본값으로 두는 경우: vLLM은 기본적으로 모델이 지원하는 최대 컨텍스트 길이를 그대로 사용하려 합니다. GPU 메모리가 충분하지 않으면 OOM이 발생하거나 아예 서버가 뜨지 않습니다. 실제 사용 패턴에 맞는 값으로 제한하는 것이 좋습니다. -
MLOps 역량 없이 무리하게 vLLM을 도입하는 경우: 텐서 병렬화 설정, 양자화 포맷 변환, 모니터링 구성 등 vLLM 운영에는 인프라 지식이 필요합니다. 역량이 부족한 상황에서 억지로 전환하다가 중단되는 사례가 많습니다. 이 경우 LiteLLM 같은 프록시 레이어를 먼저 도입하거나, 매니지드 추론 서비스를 검토하는 것이 더 현실적인 선택입니다.
실전 적용
예시 1: 이커머스 고객 응대 챗봇 — Ollama에서 vLLM으로
실무에서 자주 맞닥뜨리는 상황인데, 처음엔 잘 돌아가다가 트래픽이 늘면서 무너지는 패턴입니다. 초기 10명 수준의 동시 접속에서 응답 시간이 2초에서 45초 이상으로 치솟는 걸 경험하게 됩니다. "맞아, 나도 이거야"라고 느끼는 순간이 바로 전환을 고민할 시점입니다.
좋은 소식은 마이그레이션 자체가 복잡하지 않다는 겁니다. Ollama와 vLLM 모두 OpenAI 호환 API를 제공하기 때문에, base_url과 model 두 줄만 바꾸면 됩니다.
# Before: Ollama
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": "안녕하세요"}]
)# After: vLLM — 변경은 딱 두 줄
from openai import OpenAI
client = OpenAI(
base_url="http://your-vllm-server:8000/v1", # 변경
api_key="token-abc123",
)
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct", # 변경
messages=[{"role": "user", "content": "안녕하세요"}]
)| 변경 항목 | Ollama | vLLM |
|---|---|---|
base_url |
http://localhost:11434/v1 |
http://{서버IP}:8000/v1 |
model |
GGUF 모델명 (llama3.1:8b) |
HuggingFace 모델명 |
api_key |
임의 문자열 | 설정한 토큰 또는 임의 문자열 |
한 가지 미리 확인해야 할 건 모델 포맷입니다. Ollama는 GGUF를 사용하는데, vLLM은 GGUF를 지원하지 않고 AWQ나 GPTQ 양자화 모델, 또는 원본 HuggingFace 모델을 사용합니다. HuggingFace Hub에 AWQ 양자화된 모델이 올라와 있는 경우가 많아서 직접 변환할 필요 없이 가져다 쓰면 됩니다.
예시 2: 소규모 팀 Copilot — Ollama 유지 또는 이중 구조
5인 개발팀이 내부 코드 자동완성 도구를 운영하는 경우, 동시 사용자는 최대 5명 수준입니다. 이 경우엔 Ollama를 굳이 바꿀 이유가 없습니다.
다만 나중에 프로덕션으로 확장할 가능성이 있다면, Ollama(개발 환경) + vLLM(프로덕션) 이중 구조를 처음부터 염두에 두는 게 좋습니다. LiteLLM을 프록시로 두면 애플리케이션 코드를 건드리지 않고 백엔드만 교체할 수 있습니다.
# docker-compose.yml — LiteLLM 프록시로 양쪽 통합
services:
litellm:
image: ghcr.io/berriai/litellm:main-latest
ports:
- "4000:4000"
volumes:
- ./litellm_config.yaml:/app/config.yaml
command: ["--config", "/app/config.yaml"]핵심은 앱 코드에서 항상 "llama3"라는 모델명 하나만 사용한다는 겁니다. 백엔드 전환은 마운트하는 설정 파일만 바꾸면 됩니다.
# litellm_config_dev.yaml — 개발 환경 (Ollama 백엔드)
model_list:
- model_name: llama3 # 앱 코드에서 이 이름만 사용하면 됩니다
litellm_params:
model: ollama/llama3.1:8b
api_base: http://localhost:11434# litellm_config_prod.yaml — 프로덕션 환경 (vLLM 백엔드, 앱 코드 변경 없음)
model_list:
- model_name: llama3 # 동일한 이름, 백엔드만 교체
litellm_params:
model: openai/meta-llama/Llama-3.1-8B-Instruct
api_base: http://vllm-server:8000
api_key: "token-abc123"예시 3: Apple Silicon 환경 — vLLM 대신 MLX
Apple Silicon 맥을 쓰고 있다면 vLLM은 선택지에서 제외됩니다. vLLM은 CUDA와 ROCm만 지원하고 Metal/MPS를 지원하지 않기 때문입니다.
2026년 3월, Ollama가 Apple Silicon에서 기존 llama.cpp Metal 백엔드 대신 MLX를 추론 엔진으로 채택하는 Preview를 발표했습니다. M4 Pro(64GB)에서 Qwen3-Coder-30B-A3B 기준으로 MLX가 약 130 tok/s, llama.cpp가 43 tok/s로 약 3배 차이가 났습니다.
# Ollama MLX 프리뷰 활성화
OLLAMA_USE_MLX=1 ollama serve단, 이 기능은 현재 Preview 상태입니다. 안정 릴리스에서는 기본 비활성화되어 있으며, 지원 모델 목록도 제한적입니다. 활성화해도 아무 변화가 없다면 해당 모델이 MLX 백엔드를 아직 지원하지 않는 경우일 가능성이 높습니다. 사용 전에 Ollama 공식 릴리스 노트에서 현재 지원 모델을 확인해보시면 좋습니다. Mac 환경이라면 Ollama + MLX 조합이 현실적인 최선이고, 대부분의 경우 이것으로 충분합니다.
마치며
동시 사용자 수가 4~5명을 넘기 시작하고 NVIDIA GPU가 있다면 vLLM 전환을 검토할 시점입니다. 그 이전까지는 Ollama가 더 나은 선택입니다.
확인해볼 수 있는 첫 번째 단계가 있습니다.
-
피크 타임 동시 요청 수를 측정해보시면 좋습니다. 애플리케이션 로그나 간단한 부하 테스트 도구(k6, locust 등)로 확인해보시면 됩니다. 아직 도구가 없다면 아래 명령어로 현재 서버의 응답 특성을 빠르게 파악할 수 있습니다.
bash# wrk으로 동시 접속 10명 기준 30초 부하 테스트 wrk -t4 -c10 -d30s --timeout 60s http://localhost:11434/api/tags임계치(~4명)에 근접해 있다면 지금이 전환을 준비할 시점입니다.
-
하드웨어 조건을 먼저 확인해보시면 좋습니다.
nvidia-smi로 NVIDIA GPU가 있는지 확인해보시면 됩니다. Apple Silicon이라면 Ollama의 MLX 프리뷰(OLLAMA_USE_MLX=1)를 먼저 시도해보는 것도 좋은 선택입니다. -
코드 변경 없이 전환 테스트를 해볼 수 있습니다. Docker로 vLLM 서버를 로컬에 띄운 뒤, 기존 코드의
base_url과model파라미터 두 개만 바꿔서 동작을 확인해보시면 됩니다. OpenAI 호환 API 덕분에 나머지 코드는 그대로 사용됩니다.
참고 자료
- Ollama vs. vLLM: A deep dive into performance benchmarking | Red Hat Developer
- vLLM vs. Ollama: When to use each framework | Red Hat
- Performance vs Practicality: A Comparison of vLLM and Ollama | Medium
- From Local to Production: The Ultimate Ollama to vLLM Migration Guide | Towards AI
- Moving from Ollama to vLLM: Finding Stability for High-Throughput LLM Serving | Towards AI
- vLLM vs Ollama at 1/10/50/100 Users | GIGAGPU
- Ollama vs vLLM: Performance Benchmark 2026 | SitePoint
- Performance improvements with speculative decoding in vLLM for gpt-oss | Red Hat Developer
- Speculative Decoding | vLLM 공식 문서
- LLM Quantization Explained: GGUF vs GPTQ vs AWQ (2026 Guide) | TensorRigs
- vLLM vs Ollama: Production Serving vs Local Inference | DeployBase