AI 基础
您的 KV 缓存没有位问题,它有一个几何问题。

在相同的 2 位精度下,关于沿哪个轴量化的决定会使基准测试得分从 2.88 变化到 63.53。键和值需要相反的处理方式 —— 而原因在于注意力方程中,而不是硬件中。
让我们考虑 Llama-2-13B。将其键值缓存按量化组大小 32 分组为 2 位,同时保持其他所有内容不变 —— 相同的模型、相同的位预算、相同的组大小、相同的基准测试。
根据实现决策中的一个单一元素,CoQA 准确率结果要么为 2.88,要么为 63.53。使用全精度的得分为 66.37。
问题不在于使用的总位数。问题很简单:当计算每个尺度因子时,你选择沿哪个轴进行分组?当你决定使用通道作为键的分组维度和使用标记作为值的分组维度时,你最终会接近全精度性能。 如果你翻转任一选择,你会经历质量损失。如果你同时翻转这两个选择,模型将不再工作。

在相同的 2 位上花费在相同缓存的四种方式。来自 Llama-2-13B 的 KIVI 消融结果,组大小为 32。
量化通常被认为是一个简单的旋钮:8 位、4 位、2 位,附带平滑的准确性成本。 在 KV 缓存中,它不是这样的。它是选择坐标系统,不同的系统适用于键和值。 这篇文章解释了为什么。 简而言之:量化错误取决于组内的值范围;键和值具有非常不同的结构;人们经常因为不能从值分布中推导出正确的轴而绊倒。 你必须查看错误如何在注意力消耗后发生。 这给出了压缩中间激活的通用原则和怀疑重构错误作为质量代理的理由。
为什么 KV 缓存是问题所在
在生成阶段,变换器将之前处理过的所有键值投影(KV)数据存储在缓存中,以便不必再次计算这些数据。 该缓存随上下文长度和批大小线性增长。 最终,这将导致缓存的大小超过模型本身。
这种增长可以通过查看模型不同部分的内存消耗轻松识别。 在 LLaMA-7B 的 KVQuant 分析 中,权重在序列长度为 512 时占内存的 98%,激活占 2%。 在 128K 上下文中,比例反转为约 16% 的权重和 84% 的 KV 缓存。 当我们查看 KIVI 引用的 OPT-175B 分析时,他们发现了类似的结果。 具体来说,在批大小为 512 且 512 标记提示时,KV 缓存达到 1.2TB —— 是模型权重的几倍。
然而,容量只是问题的一半。GPU 必须为每个生成的标记从设备内存中读取整个 KV 缓存。这意味着当 GPU 读取 KV 缓存时,计算核心处于空闲状态。因此,减少缓存的总大小既可以增加可用的处理头部空间,又可以减少等待数据传输的时间。
量化错误的真正组成
统一整数量化在数学上是简单的。对于一组数字,你记录最小的数字作为零点,然后将该组的范围除以可以表示的级别数量来获得步长。然后你将每个元素四舍五入到最近的步长。两个立即的结果是:每个元素的误差由半个步长界定。第二,步长是该组的范围除以 2^B – 1。 在 2 位时,你只有 4 个级别来覆盖该组内存在的任何范围。因此,与其邻居相比,一个大 100 倍的元素不仅表现糟糕,还会为所有共享同一组的其他元素膨胀步长。组是损害的单位。选择轴意味着决定哪些元素一起受苦。用不同的方式表述这个问题,它不再是“我们可以承担多少位?”而是“哪里有极端值,我们可以将它们隔离吗?”
键:异常值位于固定通道中
大型语言模型包含与大多数激活相比异常大的激活。 Sun 和同事 在不同模型系列中编制了这些非常大的激活的目录:在 Mixtral 8x7B 中,最大幅度接近 7000,而特征中位数幅度约为 0.3 —— 相差四个数量级。这些激活非常罕见;它们在输入变化时固定在维度上,并且不是偶然的。它们作为隐式偏差,并且是将注意力集中在几个标记上的原因:注意力下沉行为。在键缓存中,这种结构非常明显:特定的通道在序列中的每个标记上都携带非常大的幅度。沿标记分组,每个组都包含这些异常通道,因此每个组的步长由异常值设置;所有普通通道都为此买单。沿通道分组,异常通道形成自己的组。它们的内部范围很大,但自成体系;普通通道独自存在。结果匹配。在 Llama-2-13B 上,KIVI 报告了每标记分组的键重构错误为 13.67,而每通道分组的错误为 4.55 —— 更重要的是,注意力评分错误为 47.00,而每通道分组的错误为 9.60。每标记量化键会产生大约五倍的评分错误。评分与键的有意义指标一致;每通道量化在两个方面都表现出色。
值:直觉在哪里破裂
值缓存没有显示出通道异常模式。它似乎相当平坦。根据范围论证,我们可以预期,无论使用哪个轴,两种方法都会产生类似的质量压缩。
它们没有。无论键管理如何实现(2.80 和 2.88 结果),压缩每通道值都会使模型崩溃。
这里有一个问题:如果你使用原始张量的原始重构错误来衡量这种损失,按通道值量化实际上看起来稍微好一点,在 3.73 和 4.57 之间。如果你用明显的方式验证你的压缩,你会选择破坏模型的配置。

