LMCache KV 오프로딩을 활용한 vLLM 프로덕션 스택(vLLM Production Stack with LMCache KV Offloading)

vLLM의 프로덕션 스택(production-stack)은 라우터(router), 엔진(engine), 관측성(observability)을 한데 엮은 표준 쿠버네티스(Kubernetes) 배포 참조 구현입니다. LMCache는 KV 오프로딩(KV offloading) 계층으로, GPU 메모리(GPU memory) 밖으로 KV 캐시(KV cache)를 꺼내 여러 질의(query)와 엔진(engine)에 걸쳐 재사용하게 해줍니다(먼저 CPU DRAM, 그다음 디스크/Ceph 단계). 2026년 1월에 도입된 vLLM 0.11.0 KV Offloading Connector는 커넥터 API(Connector API; v0.9.0+)를 통해 이 경로를 비동기적이고 플러그형(asynchronous and pluggable)으로 만듭니다. 오프로딩 지연(offload latency)은 사용자에게 직접 노출되지 않습니다. LMCache는 공유 프리픽스(shared prefix)가 없어도 가치가 있는데, GPU가 KV 슬롯(KV slot)을 모두 소진했을 때 선점된 요청(preempted request)을 프리필(prefill)부터 다시 계산하지 않고 CPU에서 복원(restore)할 수 있기 때문입니다. 4대의 a3-highgpu-4g에 분산 배치한 16개 H100(80GB HBM)으로 공개된 벤치마크(published benchmark)에서는 KV 캐시가 HBM 용량을 초과할 때 네이티브 CPU 오프로드(native CPU offload)와 LMCache가 모두 처리량(throughput)을 크게 끌어올렸습니다. 반대로 KV 점유량(footprint)이 낮을 때는 모든 구성(config)이 베이스라인(baseline)에 작은 오버헤드(overhead)만 더한 수준에 머물렀습니다.

유형: Learn 언어: Python (표준 라이브러리, 간단한 KV 스필 시뮬레이터(toy KV-spill simulator)) 선수 지식: Phase 17 · 04 (vLLM Serving Internals), Phase 17 · 06 (SGLang/RadixAttention) 예상 시간: 약 60분

학습 목표

  • vLLM 프로덕션 스택(production-stack)의 계층 구조 — 라우터(router), 엔진(engine), KV 오프로드(KV offload), 관측성(observability) — 를 도식으로 설명할 수 있다.
  • 커넥터 API(Connector API; v0.9.0+)와 0.11.0의 비동기 경로(asynchronous path)가 오프로딩 지연(offload latency)을 어떻게 가리는지 설명할 수 있다.
  • LMCache의 CPU-DRAM 캐시가 도움이 되는 구간(KV가 HBM을 초과하는 경우)과 오히려 오버헤드만 더하는 구간(KV가 HBM에 충분히 들어가는 경우)을 정량적으로 구분할 수 있다.
  • 배포 제약(deployment constraint)이 주어졌을 때 네이티브 vLLM CPU 오프로드와 LMCache 커넥터(connector) 중 어느 쪽을 골라야 하는지 판단할 수 있다.

문제

운영 중인 vLLM 서빙(serving)에서 동시성(concurrency)이 올라갈 때마다 GPU의 HBM 사용률이 100%에 도달하고 선점(preemption) 이벤트가 발생합니다. 요청은 축출(evict)되고 다시 대기열에 들어가며(requeue), 똑같은 2K 토큰(token) 프롬프트(prompt)를 1분 안에 네 번이나 다시 프리필(prefill)하게 됩니다. GPU 연산은 중복된 프리필에 낭비되고, 실효 처리량(goodput)은 원시 처리량(raw throughput)보다 훨씬 낮은 수준에 머뭅니다.

