当被复用的长上下文 KV cache 存在远端存储、需经普通云网络(单位数 Gbps)取回时,取回延迟可与重算 prefill 相当甚至更久。CacheGen 用改造过的视频编码流水线把 KV cache 编码成紧凑比特流(size 降 3.5–4.3×,TTFT 降 3.2–3.7×),并按带宽逐块自适应流式传输以守住 SLO。
复用上下文的 KV cache 可以省掉超线性增长的 prefill 计算,这一点已被 vLLM / SGLang / Prompt Cache 等系统利用。但这些系统隐含假设 KV cache 已在本地 GPU 显存,或经 NVLink(数百 Gbps)在 GPU 间共享。现实中 KV cache 体量巨大——Llama-34B 处理 Amazon 2023 年报(约 8 万 token)产生 19 GB KV cache,与模型本身相当——GPU 显存装不下这么多复用上下文,复用请求间隔可能长达数小时且不一定命中同一 GPU,因此 KV cache 通常被卸载到专用存储服务器。当它需要经普通云服务器间链路(单位数 Gbps)取回时,网络延迟可达数百毫秒到 10 秒以上,与不复用直接 prefill 相当。已有的 KV 压缩工作(丢 token、量化)都是为了缩小运行时显存占用、必须保留张量形状,没有针对传输时体积。
CacheGen 提出 "KV cache streamer" 抽象,承担三个角色:离线把 KV cache 编码成紧凑比特流、在变化的网络吞吐下流式传输、在接收端 GPU 解码回 KV cache。编码器建立在三个关于 KV cache 数值分布的经验洞察之上(§5.1),流水线与视频编码同构(group-of-pictures → delta → 量化 → 算术编码),但参数针对 KV 数据重新推导。流式层把上下文切成块(默认 1.5K token),每块离线编码成多个可独立解码的质量等级,运行时按上一块测得的吞吐挑选满足 SLO 且损失最小的配置,带宽过低时回退到发文本让 LLM 重算。
核心技术壁垒(THE 最难复现的洞察):放弃 KV cache 的张量形状约束,从而能像视频一样做"delta + 层级差异化量化 + 按 channel-layer 分组的算术编码"三重压缩。所有竞品(H2O、LLMLingua、smart quantization)都被"必须保留张量形状供 LLM 直接消费"这一约束绑死,只能丢 token 或均匀量化;CacheGen 把 KV 目标从"运行时可用"改为"传输后再解码可用",解锁了完全不同的压缩空间——这也是为何它能叠加在 H2O/LLMLingua 之上再降 3.3–4.2×。真正难复现的不是任一单步,而是"发现 KV cache 具备 channel-layer 熵集中 + token 局部性 + 浅层敏感三重结构"并把它们同时映射到一条编解码流水线。
3 Gbps 下,相较文本上下文 TTFT 降 3.1–4.7×,相较均匀量化基线降 3.2–3.7×;即便对比近乎无损的 8-bit 量化,仍降 1.67–1.81×(意味着高精度量化后仍存在大量可压缩冗余)。同质量下 KV cache 体积较均匀量化小 3.5–4.3×,质量退化不超过 2% accuracy / <0.1% F1 / <0.1 perplexity。自适应流式在 SLO=1s 下把违约率从 81% 降到 8%。离线编码延迟约 200 ms,存储成本与量化基线相当。
CacheGen 的请求生命周期分离线(编码入库)与在线(取回解码)两条路径。整体系统对照如下——基线传全尺寸 KV 张量慢,CacheGen 传压缩比特流:

Paper's Figure 1(caption: "When the context is reused, CacheGen speeds up the sharing of its KV cache by compressing (encoding) the KV cache."). (a) 基线跨网络传"整块 KV cache 张量"很慢;(b) CacheGen 传"压缩后的 KV cache"。这张图钉死了 CacheGen 在系统中的位置:它是一个介于存储服务器与推理服务器之间的上下文加载模块,不改动 LLM 本体。
三种加载方式的延迟构成对比揭示了设计取舍:

Paper's Figure 2(caption: "How different ways of loading context affect the network delay ... and the computation delay ..."). (a) 传文本:数据少但计算延迟高(要重算 prefill);(b) 传 KV cache:计算延迟低但数据量大;(c) CacheGen:传压缩 KV(或文本),网络与计算延迟同时省。关键读点是 (b) 中 "transfer KV" 那条网络时间条可长过 (a) 的 "process context" 计算条——这正是"隐藏瓶颈"的可视化。
编码流水线(change-based encoding,group-of-tokens):每 10 个连续 token 组成一组,组内第一个 token(anchor)独立压缩,其余 token 只记录相对 anchor 的 delta 张量:

Paper's Figure 6(caption: "Within a token group, CacheGen computes delta tensors between KV tensors of the anchor token and those of remaining tokens."). 注意它不像视频那样逐帧做前后 delta,而是全组共用同一个 anchor,使组内所有 token 可并行编解码——这是为解码吞吐做的关键工程取舍(牺牲一点压缩率换并行)。
请求 / 任务生命周期(arrival → schedule → dispatch → output)与调度决策可概括为:
调度纪律说明:streamer 的"调度器"以 chunk 为粒度做逐块配置决策(FCFS 顺序发送,无抢占——每块一旦发出即完成),准入/过载策略是在带宽过低时降级到文本重算(相当于用计算换带宽的软降级,而非丢弃请求)。"内存管理器"侧的分配单元是 1.5K-token 的 chunk;每个 chunk 离线预编码成多质量等级存于存储服务器的 {chunk_id: encoded_KV} 字典,无碎片问题,复用即按 chunk_id 直接命中。跨节点通信路径是普通云链路(单位数 Gbps TCP,非 NVLink/IB),传输的是编码后比特流而非张量。
无形式化作者证明 — 仅实证。
本文没有吞吐/延迟的解析模型或定理,全部结论由跨 3 模型 × 4 数据集的实测支撑;最接近"形式化"的是 App. C.1 的 Algorithm 1(自适应流式伪代码),它是一个贪心的逐块配置选择规则而非可分析的性能模型。为满足 framework 类别对成本模型的期待,此处补记:一个显式的性能模型本可澄清的问题(论文当前留白)——
T_transfer(size, bw) vs T_prefill(len, concurrency) 的闭式不等式。若有,chunk 长度、量化等级、回退阈值都能被解析地求最优,而非现在"经验取 1.5K token"。size/throughput ≤ remaining_time 的最大(最小损失)等级",是逐块贪心;论文未证明该贪心相对全局最优配置序列的差距上界,也未分析"反应滞后至多一个 chunk"带来的 SLO 违约概率。核心技术壁垒(承接 §2 Q2):最难复现处在于把三条经验洞察(token 局部性 → delta;浅层敏感 → 分层量化;channel-layer 熵集中 → 分组 AC)同时成立并映射到一条负担得起解码开销的流水线;缺任一洞察,压缩率或质量就会崩。
头号结果——TTFT 降低(跨 3 模型 4 数据集):

Paper's Figure 8(caption: "Time-to-first-token (TTFT): Across different models and different datasets, CacheGen reduces TTFT with little negative impacts on quality ..."). 每个子图横轴 TTFT、纵轴质量(accuracy/F1/perplexity),"Better" 指向左上。读点:CacheGen(绿)点几乎总在 Quantization / Text 左侧同一质量水平——即同质量更快,3 Gbps 下相对文本快 3.1–4.7×、相对量化快 3.2–3.7×。
同质量下体积降低:

Paper's Figure 9(caption: "Reducing KV cache size: Across various models, CacheGen reduces size of KV cache with little accuracy decrease on various datasets."). 证实 3.5–4.3× 的体积下降不是以质量为代价换来的(退化 ≤2% acc)。
互补性——叠加在上下文压缩之上:

Paper's Figure 10(caption: "Reducing KV cache size on top of H2O [153] and LLMlingu [72] ..."). CacheGen 在 H2O 上再降 3.5–4×、在 LLMLingua 上再降 3.3–4.2×,说明这些方法产出的浮点 KV cache 仍保有 CacheGen 所利用的统计特性——CacheGen 与它们正交互补。
自适应流式的价值隔离:

Paper's Figure 13(caption: "CacheGen reduces SLO violation rate over CacheGen without adaptation and the quantization baseline."). SLO=1s 下违约率 81%→8%,SLO=0.5s 下违约率低 60%——单独把"无自适应"版本剥出来对比,证明逐块降级/回退逻辑本身贡献显著,而非仅靠编码器。
开销与消融:

