질의마다 키 채널의 읽는 비트 수를 정해 오프로드 KV 캐시의 희소 디코딩 병목을 줄이는 Fathom
Fathom: Per-Query Read Depth for Sparse Decoding over Offloaded KV Caches
무엇인가
이 논문은 긴 에이전트 세션, 예컨대 코딩이나 브라우징 에이전트가 수십만에서 100만 토큰의 문맥을 수 시간 유지하고 서버가 여러 세션을 동시에 호스팅하는 상황을 다룬다. 이때 KV 캐시는 GPU 메모리에 가중치와 함께 남지 못하고 호스트 메모리나 더 느린 계층에 놓이며, 디코드 단계는 인터커넥트를 넘는 트래픽에 묶인다. Qwen3-8B 32k 토큰 예로 dense attention은 bf16 KV 캐시 전체를 읽어 스텝당 4.8GB를 쓰지만, top-k 희소 attention은 k=512일 때 쿼리 헤드당 승자 행의 합집합만 가져와 스텝당 약 200MB를 읽는다. 문제는 승자를 고르기 전에 모든 n개 키를 저렴한 표현으로 스캔해야 한다는 점이다. Loki, Double Sparsity, SparQ 같은 기존 per-token 스캔은 읽는 비트 수를 미리 고정한다. Loki는 주성분 좌표 r개, Double Sparsity는 오프라인으로 고른 c개 채널, SparQ는 쿼리가 고른 r개 채널을 전체 깊이로, 썸네일 스캔은 모든 채널을 2비트로 읽는다. 스캔 비용은 n에 따라 선형으로 커지고, 승자 행 가져오기 비용은 문맥 길이에 거의 늘지 않는다.
어떻게 동작하나
Fathom의 핵심은 읽기 깊이를 질의별, 채널별로 정하는 것이다. 4비트 K 캐시를 채널 우선(channel-major) 비트 플레인으로 저장한다. 각 채널은 균일 대칭 코드로 4비트 양자화되고 64토큰 블록마다 fp16 스케일 하나를 둔다. 이때 어떤 채널의 앞 t개 플레인을 읽으면 그 채널의 t비트 mid-rise 양자화기가 정확히 되고, 별도 저정밀 복사본이 필요 없다. 하나의 KV 헤드를 공유하는 쿼리 헤드 그룹에 대해 채널 j의 점수 기여 분산은 g_j = Σ_h (q_j^(h))^2 Var(k_j)로 둔다. 채널을 t비트로 읽을 때 양자화 오차 분산은 4^{-t}에 비례해 줄어들므로, 총 점수 오차는 Σ_j g_j 4^{-t_j}가 된다. 예산 Σ_j t_j ≤ B 아래 이 값을 최소화하는 것은 역수 채우기(reverse water-filling)이며, t_j = clip(round(log4(g_j/θ)), 0, 4)로 닫힌 형태를 갖는다. θ는 합이 예산에 맞는 가장 작은 물높이이고, 쿼리 그룹마다 log θ에 대한 30번의 이분법으로 찾는다. t_j=0인 채널은 아예 건너뛰고 나머지가 활성 채널이 된다. 논문에 따르면 평균 48비트 읽기는 테스트 모델에서 128개 채널 중 30~34개를 1~4 플레인씩 건드린다. 이 계획은 그룹의 G개 쿼리 헤드가 공유하므로 K 바이트는 한 번만 읽는다. 층별 예산을 탐욕적으로 배분하는 선택도 있지만 기본은 균일 예산이고, QK-norm이 있는 Qwen3에는 원시 채널을, QK-norm이 없는 Llama-3.1과 Qwen2.5에는 보정 키의 KLT 회전 플레인을 쓰는 기준 규칙을 둔다. 호스트 메모리에 있는 저장소를 읽을 때는 활성 채널마다 연속된 플레인 구간을 스테이징 버퍼로 gather한 뒤 HBM에서 스캔한다. 저장 비용은 4비트 K 복사본과 fp16 블록 스케일로 KV 헤드당 토큰당 68바이트다.
무엇과 다른가
실험은 Qwen3-8B 16k와 32k, Qwen3-4B 16k, Qwen2.5-7B 32k, Qwen2.5-7B-Instruct-1M 32k와 128k, Llama-3.1-8B 4k에서 수행됐다. 주요 타이밍은 NVIDIA A100-SXM4-80GB, PCIe 4.0, 2TB 호스트 RAM 환경에서 측정됐고, Llama-3.1-8B 4k 활성값은 L4에서 캡처됐다. 비교 대상은 Double Sparsity c=32, Loki r=32와 r=64, SparQ r=16과 r=32, 2비트 전채널 썸네일, ShadowKV식 8토큰 블록 평균 landmark 인덱스, 정확한 top-k 오라클, dense attention이다. 모든 스캔은 동일한 블록 스케일을 가진 4비트 코드를 쓴다. 비트 회계는 읽는 코드 비트에 읽는 각 채널의 64토큰당 fp16 블록 스케일 16비트를 더하는 단일 규칙을 따른다. 그래서 32채널 4비트는 136비트, 16채널은 68비트, 2비트 썸네일은 288비트, 전체 4비트 스캔은 544비트, fp16 landmark는 256비트가 된다. 품질은 선택 집합에 대한 attention 출력의 상대 L2 오차, RULER 스타일 검색·상태 추적 과제, 실제 OpenHands 에이전트의 SWE-rebench 세션에서 정확한 top-k 디코딩과의 단계 일치도로 측정됐다.
어떻게 쓰나
타깃 영역인 호스트 메모리 상주 KV 캐시와 인덱스에서 Fathom의 이득이 측정됐다. Qwen3-8B 100만 토큰에서 56비트 읽기의 디코드 스텝 GPU 시간은 136비트 스캔인 Double Sparsity, Loki, SparQ r=32보다 1.67배 낮고, landmark 인덱스보다 2.50배, 썸네일보다 3.12배 낮다. wall-clock 비율은 각각 1.38배, 2.07배, 2.59배다. SparQ r=16은 56비트 읽기보다 스캔 바이트를 22% 더 옮기고 GPU 시간은 1.05배 걸린다. Fathom의 평균 40비트 읽기는 SparQ r=16보다 바이트가 31% 적고 1.11배 빠르다. 256k에서는 32채널 스캔보다 GPU 시간이 1.37배 낮다. 실제 prefill을 쓴 32k~128k에서도 128k에 32채널 스캔보다 1.26배 빠르고 SparQ r=16과는 1.00배로 같다. SparQ r=16과 GPU 시간을 맞춘 조건에서 Fathom은 스캔 바이트를 18% 덜 읽고 attention 오차는 1.1~5.3배 낮다. Double Sparsity의 136비트 스캔과 같은 오차를 내는 데 필요한 바이트는 7개 설정, 최대 128k에서 1.8~2.9배 적다. RULER 스타일 과제에서는 모든 per-token 스캔이 32k에서 정확한 top-k 오라클과 0.008 이내, 128k에서 0.025 이내에 들어왔고 Fathom은 56비트와 74비트로 이를 달성한다. 실제 코딩 에이전트 세션에서 k=2048, 즉 문맥의 2%일 때 Fathom 56비트의 단계 일치도는 0.67로 SparQ r=16의 0.49, landmark의 0.47보다 높다. 세션별 짝지은 차이는 +0.18 ± 0.05였고 20개 중 14개 세션에서 앞섰으며, 같은 GPU 시간에 바이트는 18% 적었다. k=512, 문맥의 0.5%에서는 가장 정확한 136비트 SparQ r=32가 0.60이었고 Fathom은 92비트로 같은 0.60을 내면서 바이트를 32% 줄였다. Fathom의 56비트와 74비트 읽기는 Double Sparsity 136비트와 비슷하거나 SparQ r=16보다 높은 0.53 대 0.49를 보였다.
전제와 한계
개발자 관점에서 Fathom은 KV 캐시와 스캔 인덱스가 호스트 메모리에 있고 PCIe를 넘는 스캔 바이트가 지연을 지배하는 서빙 스택에 맞는 기법이다. 반대로 인덱스가 GPU HBM에 상주하면 이 방법은 더 빠르지 않다. 논문은 128k에서 HBM 상주 인덱스일 때 per-token 스캔들이 스텝당 45~48ms에 모이고 Fathom이 가장 빠르지 않다고 명시한다. 따라서 도입 전에 인덱스가 실제로 느린 계층에 있는지, 배치와 동시 세션 수가 충분히 큰지 확인해야 한다. 또 저장 비용이 KV 헤드당 토큰당 68바이트로 Double Sparsity의 17바이트보다 4배, 32바이트 landmark보다 2배 크다. 이 저장소가 공짜가 되는 경우는 서빙 스택이 이미 4비트 K 캐시를 채널 우선으로 유지해 승자 키를 네 플레인에서 복원할 때뿐인데, 논문은 그 경로를 구현하거나 측정하지 않았고 채널 우선 레이아웃에서 단일 토큰 복원이 저렴하지도 않다고 밝힌다. 채널 통계는 오프라인 보정이 필요하고, 층별 예산 계획은 배포 문맥 길이에 맞춰 보정해야 하며, 기본값은 보정이 필요 없는 균일 예산이다. QK-norm 유무에 따라 원시 채널과 KLT 회전 중 하나를 골라야 한다. 또한 커널은 Triton 프로토타입이고 연구용 하네스의 Python 이슈 비용이 wall-clock에 섞여 있어, 저자들은 GPU 시간을 주 지표로 삼는다.
저자들이 밝힌 한계는 분명하다. 인덱스가 HBM에 있으면 스캔이 산술에 묶여 바이트 절감이 시간 절감으로 이어지지 않는다. 비트 플레인 스캔은 비트마다 시프트와 마스크로 비트를 추출하고 추출된 비트마다 G번의 곱셈-덧셈을 하므로, 4비트 니블이 추출 요소당 네 배 정보를 담는 것에 비해 대역폭 대비 효율이 낮다. A100은 바이트당 약 5개의 정수 연산을 제공하므로 현재 데이터센터 GPU에서 이 스캔은 산술 병목이 되기 쉽다. 품질 평가는 attention 출력 오차, 합성 검색·추적 과제, 실제 에이전트 세션의 단계 일치도까지이며, 테스트 실행을 포함한 end-to-end 과제 성공률은 측정되지 않았다. 128k를 넘는 타이밍은 합성 KV 내용을 사용했고, 오프로드 표는 배치 1이 중심이며 많은 동시 세션 상황은 인덱스 크기로 논증했을 뿐 직접 측정하지 않았다. RULER 스타일 점수는 표준오차가 몇 점이라 per-token 스캔 간 작은 차이는 확립되지 않았다. 채널 통계의 보정 도메인이 에이전트 트랜스크립트로 바뀌면 단계 일치도가 +0.01에서 +0.07 변할 수 있고, 세션 자체 prefill로 보정하는 변형은 그 의존성을 없앤다. 층별 계획은 배포 문맥 길이에 맞춰 보정해야 하며 16k에서 보정한 계획을 32k에 쓰면 균일 예산보다 나쁘다. landmark 베이스라인은 ShadowKV의 청크 평균을 원 논문이 쓰지 않는 호스트 상주 인덱스 설정에서 재구현한 것이고, RetroInfer나 MagicPIG식 CPU 검색은 비교하지 않았다. 128k instruct 모델은 채팅 템플릿 없이 프롬프트되어 절대 점수가 낮아졌을 수 있다. top-k는 모든 방법에서 쿼리 헤드별로 선택했고, SparQ의 그룹 공유 top-k와 평균값 재할당은 평가하지 않았다.
결론적으로 Fathom은 이미 4비트 K 캐시를 유지하면서 그것을 느린 계층에 두는 서빙 스택에 맞는 스캔 기법이다. 4비트 K 캐시를 채널 우선 비트 플레인으로 저장해 접두 읽기가 정확한 저정밀 양자화기가 되게 하고, 질의별 역수 채우기로 점수 분산을 많이 담은 채널에 비트를 더 준다. Double Sparsity의 오차 수준에서 고정 깊이 스캔이 136비트를 읽는 7개 설정, 최대 128k에서 Fathom은 46~74비트를 읽는다. RULER 스타일 과제에서는 정확한 top-k 오라클과 맞먹고, 실제 코딩 에이전트 세션의 2% 예산에서는 정확한 top-k 단계와 0.67 일치해 SparQ r=16의 0.49를 앞선다. 모든 것이 HBM에 있는 경우에는 산술 병목 때문에 더 빠르지 않으며, 융합 커널이 격차를 줄일 수는 있어도 산술 한계를 없애지는 못한다.