GPU를 추가하면 비용이 선형으로 늘어납니다. HBM을 더 붙이는 것은 물리적으로 불가능합니다. 그러나 CPU DRAM은 상대적으로 저렴합니다. 한 소켓(socket)에 512GB 이상을 갖출 수 있고, 지연 시간(latency)은 HBM보다 몇 자릿수(order of magnitude) 더 느리지만 "잠시 따뜻하게 유지해야 하는(temporarily warm)" KV 캐시를 두기에는 충분합니다.

LMCache는 KV 캐시를 CPU DRAM으로 빼내어 선점된 요청이 빠르게 복원되도록 돕고, 여러 엔진에 걸쳐 반복되는 프리픽스(prefix)를 공유함으로써 각 엔진이 같은 프리픽스를 반복해서 프리필하지 않게 만듭니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.LMCache가 네이티브 vLLM CPU 오프로드로는 해결하지 못하는 문제는 무엇인가요?

2.vLLM에서 플러그형 KV 캐시 백엔드(pluggable KV cache backend) 인터페이스를 도입한 것은 어떤 버전이고, 2026년 1월 릴리스에서 무엇이 추가되었나요?

0/2 답변 완료

개념

vLLM 프로덕션 스택(vLLM production-stack)

github.com/vllm-project/production-stack은 표준 쿠버네티스 배포 참조 구현입니다.

  • 라우터(Router) — 캐시 인식(cache-aware) 라우터입니다(Phase 17 · 11). KV 이벤트(KV event)를 소비합니다.
  • 엔진(Engines) — vLLM 워커(worker)입니다. GPU 한 장당 하나, 또는 TP/PP(텐서 병렬/파이프라인 병렬) 그룹마다 하나를 둡니다.
  • KV 캐시 오프로드(KV cache offload) — LMCache 배포 또는 네이티브 커넥터(native connector)를 사용합니다.
  • 관측성(Observability) — Prometheus 스크레이프, Grafana 대시보드, OTel(OpenTelemetry) 트레이스로 구성됩니다.
  • 컨트롤 플레인(Control plane) — 서비스 디스커버리(service discovery), 설정, 롤링 업데이트(rolling update)를 담당합니다.

전체는 Helm 차트(chart) + 오퍼레이터(operator) 형태로 함께 배포됩니다.

KV 오프로딩 커넥터 API(KV Offloading Connector API; v0.9.0+)

vLLM 0.9.0은 플러그형 KV 캐시 백엔드(pluggable KV cache backend)를 위해 커넥터 API(Connector API)를 도입했습니다. 엔진은 블록(block)을 커넥터로 오프로드하고, 커넥터는 그 블록을 RAM, 디스크, 객체 저장소(object storage), LMCache 등 원하는 백엔드에 저장합니다. 이후 어떤 요청이 그 블록을 필요로 하면 커넥터가 다시 불러옵니다(load).

vLLM 0.11.0(2026년 1월)은 비동기 오프로드 경로(asynchronous offload path)를 추가했습니다. 일반적인 상황에서는 백그라운드(background)에서 오프로드가 진행되어 엔진이 그로 인해 차단(block)되지 않도록 한 것입니다. 다만 종단 간 지연(end-to-end latency)과 처리량은 여전히 워크로드 형태(workload shape), KV 캐시 적중률(KV cache hit rate), 시스템 부하(system pressure)에 따라 달라집니다. vLLM 공식 노트(note)도 커스텀 커널 오프로드(custom-kernel offload)가 낮은 적중률에서는 처리량을 떨어뜨릴 수 있으며, 비동기 스케줄링(async scheduling)이 추론적 디코딩(speculative decoding)과 알려진 상호작용 이슈(interaction issue)를 가진다고 명시합니다.

네이티브 CPU 오프로드와 LMCache 비교(Native CPU offload vs LMCache)

네이티브 vLLM CPU 오프로드(Native vLLM CPU offload): 엔진 로컬(engine-local) 방식입니다. KV 블록을 호스트 RAM(host RAM)에 저장합니다. 구현이 단순하고 네트워크 홉(network hop)이 없습니다. 다만 엔진 경계를 넘어 공유되지는 않습니다.

