광고
AI/기술 트렌드

KV Cache가 뭐길래

2026.04.02 13:00
76
0
1
  • 한눈에 보는 핵심요약
  • - Attention 연산 방식을 그림과 함께 요약했습니다. - KV Cache가 필요한 이유를 정리했습니다. - TurboQuant가 제안된 배경을 소개했습니다.

안녕하세요, 에디터 배니입니다.

지난해 DeepSeek에 이어 한 번 더 AI 연구가 주식 시장에 크게 영향을 미쳤습니다. 이번에는 Google의 TurboQuant가 그 주인공인데요. TurboQuant의 핵심을 한 줄로 요약하자면, KV Cache를 손실 없이 압축하여 메모리 사용을 6분의 1 수준으로 절감할 수 있다는 것입니다. 메모리 사용이 줄어든다고 하니 불쑥 ‘고성능 메모리 수요가 줄어들지 않을까’하는 우려가 시장에 반영된 것으로 보입니다. 이제 적은 메모리를 사용하고도 기존 모델을 동작시킬 수 있기 때문에 고사양 GPU가 필요하지 않으니까요.

그러나 꼭 그렇지만은 않다는 전문가 의견이 잇따르고 있습니다. 오히려 메모리 수요가 늘 것이라고 예측하기도 합니다. 그간 기술 개발에 제한이 되었던 부분이 메모리 효율의 증가로 해소되기 때문입니다. (이런 현상을 ‘제본스의 역설’이라고도 부릅니다.) 또한, KV Cache는 모델 추론(Inference)에서 비용을 절감하는 것이기 때문에 학습용 GPU와는 크게 관련이 없기도 합니다.

결국, TurboQuant가 어떻게 작동하는지 이해하기 위해서는 KV Cache가 무엇인지 알아야 합니다. KV Cache가 무엇이길래 이런 난리가 일어난 걸까요? 이번주 뉴스레터에서는 KV Cache가 무엇인지 그림과 함께 소개합니다.


KV Cache를 이해하기 위해서는 Attention을 알아야 한다.


KV Cache에서 K는 Key를, V는 Value를 의미합니다. 그리고 이 Key와 Value는 Attention 연산에서 활용됩니다. 이 Attention 연산, 더 정확히 Self-Attention 연산은 Transformer 블록의 핵심이고요. Transformer는 LLM 모델의 핵심 구조입니다. 이 Self-Attention 구조만 알아도 사실상 LLM의 핵심은 파악한 셈입니다.

Decoder-only Transformer 구조의 현대 LLM은 주어진 토큰을 보고 다음 토큰을 예측합니다. 다음 토큰을 예측한다니, 감이 잘 오지 않을 수도 있는데요. <나는 어제 치킨을 먹>까지 토큰이 주어진 상황에서 다음 토큰을 예측하라고 하면, <었>을 예측할 확률이 높습니다. 그리고 <나는 어제 치킨을 먹었>까지 토큰이 주어진다면 다음은 <다>를 예측할 확률이 높겠죠. 정말 LLM이 지능을 가지고 똑똑해서 예측을 잘했다기보다는 모델이 학습한 데이터셋에서 ‘먹’이 나오면 다음은 ‘었’이, ‘먹었’이 나오면 ‘다’가 나오는 패턴이 많았기 때문에 확률적으로 예측한 것뿐입니다.

다음 토큰을 예측한다는 의미를 이해했다면, 어떻게 계산되길래 다음 토큰을 잘 예측하는지 알아야 합니다. 저는 종종 AI 모델을 ‘거대한 계산기’라고 부르는데요. 결국, 모델 훈련 과정에서 가중치를 최적화시키고, 추론 과정에서 달라지는 입력값에 따라 이미 결정된 가중치와 연산만 하면 되기 때문입니다. 말은 쉽지만, 실제로 매우 복잡한 훈련과 연산 과정을 거칩니다. 사실상 AI 연구란 가중치를 빠르게, 정확히 최적화시키기 위해서 세계의 수많은 학자들이 연구하고 있는 셈인데요. 그중 대다수의 상황에서 준수한 성능을 보이는 하나의 연산 방식을 찾았으니, 그것이 바로 Attention 메커니즘입니다.

거두절미 하고, 가장 기본적인 Attention 연산의 수식을 알아보도록 하겠습니다. 그 유명한 <Attention Is All You Need> (Vaswani et al., 2017)에서 Attention 연산을 아래와 같이 정의합니다.

Attention Is All You Need에서 정의한 Scaled Dot-Product Attention(SDPA) 출처: <Attention Is All You Need> (Vaswani et al., 2017)

 

