长上下文推理卡的往往不是算力,而是 KV Cache:把 Key 每通道压到 1.26 bit 为什么这么难
长上下文推理的服务成本,越来越由 KV Cache 的容量与带宽决定,而不是由算力决定。最近一轮热度集中在「把 KV Cache 压到每通道 1 bit 附近」这件事上:2026-10-02 提交的 TaSQ 论文(arXiv:2610.03027,首尔大学与斯坦福)报告了一组单一 RTX 6000 Ada 显卡上的 SGLang 实测——在 Qwen3-4B-Thinking-2507、输入 2048 / 输出 32768 的负载下,同一张卡的 KV 池从 BF16 基线的 235,257 个 token 扩到 2,935,184 个 token(12.48 倍),最大批量从 6 提到 84,峰值吞吐从 220.8 提到 412.6 token/秒(1.87 倍)。代价是 QK 点积的误差,本文把它的三段推导讲清楚:为什么量化误差要按 query 敏感度加权、为什么 scale 可以全 head 共享、为什么通道分组必须看协方差。文内所有数字均标口径:论文实测、公开配置换算、或本文自行推导,三者分列。
想象一个图书馆。书本身不会变多——模型权重在部署那一刻就定死了。真正会失控的是前台那摞「刚才读过、待会儿还要引用」的摘抄卡片:每读一个新词,都要给这个词再抄一张卡片;单条短上下文里这摞卡片还只是权重的一小部分,可一旦长上下文叠加高并发,它就会膨胀到超过整座书架,而且每次回答问题都要把这摞卡片从头翻一遍。
这就是长上下文推理的真实瓶颈:KV Cache(键值缓存,把已经算过的 Key 与 Value 存下来,避免解码时重算)的容量与带宽,而不是算力。 权重是固定的、可以常驻显存;KV Cache 是随序列长度线性增长的,而且每一个解码步都要把它整摞读一遍。
这篇文章要回答的是最近一轮讨论里最具体的一个问题:既然「少存几个 bit」看起来这么直接,为什么把 KV Cache 压到每通道 1 bit 附近会这么难? 我们以 2026 年 10 月 2 日提交的一篇论文为主线——「Tailoring the Quantization Space for 1-Bit KV Cache Compression」(TaSQ,首尔大学与斯坦福,arXiv:2610.03027),先讲清楚它测量到了什么,再把它的三段推导——query 导向的通道加权、跨 head 共享 scale、协方差感知的通道分组——一步不错地推出来。
先说结论性的数字,并且当场把口径钉住:在论文的 SGLang 实测里(单张 RTX 6000 Ada,模型 Qwen3-4B-Thinking-2507,输入 2048、输出 32768 的负载),BF16 全精度基线的 KV 池只能装 235,257 个 token,TaSQ 把同一张卡上的 KV 池扩到 2,935,184 个 token——注意这两个都是token 计数、相差 12.48 倍,是同一个对象在两个不同精度下的容量上限,而不是「模型多大」或「训练数据多大」;对应的最大批量从 6 提到 84(14 倍),峰值吞吐从 220.8 提到 412.6 token/秒(1.87 倍)。这些是论文在单卡上的测量值,不是本文的复现。
🔤 先给直觉:一张卡片有多大
在进入符号之前,先把「卡片有多大」算出来,因为后面所有推导都在跟这个数字较劲。
一个解码器在自回归生成时,第 层、第 个 KV head、位置 的 Key 与 Value 一旦算出就不再改变(因果掩码保证前面的 token 不会被后面的 token 影响),于是可以缓存复用。它的大小是:
其中 是层数、 是 KV head 数(GQA 下小于 query head 数)、 是 head 维度、 是每个元素占的字节数,系数 来自 Key 与 Value 各存一份。
代入一个具体的公开配置:Llama-3.1-8B 的配置是 32 层、32 个注意力 head、8 个 KV head、hidden size 4096(因此 ),BF16 下 。于是
每个 token 的 KV 缓存是 128 KiB。 32K 上下文的纯 KV 就是 ——这还只是一个请求;并发 16 路就是 64 GiB,已经超过本文效率实测所用那张 48 GB 卡的全部显存(H100 80 GB 这类更大显存的卡另算)。
这一个算式解释了为什么本节标题是「卡片有多大」而不是「模型有多大」:模型大小是一次性成本,KV 大小是随并发与长度成倍放大的递延成本。 顺便记住 KiB 与 MiB 的口径:本文一律用 1024 进制(1 KiB = 1024 B,1 GiB = 1024 MiB);论文表格里的 bit 数一律是「每通道平均 bit」(与论文原文的 bits per element 同义),且按论文表 5 的声明不含静态码本存储与全精度缓存窗口的实现开销。
📐 符号与术语表
| 符号 / 术语 | 含义 | 在本篇里的取值或口径 |
|---|---|---|
| 层数、KV head 数、head 维度 | 例:Llama-3.1-8B 为 32 / 8 / 128;Qwen3-4B 为 36 / 8 / 128 | |
| 每个缓存元素的字节数(只用于上面那条 bytes 算式) | BF16 取 2,即 16 bit ÷ 8 | |
| 位宽 | 每通道平均 bit(与论文的 bits per element 同义) | BF16 16 bit;TaSQ 的 Key 约 1.266 bit |
| 位置 、KV head 的 RoPE 之前的 Key 向量 | 论文选择对 pre-RoPE Key 做量化 | |
| 位置 的 RoPE 旋转矩阵 | 分块对角,每两个通道一组 | |
| RoPE | 旋转位置编码:按位置把 Key / query 做二维旋转以注入位置信息 | 只作用于通道对 ,这是「RoPE 对不可拆」约束的由来 |
| 位置 的 RoPE 之后的 query | 与 做点积 | |
| Key 的量化误差, | 出现在 QK 点积误差里 | |
| query 导向的通道权重矩阵 | 取对角阵 | |
| 位置 的共享 scale | 全 个 KV head 共享一个 | |
| VQ / 码本 | 向量量化 / 一组质心 | 用最近质心代表原向量 |
| 码本大小、每组通道数 | 例:、 | |
| RMS | 均方根(root mean square) | 用于跨 head 归一化 |
🧱 账本:长上下文为什么先撞内存墙
把上面那个 128 KiB 换成服务视角的三条约束,问题就清楚了。
第一,容量约束。单卡可用显存减去权重、激活之后剩下的部分,除以「每 token 的 KV 字节数」,就是这张卡能同时容纳的上下文总量。频率上,这个量与 成正比——位宽砍一半,容量翻一倍。
第二,带宽约束。解码阶段每生成一个 token,都要读取整个 KV Cache 一次(不是读一部分)。设批量大小为 、上下文长度为 、每 token KV 字节数为 ,则每个解码步的 KV 读取量约为
而这一步真正的乘加计算量约为 量级。两者相除得到算术强度:KV Cache 的读取是典型的「搬运远多于计算」,这正是长上下文解码在 GPU 上跑不满算力的根因。位宽压到 1 bit 量级,等于把这条读取通路的压力直接降一个数量级。
第三,推理稳定性约束——这条最容易被忽略。论文引用自己团队更早的工作指出:低位宽 KV 压缩会让推理模型产生重复或不连贯的生成,而且这种生成会一直持续到长度上限才停下(Cheong 等,2026)。这意味着「压缩后精度掉一点」不是温和的退化,而是可能退化成「整段解码预算被白白烧掉」。
flowchart LR
A["用户请求 2048 token 输入"] --> B["prefill 一次算完 写入 KV"]
B --> C["KV 池 显存中的容量上限"]
C --> D["decode 循环 每步读整摞 KV"]
D --> E["生成 32768 token 输出"]
C -.-> F["位宽减半 容量翻倍"]
D -.-> G["位宽减半 每步搬运减半"]这张图说明了什么:KV Cache 是 prefill 与 decode 之间的蓄水池,它同时决定「能装多少并发」(容量)与「每步要搬多少」(带宽),这两个约束都由同一个位宽参数控制——所以低位宽量化是同时打两个瓶颈的一刀。
🎯 为什么「每通道 1 bit」难:VQ 的速率—失真基本式
向量量化(VQ)的做法是:把一组通道拼成一个 维向量 ,用码本里最近的质心代表它:
码本有 个质心时,只需存一个索引( bit),因此每通道的平均位宽是
难处从这条式子直接看出来了:位宽由 与 的比值决定,而不是由 单独决定。 要在 1 bit/通道 附近,你有两种办法:
- 把 做大:比如 、 时是 bit/通道——TaSQ 的 Key 侧正是这一档;
- 把 做小:比如 、 时是 bit/通道——NSNQuant 走的是这一档。
( 也不能随意取:它必须能被 RoPE 对整除,理由见推导三的硬约束。)
无论走哪条,都会撞上同一堵墙:每个码本要用有限的质心,去覆盖一个更宽的通道集合。 论文的表述是「在极端压缩下,每个码本必须用有限的质心去表示更大的通道组,有效利用其容量变得越来越难」。这就是 1 bit 区间里既有方法——CQ(按连续通道分组)与 NSNQuant(用免标定的全局码本)——精度明显下滑的原因。
而高码率量化理论给出了这类误差的渐近形状:对一个 质心的最优码本, 维通道组 的均方重建误差按
缩放(Gersho 与 Gray 的经典结果,论文引作该分组判据的理论依据)。注意这个式子里的两个因子: 是「索引预算」带来的收益, 是这组通道的联合统计结构带来的惩罚或收益。既然 与 在所有组之间是固定的,唯一还能动手的就是那个行列式——能不能把「相关性高的通道」放进同一组,让行列式变小。这一句就是第三节的伏笔。
🔍 三个必须被利用的结构
论文的动机部分是三条对 Key 通道的测量观察(观测对象:Llama-3.1-8B,一段 2048 token 的 GPQA 窗口,展示的是第 15 层、KV head 0)。这三条都不是理论假设,而是实测出来的分布特征。
第一,不同通道对 query 的敏感度差别很大。 QK 点积里,Key 某个通道上的误差会被对应的 query 激活值放大。论文报告,query 激活分布沿通道方向差异显著,部分通道的激活区间特别大——这意味着同样大小的重建误差,落在不同通道上对 logits 的影响完全不同。
第二,通道之间存在非均匀的相关性。 有些通道对强相关,有些几乎独立。因为 VQ 是「多个通道共享一个码本」,它能不能吃到这些相关性,取决于哪些通道被分到同一组。
第三,RoPE 前后分布差别很大。 RoPE 按位置旋转 Key,把原来相对紧凑的分布打散了。论文的实测:对 RoPE 之前的 Key 做 VQ,比在 RoPE 之后做,重建误差低 35%(32 层全层的总体重建误差)。这条观察直接决定了后面所有变换都作用在 pre-RoPE Key 上。
顺带一条对照组:Value 侧不具备这些特征。论文在附录里报告,同一 head 内 Value 通道的 loss 敏感度更均匀、通道间相关性也更弱。所以 TaSQ 的 Key 与 Value 走两条不同的路——Key 做加权重排,Value 保持常规的连续通道分组。这是一个很值得记住的「不对称设计」。
🧮 推导一:把 QK 点积误差写成一个二次型
现在开始形式化。设某个 KV head 在位置 的 pre-RoPE Key 为 (省略层下标,因为每层同样处理),量化误差为
位置 的 post-RoPE query 记为 。真正进入 attention 的 Key 是 ,于是被误差污染的那一项是 。论文把它平方后写成一个二次型:
这一步是整篇文章的支点,值得停一下:点积误差的平方,是量化误差向量 在矩阵 下的二次型。而 完全由 query 与位置决定,与 的分布无关。也就是说,如果我们想最小化「误差对 logits 的伤害」,就该让 在 度量下尽量小——这正是「按重要性加权」的数学说法。
依赖具体位置 、、具体 token,不能直接拿来用(否则每个 token 都得换一套量化空间)。于是论文在标定语料 上对所有合法因果 query-key 对取期望,得到一个与位置、token 无关的摘要:
再做一个关键近似:只保留 的对角线(附录 D 论证了该近似的合理性):
为什么要退到对角阵?因为对角阵意味着「每个通道一个权重、通道之间不混」,这种变换保持 RoPE 的成对结构(RoPE 只旋转通道对 )——如果用了满矩阵,就会把通道混在一起,RoPE 的分块对角结构被破坏,在线旋转就没法廉价实现。这个取舍是全文最工程化的一步。
有了 ,期望平方误差被近似为
右边出现了 ——这正是「把 Key 变换到加权空间后再做欧氏 VQ」的重建误差形式(因为加权空间里的误差就是 )。于是变换方式自然浮出水面:
一句话总结这段推导:在加权空间里做普通的最近邻 VQ,等价于在原始空间里按 query 敏感度加权地做 VQ。论文报告这一变换在多层上一致降低了 QK 点积的 MSE 与 attention 的 KL 散度。
⚖️ 推导二:为什么 scale 可以所有 head 共享
极端低位宽下,还有一个隐蔽的敌人:幅度离群的 token(outlier token)。如果某个 token 的 Key 整体幅值远大于其它 token,共享码本会被它「带偏」。常规做法是逐 token 逐 head 归一化:为每个 token、每个 head 存一个独立的缩放因子。但缩放因子本身要占位宽——论文引用 NSNQuant(Son 等,2026)的 head 级做法:用 bit 存的 scale,摊到每个通道上是
当 、 时,这就已经是 bit/通道——在 Key 侧总位宽约 1.266 bit/通道 的场景里,它占了约 9.9% 的预算(本文自行推导:)。论文做了一个简化的实测判断:把归一化改成所有 KV head 共享一个 RMS scale 就够了:
只跟位置 有关,不跟 head 有关。于是每个 token 只存一个尺度(而不是 个),摊到每通道的位宽从 降到
整整省了 倍(Qwen3-4B 的 ,就是 8 倍)。论文仍然用 FP16 存 scale(),因为它此时只相当于 bit/通道,几乎免费。
这也解释了几个看似奇怪的位宽数字。论文附录 B 的位宽账里出现了这样的算式:、、——它们分别是「索引位数 ÷ 每组通道数」加上「元数据摊销」。1.266 这个看起来很别扭的数字,就是 TaSQ 的 Key 侧平均位宽(10 bit 索引、每组 8 通道,加上跨 head 共享 scale 的摊销),而 Value 侧仍是常规的 1.250。
🧩 推导三:把相关通道塞进同一组
回到那条高码率失真式:组内通道的协方差行列式越小,重建误差越小。于是论文先估出加权、归一化之后的 Key 在每个 KV head 上的协方差
然后对候选通道组 定义「组代价」:
其中 是按 取出的主子矩阵、 只是数值稳定项。把它代回失真式,,因此「哪个组的行列式小,哪个组就更便宜」。
于是分组变成一个组合优化:把 个通道划分成每组 个通道,使组代价之和最小——
——并加一条硬约束:同一对 RoPE 通道必须落在同一组里(否则在线应用 RoPE 就要打乱重排,廉价性没了)。注意这条约束有多么强:它把可行解从「 个通道任意配组」压缩成「 个 RoPE 对的配组」。
求解不是穷举,而是层级匹配:从每个 RoPE 对自成一組开始,每轮为「当前组的配对」算合并代价 ,求一个最小权完美匹配,合并匹配上的组,重复到每组恰好 个通道。
这一步的实测检验值得单独说:论文报告,这个只看协方差的代价函数与真实 VQ 重建 MSE 的 Pearson 相关系数达到 (代表性层;跨层也保持一致的高相关)。也就是说,用「行列式」这个便宜、可微、不用真的跑量化的代理量去选分组,几乎等价于直接最小化重建误差。
分组解给出一个置换矩阵 ,把每组的通道排成连续块:
置换成对进行,所以 RoPE 的分块结构原样保留——这是那条「RoPE 对不可拆」约束换来的回报。
🎛️ 码本拟合:给标定 token 也加权
到这里通道侧的空间已经「被裁剪」好了。最后一件事是在这套空间里拟合码本。普通做法是 k-means,但标定语料里不同 token 对最终 loss 的影响也不同,论文沿用 Fisher 加权 k-means:定义对角经验 Fisher
把一组通道上的 Fisher 求和作为该 token、该组的权重
再解加权的 k-means 目标:
编码时对每组取最近质心、只存索引:。存储开销 = 索引( bit/组)+ 每个 token 一个共享 scale(FP16),没有别的。
🧮 把位宽账算一遍:1.266 是怎么摊出来的
「每通道 1.266 bit」这种数字容易被当成魔法,其实它由两项加起来,两项都能手算。
第一项是索引摊销。码本大小 时,一个索引是 bit;如果每组装 个通道,摊到每通道就是
第二项是元数据摊销。每个 token 存一个 FP16 scale(16 bit),它被全部 个 KV head、每个 head 的 个通道共享,所以摊到每通道是
两项相加:
这就是 TaSQ 的 Key 侧平均位宽。论文表 5 把四种方法的账逐行摊开,值得照抄一遍(Key 与 Value 分列):CQ 两侧都是 1,024 质心 VQ,;NSNQuant 两侧都是 256 质心 VQ 加归一化元数据,;NovaKV 的 Key 是 1,024 质心 VQ 加一个 16 bit 的 head 级 scale,,它的 Value 是 1 bit 标量量化加两个 16 bit 的 head 级参数,;TaSQ 的 Key 是 1,024 质心 VQ 加一个 16 bit 的跨 head scale,,Value 与 CQ 同为 1,024 质心 VQ,。同一个「1 bit 左右」的目标,可以由完全不同的 与元数据组合达成,精度却差很多;而且同一个方法 Key 与 Value 的账常常不是同一套——这也是为什么读这类论文必须逐列看位宽,而不是看一句「1 bit KV」。
顺带指出一个容易被忽略的联系:如果 scale 改成每 head 一个(即分母退化成 而不是 ),这一项就变成
于是总位宽会落在 ——与论文表 5 里 NovaKV 的 Key 位宽 1.375 完全对应(论文表 5 与表 7 都写明了「一个 16-bit head 级 scale」这一项,本文只是把它与共享 scale 的差别算出来)。共享 scale 省下的 0.109 bit/通道(论文表 7 给出的 per-head 1.3750 与 pooled 1.2656 之差)在 Key 侧约 1.266 bit 的预算里占约 8.6%。
🆚 路线对照:压缩 KV 的三条路
论文在引言里把 KV Cache 压缩的既有路线分成三类,并说明了为什么它选择量化:
| 路线 | 机制 | 优势 | 主要代价 |
|---|---|---|---|
| Token 驱逐(eviction) | 按注意力分数丢弃「不重要」的历史 token | 直接减少 token 数,实现简单 | 信息被丢弃而非压缩,长程依赖一旦落在被丢的 token 上就无法恢复 |
| 缓存合并(merging) | 把相似的历史 token 合并成一个代表 | 保留信息结构,长度显著下降 | 合并本身要额外计算,且合并规则对分布敏感 |
| 量化(quantization) | 用更少的 bit 表示同一批 token | 不丢 token,只降精度;与 kernel 融合友好 | 低位宽下精度退化,1 bit 区间尤其难 |
论文对第三条(量化)的表述是「量化是被研究与被采用得最广的一类之一」(原文为 one of the most widely studied and adopted approaches),理由是它在不改变序列长度的前提下直接削减容量与带宽需求;而在量化内部,向量量化(VQ)因为「用一个码字联合表示多个通道、能吃到通道间的多维结构」,被认为最适合超低位宽。
一句话记住三条路的差别:驱逐与合并改变的是「留下什么」,量化改变的是「留下的东西写多细」。TaSQ 属于后者,所以它的失效模式也和前者不同——它不会丢掉某个 token,它的风险是每个 token 都稍微不准一点,累积起来把推理带偏(这正是论文单独用一节讨论「推理稳定性」的原因)。
🔧 运行时:把变换吸进权重与码本
一个自然的担心是:加权、归一化、置换三步变换,推理时岂不是要额外算?论文的做法是把变换从运行时搬走。
- 加权与置换可被吸收进 Key 的投影矩阵:;
- 加权逆可分发给每个质心,变换后的码本是 ;
- 于是重建与打分变成
其中 、。因为 只置换完整的 RoPE 对, 仍是标准的分块对角旋转矩阵,实现上只需按置换后的配对顺序重排 RoPE 频率;Key 与 query 全程待在同一套置换坐标系里,所以不需要任何运行时通道重排。
flowchart TB
subgraph CAL["标定阶段 离线一次"]
A1["采集 64 段 2048 token 窗口"] --> A2["估计 query 敏感度 W_h"]
A2 --> A3["加权 Key 并跨 head 归一化 s_p"]
A3 --> A4["按协方差行列式分组 得置换 P_h"]
A4 --> A5["Fisher 加权 k-means 拟合码本 C"]
A5 --> A6["把 W 与 P 吸进投影 得到 W_hat 与码本 C_hat"]
end
subgraph RUN["运行时 每个 token"]
B1["投影得到 pre-RoPE Key"] --> B2["查码本取索引 z 与共享 scale s_p"]
B2 --> B3["重建 Key 在 kernel 内融合"]
B3 --> B4["在线 RoPE 与 QK 点积"]
end
A6 --> B1这张图说明了什么:TaSQ 的全部复杂度都落在标定阶段(离线、一次性),运行时只多了「查表 + 还原 scale + 按置换后的频率做 RoPE」这几件事,都被融进 attention kernel,不增加额外的 kernel 启动或通道重排——所以它能声称「额外开销可忽略」。服务实测也印证了这一点:TaSQ 的吞吐与一个不做任何额外变换的最小 VQ 基线(CQ)持平。
📊 实测数字:论文报告了什么
以下数字全部来自论文正文与表格,是作者在单张 RTX 6000 Ada 上的测量,不是本文复现。位宽口径统一写成「Key/Value 每通道平均 bit」。
主结果(通用任务,贪心解码;Avg 为六个基准的平均。六个缩写依次为 GSM8K 小学数学应用题、MATH500 竞赛数学、MBPP 与 HumanEval 代码生成、BBH 推理、MMLU 学科知识):
| 模型 | 方法 | 位宽 K/V | GSM8K | MATH500 | MBPP | HumanEval | BBH | MMLU | Avg |
|---|---|---|---|---|---|---|---|---|---|
| Llama-3.1-8B-Instruct | BF16 | 16.000/16.000 | 83.62 | 42.20 | 59.60 | 62.20 | 73.38 | 62.64 | 63.94 |
| Llama-3.1-8B-Instruct | TaSQ | 1.266/1.250 | 81.73 | 34.00 | 58.40 | 58.54 | 64.28 | 58.33 | 59.21 |
| Llama-3.1-8B-Instruct | NovaKV | 1.375/1.250 | 76.95 | 29.40 | 55.00 | 53.66 | 48.46 | 56.43 | 53.32 |
| Llama-3.1-8B-Instruct | NSNQuant | 1.238/1.238 | 73.39 | 31.40 | 50.20 | 57.93 | 48.57 | 58.33 | 53.30 |
| Llama-3.1-8B-Instruct | CQ | 1.250/1.250 | 68.01 | 19.60 | 52.00 | 54.27 | 40.08 | 54.21 | 48.03 |
| Qwen3-4B | BF16 | 16.000/16.000 | 86.28 | 72.60 | 64.00 | 81.71 | 78.03 | 74.72 | 76.22 |
| Qwen3-4B | TaSQ | 1.266/1.250 | 85.44 | 69.80 | 62.60 | 77.44 | 68.28 | 71.26 | 72.47 |
| Qwen3-4B | NovaKV | 1.375/1.250 | 84.53 | 66.80 | 62.60 | 76.22 | 68.80 | 67.21 | 71.03 |
读表时请注意两件事。第一,位宽并不完全相等:TaSQ 是 1.266/1.250,NovaKV 是 1.375/1.250,NSNQuant 是 1.238/1.238——所以「谁的平均分高」必须在接近但不等的位宽下读,这正是论文把位宽逐列标出来的原因。第二,这里真正难的不是通用任务:论文明确指出,在长链式推理(long-CoT)与长上下文检索上,既有方法的退化才真正拉开差距,尤其是 NovaKV「在通用任务上表现尚可,但在长上下文基准上严重退化」。
组件消融(base Llama-3.1-8B、WikiText-2、序列长度 2048 的困惑度 PPL,越低越好):
| 配置 | PPL |
|---|---|
| FP16 基线 | 6.2374 |
| 完整 TaSQ | 8.4559 |
| 去掉 query 导向加权 | 8.5172 |
| 去掉跨 head 归一化 | 8.5103 |
| 去掉协方差感知分组 | 10.1731 |
去掉分组,PPL 从 8.4559 涨到 10.1731;去掉另外两个组件,只涨到 8.51 附近。 三个组件里,分组是贡献最大的那个——这也和推导三的结论吻合:在 1 bit 量级,通道「怎么配组」比「各自乘多大权重」更决定成败。
服务效率(Qwen3-4B-Thinking-2507,单张 RTX 6000 Ada,SGLang + Triton kernel,输入 2048 / 输出 32768):
| 指标 | BF16 基线 | TaSQ | 变化 |
|---|---|---|---|
| KV 池容量(token) | 235,257 | 2,935,184 | 12.48 倍 |
| 最大批量 | 6 | 84 | 14 倍 |
| 峰值吞吐(token/s) | 220.8 | 412.6 | 1.87 倍 |
| 首个 token 延迟 TTFT | 基线 | +10% ~ +14%(8k–32k 提示) | 一次性 prefill 成本 |
注意「12.48 倍」与「14 倍」这两个数字的口径不同:前者是KV 池容量的倍数,后者是最大批量的倍数。两者同向但不等——因为批量还受权重、激活、调度等其它因素约束,容量翻了 12.48 倍不等于批量也能翻 12.48 倍(实测是 6→84,恰好 14 倍)。把这两个数混成一个「翻了十几倍」来引用,是这类文章最常见的口径事故。
🧾 本文自行推导(与上述官方数字分列)
下面的数字不是论文里的,是本文用公开配置换算出来的量级一致性检查,不得当作官方数值引用:
- 每 token KV 字节数:以 Llama-3.1-8B 的公开配置(32 层、8 KV head、head_dim 128、BF16)代入 ,得 131,072 B ≈ 128 KiB/token;32K 上下文约 4 GiB。配置取自公开的模型 config.json。
- 同一算式换到 Qwen3-4B(36 层、8 KV head、head_dim 128、bf16)得 B ≈ 144 KiB/token。
- 用 144 KiB/token 反推服务实测的两个 KV 池:BF16 的 235,257 token 约需 32.3 GiB,TaSQ 的 2,935,184 token 按位宽比 摊薄后约需 31.7 GiB。注意服务实测用的是 Qwen3-4B,容量换算一律用 144 KiB/token,不能拿前面那个 128 KiB 去乘——两个数落在同一个量级、且都塞得进 48 GB 显存卡,这说明论文报的容量数字自洽。若两个数相差数倍,就说明本文的配置假设有错,而不是论文有错。
- 容量比:若只按位宽算,,与论文报告的 12.48 倍相差约 2%,差异来自残差策略(前 64 / 最近 256 token 保持全精度)等固定开销。
⏱️ 成本摊薄:TTFT 涨 10–14% 换回什么
服务实测里唯一「变差」的一项是新版本的首个 token 延迟(TTFT)上升 10%–14%(8k–32k 提示)。这一项为什么仍然划算,可以做一次粗略的算术——下面是本文自行推导的定性估算,不是论文的数字。
设一次请求的提示长度为 、输出长度为 ,每 token KV 字节数为 。位宽压缩把 变成 (TaSQ 的 ,分子是 Key 与 Value 两侧每通道 bit 之和)。
- 一次性成本:prefill 阶段要对提示里的每个 token 做一次编码(查码本),论文实测使 TTFT 上升约 10%–14%;
- 逐步收益:解码的每一步都要读一遍 KV,读取量从 变为 ,即在解码阶段把 KV 读取压力降到原来的约 7.9%。
只要 足够大(论文的负载是输出上限 32768 token),一次性的 prefill 成本就被分摊到数万步解码里;而当批量从 6 提到 84 之后,同样的解码步数被更多请求共享,峰值吞吐从 220.8 提到 412.6 token/秒。这就是「用一点首字延迟,换大量解码吞吐与并发」的取舍。反过来说:如果你的负载是「短提示、短输出、高并发」,这个取舍就不一定成立——那是另一个工作点,论文没有测。
❓ 三个常见误读
误读一:「1 bit KV」就是每通道真的只存 1 个 bit。 实际存的是一组通道共同的一个索引,再加上每个 token 的元数据(scale),TaSQ 的账是 1.266 bit/通道;而且它并不把所有 token 都压到 1 bit——通用任务保留最近 64 个 token 全精度,推理任务保留前 64 与最近 256 个 token 全精度。少算这两块,容量换算就会偏乐观。
误读二:「容量翻 12.48 倍,所以并发也能翻 12.48 倍」。 论文的表格里这是两个不同的量:KV 池容量 235,257 → 2,935,184 token(12.48 倍)与最大批量 6 → 84(14 倍)。二者同向,但不可互推——批量还受权重、激活、调度等其它约束,把它写成「并发翻了十几倍」是把两个口径揉成了一个。
误读三:「精度掉几个点而已」。 论文单独讨论这一点的原因在于:低位宽 KV 压缩会让推理模型产生重复或不连贯的生成,并且这种生成会一直持续到长度上限才停止——失败方式不是「答案略差」,而是「整段解码预算被烧掉且任务失败」。所以评估这类方法时,输出长度分布与「撞上限率」是要跟准确率一起看的指标。
🚧 边界与未解
- 这是单卡、单模型的测量。 效率实验是一张 RTX 6000 Ada 上的 Qwen3-4B-Thinking-2507;容量倍数、吞吐倍数都不能外推到多卡、更大模型或不同序列长度分布。
- Key 与 Value 不对称是有意的、也可能被推翻。 论文明确写了:Value 侧通道特征弱,所以保留常规连续分组,并把「为 Value 设计专门的量化空间」留作未来工作。
- 标定语料的依赖未被完全消解。 加权权重、协方差、Fisher 权重都来自 64 段 2048 token 的标定窗口(48 段 gpqa_main + 16 段 codeparrot)。论文附录专门讨论了「超出标定长度」的行为,这也是 NovaKV 在长上下文上退化的镜像风险。
- 残差策略是精度的一部分。 通用任务保留最近 64 个 token 全精度、推理任务保留前 64 + 最近 256 个 token 全精度——这些「不压缩的角落」本身就是被计入成本的设计选择,比较不同方法时必须确认它们的残差口径一致。
- 本文没有复现任何实验。 所有精度、吞吐、容量数字都是论文自报;「1.87 倍」是在该卡、该模型、该输入输出配比下的结果,换负载会变。
- 热度归热度,工程决策另说。 一篇论文被 SGLang 生态与推理社区讨论,不等于它已经在你的生产栈里稳定可用;把 KV 压缩引入线上前,要按自己的推理任务(尤其是否长链式推理)单独做稳定性验证——论文那条「压缩导致重复生成直到撞长度上限」的观察,正是为此写的。
- 标定数据的领域泛化性未展开。 上述三类量的估计全部来自同一批标定窗口;换成另一个领域(例如全代码或全多语语料)后,代价函数与分组是否仍最优,论文没有给交叉领域结论。
- 它与其它压缩维度是叠加而非替代。 KV 量化可以叠在 MQA / GQA / MLA 这类「先把 KV 数量本身减少」的架构选择之上,也可以与 token 驱逐、缓存合并叠加(各打不同维度);论文只比较了同属 VQ 的基线,没有测与驱逐类方法的组合效果。
✅ 小结
把这篇论文的推导链压成四句:
- 长上下文服务的第一约束是 KV Cache 的容量与带宽,它随长度线性增长、每个解码步被整摞读取;位宽是同时打这两个瓶颈的同一个旋钮。
- 量化误差不该等权看待:QK 点积误差是 的二次型,因此按 query 期望敏感度加权(对角近似 )能在欧氏 VQ 里直接最小化「对 logits 的伤害」,代价必须付得像 RoPE 那样逐对保留结构。
- 位宽预算里,元数据也是钱:把 scale 从「每 token 每 head 一个」改成「每 token 一个、全 head 共享」,元数据从 摊薄到 ,省 倍——这就是 1.266 这个数字里那 0.016 的来源之一。
- 1 bit 区间里,分组比加权更值钱:组代价取协方差行列式()与真实重建 MSE 的相关系数达 0.994,而消融显示去掉分组造成的 PPL 上升最大。
🎯 如果你今天只想记一件事
长上下文推理的成本曲线,是由「每 token 要搬多少字节」这条线决定的,而不是由参数规模决定的。 参数规模决定你能不能把模型装进显存,而 KV 的每 token 字节数决定你能同时服务多长的上下文、多大的批量——它跟序列长度、并发数都是乘积关系,所以放大的速度快得多的那一头总是它。
这条线一旦被认清,后面所有技术选择就都能落到同一把尺子上:把 KV 的头数减少(MQA/GQA/MLA)是减少「有多少份」,把每个元素压到更低位宽(VQ、标量量化)是减少「每份多细」,把历史 token 丢掉或合并(驱逐、合并)是减少「存多少份」。TaSQ 这篇工作做的完全是第二类,它的贡献不在「敢压到 1 bit」,而在压到 1 bit 时到底该按什么准则去设计那个量化空间——按 query 敏感度加权、按协方差配组、把元数据摊薄到跨 head 共享。
最后留一个判断口径给读者:看到任何「KV 压缩 N 倍」的说法,先问三件事——它算不算残差 token?它报的是容量倍数还是批量倍数?它在长链式推理上有没有撞长度上限? 这三问答完,数字才可比。
📋 来源与核验记录
以下来源均在本轮(2026-10-14)实际打开、核对过标题与摘要/正文内容,逐条给出 URL。
一手论文与官方代码:
- Tailoring the Quantization Space for 1-Bit KV Cache Compression(TaSQ,arXiv:2610.03027,v1 提交时间 2026-10-02 09:04 UTC,作者 Minsoo Cheong(首尔大学)、Donghyun Son(斯坦福)、Sungjoo Yoo(首尔大学))—— https://arxiv.org/abs/2610.03027 ;全文(含公式与表 1、表 4、表 5、表 7):https://arxiv.org/html/2610.03027v1
- TaSQ 官方代码仓库 —— https://github.com/mscheong01/tasq
- SGLang 官方文档(论文的实现宿主;效率实验在该栈内完成)—— https://docs.sglang.ai/
- SGLang 源码仓库 —— https://github.com/sgl-project/sglang
文中被点名、且逐条实测可访问的对照实体(位宽账、长上下文评测与 KV 量化谱系):
- CQ:KV Cache is 1 Bit Per Channel: Efficient Large Language Model Inference with Coupled Quantization(arXiv:2405.03917)—— https://arxiv.org/abs/2405.03917
- NSNQuant: A Double Normalization Approach for Calibration-Free Low-Bit Vector Quantization of KV Cache(arXiv:2505.18231)—— https://arxiv.org/abs/2505.18231
- NovaKV:Spend Bits Where Queries Look: KV Cache Vector Quantization with Attention-Preserving Transforms(arXiv:2608.04074)—— https://arxiv.org/abs/2608.04074
- KV-Rescue: Recovering Reasoning Language Model KV Eviction Loss via Stepwise Interleaving(arXiv:2608.15797,对应正文第 3 节引用的 Cheong 等 2026 更早工作)—— https://arxiv.org/abs/2608.15797
- KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache(arXiv:2402.02750)—— https://arxiv.org/abs/2402.02750
- KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization(arXiv:2401.18079)—— https://arxiv.org/abs/2401.18079
- RULER: What’s the Real Context Size of Your Long-Context Language Models?(arXiv:2404.06654,论文长上下文检索评测所用基准)—— https://arxiv.org/abs/2404.06654
- Llama-3.1-8B-Instruct 公开配置(用于本文的每 token KV 字节数换算;官方仓库需授权,此处为公开镜像的 config.json)—— https://huggingface.co/NousResearch/Meta-Llama-3.1-8B-Instruct/raw/main/config.json
- Qwen3-4B 公开配置(用于服务实测所涉模型的结构换算)—— https://huggingface.co/Qwen/Qwen3-4B/raw/main/config.json
第三方转引与社区信号(热度依据,2026-10):
- Hugging Face Daily Papers 收录页(第三方索引)—— https://huggingface.co/papers/2610.03027
- LLM 推理周报(2026-09-30 至 2026-10-07 的 arXiv / vLLM / HF 社区汇总,把「KV Cache 是当前瓶颈」与 1-bit KV 量化列为当周要点之一)—— https://dev.to/felipe0liveira/the-kv-cache-is-the-bottleneck-now-1-bit-quantization-moe-stragglers-and-per-second-gpu-billing-1p7
- SGLang 与 vLLM 生态中的 KV Cache 量化实现入口(本文只作「该方向已被主流推理栈工程化」的信号,未据其下任何性能结论)—— https://github.com/sgl-project/sglang
各数字的归属对照(便于复核时逐条回源):
- 10%–14%:TTFT 增量,论文 6.1 节(8k–32k 提示)实测;
- 35%:pre-RoPE 相对 post-RoPE 做 VQ 的总重建误差下降幅度,论文 3.3 节;
- 2%:本文自行推导——只按位宽算出的容量倍数 12.72 与论文实测 12.48 的差异(精确为 1.9%);
- 7.9%:本文自行推导——由 得到的解码阶段 KV 读取量占比;
- 9.9% 与 8.6%:本文自行推导——共享 scale 省下的 0.125 与 0.109 bit 相对于 Key 侧约 1.266 bit 预算的占比。
本文自行推导(与上述官方数字分列,仅作量级一致性检查):
- 每 token KV 字节数(Llama-3.1-8B ≈ 128 KiB/token、Qwen3-4B ≈ 144 KiB/token)、32K 上下文的 4 GiB 估算;
- 用 144 KiB/token 反推两个 KV 池容量(约 32.3 GiB 与约 31.7 GiB)的自洽性检查;
- 仅按位宽比推算的容量倍数 12.72 与论文实测 12.48 的差异来源(残差策略等固定开销)。
核验方式与限度:
- 来源 1、5–11 的标题与摘要、来源 2–4 与 16 的仓库/文档标题、来源 12–13 的配置字段、来源 14–15 的页面标题,均由本文在 2026-10-14 实际请求并核对;论文中的所有精度、位宽、容量、吞吐、困惑度数字均取自其正文与表格(表 1 / 表 4 / 表 5 / 表 7 与 §3.3、§4.3、§5.1、§6.1),未使用任何二手转述。
- 本文不包含任何独立实测与复现;文内「工程惯例」类判断(如残差口径必须对齐)属经验性提醒,不是论文结论。