LLM WikiAccess-protected knowledge portal
← 스터디 홈
126편 · 약 17분

LLM KV 캐시 다계층 오프로딩: GPU HBM에서 CPU·NVMe·오브젝트 스토리지까지의 설계 패턴

요약

LLM 서빙에서 GPU 메모리가 부족한 이유는 대부분 KV 캐시 때문이다. H100 80GB 기준으로 LLaMA-3 70B 모델 가중치가 BF16으로 약 35GB를 차지하면, 남은 45GB 전체가 KV 캐시 예산이다. 128K 토큰 요청 하나가 최대 16–40GB를 점유할 수 있으므로, 동시 처리 가능한 장문 요청 수는 예상보다 훨씬 빨리 소진된다.

KV 캐시 다계층 오프로딩은 이 병목을 해소하는 아키텍처 패턴이다. 자주 사용되는 KV 데이터는 GPU HBM에 유지하고, 덜 접근되는 데이터를 CPU DRAM → NVMe SSD → 오브젝트 스토리지(S3, GCS) 순으로 내려보낸다. 각 계층은 용량, 대역폭, 비용이 다르므로 워크로드 특성에 따라 계층 설계를 달리해야 한다.

이 글은 KV 캐시가 메모리를 얼마나 사용하는지부터 각 계층의 운영 특성, vLLM/Mooncake/FlexGen의 구현 방식, 그리고 운영자가 배포 시 결정해야 할 지점까지 다룬다.


배경: KV 캐시가 GPU를 잠식하는 구조

Transformer 디코더는 각 토큰을 생성할 때 그 이전 모든 토큰의 Key와 Value 텐서를 참조한다. 이 Key·Value 행렬을 재계산하지 않고 저장해두는 것이 KV 캐시다. 자동회귀 생성(autoregressive decoding)의 핵심 최적화이지만, 그만큼 메모리를 많이 요구한다.

KV 캐시 크기 계산

KV 캐시 크기 = 2 × L × H_kv × D_head × S × B
  • 2: Key + Value 두 행렬
  • L: 트랜스포머 레이어 수
  • H_kv: KV 헤드 수 (GQA/MQA 적용 시 Q 헤드보다 적음)
  • D_head: 헤드 차원
  • S: 시퀀스 길이 (토큰 수)
  • B: 데이터타입 바이트 수 (BF16=2, FP8=1)

LLaMA-3 70B 예시 (L=80, H_kv=8, D_head=128, BF16):

  • 토큰당: 2 × 80 × 8 × 128 × 2 bytes = 327,680 bytes ≈ 320KB
  • 128K 컨텍스트 1요청: 320KB × 128,000 ≈ 40GB
  • 1M 컨텍스트 1요청: 320KB × 1,000,000 ≈ 313GB

LLaMA-3 8B 예시 (L=32, H_kv=8, D_head=128, BF16):

  • 토큰당: 2 × 32 × 8 × 128 × 2 bytes = 131,072 bytes ≈ 128KB
  • 128K 컨텍스트 1요청: 128KB × 128,000 ≈ 16GB

같은 40GB GPU에서 8B 모델(가중치 16GB)로 128K 요청을 처리하면 KV 캐시 혼자 16GB를 가져가 남은 여유가 없다. 70B 모델에서 128K 요청 2개를 동시에 받으면 KV 캐시만 80GB를 요구해 H100 전체가 부족하다.

에이전트 시대의 압력

2026년 기준 에이전트 워크로드는 단일 대화형 요청보다 훨씬 긴 컨텍스트를 생성한다. Tool 호출 결과, 검색 문서, 이전 턴 기록이 누적되면서 수십만 토큰 컨텍스트가 일반화됐다. 배치 크기가 아니라 컨텍스트 길이가 서빙 병목의 주범이 된 것이다.


계층 구조와 특성

