LLM의 기억은 공짜가 아니다: 토큰당 300KB에서 69KB로 진화한 KV 캐시의 득과 실
최근 사내에서 LLM 기반 에이전트를 프로덕션 환경에 배포하면서 가장 골치를 앓았던 부분은 모델의 추론 속도도, 할루시네이션도 아니었습니다. 바로 GPU 메모리 와 그로 인한 인프라 비용 이었죠.
우리가 ChatGPT나 Claude에 무심코 던지는 질문들은 마법처럼 허공에 머무는 것이 아닙니다. 모든 대화는 실리콘 칩 위에서 물리적인 바이트(Byte)로 존재합니다. 이를 우리는 KV Cache 라고 부릅니다.
오늘은 Future Shock에 올라온 훌륭한 아티클과 Hacker News의 심도 있는 토론을 바탕으로, LLM이 대화의 맥락을 유지하기 위해 어떤 아키텍처적 진화를 거쳐왔는지, 그리고 이것이 실제 엔지니어링 환경에서 어떤 의미를 가지는지 파헤쳐 보겠습니다.
KV 캐시: 피할 수 없는 물리적 무게
KV 캐시는 모델이 매번 처음부터 모든 토큰을 다시 계산하는 것을 방지하기 위한 핵심 메커니즘입니다. 2,000 토큰의 대화를 나눌 때 KV 캐시가 없다면, 모델은 매 토큰을 생성할 때마다 이전 2,000개의 토큰을 Quadratic(O(N²)) 비용으로 다시 읽어야 합니다. KV 캐시는 이 연산을 Linear(O(N))하게 만들어줍니다.
하지만 이 속도의 대가는 메모리입니다. 생성된 Key와 Value 쌍은 GPU의 VRAM에 고스란히 쌓입니다. 모델의 가중치(Weights)와는 별개로, 사용자 세션마다 독립적인 메모리 공간을 차지한다는 뜻이죠. 트래픽이 몰릴 때 GPU 서버가 뻗어버리는 가장 흔한 원인입니다.
메모리 최적화의 4단계 진화
지난 6년간 트랜스포머 아키텍처가 KV 캐시를 다루는 방식은 크게 네 번 진화했습니다. 이는 엔지니어들이 메모리 한계와 어떻게 타협해 왔는지를 보여주는 훌륭한 역사입니다.
- GPT-2 (2019): 토큰당 300KB. Multi-Head Attention(MHA)의 가장 단순한 형태입니다. 모든 Attention Head가 자신만의 독립적인 Key와 Value를 가졌습니다. 메모리가 넉넉하고 모델이 작았던 시절의 무식하지만 직관적인 접근입니다.
- Llama 3 (2024): 토큰당 128KB. Grouped-Query Attention(GQA)를 도입했습니다. 여러 개의 Query Head가 동일한 Key-Value 쌍을 공유합니다. 개인적으로 이는 엔지니어링 관점에서 아주 훌륭한 타협점이라고 생각합니다. 중복된 표현(Representation)을 줄이면서도 품질 저하를 거의 막아냈으니까요.
- DeepSeek V3 (2024): 토큰당 68.6KB. Multi-head Latent Attention(MLA)라는 더 극단적인 방식을 썼습니다. 원시 K-V 텐서를 저장하는 대신, 더 낮은 차원의 Latent space로 압축한 뒤 추론 시점에 압축을 풉니다. Lossy compression(손실 압축)임에도 벤치마크 성능을 유지했다는 점이 놀랍습니다.
- Gemma 3 (2025): GQA에 Sliding Window를 결합했습니다. 최근 문맥은 선명하게 유지하고, 오래된 문맥은 좁은 Global Attention 슬릿을 통해서만 바라봅니다. “모든 것을 완벽히 기억할 필요는 없다”는 실용주의적 접근입니다.
재미있게도 Hacker News의 한 유저가 지적했듯, 69KB는 보이저 1호의 전체 RAM 용량입니다. 인류의 가장 위대한 탐사선이 우주를 항해하는 데 쓰는 메모리로, 우리는 고작 토큰 하나를 기억하고 있는 셈입니다.
실전: Context Rot과 Compaction의 함정
아키텍처가 발전했다고 해서 문제가 해결된 것은 아닙니다. 긴 대화를 나누다 보면 모델이 점점 멍청해지고 앞서 말한 내용을 잊어버리는 현상을 겪어보셨을 겁니다. 이를 Context Rot 이라고 부릅니다.
메모리가 꽉 차면 모델은 스스로 이전 문맥을 요약하고 캐시를 비우는 Compaction을 수행합니다. Cursor 같은 최신 도구들은 단순히 프롬프트로 요약하는 것을 넘어, 강화학습을 통해 Compaction 자체를 학습(Learned Compaction)시킵니다.
하지만 저는 이 방식에 여전히 회의적입니다. 코드 생성처럼 테스트 통과 여부라는 명확한 Reward Signal이 있는 도메인에서는 통하겠지만, 일반적인 비즈니스 로직이나 기획 회의록 같은 텍스트에서는 어떨까요? 모델이 어떤 정보를 버리고 어떤 정보를 남길지 스스로 결정하게 두는 것은 프로덕션 환경에서 통제 불가능한 리스크를 낳습니다. 장애가 발생했을 때 디버깅이 불가능해지기 때문이죠.
현업 엔지니어를 위한 팁: KV 양자화 (Quantization)
Hacker News 스레드에서 가장 실무적으로 와닿았던 부분은 KV 캐시 자체의 양자화에 대한 논의였습니다. 모델 가중치뿐만 아니라 캐시도 양자화할 수 있습니다.
llama.cpp를 사용해 본 분들이라면 아시겠지만, Key에는 q8을, Value에는 q4를 적용하는 비대칭 양자화 기법이 널리 쓰입니다. Key는 Attention Score를 계산하는 데 사용되므로 높은 정밀도가 필요하지만, Value는 Lossy Compression에 훨씬 더 관대하기 때문입니다. 이러한 비대칭 최적화는 제가 과거에 대규모 추천 시스템을 만들 때 Feature 임베딩의 정밀도를 조절하던 경험과 정확히 맞닿아 있습니다.
최근에는 극좌표계를 활용해 품질 저하 없이 메모리 사용량을 5배 줄이는 TurboQuant나, Stanford에서 발표한 Cartridges(Gradient descent를 활용한 캐시 최적화) 같은 기술도 등장하고 있습니다. 인프라 비용을 줄여야 하는 CTO나 아키텍트라면 반드시 주시해야 할 영역입니다.
결론: 아직은 우아하지 않은 외부 기억장치
결국 현재의 LLM은 완벽한 Medium-term Memory를 가지고 있지 않습니다. 휘발성인 KV 캐시와 영구적인 모델 가중치 사이에는 거대한 간극이 존재합니다.
우리가 RAG(Retrieval-Augmented Generation)를 구축하고, Vector DB를 띄우고, SQLite에 대화 로그를 저장하는 이유는 이 간극을 메우기 위한 투박한 임시방편(Heuristic scaffolding)입니다. 하지만 엔터프라이즈 환경에서는 당분간 이 투박한 방식이 정답이라고 봅니다. 파일이나 DB는 조용히 정보를 유실하지 않으며, 문제가 생겼을 때 정확히 무엇이 잘못되었는지 감사(Audit)가 가능하기 때문입니다.
언젠가 Greg Egan의 소설 ‘Diaspora’에 나오는 디지털 인류처럼, AI가 스스로 자신의 인지 구조와 기억 방식을 재구성하는 날이 올지도 모릅니다. 하지만 그때까지 우리는 여전히 메모리 프로파일러를 켜놓고, 토큰당 캐시 비용을 계산하며, 치열하게 인프라 비용과 싸워야 할 것입니다.
References
- Original Article: The Weight of Remembering
- Hacker News Thread: From 300KB to 69KB per Token