MosaicKV:面向超长上下文LLM服务的动态二维KV缓存压缩——阅读笔记

笔记日期: 2026-07-04 笔记作者: Zhongzhu Zhou 论文标题: MosaicKV: Serving Long-Context LLM with Dynamic Two-D KV Cache Compression 作者: Sheng Qiang, Ruiwei Chen, Yinpeng Wu, Jinyu Gu, Zhichao Hua, Yubin Xia, Binyu Zang, Haibo Chen(上海交通大学IPADS实验室) arXiv: 2607.00760 状态 / Venue: arXiv预印本,2026年7月

一句话总结

MosaicKV是一个为超长上下文LLM推理服务而设计的系统,它发现了一个关键规律:KV缓存中每个 向量的重要元素分布是非均匀的——过去方法用同一个”通道掩码”套用到所有向量上,必然丢失大量 真正重要的信息。MosaicKV改为逐向量单独选择最重要的元素,并将不规则稀疏矩阵打包成连续内存 格式以规避GPU缓存未命中问题,同时把昂贵的SVD计算卸载到CPU异步处理。最终在H800 GPU上实现 了16倍注意力加速、7.3倍吞吐提升,准确率损失仅为1.76%。

前置知识

在深入技术细节之前,先介绍理解本文所需的背景知识。

Transformer自注意力机制

Transformer解码器的每个注意力层计算一种”相关性加权求和”:对于当前生成的新token,模型通过 计算当前token的查询向量(Query, Q)与所有历史token的键向量(Key, K)的点积相似度来决定 “关注谁”,然后对相应值向量(Value, V)加权求和:

Attention(Q,K,V)=softmax ⁣(QKd)V(1)\text{Attention}(Q, K, V) = \text{softmax}\!\left(\frac{Q K^\top}{\sqrt{d}}\right) V \tag{1}

其中 dd 是注意力头的维度(通常为64-128)。softmax\text{softmax} 把相似度分数转换为概率分布, 使注意力集中在得分最高的少数几个历史token上。

KV缓存:为什么需要它,代价是什么

自回归解码(每次生成一个token)的关键问题是:每次生成新token时,都要重新计算所有历史token 的K和V向量。对于一个已经有100个token的序列,第101个token需要对100对K/V做注意力。如果每步 都从头算,代价是 O(T2)O(T^2)——随序列长度二次增长,极其昂贵。

解决方案:KV缓存(KV Cache)。推理框架将每个token在每一层生成的K和V向量存入GPU显存, 后续步骤直接复用,避免重复计算。代价是大量显存占用,而且随序列长度线性增长:

KV缓存大小=2×L×T×H×d×字节数/元素(2)\text{KV缓存大小} = 2 \times L \times T \times H \times d \times \text{字节数/元素} \tag{2}

其中 LL = 层数,TT = 序列长度,HH = 注意力头数,dd = 头维度,系数2对应K和V各一份。

LLaMA-3.1-8B(32层、32头、头维度128、bf16精度)为例:

  • 128K token:2×32×131072×32×128×21282 \times 32 \times 131072 \times 32 \times 128 \times 2 \approx 128 GB
  • 1M token:1\approx 1 TB

H100/H800 GPU的HBM不过80 GB——128K上下文的KV缓存已经超过了整块显卡的显存。这就是问题的 根源。

更糟的是,随着上下文增长,注意力计算本身占据的时间比例急剧上升:

  • 128K上下文:注意力占总token生成时间(TBT)的84.7%
  • 1M上下文:注意力占TBT的97.9%

这是因为注意力的时间复杂度是 O(T)O(T)(对 TT 个历史token逐一计算),而前馈网络是 O(1)O(1) (与序列长度无关)。上下文越长,注意力越主导延迟。

SVD与旋转矩阵:通道压缩的数学基础

奇异值分解(SVD)将矩阵 ARm×nA \in \mathbb{R}^{m \times n} 分解为:

A=UΣV(3)A = U \Sigma V^\top \tag{3}

其中 U,VU, V 是正交矩阵(左/右奇异向量),Σ\Sigma 是对角矩阵(奇异值从大到小排列)。

在KV缓存压缩中,SVD用于”旋转”键/值矩阵,使重要信息集中到前几个通道。给定键矩阵 KRT×dK \in \mathbb{R}^{T \times d},旋转矩阵 RkR_kKK 的右奇异向量矩阵(等价于 KKK^\top K 的特征向量):

KK=VkΣk2Vk,Rk=Vk(4)K^\top K = V_k \Sigma_k^2 V_k^\top, \quad R_k = V_k^\top \tag{4}

旋转后:K=KRkK' = K R_k^\top。旋转后的 KK' 满足:前几列的方差(信息量)最大。这样只保留 前 rr 列就等于保留了最重要的信息分量。

保留前 rr 个通道所保存的”能量”比例为:

Energy(r)=i=1rσi2i=1dσi2(5)\text{Energy}(r) = \frac{\sum_{i=1}^{r} \sigma_i^2}{\sum_{i=1}^{d} \sigma_i^2} \tag{5}

在LLM的注意力头KV矩阵中,奇异值谱高度集中:前30%的通道通常捕获超过85%的总方差。这正是 SVD通道压缩能够工作的基础——绝大部分”信息”聚集在一个低维子空间中。