LLM KV 캐시 다계층 오프로딩 Tier 0 Tier 1 Tier 2 Tier 3 GPU HBM (활성 KV 캐시) 용량: 40–80GB 대역폭: 3–9 TB/s 지연: 수십 ns 비용/GB: ~$50+ NVLink 또는 PCIe (수백 GB/s) CPU DRAM (웜 KV 캐시) 용량: 512GB–4TB 대역폭: 100–300 GB/s 지연: 수백 ns 비용/GB: ~$3–5 PCIe / NVMe (수 GB/s) NVMe SSD (콜드 KV 캐시) 용량: 4–32TB 대역폭: 6–14 GB/s 지연: 수십–수백 μs 비용/GB: ~$0.1 네트워크 (수 Gbps) 오브젝트 스토리지 (아카이브 KV 캐시) 용량: 무제한 대역폭: 100MB/s~수 GB/s 지연: 수–수십 ms 비용/GB: ~$0.023 🔥 최고온 🧊 최저온 KV 캐시는 최근 접근 패턴에 따라 계층 간 이동 — 재사용될 가능성이 낮을수록 하위 계층으로
LLM KV 캐시 다계층 오프로딩: 계층별 용량·대역폭·비용 비교

주요 구현 방식

1. vLLM PagedAttention + CPU 스왑

vLLM의 기본 오프로딩 방식이다. GPU에서 KV 블록(기본 16토큰 단위)이 만료되거나 우선순위가 낮아지면 CPU DRAM으로 스왑한다. 요청이 재활성화되면 반대 방향으로 복사한다.

swap_out: GPU → CPU DRAM (블록 선점)
swap_in:  CPU DRAM → GPU (블록 복원)

장점: 구현이 단순하고 기존 PagedAttention 위에 자연스럽게 올라간다.

한계: PCIe 대역폭(~64GB/s)이 병목이다. H100 HBM 대역폭(3.35TB/s)의 약 2%에 불과하므로, 스왑 발생 시 처리량이 급감한다. 실시간 서빙보다는 배치 오프라인 추론에 적합하다.

# vLLM CPU 오프로딩 설정 (참고용)
# --cpu-offload-gb 16  # CPU 오프로딩 예약 용량 (GB)
# vllm serve meta-llama/Llama-3-70b-instruct \
#   --tensor-parallel-size 4 \
#   --cpu-offload-gb 16

2. NIXL 기반 Tiered KV (vLLM 0.26+)

vLLM 0.26.0에서 도입된 NIXL(Networking Infrastructure for eXtended LLM serving)은 GPU 직접 원격 메모리 접근(RDMA)을 통해 KV 캐시를 다른 노드나 외부 스토리지로 전송한다.

Mooncake 커넥터를 통해 분리 서빙 클러스터의 전용 KV 스토어(CPU 풀 또는 SSD 클러스터)에 KV 데이터를 저장한다. Prefill 노드가 생성한 KV를 Decode 노드가 직접 네트워크에서 가져온다.

Prefill Node ──NIXL RDMA──▶ KV Store Pool ──NIXL RDMA──▶ Decode Node
              (HBM→스토어)                   (스토어→HBM)

vLLM 0.26+ KV 전송 설정:

# kv_transfer_config 예시 (JSON)
{
  "kv_connector": "MooncakeStoreConnector",
  "kv_role": "kv_both",
  "kv_connector_config": {
    "storage_url": "rdma://kv-store-host:8080"
  }
}

장점: RDMA를 사용하면 CPU를 거치지 않고 GPU HBM ↔ 원격 메모리 직접 전송이 가능하다. PCIe 경유 스왑보다 훨씬 높은 대역폭을 달성한다(400Gbps+ InfiniBand 기준 수십 GB/s).

운영 조건: InfiniBand 또는 RoCE 네트워크 필요. Mooncake 서버 인스턴스 배포 및 관리 필요.

3. FlexGen — 단일 GPU NVMe 오프로딩

FlexGen(2023, Stanford)은 단일 GPU 환경에서 70B 이상 모델을 NVMe까지 오프로딩하여 서빙하는 프레임워크다. 가중치와 KV 캐시 모두를 GPU/CPU/NVMe에 분산하고, 선형 스케줄링으로 I/O를 파이프라인한다.

처리량을 극대화하는 방향이며, 대화형 저지연 서빙보다는 대규모 배치 처리에 적합하다. 최신 에이전트 워크로드보다는 오프라인 요약·번역 등에 사용된다.

현재 위치: 단일 GPU 서빙의 참조 구현으로, vLLM의 CPU 스왑과 개념적으로 유사하나 NVMe까지 확장하고 정적 스케줄링을 도입한 점이 다르다.

4. Prefix 캐시와 계층 오프로딩의 결합

RadixAttention(SGLang)과 APC(Automatic Prefix Caching, vLLM)는 동일한 시스템 프롬프트·컨텍스트를 재사용하는 요청들의 KV를 공유한다. 여기에 계층 오프로딩을 결합하면 효과가 배가된다:

  1. 자주 공유되는 prefix KV는 GPU HBM에 고정(pin)
  2. 덜 사용되는 prefix KV는 CPU DRAM 계층으로 내림
  3. 한동안 사용되지 않은 KV는 NVMe로 내림