Llama-2-13B 上的值缓存量化错误,以两种方式衡量。存储张量指标和消耗输出指标相差超过一个数量级。
解决方案是值缓存永远不会被直接读取。它被一个矩阵乘积所消耗:注意力输出是值向量在标记上的加权和,softmax 注意力评分作为权重。由于此原因,相关错误是引入的过程中的错误,而不是张量本身的错误。根据注意力输出来衡量,顺序完全颠倒。KIVI 报告的每标记值向量量化的注意力输出相对错误为 3.55,而每通道量化的错误为 49.89 —— 后者高出 14 倍以上,对于基于压缩的选择似乎更好。
解释是注意力稀疏性,它们测量为 84.3%。输出中包含的大多数信息都可以归因于少数几个非常重要的标记:注意力下沉行为。每标记量化将每个标记的错误限制在该标记内,因此无关重要标记上的错误会被几乎为零的注意力权重所消除。每通道量化将每个标记的错误扩散到共享的通道尺度上,因此糟糕表示的标记会污染重要标记的表示。使注意力高效的稀疏性也是使每标记量化安全的属性。
可以转移的教训比 KV 缓存更广泛:在张量被消耗的地方测量压缩错误,而不是存储的地方。重构错误的隐含假设是张量的每个组件在贡献最终输出时具有相等的权重。注意力显式地不这样做。任何下游操作都可以加权、门控或稀疏其输入,打破了这个假设。熟悉我之前关于 检索系统中评估指标的盲点 的文章的读者将会认识到这些结果与以前描述的失败类似:容易计算的指标报告了其他内容,而不是预期的内容。
旋转嵌入使键变得复杂
使用旋转位置嵌入(RoPE)存在一些问题。RoPE 根据每个标记的相对位置旋转通道对。这种混合部分消除了最初使每通道键量化起作用的固定通道结构 —— 一个异常通道被旋转到其邻居中,邻居继承了范围。KVQuant 的答案是排序:在应用旋转之前量化键,在解量化后应用 RoPE。结合每通道键量化、非均匀数据类型和隔离少量异常值,这使得它们在 3 位时低于 0.1 的困惑度降低,并使得在单个 A100-80GB 上支持 LLaMA-7B 的上下文长度高达 1 百万标记。
了解 RoPE 的影响程度也很重要。该论文 “RotateKV” 的作者报告了一旦添加 RoPE 后量化错误增加了 145%,并指出异常通道在注意力头之间有所不同 —— 这就是为什么在所有地方应用单个共享旋转矩阵是不够的,而适应头部旋转做得更好。
系统税收,它不是细节
每标记量化适合解码。每个标记到达;你量化它,添加到序列中(沿标记维度),没有其他东西移动。
然而,每通道量化不适合。由于通道的统计数据跨越尚未生成的标记,因此你无法在标记到达时计算尺度因子。KIVI 的解决方案是保持最近的标记 —— 高达 128 —— 以全精度存储在残差缓冲区中,并在积累足够多时对其进行量化。
事实证明,残差缓冲区变得至关重要,而不仅仅是一个偶然的事情。在 GSM8K 上使用 Llama-2-7B,全精度得分为 13.50。完全量化为 2 位,使用正确的轴,得分为 5.76。使用相同的轴和相同的位数,加上最近生成的标记的残差缓冲区,以全精度得分为 12.74。最近生成的标记的滑动窗口,以全精度,会恢复由于在难以解决的多步骤问题上进行激进量化而丢失的内容的大部分 —— 这将有意义,如果我们考虑哪些标记被一系列算术运算所关注。
正确完成所有这些事情有显著的好处 —— 正如 KIVI 报告的那样,Llama-2-7B 的峰值内存使用量减少了 2.6 倍,允许批次大小增加 4 倍,以及在实际服务任务上的吞吐量提高了 2.35 到 3.47 倍。
如何处理这些信息
- 永远不要对两者使用一个量化器。使用不同的量化器用于键(每通道)和值(每标记)。将单个量化器应用于“KV 缓存”的管道可能已经在使用少量位来表示每个值时牺牲了大部分可能的质量。
- 在 RoPE 之前量化键。这是一个正确性问题,而不是一个偏好问题。
- 存储最近生成的标记的全精度窗口。虽然存储此窗口所需的内存与缓存的大小相比非常少,但它是生成难题的准确性的重要组成部分。
- 不要在重构错误上验证。始终根据注意力输出或最终任务性能进行验证。存储指标不仅仅是噪声;对于值来说,它指向了错误的方向。
- 不要在短上下文多项选择基准上验证。KIVI 作者故意避免像 MMLU 这样的封闭任务,因为单个解码步骤只读取输出日志,并不真正使用缓存。任何不随时间建立缓存并从中生成的评估都无法观察到系统设计中的故障。
工作的方向
虽然关于几何问题的性质仍然有很多工作要做,但许多研究人员继续研究异常通道在各种变换器头部中的分布方式,以及硬件限制如何影响哪些分组最便宜: InnerQ 将通道向键和查询权重的归一化折叠到预填充中。因此,在运行时不需要任何额外的开销。另外,InnerQ 为最近生成的标记和注意力下沉标记存储高精度窗口。通过这样做,InnerQ 消除了异常通道污染邻近通道的机会。
其他人提出,我们不应该存储整个缓存,而应该存储足够的信息,以便能够在需要时 重新计算键和/或值 从较小的缓存表示中。
最后,必须记住,准确性并不是量化唯一影响的参数。 最近发表的研究表明 量化 KV 缓存会导致对齐退化。另外,这项研究记录了对齐退化,即使在使用 FP8 缓存和恢复协议的生产 vLLM 服务环境中,也可以恢复高达 97% 的对齐损失。因此,虽然配置可能会保持其基准测试结果,但这并不一定意味着它保留了您关心的所有其他相关参数。
一般原则
量化的想法被框定为“精度预算”:我可以牺牲多少位?KV 缓存表明更有用的问题是结构性的。精度以组为单位分配;组是损害的单位;沿着哪个轴分组决定了哪些元素共享命运。正确的轴是张量被消耗的轴,即您使用张量的方式,而不是存储在内存中的方式。键通过点积计算与查询一起使用。单个损坏的通道会污染所有评分。值通过标记上的加权平均计算消耗,使用 softmax 注意力评分作为权重。因此,单个损坏的标记只是被加权忽略。两个在两个连续层中生成的、尺寸相同的张量被不同地处理。对于您计划压缩的任何激活,值得问一下:什么操作消除了它,我的分组是否尊重它?
两个在两个连续层中生成的、尺寸相同的张量被不同地处理。对于您计划压缩的任何激活,值得问一下:什么操作消除了它,我的分组是否尊重它?












