LLM 서비스 기술 스택 선택 가이드
실무에서 LLM 서비스를 구축할 때 각 레이어별로 어떤 기술을 선택해야 하는지 정리한 가이드.
전체 스택 한눈에 보기
┌─────────────────────────────────────────────────────────────────┐
│ 클라이언트 레이어 │
│ Web App (React/Next.js) │ Mobile App │ API Client │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────────┐
│ API 게이트웨이 │
│ Kong │ Traefik │ Nginx │ AWS API Gateway │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────────┐
│ 애플리케이션 레이어 │
│ FastAPI │ LangChain │ LlamaIndex │ LangGraph │
└─────────────────────────────────────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌───────▼───────┐ ┌───────────▼───────────┐ ┌───────▼───────┐
│ 캐시 레이어 │ │ 검색 레이어 │ │ DB 레이어 │
│ Redis │ Dragonfly │ Elasticsearch│Qdrant │ │ PostgreSQL │
│ Memcached │ │ Milvus │ Pinecone │ │ MongoDB │
└───────┬───────┘ └───────────┬───────────┘ └───────┬───────┘
│ │ │
└────────────────────────┼────────────────────────┘
│
┌─────────────────────────────────────────────────────────────────┐
│ 추론 서빙 레이어 │
│ vLLM │ TGI │ TensorRT-LLM │ Triton │ Ollama │ llama.cpp │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────────┐
│ 모니터링 레이어 │
│ Prometheus+Grafana │ Langfuse │ LangSmith │ Phoenix │
└─────────────────────────────────────────────────────────────────┘
1. 추론 서빙 (Inference Serving)
프레임워크 비교
| 프레임워크 |
장점 |
단점 |
적합한 경우 |
| vLLM |
PagedAttention으로 높은 처리량, OpenAI 호환 API |
메모리 사용량 높음 |
프로덕션 대규모 서빙 |
| TGI (HuggingFace) |
HF 모델 쉬운 배포, 스트리밍 지원 |
vLLM보다 느림 |
HF 생태계 활용 시 |
| TensorRT-LLM |
NVIDIA 최적화, 최고 성능 |
설정 복잡, NVIDIA only |
최대 성능 필요 시 |
| Triton |
멀티 프레임워크, 동적 배칭 |
러닝커브 높음 |
여러 모델 동시 서빙 |
| Ollama |
설치 쉬움, 로컬 실행 |
확장성 제한 |
개발/테스트, 소규모 |
| llama.cpp |
CPU 지원, 경량 |
GPU 최적화 부족 |
엣지, CPU 환경 |
vLLM 모델별 권장 설정
| 모델 크기 |
GPU 권장 |
tensor-parallel |
max-model-len |
gpu-memory-util |
| 7B-8B |
A10G (24GB) |
1 |
8192 |
0.90 |
| 13B |
A100 40GB |
1 |
8192 |
0.90 |
| 34B |
A100 40GB x2 |
2 |
8192 |
0.85 |
| 70B |
A100 80GB x2 |
2 |
4096 |
0.90 |
| 70B (긴 컨텍스트) |
H100 x4 |
4 |
32768 |
0.90 |
vLLM 실행 예시
# 기본 실행 (Llama 3.1 8B)
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-8B-Instruct \
--host 0.0.0.0 \
--port 8000 \
--tensor-parallel-size 1 \
--max-model-len 8192 \
--gpu-memory-utilization 0.90
# 고성능 설정 (70B, 다중 GPU)
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 4 \
--max-model-len 16384 \
--gpu-memory-utilization 0.90 \
--enable-chunked-prefill \
--max-num-batched-tokens 65536 \
--disable-log-requests
2. 임베딩 & 리랭커
임베딩 모델 선택
| 모델 |
차원 |
언어 |
MTEB 점수 |
속도 |
용도 |
| bge-m3 |
1024 |
다국어 |
높음 |
중간 |
다국어 RAG (추천) |
| e5-large-v2 |
1024 |
영어 |
높음 |
중간 |
영어 RAG |
| multilingual-e5 |
1024 |
다국어 |
중상 |
중간 |
다국어 일반 |
| ko-sroberta |
768 |
한국어 |
중간 |
빠름 |
한국어 특화 |
| OpenAI ada-002 |
1536 |
다국어 |
높음 |
- |
API 선호 시 |
| Cohere embed-v3 |
1024 |
다국어 |
최상 |
- |
최고 품질 필요 시 |
리랭커 모델 선택
| 모델 |
언어 |
정확도 |
속도 |
비고 |
| bge-reranker-v2-m3 |
다국어 |
최상 |
중간 |
추천 |
| bge-reranker-large |
영어 |
상 |
중간 |
영어 특화 |
| cross-encoder/ms-marco |
영어 |
상 |
빠름 |
가벼움 |
| Cohere rerank-v3 |
다국어 |
최상 |
- |
API |
Triton으로 임베딩 서빙
# config.pbtxt
name: "bge-m3"
platform: "python"
max_batch_size: 64
input [
{ name: "text", data_type: TYPE_STRING, dims: [-1] }
]
output [
{ name: "embedding", data_type: TYPE_FP32, dims: [1024] }
]
instance_group [
{ count: 2, kind: KIND_GPU, gpus: [0] }
]
dynamic_batching {
preferred_batch_size: [16, 32, 64]
max_queue_delay_microseconds: 50000
}
3. 벡터 데이터베이스
선택 가이드
| DB |
특징 |
장점 |
단점 |
적합한 경우 |
| Elasticsearch |
하이브리드 검색 |
키워드+벡터, 성숙한 생태계 |
메모리 사용량 |
기존 ES 사용, 하이브리드 필요 |
| Qdrant |
고성능 벡터 DB |
빠름, Rust 기반 |
상대적으로 새로움 |
순수 벡터 검색 |
| Milvus |
대규모 벡터 DB |
확장성, 다양한 인덱스 |
운영 복잡 |
대규모 벡터 (1B+) |
| Pinecone |
관리형 서비스 |
운영 부담 없음 |
비용, 벤더 종속 |
빠른 시작, 소규모 |
| Chroma |
경량 벡터 DB |
설치 쉬움, 로컬 개발 |
확장성 제한 |
프로토타이핑, 소규모 |
| pgvector |
PostgreSQL 확장 |
기존 PG 활용 |
대규모에서 성능 |
PG 이미 사용 중 |
Elasticsearch 벡터 설정
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"analysis": {
"analyzer": {
"korean": {
"type": "custom",
"tokenizer": "nori_tokenizer",
"filter": ["nori_readingform", "lowercase"]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "korean"
},
"embedding": {
"type": "dense_vector",
"dims": 1024,
"index": true,
"similarity": "cosine",
"index_options": {
"type": "hnsw",
"m": 16,
"ef_construction": 100
}
}
}
}
}
4. 캐시 전략
캐시 레이어 선택
| 솔루션 |
특징 |
TPS |
메모리 효율 |
적합한 경우 |
| Redis |
범용, 안정적 |
100K+ |
보통 |
대부분의 경우 (추천) |
| Dragonfly |
Redis 호환, 고성능 |
400K+ |
높음 |
고성능 필요 시 |
| KeyDB |
Redis 포크, 멀티스레드 |
200K+ |
보통 |
멀티코어 활용 |
| Memcached |
단순, 빠름 |
200K+ |
높음 |
단순 캐시만 필요 |
LLM 캐시 전략
┌─────────────────────────────────────────────────────────────┐
│ 캐시 계층 구조 │
├─────────────────────────────────────────────────────────────┤
│ L1: 프롬프트 캐시 (정확 매칭) │
│ Key: hash(prompt + model + params) │
│ TTL: 24시간 │
│ Hit Rate 목표: 20-40% │
├─────────────────────────────────────────────────────────────┤
│ L2: 시맨틱 캐시 (유사 쿼리) │
│ Key: 벡터 유사도 기반 │
│ Threshold: cosine > 0.95 │
│ TTL: 12시간 │
├─────────────────────────────────────────────────────────────┤
│ L3: KV 캐시 (vLLM prefix caching) │
│ 자동 관리, 동일 프리픽스 재사용 │
│ 메모리 기반, 재시작 시 소멸 │
└─────────────────────────────────────────────────────────────┘
Redis 캐시 키 설계
# 캐시 키 패턴
CACHE_KEYS = {
# 응답 캐시 (정확 매칭)
"response": "llm:resp:{model}:{hash(prompt+params)}",
# 임베딩 캐시
"embedding": "emb:{model}:{hash(text)}",
# 검색 결과 캐시
"search": "search:{index}:{hash(query)}",
# 세션/대화 히스토리
"session": "sess:{user_id}:{session_id}",
"history": "hist:{conversation_id}",
# Rate Limiting
"ratelimit": "rl:{user_id}:{window}",
}
# TTL 설정
TTL_CONFIG = {
"response": 86400, # 24시간
"embedding": 604800, # 7일
"search": 3600, # 1시간
"session": 1800, # 30분
"history": 86400, # 24시간
}
5. 모니터링 & 관측성
도구 선택
| 도구 |
용도 |
특징 |
비용 |
| Prometheus + Grafana |
메트릭 |
오픈소스, 표준 |
무료 |
| Langfuse |
LLM 추적 |
프롬프트 버전관리, 평가 |
오픈소스/SaaS |
| LangSmith |
LLM 추적 |
LangChain 통합 |
SaaS |
| Phoenix (Arize) |
LLM 관측성 |
드리프트 감지, 평가 |
오픈소스/SaaS |
| Jaeger |
분산 추적 |
OpenTelemetry |
무료 |
핵심 메트릭
# LLM 서비스 메트릭
inference_metrics:
- name: time_to_first_token (TTFT)
description: 첫 토큰까지 시간
target: < 500ms
- name: time_per_output_token (TPOT)
description: 토큰당 생성 시간
target: < 50ms
- name: tokens_per_second
description: 초당 생성 토큰
target: > 50 tok/s
- name: requests_per_second
description: 초당 요청 수
target: 서비스 목표에 따라
- name: queue_depth
description: 대기 요청 수
alert: > 50
quality_metrics:
- name: cache_hit_rate
target: > 30%
- name: retrieval_precision
description: 검색 정확도
target: > 80%
- name: user_satisfaction
description: 👍/👎 비율
target: > 90%
Langfuse 통합 예시
from langfuse import Langfuse
from langfuse.decorators import observe
langfuse = Langfuse()
@observe()
def generate_response(user_query: str, context: list[str]):
# 검색
with langfuse.span(name="retrieval"):
docs = search_documents(user_query)
# 프롬프트 구성
prompt = langfuse.get_prompt("rag-prompt", version=2)
formatted = prompt.compile(query=user_query, context=docs)
# LLM 호출
with langfuse.generation(
name="llm-generation",
model="llama-3.1-8b",
input=formatted
) as gen:
response = call_vllm(formatted)
gen.end(output=response)
return response
6. 상황별 추천 스택
스타트업 / MVP (빠른 시작)
추론: vLLM (단일 GPU) 또는 Ollama
프레임워크: LangChain + FastAPI
벡터DB: Chroma 또는 Pinecone
캐시: Redis (단일 인스턴스)
모니터링: Langfuse (셀프호스팅)
예상 비용: GPU 서버 1대 + $100/월
중규모 서비스 (안정성 중시)
추론: vLLM (HA 구성, 2+ GPU)
임베딩: Triton (bge-m3)
프레임워크: LangChain/LlamaIndex + FastAPI
벡터DB: Elasticsearch (하이브리드 검색)
캐시: Redis Cluster
모니터링: Prometheus + Grafana + Langfuse
예상 비용: $2,000-5,000/월
대규모 엔터프라이즈
추론: TensorRT-LLM 또는 vLLM (다중 노드)
임베딩: Triton (다중 인스턴스)
오케스트레이션: Kubernetes + Istio
벡터DB: Milvus 또는 Elasticsearch 클러스터
캐시: Redis Cluster + Dragonfly
모니터링: Full Observability Stack
CI/CD: ArgoCD + MLflow
예상 비용: $10,000+/월
7. 마이그레이션 경로
Phase 1: 프로토타입
├── Ollama + Chroma + FastAPI
└── 목표: 빠른 검증
Phase 2: 초기 프로덕션
├── vLLM + Elasticsearch + Redis
└── 목표: 안정적 서비스
Phase 3: 스케일업
├── vLLM 클러스터 + Triton + Redis Cluster
└── 목표: 높은 처리량
Phase 4: 엔터프라이즈
├── TensorRT-LLM + K8s + Full Monitoring
└── 목표: 최적화, 멀티 테넌시
부록: 빠른 참조 링크
문서 버전: 1.0
최종 수정: 2026-02