一个直觉性的数学例子:假设d=4(简化),KV向量 k1=[10,0.1,0.2,0.05]k'_1 = [10, 0.1, 0.2, 0.05](旋转后), 全局top-25%通道是通道0(值10)。全局掩码只保留通道0。但若另一个向量 k2=[2,0.1,9,0.3]k'_2 = [2, 0.1, 9, 0.3], 其最重要的通道是通道2(值9),而非全局最重要的通道0。全局掩码会把 k2k'_2 的关键信息丢掉。 逐向量选择:k1k'_1 保留通道0,k2k'_2 保留通道2——各自选各自最重要的。

有了以上背景,接下来详细理解MosaicKV的动机与技术。

更深入理解:注意力机制的内存带宽瓶颈

一个关键但常被忽视的点是:解码阶段的注意力是内存带宽受限的,而非计算受限的

解码时,每生成一个新token,需要读取全部T个历史token的K和V向量(各d维),然后做O(T)次 乘加运算。对于一个H800 GPU:

  • 内存带宽上界:3.35 TB/s
  • 算力上界:~2000 TFLOPS(fp16)

T=128K、d=128的单头注意力:

  • 数据量:2 × 128K × 128 × 2字节 = 65 MB
  • 计算量:2 × 128K × 128 = 32M FLOPs

最快读完65 MB需要 65×106/(3.35×1012)2065 \times 10^6 / (3.35 \times 10^{12}) \approx 20 微秒;完成32M FLOPs 仅需 32×106/(2000×1012)0.01632 \times 10^6 / (2000 \times 10^{12}) \approx 0.016 微秒。

内存读取时间是计算时间的1000倍以上——这就是为什么CUDA core有90%空闲,而内存带宽却 饱和到90.5%。减少需要读取的KV数据量,就是减少内存读取时间,从而直接降低延迟。

问题背景:为什么超长上下文KV缓存难以为继

随着GPT-5.4、Gemini 3.1 Pro、Claude 4.6等模型将上下文窗口扩展到百万token量级,长上下文 推理成为工业界的迫切需求。然而,KV缓存的代价是惊人的。

图1:KV缓存内存瓶颈与二维压缩的解空间

graph TD
    A[超长上下文请求<br/>128K - 1M token] --> B[KV缓存占用<br/>128GB at 128K<br/>1TB at 1M]
    B --> C{压缩方案?}
    C --> D[序列压缩<br/>只选择重要token]
    C --> E[通道压缩<br/>只保留重要通道]
    C --> F[朴素二维组合<br/>两者直接叠加]
    C --> G[MosaicKV<br/>动态二维压缩]
    D --> D1[需保留全部KV在显存<br/>压缩率有限<br/>高压缩率时精度大幅下降]
    E --> E1[全局统一通道掩码<br/>忽略逐向量差异<br/>无法减少token数]
    F --> F1[70pct通道压缩时<br/>精度损失82.8pct<br/>无法使用]
    G --> G1[逐向量元素选择<br/>分段自适应策略<br/>16倍加速,1.76pct损失]
    style G fill:#4CAF50,color:#fff
    style F1 fill:#f44336,color:#fff

现有KV缓存压缩方案及其局限

在MosaicKV之前,有两条独立的技术路线分别从不同角度压缩KV缓存。

序列压缩(Token Selection)

核心观察:softmax\text{softmax} 操作会指数级放大分数差异,使得注意力概率质量集中在少数几个 高分token上。如果能快速识别这些重要token,只对它们做完整注意力即可。

Quest(Tang等,2024)以token块(block)为粒度做粗粒度评分:用当前query与每个块的 key向量的min/max界来计算块分数,选top-kk块做完整注意力。避免了逐token评分的开销。

H2O(Zhang等,2023)用”重击者”(Heavy Hitter)策略:历史上积累了高注意力分数的token 未来也可能重要,保留一个固定大小的”重击者”KV缓存加上最近token的滑动窗口。

根本局限:序列压缩必须把全部KV缓存保留在显存中——因为任何token在任何解码步都可能 被选到。1M token时依然是1 TB KV缓存,只是实际参与注意力计算的token少了,显存没有节省。 此外,高压缩率(token保留比例<10%)时准确率急剧下降。

通道压缩(Channel Compression)

核心观察:KV向量中的元素重要性不均匀——大量级的”离群点”元素集中在少数通道中。

ThinK(Xu等,2025)从预填充阶段的K缓存计算一个全局统一的通道掩码,选出前 rr 个通道, 对所有后续K向量都用这个掩码。对V向量,ThinK发现二维联合压缩精度损失太大,只用序列压缩。

ShadowKV(Sun等,2025)用SVD旋转增强通道压缩,并辅以一个”影子键”机制做token选择。

根本局限:全局通道掩码忽略了逐向量的重要性差异。对某个特定token而言,其最重要的通道 未必是全局最重要的通道。如果那些特定通道被掩码丢弃,该token的信息就丢失了。

为什么朴素的二维组合会失败

论文的基础实验直接说明问题:在Quest(序列压缩)基础上,叠加全局SVD通道压缩(同时压缩K和V 的通道维度),在LongBench上的准确率损失:

通道压缩率对比纯序列压缩的精度损失
10%~5%
30%24.5%
50%~55%
70%82.8%