이런 수학 수식이 낯설다면 어려워보일 수도 있지만, Softmax 함수와 스케일을 조절하기 위한 상수 d를 제외하면 꽤 단순한 행렬 연산이 됩니다. Q, K, V는 각각 입력 토큰에 따라 계산된 행렬입니다. 아래는 입력 토큰별로 계산된 임베딩 행렬의 예시입니다. 입력 토큰은 총 4개(나는 / 어제 / 치킨을 / 먹)이고, 차원은 8입니다. 4 × 8 행렬이 생성됐습니다. (여기서는 쉬운 예를 들기 위해 차원을 8로 설정했습니다.)

 

위 행렬에 Q, K, V를 얻기 위해 가중치를 한 번씩 더 계산합니다. 결과적으로 차원의 크기는 달라지지 않으면서, Q, K, V 각각은 조금씩 다른 값을 얻게 됩니다. 아래는 헤드가 1개일 때 예시입니다. 편의상 Multi-head Attention이 아닌, Single-head Attention이라고 생각하겠습니다.

 

 

이제 Query와 Key의 Transpose를 연산해봅시다. 4 × 8 행렬과 8 × 4 행렬을 곱하여 4 × 4의 행렬을 얻게 됩니다. 즉, (입력 토큰 수) × (입력 토큰 수)만큼의 크기가 되죠.

여기까지가 QK^T 연산과정입니다. 여기에 이제 d_k로 나누고, Softmax 연산 이후에 다시 V를 계산해주면 Attention Score를 얻을 수 있습니다. 동일하게 토큰화된 문장간의 연관성을 계산한 것이기 때문에, 자기 자신과의 Attention 값을 계산한다고 하여 Self-Attention이라고 합니다. 아무리 Q와 K의 값이 다르더라도 일반적으로는 대칭적인 구조로 나타나게 됩니다. 실제로는 위 연산 결과를 도식화하면 다음과 같습니다. 위 수식과 연결이 되시나요?

Q와 K^T를 계산한 결과

 

실제로는 다음에 나올 토큰을 예측하기 위해, Softmax 이전에 미래의 토큰을 보지 못하도록 상삼각행렬에 마스크를 씌우고, Softmax 함수를 통과시킨 후 V와 계산합니다. V도 4 × 8의 행렬이었던 것 기억하시나요? 최종적으로 얻게 되는 행렬은 4 × 4 행렬과 4 × 8 행렬을 곱한 4 × 8 행렬입니다.

다시 입력 차원과 동일한 크기의 행렬을 얻게 됐습니다. 이와 같은 연산을 반복하고 최종적으로 이 행렬을 LM Head와 곱하여 가장 확률이 높은 토큰 하나를 선택합니다. LM Head 행렬은 8 × (전체 단어 수) 입니다. 즉, 최종적으로 (입력 토큰 수) × (전체 단어 수)만큼이 계산되는 것입니다. 기술 용어로 설명하자면 (Context Length) × (Vocab Size)로 볼 수 있습니다.

‘먹’의 경우 ‘었’이 가장 높게 나왔습니다. LLM의 목표는 다음 토큰을 생성하는 것이라고 했기 때문에 다른 예측값들은 필요하지 않습니다. 이런 경우 다음 토큰으로 ‘었’을 생성하고, Context Length가 1 늘어난 채로 다시 처음부터 동일한 계산을 하게 됩니다.


그래서 KV Cache는 왜 필요할까?


새로운 토큰이 입력된 뒤에도 앞서 설명한 Attention 연산을 반복하면서 다음 토큰을 하나씩 생성해나갈 수 있습니다. 그러나 사실 더이상 앞 부분의 맥락끼리는 다시 계산할 필요가 없습니다. 우리에게 필요한 건, 생성된 다음 토큰(여기서는 ‘었’)이 입력됐을 때, 그 다음 토큰이 무엇일지만 예측된 결과입니다. 이때 KV Cache가 등장합니다.

K와 V가 생성됐을 때, 각각의 값을 미리 캐싱(Caching)해뒀다고 생각해봅시다. 이 경우, 모든 토큰을 다시 생성할 필요 없이 새롭게 생성된 하나의 토큰만 계산하면 됩니다. 위 예시에서는 ‘었’이 새롭게 생성됐었죠. 첫 번째 과정에서는 (나는 / 어제 / 치킨을 / 먹)까지 모두 입력해야 했지만, 이번에는 ‘었’만 입력해도 된다는 의미입니다. 그러면 ‘었’과 관련된 Q, K, V 값을 모두 얻을 수 있습니다.

그리고 캐싱된 KV 값을 불러와 새로 생성된 ‘었’의 K, V와 연결하고, ‘었’의 Q와 계산하면 앞서 계산한 것처럼 다음 토큰을 계산할 수 있습니다. 다음 토큰인 ‘다’를 얻었다면 마찬가지로 반복하면 됩니다.

 