LMCache 커넥터(LMCache connector): 클러스터 단위(cluster-scale) 방식입니다. 블록을 공유 LMCache 서버(CPU DRAM + Ceph/S3 계층)에 저장합니다. 모든 엔진이 같은 블록에 접근할 수 있으며, 16개 H100 환경의 벤치마크가 공개되어 있습니다.

단일 엔진의 HBM 압박(HBM pressure)이 문제라면 네이티브를 선택합니다. 여러 엔진이 프리픽스를 공유한다면 LMCache가 정답입니다. 예를 들어 공통 시스템 프롬프트(system prompt)를 쓰는 검색 증강 생성(Retrieval-Augmented Generation; RAG)이나, 공유 템플릿(shared template)을 쓰는 멀티테넌트(multi-tenant) 워크로드가 여기에 해당합니다.

벤치마크 거동(Benchmark behavior)

4대의 a3-highgpu-4g에 걸친 16개 H100(80GB HBM) 테스트는 다음과 같은 거동을 보입니다.

  • 낮은 KV 점유량(짧은 프롬프트, 낮은 동시성): 모든 구성이 베이스라인과 비슷한 수준이며, LMCache는 약 3~5%의 오버헤드를 더합니다.
  • 중간 점유량: 엔진 간 프리픽스 재사용(prefix reuse) 효과가 살아나면서 LMCache가 도움을 주기 시작합니다.
  • KV가 HBM을 초과: 네이티브 CPU 오프로드와 LMCache 모두 처리량을 크게 끌어올리며, LMCache는 엔진 간 공유(cross-engine sharing) 덕분에 이득이 더 큽니다.

LMCache가 결정적으로 유리한 경우(When LMCache is decisive)

  • 테넌트(tenant) 간에 시스템 프롬프트가 공유되는 멀티테넌트 서빙.
  • 질의(query) 전반에서 문서 청크(document chunk)가 반복되는 RAG.
  • 같은 베이스 모델 위에 올린 미세 조정(fine-tuned) 변형 모델, 특히 LoRA. 베이스 모델의 KV 재사용이 중복 작업을 줄입니다.
  • 선점이 잦은(preemption-heavy) 워크로드. 다시 프리필하는 것보다 CPU에서 복원하는 편이 더 저렴합니다.

켜지 말아야 할 경우(When NOT to enable)

  • HBM 압박이 작을 때 — 이득 없이 오버헤드만 부담합니다.
  • 짧은 컨텍스트(<1K 토큰) — 전송 시간이 다시 프리필하는 시간보다 더 깁니다.
  • 단일 테넌트·단일 프롬프트 워크로드 — 잡아낼 재사용이 없습니다.

분산 서빙(disaggregated serving)과의 통합

Phase 17 · 17의 분산 서빙(disaggregated serving)과 LMCache를 결합하면 효과가 누적됩니다. 프리필 풀(prefill pool)에서 디코드 풀(decode pool)로 옮겨진 KV가 곧장 쓰이지 않으면 LMCache에 안착(land)하고, 이후 들어오는 질의는 LMCache에서 KV를 끌어옵니다. Phase 17 · 11의 캐시 인식 라우터(cache-aware router)는 엔진의 로컬 캐시(local cache)나 LMCache 공유 캐시 중 일치(match)하는 쪽으로 요청을 라우팅(route)할 수 있습니다.

기억해야 할 숫자(Numbers you should remember)

  • vLLM 0.9.0: 커넥터 API가 처음 출시되었습니다.
  • vLLM 0.11.0(2026년 1월): 비동기 오프로드 경로가 추가되었으며, 종단 간 지연에 미치는 영향은 워크로드, KV 적중률, 시스템 부하에 따라 달라집니다. 절대적인 보장이 아닙니다.
  • 16개 H100 벤치마크: KV 점유량이 HBM을 초과할 때 LMCache가 도움이 됩니다.
  • HBM 압박이 작을 때: 이득 없이 3~5%의 오버헤드가 발생합니다.