在实际需要的压缩率(>50%)下,准确率崩溃是灾难性的。这不是超参调优的问题,而是全局通道 掩码的假设与KV缓存真实重要性分布的根本矛盾。

MosaicKV的三个关键观察

MosaicKV建立在三个实测观察之上。

图2中对应的数学直觉:假设有T=1000个token,SVD旋转后每个token的键向量 kik'_i 理论上 前r个通道最重要,但实际分布因token内容而异——代码token、问句token、实体名称token的通道 权重各有侧重,没有一个”万能掩码”能同时保住所有token的关键信息。

观察1:逐向量元素重要性非均匀分布

SVD旋转后,理论上重要信息已经集中到前几个通道。但实际上这只是近似成立。

论文发现:在256 token的上下文中,每个KV向量中前25%最重要元素,只有**62.28%**落在全局 最重要的前25%通道中。随上下文增长,这一比例会进一步下降——不同位置的token有各自独特的 “重要通道分布”。

结论:全局通道掩码25%保留率会漏掉约38%的真正重要元素。需要逐向量独立选择最重要的元素, 而不是用统一掩码。

观察2:KV缓存不同区域的分布特征差异显著

KV缓存在不同区域呈现完全不同的统计特性:

  • 高方差区域:少数通道有极大量值(离群点),多数通道接近零。这种分布可以较激进地压缩, 因为离群点通道主导了信息内容。
  • 低方差区域:元素分布较为均匀,没有突出的离群点。这种分布若过度压缩则会丢失有用信息。

用统一的全局策略处理所有区域,必然对某些区域过度压缩、对某些区域不足压缩。

结论:需要分段自适应的压缩策略,根据每个段的分布特征选择合适的压缩率。

观察3:解码阶段GPU资源严重失衡

对LLaMA-3.1-8B 256K token解码阶段进行性能分析(A800 GPU,使用FlashInfer):

  • 显存带宽利用率:90.5%——接近饱和
  • CUDA core利用率:10.35%——几乎空闲
  • CPU利用率:~0%——完全空闲

这是内存带宽瓶颈的典型特征:瓶颈在从HBM读取KV缓存,而不在计算本身。CUDA core和CPU白白 浪费着。

结论:可以利用空闲的CUDA core做自定义稀疏注意力内核,用空闲的CPU做异步压缩管理—— 几乎没有机会成本。

动态二维压缩:核心算法详解

MosaicKV的主要贡献是一套二阶段压缩算法,同时压缩序列维度和通道维度,并充分利用逐向量、 逐分段的变化性。

图2:动态二维压缩流水线

flowchart LR
    A[原始KV缓存<br/>K: T行d列矩阵<br/>V: T行d列矩阵] --> B[步骤1:SVD旋转<br/>R_k由K的右奇异向量构成<br/>K-rotated等于K乘R_k转置]
    B --> C[步骤2:分段划分<br/>S_1, S_2, ..., S_m]
    C --> D[步骤3:CPU分段策略<br/>计算每段最优保留数r_j]
    D --> E[步骤4:逐向量元素选择<br/>对每个向量k-prime-i<br/>独立选top-r个元素]
    E --> F[稀疏KV表示<br/>k-hat-i: 值+索引对<br/>v-hat-i: 值+索引对]
    F --> G[Token选择<br/>块级别分数评估<br/>选top-k个块]
    G --> H[打包稀疏注意力<br/>二维压缩输出]

步骤1:SVD旋转——为通道压缩铺路

在预填充(prefill)阶段收集完整的键矩阵 KRT×dK \in \mathbb{R}^{T \times d} 后,计算旋转矩阵:

KK=VkΣk2Vk(6)K^\top K = V_k \Sigma_k^2 V_k^\top \tag{6} Rk=Vk,K=KRk(7)R_k = V_k^\top, \quad K' = K R_k^\top \tag{7}

旋转后 KK' 的前几列方差最大(信息量最多)。对值矩阵做同样处理:

VV=VvΣv2Vv,Rv=Vv,V=VRv(8)V^\top V = V_v \Sigma_v^2 V_v^\top, \quad R_v = V_v^\top, \quad V' = V R_v^\top \tag{8}

重要细节:解码阶段每产生一个新token,其键向量也需要做同样旋转: knew=knewRkk'_\text{new} = k_\text{new} R_k^\top。这是一个 O(d2)O(d^2) 的矩阵向量乘法——对于 d=128d=128, 这只需16384次乘加运算,开销可以忽略不计。

步骤2:逐向量元素选择

这是与之前方法的核心区别。