처음에 한 번만 전체 토큰을 계산한 뒤로는 KV를 캐싱하여 새로 생성된 토큰에 대해서만 연산을 하면 됩니다. 이때 처음 한 번 전체 과정을 연산하는 것을 Prefill이라고 하고, 이후 과정을 Decoding이라고 합니다. 모델의 추론 과정은 이렇게 두 가지 단계로 구분할 수 있습니다. KV를 캐싱하고 빠르게 메모리를 불러와 사용한다면 추론 속도를 훨씬 빠르게 개선할 수 있습니다.

 

TurboQuant는 무엇을 해결했나?

 

KV Cache는 속도를 크게 개선했지만, 한 가지 문제가 있었습니다. 컨텍스트가 길어질수록 KV Cache가 차지하는 메모리도 함께 커진다는 점입니다. LLM은 새 토큰을 생성할 때마다 이전 토큰들의 Key와 Value를 다시 계산하지 않기 위해 저장해 두는데, 이 저장 공간은 토큰 수에 비례해서 계속 증가합니다. 최근처럼 입력 가능한 컨텍스트 길이가 수만, 수십만 토큰까지 늘어나는 환경에서는 이 부담이 매우 커질 수밖에 없습니다. 문제는 저장 공간만이 아닙니다. 디코딩 단계에서는 과거의 KV Cache를 계속 읽어와야 하므로, 계산 성능보다 메모리를 읽고 쓰는 속도가 병목이 되기도 합니다.

그런데 만약 이 캐시 메모리를 가볍게 보관할 수 있다면 어떨까요? 딥러닝 모델의 숫자 표현은 최근 16비트로 이뤄집니다. 그런데 이를 8비트로 저장해둔다면 절반 수준의 용량을 아낄 수 있는 것이죠. 이를 KV 양자화(KV Quantization)라고 합니다. 32비트가 8비트가 되면서 당연히 숫자를 표현할 수 있는 범위가 줄어들고 약간의 오차가 발생하지만 그를 감수할 만큼 용량을 크게 아낄 수 있습니다. 즉, KV Quantization은 약간의 정밀도 손실과 메모리 효율을 교환하는 기술이라고 볼 수 있습니다.

KV Quantization을 적용하면 메모리는 많이 아낄 수 있지만, 비트를 너무 낮추면 Key와 Value가 너무 거칠게 압축되어 Attention 계산의 정확도가 떨어질 수 있습니다. 특히 4비트 이하의 매우 낮은 비트폭에서는 품질 저하 없이 안정적으로 압축하는 것이 쉽지 않다는 문제가 지적되어 왔죠.

이번에 발표된 TurboQuant는 이 KV Quantization에서 한 발 더 나아가, 추론 중 실시간으로 생성되는 KV 벡터를 온라인으로 바로 압축하면서도, Attention에 필요한 핵심 정보는 최대한 보존하도록 설계됐습니다. 그 결과 KV Cache를 약 2.5~3.5비트 수준까지 줄이면서도 긴 문맥 성능 저하를 최소화했고, 메모리 사용량과 디코딩 병목을 동시에 줄일 수 있었습니다.


이번 글의 목표는 KV Cache를 알아보는 데 있었습니다. TurboQuant에 적용된 기술은 다소 난도가 높아 이해하기 까다로운데요. 그럼에도 기술 자체의 특징을 알고 있다면, 궁극적으로 해당 연구가 어떤 영향을 미칠지 예측해볼 수 있습니다.

개인적으로는 하나의 AI 모델이나 연구가 단숨에 사회 전반을 대상으로 큰 타격을 주기 어렵다고 생각합니다. 연구가 계속 이어져 실증적 사례를 만들기까지는 시간이 제법 걸리는 편이고, 지속적으로 다양한 환경에서 검증이 필요하기 때문입니다. 이번 연구도 사실 지난해 4월 처음 아카이빙됐는데, 올해 Google 공식 블로그에 공개되어 주목 받더니 갑자기 주가에 큰 영향을 끼쳤습니다. 전문가들의 중론은 오히려 반대를 향하는 데도 불구하고요.

그럼에도 의미 있는 것은 그만큼 새로운 가능성을 봤다는 것입니다. 전문가들은 이 기술이 온디바이스 AI 시장에 더 큰 바람을 일으킬 것으로 보는데요. 만약 실제로 제대로 적용된다면 또 다시 새로운 AI 생태계가 구성될지도 모르는 일입니다. 그동안 숨 조여왔던 메모리 예산에서 해방되어 새로운 연구들이 쏟아져 나올 수도 있고요.

 

 

#AI
이 콘텐츠가 도움이 되셨나요?
이 글에 대한 의견을 남겨주세요!
서로의 생각을 공유할수록 인사이트가 커집니다.

    추천 콘텐츠