LLM을 돌릴 때 메모리를 잡아먹는 진짜 범인
요즘 GPT 같은 대형 언어 모델(LLM)을 직접 서빙해보신 분들은 "왜 이렇게 GPU 메모리가 금방 꽉 차지?" 하고 당황한 경험이 한 번쯤 있으실 거예요. 모델 가중치(weight)만 올리면 끝일 것 같은데, 막상 긴 대화나 긴 문서를 처리하기 시작하면 메모리가 쭉쭉 빠지거든요. 그 주범 중 하나가 바로 KV 캐시(KV cache)입니다.
이게 뭐냐면요, 트랜스포머(Transformer) 모델은 토큰(단어 조각)을 하나씩 생성할 때마다 "지금까지 본 모든 토큰"을 다시 참고해요. 어텐션(attention)이라는 메커니즘 때문인데, 매번 앞 토큰들의 Key와 Value 값을 다시 계산하면 너무 느리니까, 한 번 계산한 K와 V를 메모리에 저장해두고 재활용합니다. 이 저장 공간이 KV 캐시예요. 문제는 문맥(context)이 길어질수록, 그리고 동시에 처리하는 요청이 많아질수록 이 캐시가 선형으로 계속 불어난다는 거죠. 긴 컨텍스트 시대에 들어서면서 KV 캐시가 모델 가중치보다 메모리를 더 먹는 상황도 흔해졌어요.
핵심 아이디어: '예측해서 차이만 저장하기'
Fergus Finn이 제안한 Speculative KV coding은 이 KV 캐시를 손실 없이(lossless) 최대 4배가량 압축하는 방법입니다. '손실 없이'가 중요해요. 보통 KV 캐시를 줄일 때는 양자화(quantization)처럼 정밀도를 깎거나, 덜 중요한 토큰을 버리는(eviction) 방식을 쓰는데, 이건 결과 품질이 미묘하게 바뀔 수 있거든요. 반면 이 방법은 압축을 풀면 원래 값이 비트 단위까지 완벽하게 복원됩니다.
원리는 엔트로피 코딩(entropy coding)과 추측(speculation)의 결합이에요. 엔트로피 코딩은 zip 압축에서 쓰는 그 기술인데, "자주 나오는 패턴은 짧게, 드문 패턴은 길게" 인코딩해서 전체 크기를 줄이는 방식이에요. 그런데 그냥 적용하면 잘 안 줄어들어요. 핵심은 KV 값들이 사실 꽤 예측 가능하다는 점을 이용하는 겁니다.
작동 방식을 풀어보면 이래요. 작고 가벼운 예측기(predictor)가 "다음 KV 값이 대충 이쯤일 거야"라고 추측합니다. 그러면 실제 값과 추측값의 차이(residual)만 남게 되는데, 잘 맞는 추측이라면 이 차이는 0 근처에 몰린 아주 작은 분포가 돼요. 0 근처에 몰린 값들은 엔트로피가 낮아서 코딩하면 훨씬 짧아집니다. 마치 시험 답을 다 적는 대신 "모범답안에서 틀린 부분만 빨간펜으로 표시"하는 것과 비슷해요. 추측이 정확할수록 빨간펜 표시가 적어지고, 그만큼 더 압축되는 거죠. 이 '추측 후 차이만 저장'이라는 발상이 추측 디코딩(speculative decoding)과 닮아서 이름이 붙었어요.
다른 KV 압축 방식과 뭐가 다를까
업계에는 이미 KV 캐시를 줄이려는 시도가 많아요. 양자화(INT8, INT4 등)는 가장 흔한데 손실이 발생하고, PagedAttention(vLLM)은 메모리 단편화를 줄여 활용도를 높이지만 데이터 자체를 압축하진 않아요. MQA/GQA처럼 헤드를 공유해 KV 크기를 구조적으로 줄이는 방법은 모델 학습 단계에서 결정되는 거고요. 토큰을 골라 버리는 H2O 같은 방식은 정보를 실제로 버립니다.
Speculative KV coding이 흥미로운 건, 이미 학습된 모델을 건드리지 않고, 메모리에 올라가는 데이터를 그냥 압축한다는 점이에요. 손실이 없으니 결과 품질 저하 걱정이 없고, 다른 기법들과 조합할 여지도 있죠. 물론 공짜는 아니에요. 압축·해제에 연산이 추가되니까, 메모리는 아끼지만 그만큼 약간의 계산 오버헤드가 생깁니다. 메모리가 병목이냐 연산이 병목이냐에 따라 득실이 갈리는 거죠.
한국 개발자에게 주는 시사점
LLM을 직접 서빙하거나 파인튜닝한 모델을 온프레미스로 운영하는 팀이라면 눈여겨볼 만해요. GPU 한 장에 더 많은 동시 요청(배치)을 올리거나, 더 긴 컨텍스트를 감당하려면 결국 KV 캐시 싸움이거든요. 특히 RAG처럼 긴 문서를 통째로 넣는 서비스나, 멀티턴 대화를 오래 유지해야 하는 챗봇은 이 부분이 비용에 직접 영향을 줍니다.
당장 프로덕션에 도입할 정도로 성숙한 라이브러리는 아니지만, '손실 없는 압축'이라는 방향성 자체가 매력적이에요. 엔트로피 코딩이라는 고전 정보이론 기법이 최신 LLM 인프라에서 다시 빛을 보는 모습이기도 하고요. 정보이론 기초를 탄탄히 해두면 이런 곳에서 응용력이 나온다는 좋은 사례입니다.
마무리
한 줄로 정리하면, "KV 값을 미리 예측하고 그 차이만 무손실 압축해서 메모리를 4배 아낀다"는 이야기예요. 여러분이라면 추론 비용을 줄일 때 손실을 감수한 양자화와, 연산을 더 쓰는 무손실 압축 중 어느 쪽을 택하시겠어요? 서비스 특성에 따라 답이 갈릴 것 같은데, 여러분의 워크로드는 메모리와 연산 중 어디가 더 아쉬우신가요?
🔗 출처: Hacker News
"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"
실제 수강생 후기- 비전공자도 6개월이면 첫 수익
- 20년 경력 개발자 직강
- 자동화 프로그램 + 소스코드 제공