ThinK的做法(全局掩码)

  • 从预填充K缓存计算全局最重要通道集合 I=argtopk(var(K,axis=0),r)\mathcal{I}^* = \text{argtopk}(\text{var}(K', \text{axis}=0), r)
  • 对所有向量都用同一个 I\mathcal{I}^*k^i=ki[I]\hat{k}_i = k'_i[\mathcal{I}^*]

MosaicKV的做法(逐向量选择): 对旋转后的键向量 kiRdk'_i \in \mathbb{R}^d,独立选出 rr 个量值最大的元素:

Ii=argtopk(ki,r),k^i=(ki[Ii], Ii)(9)\mathcal{I}_i = \text{argtopk}(|k'_i|, r), \quad \hat{k}_i = (k'_i[\mathcal{I}_i],\ \mathcal{I}_i) \tag{9}

稀疏表示 k^i\hat{k}_i 存储 rr 对(值,索引)。对值向量同样处理: v^i=(vi[Ji],Ji)\hat{v}_i = (v'_i[\mathcal{J}_i], \mathcal{J}_i)

直觉上的解释:想象对一组人测量身高,“最高的30人”(全局掩码)和”每个人自己最高的30%部分” (逐向量选择)选出来的是完全不同的集合——后者对每个人都更精准。

算法1:逐向量元素选择的伪代码

算法1:Per-Vector Element Selection(逐向量元素选择)
输入:  K' ∈ R^{T×d}  (SVD旋转后的键缓存)
       r (每个向量保留的元素数)
输出:  K̂ = 每个向量的 (values, indices) 列表

for i = 1 to T:
    magnitudes = |K'[i, :]|             # 每个通道元素的量值
    I_i = argtopk(magnitudes, r)        # 量值最大的r个通道索引
    K̂[i].values = K'[i, I_i]           # 选出的值
    K̂[i].indices = I_i                 # 对应的位置

return K̂

关键差异:每个token ii 的索引集 Ii\mathcal{I}_i 各不相同,而ThinK所有token共用一个 I\mathcal{I}^*

步骤3:分段自适应压缩策略

将KV缓存划分为若干段 S1,S2,,SmS_1, S_2, \ldots, S_m,每段包含 ss 个连续token。对每段,CPU根据 其分布特征选择最优的通道保留数:

rj=f(stats(Sj))(10)r_j = f(\text{stats}(S_j)) \tag{10}

其中 ff 将段的统计特征(方差、离群点比例、量值熵等)映射到最优保留数。

高方差/多离群点的段:离群点通道主导信息,可以更激进地压缩(较小的 rjr_j)。 低方差/分布均匀的段:没有突出通道,需要保留更多通道(较大的 rjr_j)。

整体预算约束:

j=1mrjSjRbudget(11)\sum_{j=1}^{m} r_j \cdot |S_j| \leq R_\text{budget} \tag{11}

这是一个约束分配问题,在CPU上每段独立求解。

算法2:分段自适应策略生成的伪代码

算法2:Dynamic Segment Strategy Generation(动态分段策略生成)
输入:  KV缓存段 S_j ∈ R^{s×d}  (已旋转)
       R_budget (本段的元素预算)
输出:  r_j (本段每个向量的保留通道数)

# 计算分布统计量
variance = mean(var(S_j, axis=0))           # 各通道方差均值
outlier_ratio = count(|S_j| > threshold) / (s * d)  # 离群元素比例
entropy = -sum(p * log(p))                  # 量值直方图熵

# 高方差/多离群点 → 可以更激进压缩
if outlier_ratio > outlier_thresh:
    r_j = R_budget / s * (1 - alpha * outlier_ratio)
else:
    r_j = R_budget / s * (1 + alpha * (1 - outlier_ratio))

r_j = clamp(r_j, r_min, r_max)
return r_j

正是这种分段差异化处理给了这个方法”Mosaic”(马赛克)的名字:不同区域的KV缓存像马赛克瓦片一样 各有不同的压缩模式。

二维压缩后的Token选择与注意力计算

Token选择:对于第 \ell 个token块 BB_\ell,用压缩后的键向量计算近似注意力分数:

s=1dmaxiB q[Ii]k^i(12)s_\ell = \frac{1}{\sqrt{d}} \max_{i \in B_\ell}\ q'[\mathcal{I}_i]^\top \hat{k}_i \tag{12}

其中 q=qRkq' = q R_k^\top 是旋转后的query向量。选出得分最高的 top-kk 个块。

二维压缩注意力:对选出token的K/V稀疏表示做完整注意力:

o=softmax ⁣(qK^d)V^(13)o = \text{softmax}\!\left(\frac{q' \hat{K}^\top}{\sqrt{d}}\right) \hat{V} \tag{13}

旋转还原:注意力输出需要旋转回原始空间:

output=oRv(14)\text{output} = o \cdot R_v \tag{14}

二维压缩的理论加速上界

设token保留率为 α=sselected/T\alpha = s_\text{selected}/T,通道保留率为 β=r/d\beta = r/d,则理论上:

理论加速比=T×dsselected×r=1α×β(15)\text{理论加速比} = \frac{T \times d}{s_\text{selected} \times r} = \frac{1}{\alpha \times \beta} \tag{15}

以典型参数 α=0.10\alpha = 0.10(保留10% token),β=0.30\beta = 0.30(保留30%通道)为例:

理论加速比=10.10×0.30=33.3×(16)\text{理论加速比} = \frac{1}{0.10 \times 0.30} = 33.3\times \tag{16}

实际报告的16倍注意力加速,扣除了打包稀疏注意力内核的开销后,约为理论加速的48%。这个效率 在真实系统中是很合理的。

压缩KV缓存管理:充分利用空闲资源

动态逐向量方案带来了两个新的工程挑战:

  1. 稀疏访问开销:每个向量使用不同的索引集,造成不规则内存访问,严重破坏GPU缓存局部性。
  2. 管理开销:SVD计算、策略生成和重压缩开销很大,不能在解码关键路径上执行。

MosaicKV用压缩KV缓存管理系统解决这两个问题。

打包稀疏注意力(Packed Sparse Attention)

逐向量不同索引模式(k^i\hat{k}_i 有各自的 Ii\mathcal{I}_i)使朴素稀疏注意力代价很高。 直接实现会对每个token ii 从散乱内存位置读取 k^i\hat{k}_i.values,导致大量HBM缓存未命中, 完全抵消压缩带来的计算节省。

MosaicKV的解法:将所有稀疏向量打包成连续密集格式

nn 个选出token,每个保留 rr 个元素:

  • 将值打包成 PKRn×rP_K \in \mathbb{R}^{n \times r}(内存连续)
  • 将索引打包成 IKZn×rI_K \in \mathbb{Z}^{n \times r}

注意力计算直接在 PKP_K 上操作(密集矩阵访问,无散乱读取),但需要一个修改版的注意力内核, 理解元素 PK[i,j]P_K[i, j] 对应原始空间的第 IK[i,j]I_K[i, j] 个维度。

这个自定义内核使用CUDA cores而非Tensor cores。Tensor cores针对规整的矩阵乘法设计, 对于打包稀疏格式,CUDA cores提供更灵活的线程级计算。观察3已经证实CUDA cores在基线注意力 中仅有10.35%的利用率,完全有余量运行这个自定义内核。

图3:打包稀疏注意力 vs 朴素稀疏访问对比

graph LR
    subgraph NaiveSparse["朴素稀疏方案(慢)"]
        A1[k-hat-1: val 3.1,-2.4 idx 5,12] --> C1[散乱HBM读取<br/>每个元素一次缓存未命中]
        A2[k-hat-2: val 1.8,0.9 idx 3,7] --> C1
        A3[k-hat-3: val 2.2,-1.1 idx 9,2] --> C1
    end
    subgraph MosaicPacked["MosaicKV打包密集方案(快)"]
        B1[P_K: 密集n-by-r矩阵<br/>连续内存布局] --> C2[CUDA core注意力<br/>密集访问无缓存未命中]
        B2[I_K: 索引矩阵n-by-r] --> C2
    end
    C1 --> D1[缓存未命中率高<br/>带宽节省无法实现]
    C2 --> D2[缓存未命中率低<br/>实现完整带宽节省]

异构双缓冲(Heterogeneous Double Compression Buffering)

第二个挑战是管理开销。对一个段 SjS_j 做SVD计算的时间复杂度是 O(sd2)O(s \cdot d^2)——对于 典型参数,这需要数十毫秒,完全不可能在解码关键路径上执行。

MosaicKV使用双缓冲方案,配合两条异步流水线:

GPU端缓冲(快速、近似): 解码过程中产生新KV向量时,立即用简单快速方案(全局旋转 + 固定top-rr通道)压缩,存入 GPU缓冲区。当前及后续解码步骤立即使用这些近似压缩的向量,不需要等待

CPU端缓冲(慢速、精确): 同时,CPU接收原始KV向量的副本,执行完整流程:

  1. 累积新向量到当前段
  2. 段满时:计算逐段SVD旋转矩阵
  3. 执行算法2的策略生成
  4. 执行算法1的逐向量元素选择
  5. 打包为密集格式 (PK,IK)(P_K, I_K)

切换机制: CPU完成处理后,触发一次原子交换:GPU缓冲中该段的近似压缩表示被替换为CPU的精确压缩版本。 切换操作经过仔细同步,不阻塞任何正在进行的解码计算。

图4:异构双缓冲时序图

sequenceDiagram
    participant GPU as GPU(解码)
    participant GPUB as GPU缓冲
    participant CPUB as CPU缓冲
    participant CPU as CPU(异步)

    GPU->>GPUB: 新KV向量到达
    GPUB->>GPUB: 快速压缩<br/>全局旋转+固定top-r
    GPU->>GPUB: 读取压缩KV<br/>用于当前解码步
    Note over GPU,GPUB: 解码正常继续<br/>无需等待

    GPUB->>CPUB: 原始KV向量拷贝至CPU
    CPU->>CPUB: 累积直到段满
    CPU->>CPU: 计算逐段SVD旋转
    CPU->>CPU: 执行策略生成(算法2)
    CPU->>CPU: 执行逐向量元素选择(算法1)
    CPU->>CPU: 打包为密集格式

    CPU->>GPUB: 原子交换:用精确压缩替换快速压缩段
    Note over GPUB: 后续解码步使用<br/>精确压缩版本

这个设计同时实现了低管理延迟(解码从不阻塞)和高压缩质量(CPU有充分时间计算最优策略)。

系统架构总览

图5:MosaicKV完整系统架构

flowchart TD
    A[Long-Context Input 100K-1M tokens] --> B[Standard Transformer Prefill]
    B --> C[Compute SVD Rotation Matrices R_k and R_v]
    C --> D[Rotate KV Cache<br/>K-prime = K times R_k-transpose<br/>V-prime = V times R_v-transpose]
    D --> E[Init Compression<br/>CPU computes per-segment strategy<br/>GPU does per-vector selection and packing]
    E --> F[Decode: New token KV vector arrives]
    F --> G[GPU fast compression into GPU buffer]
    G --> H[Token Selection<br/>block-level scores select top-k blocks]
    H --> I[Packed Sparse Attention<br/>CUDA cores on P_K and P_V]
    I --> J[Rotate output back<br/>output times R_v and continue]
    J --> F
    G --> K[CPU receives raw KV vectors async]
    K --> L[Accumulate to full segment]
    L --> M[Per-segment SVD plus strategy generation]
    M --> N[Per-vector element selection and packing]
    N --> O[Atomic swap into GPU buffer<br/>optimal replaces fast compression]
    O --> G

实验评估

实验配置

  • 硬件:H800 GPU(80 GB HBM)
  • 模型:LLaMA-3.1-8B(主要),以及其他补充模型
  • 基线:无压缩基线、Quest(仅序列压缩)、ThinK(通道压缩)、ShadowKV(部分二维)
  • 基准测试:LongBench(多任务长文档理解)、RULER(合成检索任务)
  • 上下文范围:64K至1M token

显存减少

在128K上下文长度下,MosaicKV将KV缓存显存减少约3倍

以LLaMA-3.1-8B、256K上下文、单个请求为例,数值验证:

原始KV缓存(per层 per头):

原始大小=2×256000×128×2=131 MB(17)\text{原始大小} = 2 \times 256000 \times 128 \times 2 = 131\ \text{MB} \tag{17}

MosaicKV压缩后(假设10% token保留、30%通道保留):

  • 全K缓存(用于token选择):256000×38×219.5 MB256000 \times 38 \times 2 \approx 19.5\ \text{MB}(所有token都需要用于选择)
  • 选出token的精确K/V:25600×38×2×23.9 MB25600 \times 38 \times 2 \times 2 \approx 3.9\ \text{MB}
  • 索引存储:256000×38×219.5 MB256000 \times 38 \times 2 \approx 19.5\ \text{MB}

总计:约42 MB vs 原始131 MB → 约3.1倍缩减,与论文报告的~3倍一致。

乘以32层32头:全模型从约134 GB降到约43 GB——加上16 GB模型权重和激活,H800可以装下。

注意力加速

MosaicKV实现了最高16倍注意力加速。加速来自两个来源:

  1. 计算量减少:从对 T×dT \times d 个元素做注意力,变为对 sselected×rs_\text{selected} \times r 个元素:
理论加速=T×ds×r=1α×β(18)\text{理论加速} = \frac{T \times d}{s \times r} = \frac{1}{\alpha \times \beta} \tag{18}

以10% token保留、30%通道保留:10.10×0.3033×\frac{1}{0.10 \times 0.30} \approx 33\times理论加速。 实际16倍考虑了打包稀疏注意力内核的开销,约为理论值的48%。

  1. 缓存局部性改善:打包密集格式避免了散乱HBM访问,使内存带宽被高效利用。

解码延迟与吞吐

  • 解码延迟:在256K上下文下降低4.8倍
  • 吞吐(tokens/s):提升7.3倍

吞吐提升高于延迟改善的原因:更低的显存占用使得每块GPU可以同时服务更多并发请求(更大批次), 批处理效率的提升叠加在单请求延迟改善之上。

图6:主要性能指标对比(相对无压缩基线)

graph LR
    A["无压缩基线<br/>1.0x吞吐"] --> B["Quest仅序列<br/>约2.1x吞吐"]
    B --> C["ThinK仅通道<br/>约1.8x吞吐"]
    C --> D["MosaicKV全二维<br/>7.3x吞吐"]
    style A fill:#cccccc
    style B fill:#88aaff
    style C fill:#88aaff
    style D fill:#4CAF50,color:#fff
方法相对吞吐准确率损失显存节省
无压缩1.0×0%
Quest(仅序列)~2.1×~5-15%~1×(全KV常驻)
ThinK(通道)~1.8×~8%~1.5×
MosaicKV7.3×1.76%

精度结果:LongBench和RULER

平均准确率损失仅1.76%(LongBench + RULER综合)。

对比参照:

  • Quest单独使用(等价token保留率):~8-15%准确率损失
  • ThinK(30%通道压缩):~8%准确率损失
  • 朴素二维组合:24.5%~82.8%损失

准确率保留来自逐向量元素选择:每个向量保留自己最重要的元素,避免了全局掩码的系统性信息 丢失。

消融实验

  • 逐向量选择 vs 全局掩码:逐向量选择在相同压缩率下,恢复了全局掩码~60%的精度损失
  • 分段自适应策略 vs 均匀策略:自适应策略在相同显存预算下额外提升2-5%精度
  • CPU双缓冲的必要性:去掉双缓冲(同步管理),解码延迟增加约30%

数值计算示例:256K上下文时的压缩率

为使压缩率概念具体化,考虑LLaMA-3.1-8B单个请求、256K token上下文,MosaicKV配置为 10% token保留率、30%通道保留率(保留r=38个通道,d=128)。

原始KV缓存(每层每头)

原始大小=2×256000×128×2 字节131 MB(19)\text{原始大小} = 2 \times 256000 \times 128 \times 2\ \text{字节} \approx 131\ \text{MB} \tag{19}

MosaicKV压缩后(每层每头)

全K缓存(所有token,30%通道,用于token选择):

256000×38×219.5 MB(20)256000 \times 38 \times 2 \approx 19.5\ \text{MB} \tag{20}

选出token(25600个)的精确K/V(注意力计算用):

25600×38×2×23.9 MB(21)25600 \times 38 \times 2 \times 2 \approx 3.9\ \text{MB} \tag{21}

索引存储(所有token,每token 38个2字节索引):

256000×38×219.5 MB(22)256000 \times 38 \times 2 \approx 19.5\ \text{MB} \tag{22}

合计约42 MB vs 原始131 MB → 约3.1倍节省,与论文报告的~3倍完全吻合。

扩展到全模型(32层 × 32头):从约134 GB降到约43 GB——加上16 GB模型权重,完全可以放进 H800的80 GB显存,还有余量服务更多并发请求。

与现有方法的比较

表1:MosaicKV与主要KV缓存压缩方案的系统比较

方法压缩维度Token选择通道压缩精度损失吞吐提升
Quest序列Query感知块选择~5-15%(高压缩率时)~2×
ThinK通道(仅K)可选全局掩码(仅K)~8%(30%压缩率时)~1.8×
InfiniGen通道(仅加速选择)SVD加速选择全KV保留~3%~1.5×
ShadowKV部分二维SVD增强SVD旋转~5%~3×
MosaicKV两维(K和V)块级别逐向量,自适应1.76%7.3×

局限性与适用边界

SVD预填充开销:预填充阶段的SVD计算开销正比于 O(Td2)O(T d^2)。对于超长预填充(>512K token), 这可能变得显著。论文未测量或讨论预填充延迟。

CPU流水线延迟:GPU开始解码后的最初几个段,CPU尚未处理完毕,只能使用快速近似压缩。如果 生成的token数量很少(例如用于分类的短输出),CPU可能在请求结束前都没赶上,整个请求都只 使用近似压缩。

注意力头架构假设:方法假设标准多头注意力(MHA)。对于多查询注意力(MQA)或分组查询注意力 (GQA)——许多头共享同一份KV向量——逐向量选择的效果尚不明确,因为共享向量面对更多元的查询。

单GPU评估:结果均在单H800上。在多GPU张量并行服务(每GPU持有部分头)中,每个GPU分片 独立做SVD旋转和CPU缓冲的开销未经评估。

批处理交互:token选择步骤必须逐请求执行(不同请求有不同query)。在批处理服务中,这意味着 在共享KV缓存上为每个请求跑独立选择——随批次大小的开销扩展情况未讨论。

批判性分析:不足与可改进之处

不好的地方

1. 泛化性声明过强——实际只测了一个模型

16倍加速、7.3倍吞吐、1.76%精度损失被作为通用结论呈现,但主要实验模型只有LLaMA-3.1-8B。 论文提到”多个LLM模型”,却没有逐模型列表,无法评估架构差异带来的性能方差。

头维度较小(d=64d = 64)的模型通道压缩空间更小:30%保留率只剩19个通道,精度对此的敏感性 完全没有测试。使用GQA(如Mistral-7B)或MLA(如DeepSeek系列)的模型,其逐向量选择效果也 可能截然不同。

2. 基线不完整——缺乏与ShadowKV直接的吞吐-精度权衡对比

论文批评InfiniGen和ThinK是不完整的二维方案,但ShadowKV已经是部分二维SVD方案,发表时间 早于本工作。在吞吐-精度权衡曲线上,与ShadowKV的直接对比明显缺失,只是在文中一笔带过。

3. 缺少关键消融:逐向量选择的argtopk开销

逐向量元素选择对每个新KV向量都需要argtopk操作。对于批次大小32、生成1000个token、128头维度: 32000 × 128 = 4M次argtopk调用。论文未报告此操作的开销,也未对比在上下文较短(注意力尚未成为 瓶颈)时该开销是否会反而增加延迟。

4. 评估上下文范围选择有利于己方

16倍加速是在最长上下文(可能是1M token)下的峰值结果。在企业实际部署中更常见的32K上下文下, 相比更简单的序列压缩,二维方法的收益有多少,论文未提供上下文长度敏感性曲线,用户无法判断 切换点在哪里。

5. 精度指标粒度不足

仅报告LongBench + RULER的综合平均损失1.76%,掩盖了任务级差异。LongBench的某些子任务 (如段落检索、多文档问答)对KV缓存压缩极其敏感,而其他任务(如摘要、代码补全)更为宽容。 缺乏逐任务结果,用户无法评估自己的特定应用场景是否在1.76%的”安全区”之内。

作者淡化或回避的局限

CPU带宽和内存开销:CPU缓冲需要通过PCIe将原始KV向量从GPU HBM传输至CPU RAM。PCIe 5.0 峰值约32 GB/s,论文未量化PCIe利用率,也未说明当token生成速率很高时CPU缓冲是否会成为瓶颈。

旋转矩阵失效问题:SVD旋转矩阵 Rk,RvR_k, R_v 在预填充阶段一次性计算。随解码继续,KV缓存 不断增长,最优旋转方向可能漂移。对于超长生成序列(如1M token提示后再生成10K token),旋转 矩阵失效导致的精度退化完全未讨论,也未提是否有周期性更新机制。

索引存储的”税”:存储索引数组 Ii\mathcal{I}_i(每token per head per layer)有额外开销。 对1M token的10%保留(100K token)、r=38r = 38、使用2字节索引: 100K×38×2=7.6100K \times 38 \times 2 = 7.6 MB / 层 / 头。32层32头 = 约7.8 GB——这是索引专用显存, 没有被纳入论文的”3倍显存节省”统计中。

可以改进的地方

1. 跨架构全面测试:补充Mistral-7B(GQA)、Falcon-40B(MQA)、DeepSeek-V3(MLA)的测试, 说明MosaicKV在不同KV共享架构下的适用性或必要的改动。

2. 上下文长度敏感性曲线:提供8K / 32K / 64K / 128K / 256K / 1M等上下文长度下的延迟分解, 让用户知道MosaicKV从哪个上下文长度开始”值得用”。

3. 索引压缩:索引值范围仅[0, 127],只需7位。可用packed nibbles或delta编码,将索引存储 开销减少约一半,真正实现更好的净显存节省。

4. 在线旋转矩阵更新:维护KV缓存的滑动统计(如指数移动平均的 KKK^\top K),周期性重计算 旋转矩阵,解决长生成序列下的旋转失效问题。

5. 逐任务精度分解:公开LongBench各子任务的精度结果,让用户可以根据自己的应用场景评估 1.76%损失的可接受性。

6. 真实批处理服务实验:在批次大小16-64、混合上下文长度、跨请求prefix sharing的条件下评估 MosaicKV,验证逐请求token选择是否与生产服务系统兼容。

总结

MosaicKV提出了一个有理论支撑、工程实现扎实的超长上下文KV缓存压缩方案。其核心洞察——逐 向量元素选择大幅优于全局通道掩码——既直观又有实验支持。

工程设计同样精心:异构CPU/GPU双缓冲将昂贵的SVD计算从解码关键路径移出,把潜在的性能负担 (昂贵的SVD)变成零开销的后台任务,充分利用了基线注意力中大量闲置的CUDA core和CPU资源。

7.3倍吞吐提升、16倍注意力加速、1.76%精度损失,是对单维方法的显著进步。如果精度结果在 更细粒度的任务分析下仍然成立,且方法能推广到多种架构,这将是长上下文LLM生产部署的重要技术。

主要待回答的问题包括:GQA/MQA/MLA架构的适用性、不同上下文长度下的实际收益、索引存储开销 的精确核算,以及生产批处理场景下的行为——这些都值得后续工作深入探究。

从更宏观的视角看,MosaicKV代表了一种在系统层面主动管理”信息异质性”的思路:不把KV缓存当作 均匀的数据块,而是尊重其内部的统计结构,为不同区域分配不同的压缩资源。这种”差异化管理”的 理念在未来可能会延伸到其他GPU内存管理场景——例如激活值存储、梯度缓存,乃至更广泛的GPU/CPU 异构内存层次管理,具有一定的方法论意义。

与相关工作的技术对比深析

MosaicKV vs ThinK:通道压缩策略的本质区别

ThinK是目前最接近MosaicKV思路的先前工作,但两者在核心设计上有根本差异:

ThinK

  • 通道掩码:全局计算,只对K,不对V做通道压缩
  • 选择标准:通道在预填充K缓存上的整体方差
  • 数学表达:所有token共用 k^i=ki[I]\hat{k}_i = k'_i[\mathcal{I}^*],其中 I\mathcal{I}^* 固定
  • 局限:V只做序列压缩;即便对K,也因为全局掩码错过了部分向量的关键通道

MosaicKV

  • 通道掩码:逐向量独立,K和V都做通道压缩
  • 选择标准:每个向量自身的元素量值
  • 数学表达:每个token有自己的 k^i=ki[Ii]\hat{k}_i = k'_i[\mathcal{I}_i]Ii\mathcal{I}_i 因token而异
  • 核心提升:全面二维压缩(K+V均做序列+通道),精度损失仅1.76%

这一差异在精度上体现为:相同压缩率下,MosaicKV对比ThinK在准确率上有显著优势,尤其在 通道压缩率>30%时。

MosaicKV vs ShadowKV:部分二维 vs 完整二维

ShadowKV也用了SVD旋转,并做了一定程度的二维压缩,但有重要局限:

  • token选择时用低精度K摘要,但attention实际用的仍然是(部分压缩的)完整K
  • V向量并未全面做二维压缩

MosaicKV是第一个在整个解码阶段(包括token选择和注意力计算)对K和V都实现全二维压缩的系统。 这也是”全二维”(full-lifecycle two-D compression)这一表述的含义。

参考文献

  • Quest: Tang et al., 2024. “Quest: Query-Aware Sparsity for Efficient Long-Context LLM Inference.”
  • ThinK: Xu et al., 2025. “ThinK: Thinner Key Cache by Query-Driven Pruning.”
  • ShadowKV: Sun et al., 2025. “ShadowKV: KV Cache in Shadows for High-Throughput Long-Context LLM Inference.”
  • InfiniGen: Lee et al., 2024. “InfiniGen: Efficient Generative Inference of Large Language Models with Dynamic KV Cache Management.”
  • H2O: Zhang et al., 2023. “H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models.”
  • FlashAttention: Dao et al., 2022. “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness.”
  • FlashInfer: Ye et al., 2025. “FlashInfer: Efficient and Customizable Attention Engine for LLM Inference Serving.”
  • LongBench: Bai et al., 2024. “LongBench: A Bilingual, Multitask Benchmark for Long Context Understanding.”
  • RULER: Hsieh et al., 2024. “RULER: What’s the Real Context Size of Your Long-Context Language Models?”