Documents
Home>Documents>AI>Inference

GQA를 쓰면 KV 캐시가 줄어드는데 왜 TPOT는 기대만큼 안 줄어드는가: Attention 헤드 구조와 메모리 대역폭의 실측

17 min readSep 9, 2026Sep 9, 2026

GQA가 KV 캐시를 줄인다는 건 안다. Llama-3 70B가 Llama-2 70B보다 KV 캐시를 8분의 1로 줄인다는 것도 이미 알려진 사실이다. 그런데 실제 서빙을 돌리면 TPOT가 8분의 1이 되지 않는다. 2분의 1도 안 되는 경우가 많다. 왜인지를 제대로 이해하려면 decode 단계에서 GPU가 실제로 어디서 시간을 쓰는지를 먼저 봐야 한다.

MLA(Multi-head Latent Attention)는 이 그림을 더 복잡하게 만든다. DeepSeek 계열 모델이 프로덕션에 올라오는 사례가 늘면서 "MLA가 GQA보다 낫다"는 말이 돌고 있는데, 어떤 조건에서 낫고 어떤 조건에서 그렇지 않은지를 모르면 제대로 쓸 수 없다.

헤드 구조별 KV 캐시 크기: 수식으로 먼저 확인하다

MHA, MQA, GQA, MLA 모두 결국 "레이어당 토큰당 KV 캐시 bytes"를 줄이는 게 목표다. 수식은 공통이고 n_kv 값만 다르다.

KV cache bytes = n_layers × n_kv × d_head × 2(K+V) × L × B × bytes_per_elem

Llama-3 70B 아키텍처(n_layers=80, n_heads=64, d_head=128, FP16)로 시퀀스 하나에 컨텍스트 8K를 잡으면 각 변형의 차이가 명확하다.

방식n_kvKV cache/seq (ctx=8K)비고
MHA (Llama-2 70B)6421.5 GB모든 Q 헤드가 독립 KV
GQA-8 (Llama-3 70B)82.7 GB8그룹, 8배 절감
MQA10.34 GBKV 헤드 1개 전체 공유

배치 32로 서빙하면 MHA는 688 GB, GQA-8은 86 GB다. A100 80GB 서버 8장짜리에서 MHA 배치 32는 VRAM이 터지고, GQA-8이면 2장에 들어간다. 이 용량 차이가 처리량에 직결된다.

MLA는 수식 자체가 달라서 별도 섹션에서 다룬다.

KV 캐시가 줄어도 TPOT가 안 줄어드는 이유

Decode 단계는 memory-bound다. GPU 연산 장치가 HBM에서 데이터가 올라오길 기다리는 시간이 지배한다. 그렇다면 KV 캐시 bytes가 줄면 HBM 로딩도 줄고 TPOT도 줄어야 하는데, 이 추론에는 빠진 항목이 있다.

Decode step마다 GPU가 HBM에서 읽는 건 KV 캐시만이 아니다. 가중치 행렬을 매 토큰마다 다시 읽는다. Llama-3 70B를 BF16으로 올리면 가중치만 140 GB다. H100 SXM의 HBM3 대역폭이 약 3.35 TB/s이므로 140 GB를 읽는 데만 이론상 41 ms 걸린다. GQA든 MHA든 이 비용은 동일하다.

KV 캐시 로딩 비용은 시퀀스 길이와 배치 크기에 비례한다. 배치=1, 컨텍스트=8K에서 GQA-8 KV 캐시는 2.7 GB다. 가중치 140 GB에 비하면 작다. 배치가 커지면 역전된다. 배치=64, 컨텍스트=8K라면 GQA-8 KV 캐시가 172 GB로 가중치를 넘어선다. 이 교차점부터 KV 캐시 절감이 TPOT에 실질적으로 반영된다.

Roofline 모델로 보면: A100의 FP16 ridge point는 약 153 FLOPs/byte, H100은 약 295 FLOPs/byte다. Decode 단계의 산술 집약도(arithmetic intensity)는 배치=1에서 10 FLOPs/byte 이하에 머무는 경우가 많아 ridge point의 1/15 수준이다. 이 구간에서는 어떤 방식으로 HBM 로딩을 줄여도 bottleneck의 일부만 건드린다.

KV 캐시 절감이 TPOT에 연결되는 경로는 두 갈래다. 하나는 KV 로딩 bytes가 직접 줄어드는 것으로, large batch + long context 구간에서만 유의미하다. 다른 하나는 같은 VRAM에 더 많은 시퀀스를 올릴 수 있어서 배치 크기 자체를 늘리는 것인데, 이쪽이 small batch 구간에서도 처리량을 올리는 주된 경로다. 서빙 throughput 관점에서는 두 번째 경로가 더 자주 작동한다.