중요한 점은 prefix KV는 접근 패턴이 예측 가능하다는 것이다. 시스템 프롬프트가 같은 요청이 일정 주기로 들어온다면, CPU DRAM에서 GPU로 올려두는 사전 예열(prefetch) 전략이 유효하다.


계층별 사용 지침

워크로드권장 계층이유
인터랙티브 챗봇 (TTFT < 1s)GPU HBM + CPU DRAM지연 최소화 필요
긴 문서 분석 (지연 허용)GPU + CPU + NVMe비용 최적화
오프라인 배치 처리GPU + CPU + NVMe + S3최대 용량
공유 시스템 프롬프트 (고반복)GPU HBM 고정재사용률 극대화
Prefill/Decode 분리 클러스터NIXL + KV 스토어 풀P/D간 KV 전송

운영자 관점: 배포 결정 지점

GPU ↔ CPU 경계 설정

--cpu-offload-gb (vLLM 기준)를 설정할 때는 서버의 총 DRAM에서 OS, 모델 워커, 기타 프로세스가 사용하는 양을 제외해야 한다. 일반적으로 CPU DRAM의 50–70% 이하로 설정하고, 나머지를 시스템 여유분으로 남긴다.

스왑 발생 시 TTFT 스파이크 처리

CPU 스왑이 발생하면 해당 요청의 첫 토큰 지연(TTFT)이 크게 늘어난다. 이를 탐지하려면 요청별 스왑 횟수와 스왑 대기 시간을 모니터링해야 한다. vLLM 메트릭에서 vllm:cpu_swap_in_blocks_total, vllm:cpu_swap_out_blocks_total을 추적한다.

관측 지표

  • gpu_kv_cache_usage_perc: GPU KV 캐시 사용률 (90% 이상이면 위험)
  • cpu_kv_cache_usage_perc: CPU 오프로딩 사용률
  • num_preempted_reqs: 선점된 요청 수 (스왑 발생 지표)
  • cache_hit_rate: prefix 캐시 히트율 (높을수록 좋음)
  • time_to_first_token_ms: TTFT 분포 (스왑 발생 시 p99 급증)

FP8 KV 캐시 적용 시 계층 용량 변화

BF16 대신 FP8로 KV 캐시를 저장하면 동일한 계층에서 2배 용량을 확보할 수 있다. vLLM 0.25+에서 --kv-cache-dtype fp8로 설정한다. 품질 손실은 모델과 워크로드에 따라 다르지만, 대부분 실용적인 수준에서 수용 가능하다.


체크리스트

  • [ ] 서빙할 모델과 목표 컨텍스트 길이로 KV 캐시 크기를 계산했는가
  • [ ] GPU HBM 용량 대비 KV 캐시 예산이 적절한가 파악했는가
  • [ ] 인터랙티브 서빙인지 배치 서빙인지에 따라 계층 전략을 구분했는가
  • [ ] CPU 오프로딩을 사용할 경우 PCIe 대역폭 한계를 TTFT SLO와 비교했는가
  • [ ] NIXL/Mooncake 사용 시 RDMA 네트워크 인프라(InfiniBand/RoCE)가 준비됐는가
  • [ ] FP8 KV 캐시 적용으로 동일 용량에서 2배 컨텍스트 처리가 가능한지 평가했는가
  • [ ] vLLM 메트릭에서 스왑 발생 알림을 설정했는가

References

  • vLLM PagedAttention 논문 (SOSP 2023): https://arxiv.org/abs/2309.06180
  • Mooncake 분리 서빙 아키텍처 (ATC 2025): https://arxiv.org/abs/2407.00079
  • FlexGen — 단일 GPU 오프로딩: https://arxiv.org/abs/2303.06865
  • vLLM CPU Offloading 문서: https://docs.vllm.ai/en/latest/features/cpu_offload.html
  • vLLM KV Transfer 설정 가이드: https://docs.vllm.ai/en/latest/features/disagg_prefill.html
  • vLLM FP8 KV 캐시: https://docs.vllm.ai/en/latest/quantization/fp8_e5m2_kvcache.html
  • SGLang RadixAttention (KV 공유): https://arxiv.org/abs/2312.07104