모델 파일은 주로 가중치를 담는다. 실행할 때는 이미 읽은 토큰의 K·V, 중간 계산과 런타임 공간이 추가로 필요하다. 특히 전체 문맥의 K·V를 보관하는 구조에서는 문맥 길이와 동시 시퀀스 수가 늘수록 캐시도 커진다. 용량에 들어가는 것과 빠르게 응답하는 것 역시 별개의 조건이다.
파일이 들어가도 실행이 버거운 이유
모델을 고를 때 가장 먼저 보이는 숫자는 매개변수 수와 다운로드 크기다. 이 둘은 중요한 출발점이지만 실행 중 필요한 메모리 전체를 뜻하지 않는다. 같은 모델을 올려도 문맥을 늘리거나 여러 요청을 동시에 처리하면 메모리가 더 필요할 수 있다.
추론 메모리를 이해하려면 세 부분으로 나누는 편이 낫다. 가중치는 학습으로 정해진 값을 담고, KV 캐시는 이번 입력과 생성 중 이미 처리한 토큰의 정보를 보관한다. 나머지는 중간 계산, 커널 작업 공간, 런타임과 메모리 관리에 쓰인다. 실제 배치와 엔진에 따라 일부 값은 장치 사이에 나뉘거나 CPU로 옮겨질 수 있다.
장치 메모리 사용량의 개념적 구성
= 장치에 올라간 가중치
+ 장치에 보관하는 KV 캐시
+ 중간 계산·작업 공간
+ 런타임·할당 관리 등의 추가 공간
이 식은 회계용 분류다. 항목들이 항상 서로 독립적으로 측정되거나 모두 최대값까지 동시에 할당된다는 뜻은 아니다. 정적 캐시와 동적 캐시, 메모리 풀의 예약 방식에 따라서도 모니터에 보이는 사용량은 달라질 수 있다.
KV 캐시는 어떤 계산을 아끼는가
자기회귀 모델은 앞선 토큰을 조건으로 다음 토큰을 만든다. 일반적인 causal Transformer에서 이미 처리한 토큰의 key와 value는 이후 토큰을 계산할 때 다시 사용할 수 있다. 이를 레이어별로 보관하는 것이 KV 캐시다. 매번 과거 부분의 K·V를 다시 계산하는 비용을 줄이는 대신 메모리를 쓴다. 이 동작은 Transformers의 캐시 설명에서 확인할 수 있다.
캐시를 쓴다고 과거 토큰과의 관계를 모두 계산하지 않아도 되는 것은 아니다. 새 토큰의 query가 앞선 key·value를 참조하는 작업은 남는다. 따라서 긴 문맥은 저장 공간뿐 아니라 실행 중 데이터 이동과 계산에도 영향을 준다.
또한 API의 “프롬프트 캐시 할인”과 여기서 말하는 KV 캐시는 같은 층의 용어가 아니다. 전자는 제품이 노출하는 재사용·과금 정책이고, 후자는 모델 실행 내부의 자료 구조다. 내부에서 연관될 수 있지만 할인율만 보고 내 장치의 KV 메모리 크기를 계산할 수는 없다.
가장 단순한 크기식부터 계산한다
아래 식은 각 레이어가 같은 수의 KV 헤드를 가지며, 전체 문맥을 캐시에 보관하고, 시퀀스 사이의 캐시 공유가 없는 경우에 적용하는 원시 저장량 계산이다. 압축·패딩·메타데이터·메모리 할당 여유는 제외한다.
KV bytes = 2 × L × Hkv × D × T × B × S
2 : key와 value 두 종류
L : 레이어 수
Hkv : 레이어당 KV 헤드 수
D : 헤드 차원
T : 시퀀스당 보관 토큰 수 (입력 + 지금까지 생성한 토큰)
B : 동시에 캐시를 보관하는 시퀀스 수
S : 값 하나의 바이트 수
이 글에서 사용할 가상의 구조는 L=32, Hkv=8, D=128, S=2다. 실제 제품의 사양을 뜻하지 않는다. 이 구조에서 시퀀스 하나의 토큰 하나는 2 × 32 × 8 × 128 × 2 = 131,072 bytes, 즉 128 KiB의 원시 캐시를 요구한다.
| 보관 토큰 수 T | 동시 시퀀스 B | 계산한 KV 저장량 |
|---|---|---|
| 8,192 | 1 | 1 GiB |
| 32,768 | 1 | 4 GiB |
| 32,768 | 4 | 16 GiB |
| 65,536 | 4 | 32 GiB |
표는 공식에 가정값을 넣은 계산 결과이며 GPU 실측이 아니다. GiB는 2³⁰ bytes다. 판매 사양의 십진 GB와 단위가 다르다. 시퀀스 길이가 제각각이면 같은 T에 B를 곱하기보다 각 시퀀스의 실제 보관 토큰 수를 합산해야 한다. 빔 탐색이나 분기 복제 역시 구현에 따라 캐시의 수와 공유 방식을 바꾼다.
가중치 양자화와 KV 양자화를 구분한다
가상의 70억 개 매개변수를 각각 정확히 4비트로 저장한다면 원시 가중치 데이터는 7,000,000,000 × 4 ÷ 8 bytes, 약 3.26 GiB다. 그러나 실제 파일에는 스케일·메타데이터 등이 더해질 수 있고, 일부 텐서는 다른 정밀도로 저장될 수 있다. 이 숫자는 다운로드 크기나 실행 중 측정값이 아니다.
여기서 가중치를 4비트로 바꿨다고 KV 캐시도 자동으로 4비트가 되는 것은 아니다. 캐시의 자료형과 양자화 지원은 별도로 확인해야 한다. 위 표는 값 하나가 2 bytes인 캐시를 가정했다. 같은 구조에서 캐시 자료형이 바뀌면 원시 크기는 달라지지만, 실제 메모리에는 양자화 보조값과 구현 비용이 붙을 수 있다.
“양자화 모델을 쓰면 얼마나 긴 문맥까지 가능할까”라는 질문에는 최소한 모델 구조, 가중치 형식, 캐시 형식, 엔진, 동시 시퀀스 수가 필요하다. 매개변수 수만으로는 답을 정할 수 없다.
GQA와 PagedAttention은 서로 다른 부분을 바꾼다
일반적인 multi-head attention에서는 쿼리 헤드와 KV 헤드의 수가 같을 수 있다. GQA(grouped-query attention)는 여러 쿼리 헤드가 KV 헤드를 공유하도록 만든다. GQA 논문이 다루는 구조를 위 식에 대입하면 캐시 크기에 들어가는 것은 쿼리 헤드 수가 아니라 Hkv다. 모델 설정에서 두 숫자를 혼동하면 추정이 크게 달라진다.
이는 캐시를 더 효율적으로 배치하는 것과는 다른 변화다. PagedAttention 논문은 요청의 캐시를 관리할 때 생기는 메모리 낭비와 공유 문제를 다룬다. 필요한 블록을 효율적으로 관리하면 같은 장치에서 더 많은 요청을 처리할 여지가 생기지만, 한 토큰이 본질적으로 요구하는 K·V 벡터 자체가 저절로 없어지는 것은 아니다.
| 접근 | 바꾸는 것 | 따로 남는 질문 |
|---|---|---|
| GQA·MQA | 공유하는 KV 헤드의 구조 | 해당 모델의 품질·구조와 엔진 지원 |
| KV 양자화 | 캐시 값의 표현 정밀도 | 오차, 보조 데이터, 실행 속도 |
| 페이지 단위 관리 | 할당·회수·공유 방식 | 실제 점유율과 스케줄링 |
| 슬라이딩 윈도 | 일부 레이어가 보관·참조하는 범위 | 모델의 구조와 정보 접근 범위 |
| 오프로딩 | 데이터를 보관하는 장치 | 장치 사이 전송 비용 |
압축된 잠재 표현을 사용하는 캐시나 혼합 레이어 구조에는 앞의 단순식을 그대로 적용할 수 없다. 계산기를 제품 사양표처럼 사용하는 대신, 실제 아키텍처와 캐시 구현을 확인하는 출발점으로 써야 한다.
용량과 속도는 두 개의 질문이다
메모리에 들어간다는 것은 필요한 데이터를 보관할 수 있다는 뜻이다. 빨리 응답하려면 그 데이터를 계산 장치로 이동시키고 연산하는 과정도 빨라야 한다. MQA 논문은 증분 디코딩에서 메모리 대역폭 부담을 줄이려는 동기를 설명한다.
입력을 처리하는 prefill과 새 토큰을 순차적으로 생성하는 decode도 나누어 관측할 필요가 있다. 첫 토큰이 나오는 시간, 이후 토큰 사이 간격, 여러 요청을 처리하는 전체 처리량은 서로 다른 경험을 설명한다. 배치를 늘려 전체 처리량이 좋아져도 한 사용자의 대기 시간은 달라질 수 있다. 특정 구간이 항상 계산 병목 또는 대역폭 병목이라고 단정하려면 안 되고, 모델·하드웨어·배치·커널 조건을 함께 봐야 한다.
실제 장비를 비교한다면 같은 입력 길이, 출력 길이, 동시 요청, 정밀도와 품질 기준을 맞추고 다음을 기록하는 편이 좋다.
- 모델·가중치 형식·추론 엔진과 버전.
- 시작 전 메모리, 로드 후 메모리, 생성 중 최고 사용량.
- 첫 토큰 지연과 생성 구간 속도, 전체 완료 시간.
- 사용하지 못한 메모리가 예약·캐시·다른 프로세스 가운데 어디에 속하는지.
이 글에서는 장비 벤치마크를 수행하지 않았다. 계산 표는 왜 문맥과 동시 요청이 메모리를 늘리는지 보여주는 설명 자료다. 구매나 서버 용량 확정에는 실제 모델과 업무의 측정 결과가 더 필요하다.
- 가중치 크기와 실행 메모리는 다르다. KV 캐시와 런타임 여유를 따로 계산한다.
- 전체 어텐션의 KV 캐시는 레이어·KV 헤드·문맥·동시 시퀀스 수에 비례한다.
- 메모리 용량은 실행 가능성, 대역폭과 계산량은 속도 판단에 함께 필요하다.
근거와 원자료
자료의 발행 시점과 이번 글에서 참고한 범위를 함께 기록합니다.
- How caching works ↗Hugging Face · Transformers · 상시 갱신 문서
자기회귀 추론에서 레이어별 K·V 재사용. main 문서이며 특정 설치 버전의 실행 기록이 아님.
- Efficient Memory Management for Large Language Model Serving with PagedAttention ↗Kwon 외 · SOSP · 2023
KV 메모리 할당·공유와 서빙 처리량의 관계. 특정 장비 벤치마크를 수행하지 않음.
- GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints ↗Ainslie 외 · EMNLP · 2023
여러 쿼리 헤드가 K·V 헤드를 공유하는 구조.
- Fast Transformer Decoding: One Write-Head is All You Need ↗Noam Shazeer · 2019
디코딩의 메모리 대역폭과 K·V 공유 동기.
갱신 기록
첫 발행. 일반 KV 캐시의 크기식을 전개하고 가정 기반 계산 도구를 연결했다.
오류를 발견했다면 →