Day 24: 로컬 모델 서빙
클라우드 API에 의존하지 않고 내 컴퓨터에서 LLM을 실행하면 비용 절감, 데이터 프라이버시, 오프라인 사용이 가능합니다. 오늘은 로컬 서빙의 대표 도구 4가지를 비교합니다.
Ollama: 가장 쉬운 로컬 LLM
Ollama는 Docker처럼 모델을 pull하고 run하는 방식으로, 설정 없이 바로 LLM을 실행할 수 있습니다.
# Ollama 설치 후 모델 다운로드 (터미널에서)
# ollama pull llama3.1:8b
# ollama pull gemma2:9b
# ollama run llama3.1:8b # 대화 시작
# Python에서 Ollama API 호출
import requests
import json
def ollama_generate(prompt, model="llama3.1:8b"):
"""Ollama REST API로 텍스트 생성"""
response = requests.post(
"http://localhost:11434/api/generate",
json={
"model": model,
"prompt": prompt,
"stream": False,
"options": {
"temperature": 0.7,
"top_p": 0.9,
"num_predict": 200,
},
},
)
result = response.json()
return result["response"]
answer = ollama_generate("파이썬의 장점 3가지를 알려주세요.")
print(answer)
# OpenAI 호환 API (기존 코드 그대로 사용 가능)
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": "안녕하세요!"}],
)
print(response.choices[0].message.content)
vLLM: 고성능 GPU 서빙
vLLM은 PagedAttention 기술로 처리량(throughput)을 극대화하는 서빙 엔진입니다. 여러 사용자의 요청을 동시에 처리할 때 위력을 발휘합니다.
# pip install vllm
# 터미널에서 vLLM 서버 시작
# vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000
# Python 클라이언트
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "한국어로 답변하세요."},
{"role": "user", "content": "머신러닝과 딥러닝의 차이를 설명해주세요."},
],
temperature=0.7,
max_tokens=300,
)
print(response.choices[0].message.content)
# vLLM 장점: 연속 배칭, PagedAttention, 높은 처리량
# GPU가 있다면 프로덕션 서빙에 가장 추천
llama.cpp: CPU 기반 경량 서빙
GPU 없이 CPU만으로 LLM을 실행할 수 있습니다. GGUF 포맷의 양자화 모델을 사용합니다.
# llama-cpp-python 설치 (CPU 버전)
# pip install llama-cpp-python
# GPU 가속 버전 (CUDA)
# CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python
from llama_cpp import Llama
# GGUF 모델 로드
llm = Llama(
model_path="./models/llama-3.1-8b-instruct-q4_k_m.gguf",
n_ctx=4096, # 컨텍스트 길이
n_threads=8, # CPU 스레드 수
n_gpu_layers=0, # GPU 레이어 수 (0이면 CPU만 사용)
)
output = llm(
"파이썬이란?",
max_tokens=200,
temperature=0.7,
top_p=0.9,
echo=False,
)
print(output["choices"][0]["text"])
서빙 도구 비교표
comparison = {
"도구": ["Ollama", "vLLM", "llama.cpp", "Text Gen WebUI"],
"난이도": ["매우 쉬움", "보통", "보통", "쉬움"],
"GPU 필수": ["아니오", "예", "아니오", "아니오"],
"CPU 지원": ["예", "아니오", "예(주력)", "예"],
"처리량": ["보통", "매우 높음", "낮음", "보통"],
"API 호환": ["OpenAI 호환", "OpenAI 호환", "자체 API", "OpenAI 호환"],
"추천 용도": ["개인 사용", "프로덕션", "CPU 서버", "웹 UI 실험"],
}
for key, vals in comparison.items():
print(f"{key:12} | {' | '.join(vals)}")
# 선택 가이드:
# - 빠르게 시작하고 싶다 -> Ollama
# - GPU 있고 프로덕션 서빙 -> vLLM
# - GPU 없고 CPU만 있다 -> llama.cpp
# - 웹 UI로 편하게 쓰고 싶다 -> Text Generation WebUI
오늘의 연습문제
- Ollama를 설치하고 3개 이상의 모델을 다운로드하여, 같은 질문에 대한 응답 품질과 속도를 비교해보세요.
- Ollama의 OpenAI 호환 API를 활용하여 간단한 챗봇 스크립트를 작성하세요. 대화 기록을 유지하는 멀티턴 대화를 구현합니다.
- llama.cpp로 GGUF 모델을 로드할 때
n_gpu_layers를 0, 10, 전체로 바꿔가며 추론 속도(tokens/sec)를 측정하고 비교해보세요.