查询自定时KV扫描深度,百万token decode比136-bit扫描快1.67倍

Fathom: Per-Query Read Depth for Sparse Decoding over Offloaded KV Caches

Vivek Kalyanarangan

cs.LG, cs.CL, cs.DC

2026-09-16

Fathom按每个查询给key通道分配不同读深度。百万token上GPU时间比Loki和SparQ的136-bit扫描快1.67倍,同等耗时下少读18%字节;索引放进GPU则不再更快。

这篇在解决什么

Agent 会话拉到几十万、上百万 token,多会话同时在线时,KV 和给它排序的索引都得放主机内存。稀疏注意力只取 top-k 的 key/value,但分数事先不知道,所以每种方法都要先扫一遍全部 n 个 key 的廉价表示。

Qwen3-8B、32k token 时,稠密注意力每步读 4.8 GB;k=512 的 winner 行大约 200 MB,不随上下文涨。Loki、Double Sparsity、SparQ r=32 这类 136-bit 扫描,32k 就要 160 MB,百万 token 涨到 5.1 GB,成为 decode 的主流量。现有扫描要么固定读哪些通道,要么所有通道同一深度。

方法

两件事叠在一起。

按通道存成 bit plane。 Key 先按通道做 4-bit 均匀量化,每 64 token 一块 fp16 scale。每个通道的 4 个 bit 拆成 4 张平面,通道主序存放。读前 t 张平面,恰好是同一块 scale 下的 t-bit 量化器,不用另存一份低精度副本。

每个查询自己做 reverse water-filling。 通道 j 对分数方差的贡献是 query 在该通道上的平方,再乘 key 的校准方差。每多读 1 bit,该通道剩余误差大约除以 4。在总预算 B 下,按这条边际收益给每个通道 0 到 4 bit。平均 48 bit 大约动 128 通道里的 30 到 34 个。同一 KV 头下的 query 头共用一份读取计划。

有 QK-norm 的模型(Qwen3)用原始通道;没有的(Llama-3.1、Qwen2.5)先对 key 做校准 KLT 再存平面。默认各层同一预算。按层分配要在部署上下文长度上校准,换长度会变差。

主机内存上的平面按通道是连续的。一次 gather 把活跃通道的前缀拷进 HBM 再扫,拷贝跑在 PCIe 链路速率上。

结果

A100,Qwen3-8B,k=512,KV 行和扫描索引都在主机内存。

百万 token 上,56-bit 读取的 GPU 时间相对 136-bit 扫描快 1.67×,相对 8-token block landmark 快 2.50×。SparQ r=16(68 bit)的 GPU 时间和 56-bit Fathom 几乎一样(1.05×),Fathom 少读 18% 扫描字节,七个设置里六个注意力误差更低,最大约 5.3×。47-bit 读取比 SparQ r=16 再快 1.11×。128k 真实 prefill 上相对 136-bit 扫描快 1.26×。

索引放进 HBM、只把 KV 行卸到主机时,各 per-token 扫描都落在 45–48 ms,Fathom 不再更快。

等误差字节:Double Sparsity 的 136-bit 误差在 46–74 bit 达到,节省 1.8–2.9×。

RULER 类任务上,所有 per-token 扫描都和精确 top-k 分不开。32k 上 Fathom 56-bit 得分 0.881,精确 top-k 0.874,稠密 0.884。真正拉开的是真实编码 agent 会话(约 95k token 的 OpenHands 轨迹):

方法bitsk=512 步一致率k=2048 步一致率
Fathom 56-bit560.530.67
SparQ r=16680.490.49
SparQ r=321360.60未测
Fathom 92-bit920.60未测

k=512 时 92 bit 追上最准的 136-bit 扫描。没有测带测试执行的端到端任务成功率。

为什么重要

适用面很窄,但窄在正在变大的场景:长上下文、多会话、KV 和索引都在主机或更慢层。已经在用 4-bit K cache 的服务栈可以把平面当那份缓存,不必再复制一份索引。论文自己没把这条路径测通,winner 的 key 仍从 bf16 行取。

索引能放进 GPU 就别用。HBM 上扫描是算力瓶颈:少读 bit 减的是字节,减不掉每个通道、token、头上的乘加,bit 抽取还更贵。摘要把这一点写死了。

局限与存疑

超过 128k 的计时用了合成 KV。Triton kernel 是原型,offload harness 有 Python 开销,所以主指标用 GPU 时间。wall-clock 上 SparQ r=16 在百万 token 还快 7%。计划了 100 个 agent 会话,预算原因停在 40 个。多会话并发只从索引体积推断,没有实测。没和 MagicPIG、RetroInfer 这类 CPU 检索比。RULER 的标准误差大约 0.014 到 0.034,per-token 扫描之间的小差距站不住。128k 的 instruct 模型没加 chat template,绝对分偏低,但不影响扫描之间的比较。

术语

原文与代码

相关论文

全部论文解读