사용해보기

code/main.py는 LMCache를 켠 경우와 끈 경우의 선점이 잦은(preemption-heavy) 워크로드를 시뮬레이션합니다. 피한 재프리필(avoided re-prefill) 횟수, 처리량 향상(throughput gain), 손익분기(break-even)에 도달하는 HBM 사용률(HBM utilization)을 함께 보고합니다.

산출물 만들기

이 lesson은 outputs/skill-vllm-stack-decider.md를 만듭니다. 워크로드 형태(workload shape)와 vLLM 배포 정보가 주어졌을 때 네이티브, LMCache, 둘 다 사용하지 않는 선택지 중 하나를 결정해 주는 스킬(skill)입니다.

연습문제

  1. 쉬움: code/main.py를 실행해 봅니다. 어느 HBM 사용률(HBM utilization)부터 LMCache가 본전을 뽑기 시작합니까?
  2. 중간: 한 테넌트가 6K 토큰짜리 시스템 프롬프트를 시간당 200건의 질의에 공유합니다. 테넌트당 LMCache로 절약되는 비용을 추정해 봅니다.
  3. 중간: LMCache 서버는 단일 장애점(single point of failure)이 될 수 있습니다. 고가용성(High Availability; HA) 전략을 설계해 봅니다(복제본(replica) 운영, 네이티브로의 폴백(fallback to native) 등).
  4. 어려움: LMCache가 회전 디스크(spinning disk) 위의 Ceph에 저장한다고 가정합니다. 70B FP8 모델에서 4K 토큰 KV(500MB)를 다시 읽는 시간은 다시 프리필하는 시간과 비교했을 때 어떻습니까?
  5. 어려움: vLLM 0.11.0의 비동기 경로가 정말 "공짜(free)"인지 따져 봅니다. 오버헤드는 어디에 숨어 있습니까?

핵심 용어

용어흔한 설명실제 의미
프로덕션 스택(Production-stack)"참조 배포"vLLM의 쿠버네티스 Helm 차트 + 오퍼레이터
커넥터 API(Connector API)"KV 백엔드 인터페이스"vLLM 0.9.0+의 플러그형 KV 저장소 인터페이스
네이티브 CPU 오프로드(Native CPU offload)"엔진 로컬 스필"같은 엔진의 호스트 RAM에 KV를 저장하는 방식
LMCache"클러스터 KV 캐시"CPU DRAM + 디스크 위에 동작하는 엔진 간 공유 KV 캐시 서버
0.11.0 async"논블로킹 오프로드(non-blocking offload)"엔진 실행 스트림 뒤로 숨겨진 오프로드
선점(Preemption)"공간을 만들기 위한 축출"HBM이 가득 찼을 때 KV 캐시를 밀어내는 셔플
프리픽스 재사용(Prefix reuse)"같은 시스템 프롬프트"여러 질의가 앞부분을 공유해 캐시 적중이 나는 상황
Ceph 계층(Ceph tier)"디스크 계층"캐시 계층 구조에서 DRAM 아래에 놓이는 영속 저장소

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

vllm-stack-decider

Decide vLLM deployment layout — production-stack Helm chart, KV offload (native CPU or LMCache), router/observability integration — given workload and fleet size.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.16대의 H100 클러스터에서 LMCache를 켰더니 처리량 오버헤드가 3~5% 발생하고, KV 점유량(occupancy)은 HBM 용량에 훨씬 미치지 못합니다. LMCache를 계속 켜 두어야 할까요?

2.vLLM 배포에서 높은 동시성(concurrency)으로 인해 선점(preemption) 이벤트가 빈번하게 발생합니다. 같은 2K-토큰 프롬프트가 1분 안에 네 번이나 재프리필됩니다. LMCache는 이를 어떻게 해결하나요?

3.LMCache 대신 네이티브 vLLM CPU 오프로드를 선택해야 하는 경우는 언제인가요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다