MLA는 무엇이 다른가: 저차원 압축의 서빙 함의

DeepSeek-V2 논문(arXiv:2405.04434)의 MLA는 KV를 헤드별 고차원 텐서로 캐시하는 대신 저차원 latent vector 하나를 캐시하고, attention 계산 시 각 Q 헤드에 맞는 K·V를 up-projection으로 복원한다.

DeepSeek-V2 수치로 보면: query 헤드 수 n_h=128, 헤드 차원 d_h=128, KV 압축 차원 d_c=512, decoupled RoPE 차원 d_h^R=64. 레이어당 토큰당 캐시 크기를 MHA와 비교하면:

cache dims/token/layerFP16 bytes
MHA 등가 (n_h=128)2 × 128 × 128 = 32,76864 KB
MLA latent512 + 64 = 5761.1 KB

약 57배 차이다. 논문에서는 이 캐시 크기가 GQA로 환산하면 KV 헤드 2.25개 수준(576 / (2 × d_h) = 576/256 ≈ 2.25)이라고 표현한다. DeepSeek-V2 60개 레이어, 시퀀스 하나, 컨텍스트 8K를 잡으면 MHA 등가가 약 30 GB인 자리에 MLA는 540 MB다. DeepSeek-V2는 직전 버전인 DeepSeek 67B 대비 KV 캐시를 93.3% 줄였다고 보고한다.

GQA와 구조적으로 다른 지점이 있다. GQA는 KV 헤드 수를 줄여서 캐시와 attention 연산 FLOPs를 함께 줄인다. MLA는 캐시에 저장하는 건 압축된 latent vector지만 매 decode step에서 각 Q 헤드에 맞는 K·V를 up-projection으로 복원해야 한다. 로딩 bytes는 줄고 FLOPs는 늘어난다 — 산술 집약도가 올라간다. HBM 대역폭 대비 연산 능력이 충분한 H100에서는 bytes 감소가 이득이고, 상대적으로 대역폭이 넓고 compute ceiling이 낮은 구형 GPU에서는 FLOPs 증가가 부담이 될 수 있다.

vLLM은 v0.7.1부터 DeepSeek MLA를 네이티브로 지원하는데, "matrix absorption" 기법으로 up-projection을 Q side의 down-projection과 수학적으로 합성해 decode 시 명시적인 복원 없이 attention을 계산한다. latent를 직접 캐시하면서 FLOPs overhead를 최소화하는 방향이다. 단, decoupled RoPE 부분(d_h^R=64)은 위치 의존성 때문에 absorption이 불가능해 명시적으로 저장하고 처리한다 — 이게 캐시 크기에 512가 아닌 576이 들어가는 이유다.

배치 크기 × 컨텍스트 길이에 따른 구조별 특성

가중치 로딩 비용과 KV 캐시 로딩 비용의 상대적 크기가 어느 구조가 유리한지를 결정한다. 이론적으로 정리하면:

짧은 컨텍스트 (≤2K)긴 컨텍스트 (≥8K)
소배치 (B≤8)구조 간 TPOT 차이 미미 (가중치 지배)GQA/MLA TPOT 개선 시작
대배치 (B≥32)KV 용량이 처리량 한계 결정 → GQA/MLA 우위MLA 용량 우위 뚜렷, TPOT 격차 벌어짐

소배치·짧은 컨텍스트에서는 GQA-8이 MHA보다 TPOT가 의미 있게 빠르다고 단언하기 어렵다. 가중치 로딩 비용이 워낙 지배적이라 KV 측 절감이 측정 오차 안에 묻히는 경우가 많다. 반대로 대배치·장컨텍스트에서 GQA가 MHA보다 동일 latency에 더 많은 시퀀스를 처리하는 건 일관되게 관측된다.

MLA는 캐시 용량 측면에서는 모든 구간에서 GQA를 압도한다. TPOT 측면에서는 H100 이상 환경에서 GQA와 동등하거나 소폭 우위다. 짧은 컨텍스트·소배치에서 up-projection overhead가 오히려 GQA보다 느리게 나타나는 경우도 보고되어 있어 일괄적으로 "MLA가 항상 빠르다"고 말할 수 없다.

