LLM 추론을 위한 KV 캐시 (KV Cache) 최적화 가이드
요약
LLM 프로덕션 환경에서 발생하는 VRAM 부족 문제의 주요 원인인 KV 캐시의 메모리 점유 메커니즘을 분석합니다. 컨텍스트 길이에 따른 메모리 계산법과 PagedAttention 등 이를 최적화하기 위한 기술적 솔루션을 다룹니다.
핵심 포인트
- KV 캐시는 배치 크기와 컨텍스트 길이에 따라 선형적으로 증가하여 OOM의 주원인이 됨
- Llama 2 70B 기준 32K 컨텍스트 사용 시 시퀀스당 약 10.74GB의 VRAM 소모
- PagedAttention 기술을 통해 메모리 파편화로 인한 낭비를 4% 미만으로 절감 가능
- vLLM 프레임워크는 PagedAttention을 기본 메모리 관리자로 활용함
만약 당신이 대규모 언어 모델 (LLMs) 또는 멀티 테넌트 (multi-tenant) AI 에이전트를 프로덕션 환경에 배포하고 있다면, 아마도 예상치 못한 메모리 부족 (Out-Of-Memory, OOM) 오류를 겪어본 적이 있을 것입니다.
대부분의 엔지니어링 팀은 모델 가중치 (model weights) (예: FP16 정밀도의 70B 파라미터 모델의 경우 약 140 GB)를 기준으로 GPU 크기를 결정하고, 남은 VRAM을 여유 공간으로 취급합니다. 하지만 프로덕션 환경에서는 이러한 가정이 빠르게 무너집니다.
LLM 배포의 소리 없는 살인자는 모델 가중치가 아니라, 바로 KV (Key-Value) 캐시입니다.
1. KV 캐시란 무엇이며 왜 VRAM을 초과하는가?
LLM 생성 과정 동안, 모델은 매 새로운 단계마다 전체 시퀀스에 대해 어텐션 (attention)을 다시 계산할 필요가 없도록 이전에 처리된 토큰들의 키 (key) 및 값 (value) 텐서를 VRAM에 저장합니다.
이 방식은 추론 (inference) 속도를 획기적으로 가속화하지만, 캐시는 배치 크기 (batch size) 및 컨텍스트 길이 (context length)에 따라 선형적으로 증가합니다. 장시간 실행되는 에이전트 워크로드 (16K–32K+ 토큰)의 경우, KV 캐시는 종종 모델 가중치 자체보다 훨씬 더 많은 VRAM을 소비합니다.
문제점: 32K 컨텍스트 창을 가진 단일 에이전트 세션은 단 하나의 출력 토큰을 생성하기도 전에 수십 기가바이트의 VRAM을 잡아먹을 수 있습니다. 이를 동시 세션 수만큼 곱하면, OOM 오류는 필연적이 됩니다.
2. 수학적 계산: KV 캐시 메모리 점유율 계산하기
KV 캐시 메모리 점유율은 정확히 다음 공식에 따라 확장됩니다:
Memory = 2 × batch_size × seq_len × num_layers × num_kv_heads × head_dim × precision_bytes
(앞의 2는 키 (Key)와 값 (Value) 텐서를 각각 별도로 저장하는 것을 의미합니다).
실제 사례: 32K 컨텍스트에서의 Llama 2 70B
Llama 2 70B의 파라미터를 대입해 보겠습니다:
- 레이어 (Layers): 80
- KV 헤드 (KV Heads): 8 (Grouped-Query Attention 사용)
- 헤드 차원 (Head Dimension): 128
- 정밀도 (Precision): FP16 (값당 2 바이트)
32,768 토큰 컨텍스트에서의 단일 시퀀스 (1 single sequence) 기준:
Memory = 2 × 1 × 32,768 × 80 × 8 × 128 × 2 bytes
= 10,737,418,240 bytes
≈ 시퀀스당 10.74 GB
단 한 명의 사용자가 10.74 GB의 VRAM을 소비합니다. 만약 Llama 2 70B가 GQA (8 heads) 대신 표준 Multi-Head Attention (64 heads)을 사용했다면, 그 수치는 시퀀스당 85 GB 이상으로 치솟았을 것입니다.
3. 핵심 KV 캐시 (KV Cache) 최적화 기술
메모리 부족 현상을 방지하기 위해, 현대의 서빙 프레임워크는 네 가지 주요 아키텍처 솔루션을 결합합니다:
| 기술 | 작동 방식 | 영향 |
|---|---|---|
| PagedAttention | OS의 가상 메모리 원리를 GPU RAM에 적용하여, 블록 테이블(block tables)을 통해 캐시를 비연속적인 블록으로 나눕니다. | 파편화(fragmentation)로 인한 낭비를 60~80%에서 4% 미만으로 줄입니다. |
| ... |
4. 실습 튜토리얼: vLLM을 이용한 PagedAttention 구현
vLLM은 기본 메모리 관리자로 PagedAttention을 활용합니다. 최적화된 추론 서버를 구성하고 배포하는 방법은 다음과 같습니다.
1단계: vLLM 설치
pip install vllm
2단계: PagedAttention 및 최적화 플래그를 사용하여 서버 시작
높은 메모리 할당, 접두사 캐싱 (prefix caching), 그리고 FP8 KV 캐시 양자화 (quantization)를 적용하여 서버를 실행합니다:
vllm serve meta-llama/Llama-2-70b-chat-hf \
--gpu-memory-utilization 0.90 \
--max-model-len 32768 \
...
--gpu-memory-utilization 0.90: 모델 가중치와 페이지화된 KV 캐시 풀(paged KV cache pool)을 위해 GPU VRAM의 90%를 할당합니다.--enable-prefix-caching: 요청 간에 동일한 프롬프트 접두사 (prompt prefixes)를 다시 계산하는 것을 방지합니다.--kv-cache-dtype fp8: 토큰당 KV 캐시 메모리 점유율을 절반으로 줄입니다.
3단계: 동시 부하 벤치마크 실행
vLLM에는 높은 부하 상황에서의 처리량 (throughput)을 측정하기 위한 내장 벤치마킹 스크립트가 포함되어 있습니다:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-2-70b-chat-hf &
...
실행 중에 nvidia-smi를 통해 메모리 사용량을 모니터링하여, 메모리가 충돌 없이 설정한 한계치까지 깔끔하게 확장되는지 확인하십시오.
5. 연구 벤치마크 및 성능 영향
원본 PagedAttention 연구 논문 (Kwon et al., SOSP 2023)에 따르면:
- 메모리 낭비 (Memory Waste): 기존의 단순 연속 할당 (naive contiguous allocation) 방식의 60–80%에서 4% 미만으로 감소했습니다.
- 처리량 (Throughput): 동일한 지연 시간 (latency) 기준, 이전의 최첨단 서빙 시스템 (Orca 및 FasterTransformer 등)과 비교하여 2–4배 더 높은 처리량을 달성했습니다.
- 운영 규모 (Production Scale): 실제 배포 사례 (LMSYS Chatbot Arena 등)에서 2–3배 더 많은 트래픽을 처리하면서도 필요한 총 GPU 수를 50% 줄였습니다.
💡 요약 및 다음 단계
긴 문맥 (long-context) LLM 애플리케이션에서 KV 캐시 (KV cache) 최적화는 선택 사항이 아닙니다. 인프라 비용을 통제하고 메모리 부족 (OOM)으로 인한 다운타임을 방지하기 위해 필수적입니다.
👉 이 글은 원래 **GPUYard**에 게시되었습니다. LLM 인프라 및 MLOps 최적화에 대한 더 심도 있는 내용을 확인하려면 원문 기사를 참조하세요!
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기