问题背景:为什么大家都盯上 KV Cache
模型权重可以量化、分片、静态加载,但 KV Cache 是随请求长度和 batch 动态增长的。上下文越长、并发越高、输出越长,显存压力就越狠。很多线上系统不是算力先满,而是 KV Cache 先把服务卡死。
痛点 1:显存被上下文长度线性吃掉
每来一个 token,所有层都可能新增 K/V 状态。对长对话、长文档 RAG、代码补全来说,cache 是持续膨胀的。
痛点 2:batch 上不去
单请求 cache 太大,系统可容纳的并发自然下降。吞吐不是被算子打满,而是被内存顶住。
痛点 3:量化不是万能药
KV 做低比特量化能省内存,但它主要压缩的是数值位宽,没碰 hidden dimension 里的结构冗余。
PALU 的核心思想:不直接缓存 K/V,缓存更小的低秩中间态
论文摘要给出的核心描述是:decompose the linear layers into low-rank matrices, cache compressed intermediate states, and reconstruct the full keys and values on the fly。这句话几乎就是 PALU 的全貌。
传统做法
输入隐状态 x 经过完整线性层直接得到 K = xWk、V = xWv,然后把完整的 K/V 缓存起来,后续 decode 反复读取。
PALU 做法
把 Wk、Wv 拆成两个更小矩阵的乘积。先投影到低维空间,缓存这个低维表示;在真正做 attention 前,再把它恢复成完整 K/V 或与后续算子融合。
低秩投影分解:它到底分解了什么
下面是工程上最该抓住的形式。具体符号在不同实现里会略有差异,但结构本质是一样的。
PALU 的关键不在“低秩”三个字本身,而在缓存哪一段:缓存的不是完整 K/V,而是维度更小的 z_k / z_v 这类中间态,所以内存占用按 rank 比例下降。
为什么可压缩
原论文的出发点是:K/V 在 hidden 维度存在冗余,完整存下来浪费。既然线性投影本身可近似为低秩,就没必要把高维结果整块缓存。
为什么还能保精度
rank 不是拍脑袋固定,而是要搜索;而且论文还提了 medium-grained low-rank decomposition 和 efficient rank search,意思是它不是简单粗暴地全层统一砍维。
为什么比单纯量化更有意思
量化压的是数值精度,PALU 压的是表示维度。两者方向正交,所以理论上更容易叠加。
PALU 和 LoRA / QLoRA / 常见低秩方法有什么本质区别
| 方法 | 优化对象 | 发生阶段 | 主要收益 | 和 PALU 的关系 |
|---|---|---|---|---|
| LoRA | 参数更新增量 ΔW | 训练 / 微调 | 少训参数、降训练成本 | LoRA 是为了学得更便宜;PALU 是为了推得更便宜。 |
| QLoRA | 低比特权重 + LoRA 训练 | 训练 / 微调 | 更低微调显存 | 核心还是 finetune 路线,不是 KV Cache 路线。 |
| KV Quantization | K/V 数值位宽 | 推理 | 省 cache 内存 | 和 PALU 可叠加,一个压 bit,一个压 hidden dim。 |
| Token Eviction / Selection | 序列长度维度 | 推理 | 少存 token | 它沿 sequence 砍,PALU 沿 feature 砍。 |
| PALU | 投影层结构 + KV 中间表示 | 推理 | 省显存、提吞吐、适配长上下文 | 更接近 serving infra 技术栈。 |
一句话区分 LoRA 和 PALU
LoRA:我不想改那么多参数,所以把“要学的更新”做成低秩。
PALU:我不想缓存那么大的 K/V,所以把“生成 K/V 的投影”做成低秩。
一句话区分 QLoRA 和 PALU
QLoRA:为训练内存服务。
PALU:���推理缓存内存服务。方向不同,系统位置也不同。
把它放进一次真实推理流程里看
Prefill 阶段
- 输入 token 过 embedding 和前面若干层。
- 到 attention 层时,不直接生成完整 K/V 并缓存。
- 先计算低维 latent 表示,比如
z_k = xA_k、z_v = xA_v。 - 缓存的是这些低维表示,因此每个 token 的 cache footprint 变小。
Decode 阶段
- 新 token 到来,需要和历史 cache 做 attention。
- 系统读取压缩态
z,再通过后半段矩阵B重建 K/V,或者与 attention kernel 融合计算。 - 如果 kernel 融合做得好,就不一定显式 materialize 全量 K/V。
- 因此论文里才会强调 optimized GPU kernel with matrix fusion。
为什么 GPU kernel 很关键
光有“低秩分解”还不够。你要是把它写成很多零碎小矩阵乘,省下来的显存可能会被 kernel launch、内存搬运、reconstruction overhead 吃回去。所以 PALU 论文把 矩阵融合 单独拎出来,说明作者知道这不是纯算法题,而是个系统题。
工程上怎么应用:哪些系统最适合吃到 PALU 红利
长上下文 Chat / Agent
多轮对话、工具调用、系统提示重、输出还长,这类业务最容易让 cache 撑爆显存。
RAG / 文档问答
检索回来的上下文长,prefill 成本高,缓存驻留时间也长,特别适合。
代码生成
上下文和输出都容易很长,还常常需要大 batch 才划算。
短请求分类/抽取
上下文短、decode 短的任务,cache 本来就不大,PALU 收益可能没那么大。
在 serving 里的直接收益
- 单卡可承载更大 batch。
- 可支持更长 context window,而不必立刻堆更多卡。
- prefill/decode 阶段的内存压力下降,更容易稳定调度。
- 和 paged KV cache、prefix cache、continuous batching 不是冲突关系,能组合。
在成本上的意义
- 同等 SLA 下减少显存瓶颈,提升 GPU 利用率。
- 同样硬件预算下放更多并发。
- 对长上下文业务,单位请求成本更容易压下去。
- 如果本来就是 memory-bound 服务,收益通常比 compute-bound 场景更明显。
怎么落地:给工程团队的实际接入路线
路线 A:做成模型变体
直接把 attention 的 K/V projection 按 PALU 形式改写,导出一套专门用于 serving 的权重和计算图。这条路线收益最大,但需要模型转换和 kernel 配合。
路线 B:先离线 rank search
先对每层/每组头离线分析可压缩性,拿到 rank 配置,再把 serving runtime 改造成读取压缩 cache。这个更现实。
路线 C:先和量化联用
如果你们线上已经有 KV quantization,可以把 PALU 作为第二层压缩。这样迭代更有连续性,也更方便做 A/B。
一套靠谱的实施顺序
- 先做画像:确认服务到底是 memory-bound 还是 compute-bound。不是所有模型都值得上。
- 抽样分析层敏感度:不同层、不同 head、不同 rank,对精度影响不一样,别一刀切。
- 做离线评测:perplexity、长文本 QA、RAG recall、代码 pass@k,这些都要看,不要只看单一 benchmark。
- 做系统评测:prefill latency、decode throughput、显存峰值、batch 上限、尾延迟 P95/P99。
- 再做 kernel 融合:如果没有 fused kernel,理论收益会被打折。
- 最后灰度:优先灰度在长上下文占比高的流量池。
在 vLLM / SGLang / 自研引擎里怎么想
落点一般不在 scheduler,而在 attention backend + cache manager + model runner 三处:
- 模型 runner 知道如何生成压缩态。
- cache manager 知道如何存这种压缩态。
- attention kernel 知道如何从压缩态恢复或直接消费。
对线上观测要补哪些指标
- 每 token 平均 cache bytes。
- 各层 rank 配置与命中率。
- 重建开销占 attention 时间比例。
- 开启 PALU 前后 batch 上限变化。
- 长请求 vs 短请求的收益分层。
风险、边界和别踩的坑
不是所有层都适合压同一个 rank
如果全模型一刀切,通常不是精度掉得快,就是收益没吃满。所以论文才提 rank search。
没有 fused kernel,收益会缩水
省了存储,不代表总时延一定降。重建 K/V 的额外算子如果没融合,可能让收益打折。
精度评估不能只看 perplexity
长链路任务里,微小表征误差会在长上下文、多跳检索、代码生成里被放大。
什么时候不建议优先上 PALU
- 业务以短 prompt、短 output 为主。
- 当前瓶颈主要在算力,而不是显存。
- 团队还没有能力维护自定义 attention kernel。
- 线上模型版本切换非常频繁,模型转换链太重。
什么时候特别值得试
- GPU 显存总是先顶满。
- 长上下文请求占比较高。
- 已经在做 KV quantization,还想继续挖空间。
- 服务端用了连续 batching,但 batch 上限依然被 cache 限住。
参考与出处
- OpenReview 论文页:Palu: KV-Cache Compression with Low-Rank Projection。
- 论文摘要关键信息:低秩分解线性层、缓存压缩中间态、在线重建完整 K/V、medium-grained decomposition、rank search、量化友好、GPU fused kernel。
- 工程解读基线:LoRA / QLoRA / KV quantization / serving cache manager / attention kernel 常见实现范式。