쿼리 헤드는 그대로 두고 키·값(K/V) 헤드 수만 줄여 여러 쿼리 헤드가 K/V 하나를 같이 쓰게 하는 어텐션 방식으로, 긴 문맥이나 큰 배치에서 KV 캐시 메모리를 아끼고 생성 속도를 높일 때 쓴다. 품질은 멀티헤드 어텐션(MHA)에, 속도는 멀티쿼리 어텐션(MQA)에 가깝다.
| 방식 | K/V 헤드 수 | 특징 |
|---|---|---|
| MHA | 쿼리 헤드 수와 같음 | 품질이 가장 좋지만 메모리를 가장 많이 씀 |
| GQA | 그 사이 (예: 32개 중 8개) | 품질은 MHA에, 속도는 MQA에 가까움 |
| MQA | 1개 | 가장 빠르지만 품질이 떨어짐 |
모델은 토큰을 하나씩 생성할 때마다 앞 토큰들의 키와 값을 KV 캐시에 저장해 두고 매번 다시 읽는다. 이 저장하고 읽는 양이 병목인데, 캐시 크기는 K/V 헤드 수에 비례한다. 쿼리 헤드 32개를 K/V 헤드 8개로 묶으면 쿼리 헤드 4개가 K/V 하나를 같이 쓰고, 캐시는 1/4로 줄어든다.
쿼리 헤드 32개 기준 KV 캐시 크기. 레이어 하나, 토큰 하나당 캐시 크기 = 2 × K/V 헤드 수 × 헤드 차원 × 원소당 바이트.
이렇게 아낀 메모리로 배치를 키우거나 문맥을 늘릴 수 있어서 서빙 처리량이 올라간다.
GQA는 모델을 설계할 때 정하는 구조다. 그래서 보통은 GQA가 이미 적용된 오픈 모델을 받아 쓰게 된다. 모델 설정에서 쿼리 헤드 수와 K/V 헤드 수가 다르면 GQA 모델이다. 그룹 수를 1로 두면 MQA가 되고, 쿼리 헤드 수와 같게 두면 MHA가 된다.
| 상황 | 방법 |
|---|---|
| 직접 구현 | PyTorch scaled_dot_product_attention에 enable_gqa=True를 주면 K/V를 직접 복제하지 않아도 됨 |
| 기존 MHA 모델 변환 | K/V 헤드를 그룹별로 합친 뒤 짧게 추가 학습(업트레이닝) |
| 서빙 | TensorRT-LLM 같은 엔진은 MHA·MQA·GQA를 같은 어텐션 연산 하나로 처리함 |
GQA는 K/V 개수만 줄일 뿐, 이전 토큰을 모두 보는 전체 어텐션은 그대로 한다. 문맥을 줄이거나 어텐션을 희소하게 만들지 않으므로, 문맥이 길어질수록 비용이 커지는 성질은 바뀌지 않는다. 문맥 길이에 따른 비용 자체를 줄이려면 슬라이딩 윈도우 어텐션처럼 보는 범위를 줄이는 기법을 함께 써야 한다. 그룹을 너무 적게 잡으면 MQA처럼 품질이 떨어질 수 있으므로, 그룹 수는 메모리와 품질 사이에서 정해야 한다.
GQA는 사용자가 따로 켜는 기능이 아니라 요즘 오픈 LLM 상당수에 이미 들어 있는 구조다. 사람들은 GQA 모델을 골라 쓰면서 아낀 KV 캐시 메모리를 더 긴 문맥이나 더 많은 동시 요청에 돌린다.
| 어디서 | 어떻게 쓰나 |
|---|---|
| 로컬 LLM 실행 | 같은 GPU 메모리로 더 긴 대화를 돌리려고 K/V 헤드가 적은 오픈 모델을 고름 |
| LLM 서빙 | vLLM·TensorRT-LLM 같은 엔진에서 줄어든 캐시만큼 배치를 키워 처리량을 높임 |
| 모델 설계·변환 | 새 모델은 처음부터 K/V 헤드 수를 정하고, 기존 MHA 모델은 업트레이닝으로 GQA로 바꿈 |