百万 token 的会话,KV cache 早就不在显存里了。这不新鲜。
新鲜的是很少有人往下追一步:搬出去之后,瓶颈换成了什么。
画张图:
GPU 显存 主机内存
┌──────────┐ ┌───────────────────────┐
│ 当前层的 │◄──── PCIe ───│ KV cache(百万 token)│
│ 计算 │ │ + 排序索引 │
└──────────┘ └───────────────────────┘
解码每一步的 top-k,不是"在显存里挑几个最大值"那么轻。键在主机那头,排序索引也在主机那头。你要挑,得先扫;要扫,读的是字节,不是 FLOPs。计算单元闲着,链路在冒烟。
这个前提我接受得很快,因为它顺手解释了一个我一直没绕明白的现象:长上下文的推理优化,越来越不像在讲"怎么算得更少",越来越像在讲"怎么少搬点东西"。token 稀疏、层稀疏、KV 量化——名字五花八门,干的是同一件事,给那条链路减压。
九月中旬挂上 arXiv 的 Fathom 就在这一堆里。v1 是 9 月 15 日,v3 是 9 月 18 日,三天里改到第三版,作者手速挺猛。
但它挑的角度跟我以为的不一样。这也是我第一版画错的地方。
我先入为主,以为它是"通道稀疏":每个查询挑一部分通道读,剩下的不管。
不是。
我回去把它的存储布局画了一遍,才发现自己看错了维度。
4-bit 的 K 缓存,按通道主序存成位平面。这句话我第一次读的时候直接滑过去了——"位平面"听着像个实现细节,其实它整篇的立命之本就在这三个字上。
某个通道 c,四个位平面挨着放:
plane3 plane2 plane1 plane0
│ │ │ │
▼ ▼ ▼ ▼
[ 1 ] [ 0 ] [ 1 ] [ 1 ] ← 键 1
[ 0 ] [ 1 ] [ 1 ] [ 0 ] ← 键 2
[ 1 ] [ 1 ] [ 0 ] [ 0 ] ← 键 3
通道主序的意思是,同一个通道下所有键的比特挨着排。于是"读 t 个平面的前缀",读出来的正好是这个通道的 t 比特量化器:1 位是符号,2 位粗一点,4 位最精细。前 t 个平面拼起来,本身就是一个合法的、只是更粗的量化器,不需要额外解码器去凑。
等等等等,先别急。
这意味着读出精度不是个全有全无的开关,是个能逐级往下拧的旋钮。✨
一旦它是旋钮,整个问题的形状就变了。
那我第一版错在哪?我以为它在"读哪些通道"上做稀疏,实际上通道它一个不少,它抠的是"每个通道读多深"。题目里那个 read depth 就是这个意思。扭的是旋钮,不是开关。
(位平面这套我第一次见是在图像压缩里。扯远了——但这里确实是一回事:把精度拆成可以分级读的层,要几分精度读几层。拉回来。)
那"读多深"谁定?每个查询自己算。反向注水法,按通道的方差加权分比特预算:方差大的通道多给几位,方差小的少给。逐查询走一遍。
打个比方:像一本按条目排的字典,每一条你自己决定读到第几层细节——生僻条目读满四层,常见条目读一层就够。这比喻抓的是"深度逐条可调"这个方向。
漏风的地方得标出来。我说"每个查询自己决定",这话有点飘。真实情况是预算由方差算出来的,是个确定性的分配算法——不是学出来的策略,更不是查询读懂了你在问什么然后灵机一动。所以"自己决定"这四个字,在"怎么决定"这一层是漏的。拿它抓大方向可以,别拿它当它懂你的证据。
说跑出来的数。Qwen3-8B,百万 token,跟 Double Sparsity、Loki、SparQ r=32 那条 136-bit 扫描比,GPU 时间上快 1.67 倍。
我觉得更能说明问题的是另一条:同样 GPU 时间下,跟 SparQ 的 68-bit 读(r=16)比,Fathom 少读 18% 的字节,七种模型加上下文设置里六种注意力误差更低。等时间的对照比等精度的对照诚实得多。RULER 风格任务上,它逐 token 的扫描跟精确 top-k 解码结果一致;真实编码 agent 会话里,92 bit 就打到了 136-bit 最精确扫描的步骤一致率。存储也没多要东西——用的就是量化服务栈里本来就有的那份 4-bit K 副本。
好,现在说这篇里我最想标出来的一条,也是最诚实的一条:
索引驻留在 GPU 内存时,Fathom 没有速度提升。
干脆,一行,不解释。但这一行比前面所有数字都更有信息量。它说明 Fathom 优化的那段读流量,只在键和索引都躺在主机内存那头的时候才成为瓶颈。索引一旦回到显存,扫描本来就不贵,你再怎么抠读取深度,省的是不存在的时间。
所以它不是一个"更好"的方法,是个"位置敏感"的方法。全部价值押在一个前提上:你的 KV cache 是被 offload 出去的。前提不成立,它归零。
我挺欣赏这种把适用边界直接写进结论的做法。比那些在哪儿都说自己快的方案舒服多了。
画开完了,照例自检:现在你能不能一句话说清 Fathom 在哪一维上做稀疏?如果脱口而出是"选通道",那还没扣上,回去再看一眼那张位平面的图。
我目前的判断是:这一轮长上下文的优化,重心正在从"让模型算得少"搬到"让数据搬得少",而后者比前者更看你把东西摆在哪。这话我说得有点满,但先这么信着。
下期想画开哪个?我候选清单上躺着两个:KV cache 的淘汰策略到底在淘汰什么,还有 paged attention 的分页到底在分什么。
本期画开:稀疏的维度搞错了,优化就跑偏了。
