도입
LLM 추론은 “요청을 골고루” 보내는 것만으로는 성능이 잘 나오지 않습니다. 이 글에서는 Prefill/Decode 분리, KV cache 라우팅, MoE 최적화 같은 흐름을 한 장의 청사진으로 정리하고, 특히 운영 복잡도와 성능 이득의 균형을 어떻게 잡을지(금융권 같은 규제 환경 포함) 관점까지 정리해보겠습니다.
왜 LLM 서빙은 기존 로드밸런싱으로 버티기 어려울까요?
전통적인 stateless HTTP 서비스는 라운드로빈이나 최소 연결(min-conn) 같은 정책으로도 꽤 잘 돌아갑니다. 그런데 LLM 추론은 구조적으로 다릅니다.
- 상태(state)가 큽니다: KV cache가 대표적입니다. 같은 대화/세션이 이어질수록 “이미 계산한 것”을 재사용할 수 있는데, 요청이 다른 노드로 튀면 캐시 히트가 깨지고 곧바로 TTFT(Time To First Token) 가 나빠집니다.
- 단계(stage)가 다릅니다: Prefill(프롬프트를 한 번에 처리)과 Decode(토큰을 한 개씩 생성)는 연산 특성/병목 지점이 완전히 다릅니다. 한 덩어리로 묶어 서빙하면, 어느 순간에는 Prefill이, 다른 순간에는 Decode가 병목이 되며 자원 효율이 급격히 흔들립니다.
- 요청 변동성이 큽니다: 프롬프트 길이 분포의 꼬리(95/99p), 버스트 트래픽, 세션 지속성 등이 큐잉과 TTFT를 크게 흔듭니다.
Red Hat의 llm-d 관련 글도 이런 맥락에서 “LLM은 상태·변동성 때문에 기존 라운드로빈이 비효율적이며, KV cache 라우팅과 Prefill/Decode 분리 같은 분산 서빙이 필요하다”는 문제의식을 강하게 제시합니다.
청사진 1: Prefill / Decode 분리(Disaggregated Serving)
Prefill은 대개 큰 행렬 연산을 한 번에 많이 수행하고, Decode는 짧은 스텝을 반복하며 KV cache를 계속 참조합니다. 따라서 이상적인 구성은 다음처럼 역할을 나누는 것입니다.
- Prefill pod 풀: 긴 입력을 빠르게 소화(대역폭/연산 집중)
- Decode pod 풀: 스트리밍으로 토큰 생성(지연 민감, KV cache 민감)
vLLM production stack 문서는 Kubernetes + Helm 기반으로 이 분리(disaggregation)를 구성하는 절차를 제공하고, 특히 Prefill 결과(KV 등)를 Decode 쪽으로 전달하는 메커니즘까지 포함해 “실제로 굴리는 방법”에 가깝게 안내합니다.
(예시) “분리 자체”가 가져오는 효과
- TTFT 최적화: Prefill 큐가 과밀해도 Decode가 같이 밀리지 않도록 분리 가능
- 자원 최적화: Prefill/Decode가 원하는 GPU 특성이 다를 수 있어, 풀을 따로 스케일링 가능
- 장애 격리: Decode 쪽 이슈가 Prefill까지 전파되는 범위를 줄임(반대로 인터페이스 복잡도는 늘어납니다)
청사진 2: KV cache 라우팅(캐시 친화 라우팅)
P/D 분리를 하든 안 하든, KV cache가 어디에 있는지가 성능을 크게 좌우합니다. 그래서 등장하는 것이 “KV cache를 고려하는 라우터”입니다.
vLLM Router는 이런 문제를 정면으로 다룹니다.
- 일관 해시(consistent hashing) 같은 방식으로 “비슷한 요청/세션”이 같은 Decode 워커로 가게 만들어 캐시 히트율을 올리는 방향
- Prefill/Decode 분산 구조를 “인지”하는 라우팅(그냥 L7 LB처럼 무지성 분산이 아님)
- 결과적으로 처리량과 TTFT를 기존 LB 대비 개선하는 것을 목표로 함
핵심은 한 줄입니다. “요청을 균등 분배”하는 게 아니라 “캐시를 최대한 재사용”하도록 분배해야 한다는 점입니다.
청사진 3: 대규모(멀티노드) 최적화와 MoE까지
규모가 커지면 “라우팅만 잘해도” 한계가 옵니다. 커널/통신/병렬화 전략이 토큰/달러를 좌우합니다.
vLLM의 Large Scale Serving 글은 H200 멀티노드 환경에서 Wide-EP, DBO, MoE 커널/통신 최적화 등을 통해 GPU당 2.2k tok/s 같은 수치를 제시하며, 단순 TPS가 아니라 토큰/달러(token/$) 개선을 강조합니다.
즉, 청사진은 보통 아래 순서로 확장됩니다.
- 단일 노드 최적화(배칭, 스케줄링)
- KV cache 친화 라우팅
- Prefill/Decode 분리
- 멀티노드 통신/병렬화 최적화 + MoE 커널 최적화
Kubernetes 네이티브 표준화 흐름: llm-d가 말하는 것
최근 흐름을 한 문장으로 요약하면 이렇습니다.
- “Kubernetes에서 LLM inference를 표준 오브젝트/패턴으로 만들자”
- 그리고 그 표준의 핵심은 상태(KV)·단계(P/D)를 아는 분산 서빙입니다.
Techzine는 llm-d의 CNCF Sandbox 편입 소식을 다루며 벤더 중립 추론 표준, GAIE/EPP, P/D 분리, 계층형 KV 오프로딩 같은 키워드를 부각합니다. (세부는 앞으로 구현/생태계가 더 정리되겠지만, 방향성 자체는 “라우팅+분리+오프로딩”으로 수렴하는 분위기입니다.)
운영 복잡도 vs 성능: “운영계/개발계”로 나누되, 기준은 트래픽·캐시가 됩니다
대화에서 정리된 결론은 현실적입니다. 운영계는 안정성/예측가능성, 개발계는 실험/변경속도가 우선입니다. 문제는 P/D 분리 + KV 라우팅을 도입하면 이 둘의 충돌이 쉽게 생긴다는 점입니다.
- 개발계: 자주 스케일/재배치/업데이트해도 괜찮음
- 운영계: 작은 재배치도 캐시 미스 증가 → TTFT 악화 → 비용 상승으로 직결될 수 있음
그래서 “계 분리”만으로는 부족하고, 운영계에는 보통 아래 같은 가드레일이 필요합니다.
- 라우팅 정책/해시 링의 안정성(rollout 시 키 변화 최소화)
- SLO 기반 자동스케일 제한(스케일이 성능을 바로 올리지 않고 캐시를 깨는 경우가 있음)
- 카나리 승격 조건에 “캐시 히트율/TTFT”를 포함(단순 에러율만으로 부족)
동일 모델을 테스트해야 할 때, 무엇이 진짜 변수일까요?
“동일 모델을 띄웠는데도” 운영과 성능이 다르게 나오는 가장 큰 원인은 보통 아래 둘입니다.
- 트래픽 분포: 프롬프트 길이 꼬리, 도착률 버스트, 스트리밍 여부
- 캐시 워밍 정도: 핫키/세션 반복이 재현되지 않으면 TTFT가 달라짐
결국 운영/개발을 가르는 기준은 “모델”보다 트래픽과 캐시가 됩니다.
TTFT를 보려면: 미러링 vs 리플레이 vs 합성(금융권 관점 포함)
TTFT는 대충 이런 합으로 생각할 수 있습니다.
- TTFT ≈ 큐잉(대기열) + Prefill 시간 + 라우팅/캐시 적중 여부
그래서 “도착률 변동 + 프롬프트 길이 꼬리”를 얼마나 재현하느냐가 핵심입니다.
1) 미러링(Shadow traffic)
운영 요청을 동시에 검증 클러스터에도 복제해 보내고 응답은 버립니다(로그만 비교).
- 장점: 운영과 같은 순간의 트래픽 믹스라 TTFT 재현력 최고
- 단점: 비용 증가(거의 2배), 운영 장애의 영향, 무엇보다 금융권에서는 PII/규제 이슈로 가장 어렵기 쉬움
2) 리플레이(Replay)
운영에서 수집한 요청 로그(길이, 도착 간격, 메타데이터 등)를 저장해두었다가 재생합니다.
- 장점: 재현성 좋고, 시간/부하를 통제 가능
- 단점: “무엇을 저장했는가”에 따라 TTFT가 달라짐(PII 마스킹, 샘플링, 스트리밍 정보 누락 등)
금융권이라면 보통 운영망 내부에서만, 그리고 강한 마스킹/토큰화를 전제로 제한적으로 가능해집니다.
3) 합성(Synthetic)
실제 로그 없이 길이 분포/도착률/반복률/핫키 비율 등을 모델링해 인공 트래픽을 생성합니다.
- 장점: 개인정보 이슈가 적고, 스트레스 테스트에 유리
- 단점: 캐시 패턴(세션 지속성, 반복 프롬프트)을 잘못 모델링하면 TTFT가 실제와 다르게 나올 수 있음
금융권에서는 현실적으로 “원문 프롬프트 저장 불가”가 잦아서, TTFT 목적이라면 합성 트래픽이라도 최소한 다음은 맞추는 편이 안전합니다.
- 프롬프트 길이 분포(특히 95/99p 꼬리)
- 도착률 버스트 패턴(피크 시간대, 이벤트성 급증)
- 요청을 몇 개의 “업무 클래스”(예: 상품조회/약관요약/민원응대)로 나눠 클래스별 반복률을 모델링(캐시 효과를 흉내)
마무리: “상태·단계를 아는 서빙”이 표준이 되는 중입니다
대규모 LLM 서빙의 방향은 점점 명확해지고 있습니다. Prefill/Decode 분리로 단계 병목을 분해하고, KV cache 라우팅으로 상태 재사용을 극대화하는 것이 처리량과 TTFT를 함께 잡는 핵심입니다. 다만 이 구조는 운영 난이도를 확실히 올리므로, 운영계/개발계를 트래픽·캐시 기준으로 분리하고(특히 금융권은 더), TTFT 검증은 미러링/리플레이/합성 중 규제와 비용에 맞는 방식을 신중히 선택하는 것이 현실적인 출발점입니다.
참고 자료
- https://arxiv.org/pdf/2401.09670
- https://vllm.ai/blog/large-scale-serving
- https://vllm.ai/blog/vllm-router-release
- https://docs.vllm.ai/projects/production-stack/en/vllm-stack-0.1.5/tutorials/disagg.html
- https://thenewstack.io/llm-d-cncf-kubernetes-inference/
- https://developers.redhat.com/articles/2025/05/20/llm-d-kubernetes-native-distributed-inferencing
- https://www.techzine.eu/news/infrastructure/139839/llm-d-joins-the-cncf/
- https://kccnceu2026.sched.com/