<aside> <img src="/icons/attachment_red.svg" alt="/icons/attachment_red.svg" width="40px" />
参考文献
https://arxiv.org/abs/2405.05254 (2024-05)
https://arxiv.org/abs/2412.06464 (2024-12)
https://arxiv.org/abs/2505.09388 (2025-05)
https://arxiv.org/abs/2510.26692 (2025-11)
https://arxiv.org/abs/2512.02556 (2025-12)
https://arxiv.org/abs/2602.15763 (2026-02)
https://arxiv.org/abs/2603.12201 (2026-03)
https://arxiv.org/abs/2606.19348 (2026-04)
https://arxiv.org/abs/2608.30320 (2026-09)
</aside>

在现代成熟的推理框架之下,一种新Attention机制的提出必须适配其相应的KV Cache管理机制。**一边是怎么算(compute bound,影响prefilling),一边是怎么存(memory bound,影响decoding)。**近期所有在注意力方向的研究,无非就围绕这两块进行优化。本文将详细论述从Qwen3系列,GLM5.2系列到Deepseek V4系列的注意力机制以及其相应的KV Cache优化机制。
<aside> <img src="/icons/cellular_blue.svg" alt="/icons/cellular_blue.svg" width="40px" />
本文所有实验均在4卡H100上完成。
</aside>
详细参考:深度讲解大模型分布式文本并行优化:PCP,DCP - 知乎
DCP 的本质是:以复制 Q(唯一的 Q Token 被广播或复制到所有 Rank**) + 分片 KV 的方式,利用多卡显存共同支撑超长序列的逐 token 生成。**
将KV Cache在Attention计算前AllGather(一般不这么做,要把 KV 搬到 Q 所在的卡,通信开销太大),或者每卡计算局部注意力 AllReduce(把 Q 放到每张 KV 所在的卡,也就是复制Q)。
每层的 KV cache 逻辑形状如下:
[ num_tokens , num_kv_heads , head_dim ]
↑ ↑
token 维 head 维
(随请求长度增长) (模型结构固定)
TP 和 DCP 是拿刀从这个张量的两个不同方向下手。
head 0 head 1 head 2 head 3
┌────────┬────────┬────────┬────────┐
tok 0 │ rank0 │ rank1 │ rank2 │ rank3 │
tok 1 │ rank0 │ rank1 │ rank2 │ rank3 │
... │ ... │ ... │ ... │ ... │
tok N │ rank0 │ rank1 │ rank2 │ rank3 │
└────────┴────────┴────────┴────────┘
每个 rank 拿走几个完整的 head,但持有该 head 的全部 token
好处是 attention 算得很干净:每个 rank 手里有它那几个 head 的完整历史,本地就能算完整的 attention,只在最后 output projection 后做一次 all-reduce。这也是 TP 的天然形态——它本来就是为了切权重矩阵设计的,KV cache 跟着 head 走只是副产品。
问题在于 head 维不够长。 GQA 之后 num_kv_heads 通常只有 8,那 TP 最多切 8 份;TP=16 时 vLLM 只能让每 2 个 rank 各存一份重复的 KV,单卡 KV 占用不再下降,max_model_len 也就卡死了。MLA 更极端——它的 cache 是每 token 一个 latent 向量,根本没有 head 维,TP 一刀都切不下去,每个 rank 都得存一份完整副本。