콘텐츠로 이동

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
└── 목표: 최적화, 멀티 테넌시

부록: 빠른 참조 링크

기술 공식 문서 GitHub
vLLM docs.vllm.ai vllm-project/vllm
Triton docs.nvidia.com triton-inference-server
LangChain python.langchain.com langchain-ai/langchain
Langfuse langfuse.com/docs langfuse/langfuse
Elasticsearch elastic.co/guide -
Qdrant qdrant.tech/documentation qdrant/qdrant

문서 버전: 1.0 최종 수정: 2026-02