KV 캐시 양자화(quantization)는 이 커뮤니티에서 오랫동안 뜨거운 논쟁거리였으며, 의견은 '절대 양자화하지 말라'부터 '4비트도 괜찮다'까지 다양했습니다. 일화적 증거가 다소 일관성이 없었기 때문에, 저는 KLD(Kullback-Leibler Divergence)를 통해 KV 캐시 양자화가 모델에 얼마나 영향을 미치는지 정량적으로 측정하기로 결정했습니다. KLD는 모델의 출력 분포가 어떻게 변화하는지를 측정하는 좋은 지표입니다.
저는 llama.cpp, exllamav3, vLLM 세 가지 프레임워크에서 35가지 가중치(weight) 양자화 옵션을 테스트했으며, 각각 16비트, 8비트, 그리고 (지원되는 경우) 4비트 KV 캐시를 사용했습니다. 또한 이번에는 에이전틱 도구 사용(agentic tool-use, Qwen3.8 27B의 전체 정밀도 출력으로 생성됨)과 다양한 도메인의 여러 텍스트를 혼합하여 KLD 데이터셋과 측정 방법론을 수정했습니다. 현재 데이터셋은 행당 최대 64k 토큰 컨텍스트까지 확장됩니다.
요약하자면, 8비트 KV 캐시가 잘 작동합니다. llama.cpp와 ExLlamaV3에서는 캐시 크기가 절반으로 줄어들고 KLD에 실질적인 차이가 없습니다. vLLM에서도 약간의 차이는 있지만, VRAM이 부족한 사람들에게는 여전히 좋은 트레이드오프입니다. 4비트 캐시는 측정 가능한 영향을 미칩니다. Q8 가중치에는 큰 타격을 주지만, 만약 Q3 이하를 사용하고 있다면 잠재적으로 가치가 있을 수 있습니다. 하지만 그럼에도 불구하고 추천하지 않습니다. 4비트 캐시의 영향은 컨텍스트가 커질수록 증가합니다.
테스트된 긴 문서에서 추가되는 KL 값은 첫 4k 토큰 대비 16-32k 토큰 구간에서 약 15~30% 더 높았습니다. 관심이 있다면, 블로그 게시물에 모든 데이터와 결과가 담긴 인터랙티브 차트와 표가 있습니다.
숫자 읽는 방법:
각 양자화 옵션은 양자화되지 않은 bf16 모델의 복사본과 토큰별로 비교됩니다. KL 발산(KL divergence)은 양자화된 모델의 다음 토큰 확률이 원래 모델에서 얼마나 벗어나는지를 측정합니다 (0은 변화가 없음을 의미). Top-1 일치도는 두 모델이 동일한 가장 가능성 높은 토큰을 선택하는 빈도를 나타냅니다. 참고 자료로, 저는 llama.cpp와 vLLM 모두에서 양자화되지 않은 모델을 실행하고 둘을 비교했습니다. 그 결과는 0.0004의 KL 차이를 보였는데, 이는 본질적으로 두 개의 (올바른) 구현이 다른 순서로 부동 소수점 연산을 수행하는 것에 불과합니다.
따라서, 여기에서 다양한 엔진으로 실행되는 양자화(quants)에 대한 KLD 수치를 문제없이 비교할 수 있습니다. 참고: exllamav3 양자화는 bf16 llama.cpp 참조 로짓(logits)으로 측정되었습니다.
가중치 양자화 KLD 발산(KL divergence) 대 로드된 가중치 크기, 16비트 KV 캐시: 블로그 게시물에는 인터랙티브 차트와 표에 전체 KLD 수치가 있으니 관심이 있다면 확인해 보세요. vLLM 체크포인트는 여전히 성능이 떨어집니다. Qwen3.6 벤치마크에서와 마찬가지로, 모든 vLLM 체크포인트는 더 작은 GGUF 또는 EXL3 양자화에 의해 능가됩니다. 그 일부는 활성화(activation) 양자화 때문입니다.
NVIDIA와 Unsloth의 NVFP4 체크포인트는 MLP 레이어를 W4A4(4비트 활성화)로 실행하고 어텐션(attention)은 FP8 W8A8로, 그리고 Qwen의 FP8은 전체적으로 W8A8을 사용합니다. 저는 NVIDIA의 NVFP4와 Qwen의 FP8을 vLLM의 Marlin 커널을 통해 다시 실행했습니다. 이 커널은 동일한 양자화된 가중치를 사용하지만 활성화는 bf16으로 유지합니다: NVFP4: KL이 0.0256에서 0.0117로 떨어져 절반 이상 감소했습니다. FP8: KL이 0.0039에서 0.0028로 떨어져 약 30% 적습니다. 그럼에도 불구하고, 이는 UD-Q5_K_XL과 동률일 뿐이며, 이 모델은 8.7 GiB 더 작습니다.
KV 캐시 양자화 (KV cache quantization):
| KV 캐시 | 토큰당 | 64k 컨텍스트에서 절약된 용량 대 16비트 f16 / bf16 |
|---|
| - 8비트: llama.cpp q8_0 , EXL3 8비트 | 34 KiB | 2.13 GiB |
| - 8비트: vLLM fp8_e4m3 | 32 KiB | 2.00 GiB |
| - 4비트: llama.cpp q4_0 , EXL3 4비트 | 18 KiB | 1.13 GiB |
아래의 각 점은 8비트 또는 4비트 KV 캐시를 가진 하나의 가중치 양자화입니다. 그 높이는 16비트 캐시에 있는 동일한 가중치와 비교했을 때의 KL 증가를 보여줍니다. 0은 변화가 없음을 의미하며, 더 높은 지점은 더 큰 증가를 나타냅니다. 저는 동일한 토큰에 대해 프롬프트별 차이를 계산했습니다.
KV 캐시 페널티 대 로드된 가중치 크기: 열린 마커는 8비트 KV를, 채워진 마커는 4비트 KV를 보여줍니다. 색상은 엔진을 식별합니다. 점선은 두 bf16 참조 엔진 간의 KL 차이를 표시합니다. vLLM에는 4비트 KV 캐시 옵션이 없습니다. llama.cpp와 ExLlamaV3에서 8비트는 본질적으로 무료입니다. 모든 양자화에 대해, q8_0과 ExLlamaV3의 8비트 캐시는 어느 방향으로든 KL을 0.00012보다 적게 변화시킵니다.
일부 양자화 버전은 이를 적용했을 때 측정값이 약간 더 좋게 나타나는데, 이는 수치적 노이즈(noise of the numerics) 범위 내에 있다는 것을 의미합니다. vLLM의 FP8 캐시는 약간의 KLD 증가를 보입니다. 이는 모든 체크포인트에서 0.0004에서 0.0006을 추가하는데, 여전히 극히 작지만 거의 모든 프롬프트(prompt)에서 나타납니다. 이는 FP8 캐시를 활성화하여 vLLM의 어텐션 백엔드(attention backend)를 FlashAttention에서 FlashInfer로 전환했기 때문일 수 있습니다.
llama.cpp의 4비트 캐시는 대략 고정된 패널티를 추가합니다. 테스트된 GGUF 양자화 버전 전반에 걸쳐 q4_0은 +0.0016에서 +0.0027 KL을 추가합니다. 이 증가는 더 정밀한 가중치(weights)에 상대적으로 더 큰 영향을 미칩니다: Q3 클래스 양자화 버전(KL이 0.025-0.035 정도)에서는 6~10%를 추가하고, UD-Q4_K_XL에서는 약 39%를 추가하며, Q8_0에서는 약 390%를 추가합니다. KL은 0.0007에서 0.0034로 증가하여, 16비트 캐시를 사용한 UD-Q5_K_XL보다 나쁩니다.
EXL3의 4비트 캐시 패널티는 가중치 정밀도(weight precision)에 따라 달라지는 것으로 보입니다. 이는 2.0-2.5 bpw 가중치에서는 단지 +0.0002에서 +0.0004 KL을 추가하고, 3.0 bpw 가중치에서는 약 +0.0021에서 +0.0022를, 4.0 bpw 가중치에서는 +0.0026에서 +0.0028을 추가합니다. 6.0 및 8.0 bpw에서는 패널티가 약 +0.0032에서 +0.0033에 도달합니다. 따라서 이 증가는 EXL3 양자화 버전 전반에 걸쳐 일정하지 않습니다.
4비트 캐시 패널티는 컨텍스트(context)에 따라 증가합니다
세트에 포함된 12개의 긴 문서는 모든 위치에서 점수가 매겨지므로, 4비트 패널티가 토큰이 컨텍스트의 어느 깊이에 있는지에 따라 달라지는지 확인할 수 있었습니다. 실제로 약간 증가하는 것을 확인했습니다.
| Position | Q8_0 Weights + q4_0 KV | UD-Q5_K_XL Weights + q4_0 KV | EXL3 8.0 BPW Weights + 4-bit KV |
|---|
| First 4k tokens | +0.0035 | +0.0030 | +0.0041 |
| 4k–8k | +0.0037 | +0.0033 | +0.0044 |
| 8k–16k | +0.0040 | +0.0036 | +0.0047 |
| 16k–32k | +0.0041 | +0.0038 | +0.0050 |
| 32k–64k (one document) | +0.0044 | +0.0038 | +0.0053 |
16-32k 컨텍스트에서의 손상은 첫 4k 토큰보다 약 15~30% 더 큰 것으로 나타났습니다. 반면, 16비트 캐시를 사용한 동일한 양자화 버전들은 이러한 컨텍스트 길이 전반에 걸쳐 영향을 받지 않았으므로, 이는 4비트 캐시 손상의 매우 명확한 지표입니다. 저는 128k 이상의 컨텍스트 길이에서는 이보다 더 나쁠 것으로 예상합니다.
모델 양자화 KLD 대 KV 캐시 KLD: KV 캐시 양자화로 인한 KLD는 가중치 양자화에서 발생하는 KLD와 비교했을 때 다른 품질 트레이드오프를 가질 가능성이 높다. 경험적 증거에 따르면, KV 캐시 양자화는 가중치 양자화보다 긴 컨텍스트 길이에서 모델 성능에 더 해로울 수 있으므로 4-bit KV 캐시 사용에 주의해야 한다.
가중치 + 64k KV 캐시 대 KL 다이버전스를 보여주는 최종 차트: 이 선은 4-bit KV를 제외한 권장 양자화(recommended quants)를 강조 표시한다. 마름모는 8-bit KV를 나타내고, 흐릿하게 처리된 원과 삼각형은 각각 16-bit 및 4-bit KV를 나타낸다. 메모리에는 64k 컨텍스트에서의 가중치와 KV 캐시가 포함된다.
방법론: 각 양자화는 비양자화된 bf16 참조 값과 비교하여 점수가 매겨졌다. GGUF 및 EXL3 양자화는 llama.cpp의 Bartowski가 만든 bf16 GGUF와 비교되었다. vLLM 체크포인트는 vLLM의 공식 bf16 safetensors와 비교되었다. KL은 이전 벤치마크와 동일한 방식으로 계산되었다.
각 위치에서 두 모델 모두의 상위 200개 로그 확률을 가져와 전체 어휘 사전에 대한 하한값 D_KL(P_reference ‖ P_quant)를 계산한다. 평균적으로, 참조 값은 자신의 상위 200개 토큰 밖에 0.0036의 확률을 할당했다. KV 델타는 쌍으로 이루어져 있으며, 이는 동일한 토큰에 대한 프롬프트별 차이(per-prompt differences)를 통해 계산된다.
체크포인트는 활성화 양자화(activation quantization)를 포함하여 선언된 설정으로 실행되었다 (Unsloth의 NVFP4와 공식 FP8 양자화를 제외한, 가중치만 사용하고 활성화 양자화가 없는 두 가지 재실행). 제출자: /u/Hefty_Wolverine_553 [링크] [댓글]