토큰당 300KB에서 69KB로: LLM 아키텍처가 KV Cache 문제를 해결하는 방법
From 300KB to 69KB per Token: How LLM Architectures Solve the KV Cache Problem
TL;DR Highlight
GPT-2부터 DeepSeek V3까지, LLM이 대화 맥락을 GPU 메모리에 저장하는 KV Cache 방식이 어떻게 진화해왔는지 정리한 글. 토큰당 메모리 비용이 300KB에서 69KB로 줄어든 과정을 아키텍처별로 비교 설명한다.
Who Should Read
LLM을 직접 서빙하거나 추론 비용을 최적화해야 하는 ML 엔지니어, 또는 LLM 아키텍처 내부 동작 방식을 이해하고 싶은 백엔드/인프라 개발자.
Core Mechanics
- KV Cache는 단순한 추상 개념이 아니라 GPU 메모리에 물리적으로 존재하는 바이트다. 토큰마다 query, key, value 세 벡터를 계산하고, key-value 쌍을 GPU 메모리에 저장해두면 다음 토큰 생성 시 이전 토큰 전체를 다시 계산할 필요가 없어진다. 이 덕분에 연산 복잡도가 O(n²)에서 O(n)으로 줄어든다.
- KV Cache 없이 2,000토큰짜리 대화를 처리하면, 매 토큰 생성마다 전체 2,000토큰을 처음부터 재처리해야 한다. 즉, 2,000토큰 대화라면 전체 히스토리를 2,000번 반복 읽는 셈이다. KV Cache는 이 중복 계산을 제거한다.
- GPT-2(2019)는 Multi-Head Attention의 가장 단순한 형태로, 모든 attention head가 독립적인 key-value 쌍을 유지했다. 결과적으로 토큰당 KV Cache 비용이 300KiB였으며, 4,000토큰 대화 하나가 모델 가중치와 별도로 약 1.2GB의 GPU 메모리를 차지했다.
- Llama 3(2024)는 GQA(Grouped-Query Attention)를 전 모델 크기에 도입했다. 여러 query head가 동일한 key-value 쌍을 공유하는 방식으로, 토큰당 비용이 128KiB로 GPT-2 대비 절반 이하로 줄었다. 벤치마크상 품질 손실은 거의 없었는데, 어차피 많은 attention head가 중복된 표현을 학습하고 있었기 때문이다.
- DeepSeek V3(2024)는 MLA(Multi-Head Latent Attention)를 적용해 key-value 텐서를 그대로 캐싱하는 대신 저차원 latent space로 압축해서 저장하고, 추론 시 다시 복원하는 방식을 택했다. 671B 파라미터 모델(MoE 라우팅으로 토큰당 37B만 활성화)임에도 토큰당 캐시 비용이 68.6KiB까지 줄었다. 특히 손실 압축임에도 일부 벤치마크에서 원본 MHA보다 약간 더 나은 성능을 보였다.
- Gemma 3(2025)는 GQA에 슬라이딩 윈도우 방식을 결합했다. 로컬:글로벌 attention 레이어 비율을 5:1로 두고, 로컬 레이어는 최근 1,024토큰만 처리한다. 오래된 맥락은 좁은 글로벌 attention을 통해서만 참조된다. 이렇게 공격적으로 필터링해도 perplexity 손실이 거의 없었다.
- KV Cache 자체를 없애는 접근법도 있다. Mamba(2023) 같은 State Space Model(SSM)은 고정 크기의 hidden state를 유지하며 토큰마다 업데이트한다. 메모리가 늘어나지 않는 대신, 모델이 실시간으로 무엇을 압축할지 결정해야 한다는 트레이드오프가 있다.
Evidence
- KV Cache를 아예 그라디언트 디센트로 최적화하는 'Cartridges'라는 연구가 댓글에서 소개됐다. Stanford Hazy Research 팀의 접근법으로, 네트워크 가중치는 고정한 채로 KV Cache 자체를 학습시켜 대형 문서나 코드베이스 전체를 더 작은 토큰 집합으로 압축한다. LLM이 즉흥으로 요약하는 방식보다 체계적으로 압축할 수 있다는 점이 흥미롭다는 반응이었다.
- 아키텍처 레벨 최적화 외에도 추론 시점에 KV Cache 자체를 양자화(quantize)할 수 있다는 실용적인 팁이 공유됐다. llama.cpp에서 key는 q8, value는 q4로 양자화하면 GQA나 MLA가 이미 절약한 것 위에 메모리를 다시 절반 가까이 줄일 수 있다고 한다. 실제로 M2 Max 96GB에서 Qwen 70B 4-bit 모델을 돌릴 때, KV 양자화 덕분에 긴 컨텍스트가 unified memory 내에 들어맞았다는 경험이 공유됐다.
- Key와 Value에 다른 양자화 수준을 적용하는 비대칭 전략도 언급됐다. Key는 attention score를 결정하는 데 직접 관여하기 때문에 정밀도가 중요하지만, Value는 손실 압축에 훨씬 관대하다. 그래서 key에는 q8, value에는 q4를 쓰는 비대칭 방식이 실용적으로 잘 동작한다는 설명이었다.
- Voyager 1의 RAM 용량이 69KB라는 재미있는 사실이 댓글에 달렸다. DeepSeek V3의 토큰당 KV Cache 크기가 Voyager 1 전체 메모리와 같다는 우연의 일치로, 현대 AI 모델의 메모리 소비 규모를 유머러스하게 환기시켜 준다.
How to Apply
- llama.cpp로 대형 모델(70B+)을 로컬 또는 온프레미스에서 서빙할 때 긴 컨텍스트를 처리해야 한다면, KV Cache 양자화 옵션(key: q8, value: q4)을 활성화해서 GQA/MLA 절감분에 추가로 메모리를 절반 수준으로 더 줄일 수 있다. 특히 Apple Silicon의 unified memory 환경에서 효과적이다.
- 새 모델을 아키텍처 선택 기준으로 비교할 때 Sebastian Raschka의 LLM Architecture Gallery를 참고하면 모델별 토큰당 KV Cache 비용을 수치로 확인할 수 있다. GQA 지원 여부, MLA 적용 여부가 장기 컨텍스트 서빙 비용에 직접 영향을 미치므로, 비용 민감한 서비스라면 이 수치를 배포 전 체크리스트에 포함시켜라.
- 대형 문서나 코드베이스를 반복적으로 참조하는 RAG 파이프라인을 운영 중이라면, Stanford의 Cartridges 접근법(https://hazyresearch.stanford.edu/blog/2025-06-08-cartridges)을 검토해볼 만하다. KV Cache를 그라디언트로 직접 최적화해 문서를 더 압축된 형태로 캐싱하면, 매번 전체 문서를 컨텍스트에 넣는 것보다 메모리 효율이 높아질 수 있다.
Terminology
KV CacheLLM이 이전 토큰들의 key-value 벡터를 GPU 메모리에 저장해두는 공간. 대화 히스토리를 매번 다시 계산하지 않기 위한 일종의 '단기 작업 메모리'다.
Multi-Head Attention입력을 여러 시각(head)에서 동시에 바라보는 Transformer의 핵심 연산. 각 head가 독립적으로 key-value 쌍을 관리해서 메모리 비용이 head 수에 비례해 늘어난다.
GQA (Grouped-Query Attention)여러 query head가 하나의 key-value 쌍을 공유하는 방식. 메모리를 크게 줄이면서도 성능 손실이 거의 없어서 Llama 3 등 최신 모델들이 채택했다.
MLA (Multi-Head Latent Attention)key-value 쌍을 압축된 저차원 표현(latent vector)으로 캐싱하고, 필요할 때 복원하는 방식. DeepSeek가 개발했으며 GQA보다 메모리를 더 줄일 수 있다.
State Space Model (SSM)Mamba 같은 모델이 사용하는 방식으로, KV Cache 없이 고정 크기의 hidden state만 유지하며 새 토큰마다 업데이트한다. 메모리가 늘어나지 않는 대신 오래된 정보는 점진적으로 손실된다.
양자화 (Quantization)모델 가중치나 캐시 값을 32비트 부동소수점에서 8비트(q8)나 4비트(q4) 같은 낮은 정밀도로 압축해 메모리를 줄이는 기법. 정확도를 조금 희생하는 대신 메모리와 속도를 크게 개선한다.