Paper's Figure 15(caption: "Contributions of individual ideas behind KV encoder: change-based encoding, layer-wise quantization, and AC based on channel-layer grouping."). 从均匀量化基线逐步叠加 channel-layer AC → change-based encoding → 分层量化,熵-精度曲线逐级右移,AC 与 change-based encoding 贡献最大。配合 Fig 14(此处未内嵌)显示离线编码 ~200 ms、存储与量化基线持平、解码经 GPU + pipeline 后对端到端延迟影响极小。
§6 Workload characterization — 赢/输的具体区间(据 §7.3 Fig 11/12、App. D Fig 19):
| Workload regime | CacheGen | Baseline (best of quant/text) | Why |
|---|---|---|---|
| 短上下文 (<1K token) | 自动回退到传文本 | 文本 prefill 更快 | 压缩+解码开销 > 省下的传输,短文本 KV 本就不大 |
| 长上下文 + 低带宽 (单位数 Gbps) | 大幅领先 | 传全尺寸 KV 或重算都慢 | 传输时体积降 3.5–4.3× 直接砍传输条 |
| 高带宽 (>20 Gbps) | 领先收窄趋近持平 | 量化基线传 KV 也很快 | 传输不再是瓶颈, 压缩收益被吃掉 |
| 高并发 (多请求争一 GPU) | 显著领先 | 文本 prefill 抢算力, TTFT 飙升 | 复用 KV 避免昂贵 prefill, 释放算力 |
| 带宽剧烈波动 | 自适应守住 SLO | 固定等级频繁违约 | 逐块降级/回退文本 |
论文诚实地暴露了"输"的区间(短上下文、超高带宽、超高端 GPU),而非只报平均。
| 步骤 | 论断 | 论文内依据 |
|---|---|---|
| 1 | 长上下文可复用,复用 KV cache 可省超线性 prefill | §2.2:FiD 长上下文 accuracy 40%→48%;财报/法律/对话历史被多次查询复用 |
| 2 | 但被复用 KV cache 常不在本地显存,需经普通网络取回 | §3:Llama-34B×80K token = 19 GB KV cache;间隔数小时、不命中同 GPU → 卸载到存储服务器 |
| 3 | 经单位数 Gbps 云链路取回,网络延迟 ≥ 直接 prefill,成隐藏瓶颈 | §3 + Fig 2b:传 KV 时间条长过重算计算条 |
| 4 | KV cache 数值有可利用的分布结构(token 局部性 / 浅层敏感 / channel-layer 熵集中) | §5.1:Fig 3 delta 方差低 2.4–2.9×;Fig 4 浅层加噪掉分更多;Fig 5 按 channel/layer 分组熵更低 |
| 5 | 因此可放弃张量形状,用 delta + 分层量化 + channel-layer AC 编成比特流 | §5.2 + Fig 6 + Fig 15 消融:三步各自压低熵-精度曲线 |
| 6 | 传输时体积大幅下降,同质量 TTFT 降 3.2–3.7× | §7.2 Fig 8/9:size 3.5–4.3×、TTFT 3.2–3.7× |
| 7 | 变带宽下逐块自适应可守 SLO | §7.4 Fig 13:SLO=1s 违约 81%→8% |
代码公开:https://github.com/UChi-JCL/CacheGen(本地未克隆,具体行号 [实现未公开] 于本仓库;以下按论文 §6 描述定位)。约 2K 行 Python + 约 1K 行 CUDA,基于 PyTorch v2.0 / CUDA 12.0。
框架集成两个接口(§6):
calculate_kv(context) -> KVCache:对 HuggingFace transformers 用 max_length=0、return_dict_in_generate=True 拿到 KV cache。generate_with_kv(KVCache) -> text:通过 past_key_values 参数塞入预算好的 KV,跳过 prefill;约 500 行 Python 完成 HF 集成。也接入 FastChat / llama.cpp / GGML;在 LangChain 的 BaseLLM._generate 内挂钩,判断当前上下文 KV 是否已存在再择路。KV 管理两个模块(§6):
store_kv(LLM) -> {chunk_id: encoded_KV}:调 calculate_kv,沿 token 维切块,逐块多等级编码,存字典到存储服务器。get_kv(chunk_id) -> encoded_KV:从存储服务器取该块编码比特流传给推理服务器。关键实现细节(易被忽略的 1–2 个技巧):
自适应逻辑(App. C.1 Algorithm 1)为逐块贪心:测吞吐 → 若重算时间 ≤ 剩余 SLO 则发文本,否则取满足 size/throughput ≤ remaining_time 的最大(最小损失)等级编码发送。默认量化:层分三等距组,bin size 分别 0.5 / 1 / 1.5(§C.2);默认块长 1.5K token,首块默认中等等级(Llama-7B 约 140 MB/chunk)。