vLLM에서 GQA 모델을 돌릴 때 --max-num-seqs를 늘리면서 TPOT를 관찰하면 배치가 작을 땐 TPOT가 거의 변하지 않다가 KV 메모리가 포화하기 시작하는 시점에서 GQA의 용량 이점이 처리량으로 전환되는 패턴이 나온다. TTFT는 prefill 단계로 attention FLOPs가 실제로 줄어드는 효과가 있어 컨텍스트 길이와 관계없이 GQA > MHA가 소폭 관측된다.

품질 손실은 어디서 드러나는가

GQA 논문(Ainslie et al., 2023)에서는 MQA가 MHA 대비 품질 손실을 보이는 반면 GQA가 그 중간 지점을 점한다고 보여준다. 이 손실이 두드러지는 구간이 long-context recall이다.

Needle-in-Haystack 류 태스크에서 컨텍스트가 16K, 32K로 늘어나면 MQA는 특정 depth 구간에서 recall 정확도가 급격히 무너진다. GQA는 그룹 수로 이 손실 곡선을 제어할 수 있다 — 그룹이 많을수록 MHA에 가까워지고 품질이 올라가며 캐시 절감 폭은 줄어든다. Llama-3 70B가 GQA-2 대신 GQA-8을 택한 게 우연이 아닐 것이다. GQA-2는 아마 내부 long-context 벤치마크에서 허용 불가한 품질 손실이 나왔을 거라고 추측된다.

MLA는 압축-복원 과정에서 수치 오차가 누적되는 조건이 있다. 특히 very long context에서 decoupled RoPE와 latent 복원의 상호작용이 attention score 분포에 영향을 줄 수 있다. DeepSeek-V2가 "MHA를 상회한다"는 건 그 모델에 맞게 d_c와 학습 과정을 최적화했기 때문이고, 같은 압축 비율을 다른 아키텍처에 그대로 적용하면 결과가 다를 수 있다.

현재로서는 MLA를 채택한 사례가 DeepSeek 계열에 집중되어 있어 독립적인 third-party long-context 벤치마크가 충분히 쌓이지 않았다. LongBench나 Needle-in-Haystack에서 GQA-8과 MLA를 동일 파라미터 수 기준으로 직접 비교한 결과가 많지 않다는 것이 현재 판단을 어렵게 만드는 요인이다.

서빙 엔지니어가 모델 구조를 고를 수 없을 때

모델 구조는 대부분 이미 정해진다. 그 이후에 조정할 수 있는 레버는 세 가지다.

TP degree와 KV 헤드 수의 궁합. GQA 모델에서 tensor parallel degree가 n_kv_heads보다 크면 KV 헤드가 복제된다. Llama-3 70B(n_kv=8)를 TP=4로 돌리면 GPU당 KV 헤드 2개로 정상이지만, TP=16이면 vLLM이 KV 헤드를 복제해서 처리한다. 복제된 KV 캐시는 중복 저장되어 GQA의 메모리 이점이 일부 사라진다. num_kv_heads % tensor_parallel_size == 0 조건을 지키는 게 안전하고, 어길 때는 복제 overhead를 인식하고 있어야 한다.

KV 캐시 양자화. vLLM에서 --kv-cache-dtype fp8을 주면 GQA-8의 2.7 GB/seq가 1.35 GB/seq로 내려간다. GQA는 KV 헤드 단위로 양자화 granularity가 자연스럽다. MLA는 latent vector를 FP8으로 내리면 up-projection 후 오차가 증폭될 수 있어 더 조심스럽다. 실제로 오차가 문제가 되는지는 모델과 태스크에 따라 다르고, Needle-in-Haystack으로 직접 확인하는 게 가장 확실하다.

Prefix Caching 히트율. KV 캐시 entry 크기가 작을수록 같은 캐시 메모리에 더 많은 prefix block을 담는다. GQA가 MHA보다 prefix cache를 효율적으로 쓰고, MLA는 latent block이 훨씬 작아 이론상 히트율이 더 높다. 다만 vLLM에서 MLA의 latent cache block 관리 방식을 확인해야 한다 — block 크기 설정이 맞지 않으면 히트율이 이론만큼 나오지 않는다.

세 레버 중 어느 것도 Attention 구조를 바꾸는 것만큼 극적이지 않다. 그래도 TP degree 선택 하나를 잘못 잡으면 GQA를 쓰는 이점을 절반쯤 날릴 수 있으니 가장 먼저 확인하는 게 맞다.

Tags
LLMInferenceKV 캐시서빙GPU아키텍처vLLM메모리Transformer

관련 문서