跳转到主要内容

KV Cache Hit Ratio 修正模型:从直觉到统一公式

· 约 7 分钟阅读

1. 问题:KV cache hit 后,prefill 计算量到底降了多少?

KV cache hit ratio(记为 hh)是推理系统的关键指标。当 h>0h > 0 时,前缀部分的 KV 已经被缓存,prefill 只需要对 suffix token 做新计算。但不同类型的算子对 hit 的响应方式不同,不能简单地用 (1h)(1 - h) 线性缩放。

本文用三张图,逐步拆解 hit 后 attention、FFN、端到端 TTFT/TPM 的缩放行为,最终给出一个统一修正模型。

2. 图一:Attention 为什么按 1h21 - h^2 缩放?

KV Cache Hit 对 Prefill Causal Attention 计算面积的影响

这张图解释的是 prefill causal attention 的二维 token 交互面积。

设总输入长度为 NN,命中 prefix 长度为 H=hNH = hN,未命中 suffix 长度为 M=(1h)NM = (1-h)N。0-hit 全量 prefill attention 的因果注意力区域约为 N2/2N^2/2。命中 prefix 后,prefix 内部的 attention 输出已经复用,不再重算;新计算只发生在 suffix token 上,它们既要 attend 到 cached prefix,也要 attend 到 suffix 内部:

Whit=MH+M22WhitW0=MH+M2/2N2/2=2h(1h)+(1h)2=1h2\begin{aligned} W_{\text{hit}} &= M \cdot H + \frac{M^2}{2} \\[6pt] \frac{W_{\text{hit}}}{W_0} &= \frac{M \cdot H + M^2/2}{N^2/2} = 2h(1-h) + (1-h)^2 = 1 - h^2 \end{aligned}

直觉:即使只有 suffix token 需要新算,它们仍然要读取/关注 cached prefix,剩余 attention 区域是「去掉 prefix-prefix 区域」后的面积。所以 attention 不是按 miss token 数 1h1-h 线性下降,而是按 1h21-h^2 下降——下降得更慢,因为 suffix 还要”回头看” prefix。

这是可解释的一阶近似。如果 breakdown 能把 QKV/O projection 和真正的 FlashAttention 分开,projection 部分更接近 1h1-h 线性缩放;把 attention bucket 作为整体处理时,1h21-h^2 是合理的近似。

3. 图二:Attention vs FFN,谁受益更大?

Attention vs FFN 计算量对比

这张图对比同一 hit ratio 下 attention 和 FFN/GEMM 的缩放差异:

算子缩放函数原因
Attention1h21 - h^2二维 token 交互面积,suffix 仍需 attend prefix
FFN / GEMM1h1 - h逐 token 独立处理(1D 序列),只需重算 suffix
Communication1\approx 1dispatch/通信保守视作固定项

关键洞察:FFN/GEMM 按 1h1-h 线性缩放,比 attention 的 1h21-h^2 受益更大。也就是说,随着 hit ratio 提高,FFN 的计算量下降得更快,attention 反而成为越来越大的瓶颈。

这也解释了为什么高 hit ratio 场景下,优化注意力机制(FlashAttention、PagedAttention 等)比优化 FFN 更重要。

4. 图三:端到端 TTFT 与 TPM 的影响

KV Cache Hit 对 Prefill TTFT 与 TPM 的影响

这张图展示的是 hit ratio 对端到端 Time-To-First-Token(TTFT)和 Tokens-Per-Minute(TPM)的综合影响。

Hit 后有两个相反的趋势:

  1. 计算量下降 → TTFT 降低 → TPM 提升
  2. KV cache load 增加 → 需要从存储池/Host DRAM 经 PCIe 加载 KV 到 GPU HBM → TTFT 增加

统一模型把 TTFT 拆成三部分:

Tcompute(h)=Tattn,0(1h2)+Tffn,0(1h)Tload(h)=hNSkv/gpuBpcie/gpuToverlap(h)=αmin ⁣(Tload(h),  Tcompute(h))TTFT(h)=Tfixed+Tload(h)+Tcompute(h)Toverlap(h)\begin{aligned} T_{\text{compute}}(h) &= T_{\text{attn},0} \cdot (1 - h^2) + T_{\text{ffn},0} \cdot (1 - h) \\[6pt] T_{\text{load}}(h) &= \frac{h \cdot N \cdot S_{\text{kv/gpu}}}{B_{\text{pcie/gpu}}} \\[6pt] T_{\text{overlap}}(h) &= \alpha \cdot \min\!\big(T_{\text{load}}(h),\; T_{\text{compute}}(h)\big) \\[6pt] \text{TTFT}(h) &= T_{\text{fixed}} + T_{\text{load}}(h) + T_{\text{compute}}(h) - T_{\text{overlap}}(h) \end{aligned}

其中:

  • Tcompute(h)T_{\text{compute}}(h):hit 后可变计算时间,attention 按 1h21-h^2、FFN 按 1h1-h 缩放
  • Tload(h)T_{\text{load}}(h):KV cache 从 Host 经 PCIe 加载到 HBM 的时间,随 hh 线性增长
  • TfixedT_{\text{fixed}}:不可缩放的固定开销(communication、dispatch、框架调度等)
  • Toverlap(h)T_{\text{overlap}}(h):KV load 和 miss-token compute 的重叠时间

α\alpha(overlap ratio)是关键参数:

α\alpha含义TTFT 公式
0完全不重叠(线上现状/保守复刻)Tfixed+Tload+TcomputeT_{\text{fixed}} + T_{\text{load}} + T_{\text{compute}}
1充分重叠(优化目标)Tfixed+max(Tload,  Tcompute)T_{\text{fixed}} + \max(T_{\text{load}},\; T_{\text{compute}})

5. 两种 TPM 口径

Hit ratio 修正后需要区分两种 TPM 口径:

口径公式用途
Delivered TPM(ISL+OSL)×60000/tchip(\text{ISL} + \text{OSL}) \times 60000 \,/\, t_{\text{chip}}经营、营收、对外交付 token。cached input 也算交付 token。
Physical TPM(ISL×(1h)+OSL)×60000/tchip(\text{ISL} \times (1 - h) + \text{OSL}) \times 60000 \,/\, t_{\text{chip}}硬件实际消耗口径。cached input 不再重复计入 prefill 计算。

其中 tchip=tprefill(h)+tdecodet_{\text{chip}} = t_{\text{prefill}}(h) + t_{\text{decode}}

端到端修正时必须保留 decode 项。高 OSL、decode 占比高的场景下,只修正 prefill 会明显高估整体 TPM 增益。

6. 统一模型:从简化到通用

6.1 轻量化一阶模型

如果缺少 trace/breakdown 细分,退化为:

Tcompute(h)=(1h)T0TTFT(h)=Tload(h)+(1h)T0\begin{aligned} T_{\text{compute}}(h) &= (1 - h) \cdot T_0 \\[4pt] \text{TTFT}(h) &= T_{\text{load}}(h) + (1 - h) \cdot T_0 \end{aligned}

进一步假设 KV load 和 compute 充分 overlap,得到:

Θ(h)=Θ0max(1h,  δh)\Theta(h) = \frac{\Theta_0}{\max(1 - h,\; \delta \cdot h)}

其中 δ=NSkv/(BpcieT0)\delta = N \cdot S_{\text{kv}} / (B_{\text{pcie}} \cdot T_0) 是全量 KV load 时间与 0-hit prefill 时间的比值。这个公式简洁优美,明确表达了:KV cache hit 一方面减少计算,另一方面增加 KV load,最终产能不能按 1/(1h)1/(1-h) 无限放大。

6.2 完整统一模型

有 trace/breakdown 时,保留分阶段缩放:

Tcompute(h)=Tattn,0(1h2)+Tffn,0(1h)+Tother,0fother(h)Tload(h)=hNSkv/gpuBpcie/gpuTTFT(h)=Tfixed+Tload(h)+Tcompute(h)Toverlap(h)\begin{aligned} T_{\text{compute}}(h) &= T_{\text{attn},0} \cdot (1 - h^2) + T_{\text{ffn},0} \cdot (1 - h) + T_{\text{other},0} \cdot f_{\text{other}}(h) \\[6pt] T_{\text{load}}(h) &= \frac{h \cdot N \cdot S_{\text{kv/gpu}}}{B_{\text{pcie/gpu}}} \\[6pt] \text{TTFT}(h) &= T_{\text{fixed}} + T_{\text{load}}(h) + T_{\text{compute}}(h) - T_{\text{overlap}}(h) \end{aligned}

6.3 对比

维度一阶模型统一模型
计算侧(1h)T0(1-h) \cdot T_0 单线性按 Attention / FFN / 通信分别缩放
KV loadδhT0\delta \cdot h \cdot T_0,隐含 overlap显式 TloadT_{\text{load}} + 可控 overlap 参数
固定开销TfixedT_{\text{fixed}} 保留
端到端只看 prefillprefill + decode chip-time
口径容易混淆Delivered / Physical 双口径

7. KV cache load 大小

7.1 峰值显存占用

KV Cache 峰值显存占用:从单 Token 到 Batch 全局

KV cache 的峰值显存占用由三个维度共同决定:

MKVpeak=BNmaxSkv/tok/gpuM_{\text{KV}}^{\text{peak}} = B \cdot N_{\max} \cdot S_{\text{kv/tok/gpu}}

其中每 token 每卡的 KV cache 大小为:

Skv/tok/gpu=2Lnkv_headsntpdheadbelemS_{\text{kv/tok/gpu}} = 2 \cdot L \cdot \frac{n_{\text{kv\_heads}}}{n_{\text{tp}}} \cdot d_{\text{head}} \cdot b_{\text{elem}}
  • 2:K 和 V 两份缓存
  • LL:模型层数
  • nkv_heads/ntpn_{\text{kv\_heads}} / n_{\text{tp}}:GQA/MQA 下每卡分到的 KV head 数(ntpn_{\text{tp}} 为 tensor parallel 分片数)
  • dheadd_{\text{head}}:每个 attention head 的维度
  • belemb_{\text{elem}}:精度字节数(FP16/BF16 = 2,FP8 = 1)

峰值出现在所有 batch 中的 request 同时达到 NmaxN_{\max} 时。以 Qwen2.5-72B(ntp=4n_{\text{tp}}=4)为例:

Sper_tok=2×80×84×128×2=163,840  bytes=160  KB/tokenMKVpeak=32×8192×160  KB40  GB\begin{aligned} S_{\text{per\_tok}} &= 2 \times 80 \times \frac{8}{4} \times 128 \times 2 = 163{,}840 \;\text{bytes} = 160 \;\text{KB/token} \\[6pt] M_{\text{KV}}^{\text{peak}} &= 32 \times 8192 \times 160 \;\text{KB} \approx 40 \;\text{GB} \end{aligned}

这意味着在 batch_size=32、seq_len=8192 的配置下,仅 KV cache 就需要约 40 GB 显存——这还没算模型权重和 activation。这也是为什么 KV cache 管理(PagedAttention、prefix caching、offload 等)是大模型推理的核心挑战之一。

7.2 PCIe 加载带宽

每 token KV cache 大小按每卡 shard 口径计算:

Skv/gpu=2Lnkv_heads/gpudheadbelemS_{\text{kv/gpu}} = 2 \cdot L \cdot n_{\text{kv\_heads/gpu}} \cdot d_{\text{head}} \cdot b_{\text{elem}}

其中 22 是 K 和 V,LL 是层数,nkv_heads/gpu=nkv_heads/ntpn_{\text{kv\_heads/gpu}} = n_{\text{kv\_heads}} / n_{\text{tp}}

必须强调 per_gpu:TP 并行把 KV heads 按 shard 分到不同 GPU,单卡只加载本卡 shard。如果直接用全模型 KV 大小除以单卡 PCIe 带宽,会把 TloadT_{\text{load}} 高估约 ntpn_{\text{tp}} 倍。

PCIe 有效带宽建议值:

PCIe 规格建议有效带宽
Gen4 x1625 GB/s
Gen5 x1650 GB/s

8. 从一个 hit 修正到另一个 hit

实际场景中经常不是从 0-hit 开始,而是「压测实际 hit 为 hmeasuredh_{\text{measured}},线上目标 hit 为 htargeth_{\text{target}}」。此时按同一模型做相对修正:

P(h)=tprefill at hit hD=tdecode(不随 prefill hit 变化)C(h)=P(h)+DTPMdeliveredtarget=TPMdeliveredmeasured×C(hmeasured)C(htarget)\begin{aligned} P(h) &= t_{\text{prefill}} \text{ at hit } h \\ D &= t_{\text{decode}} \quad \text{(不随 prefill hit 变化)} \\ C(h) &= P(h) + D \\[6pt] \text{TPM}_{\text{delivered}}^{\text{target}} &= \text{TPM}_{\text{delivered}}^{\text{measured}} \times \frac{C(h_{\text{measured}})}{C(h_{\text{target}})} \end{aligned}

如果只需要 Physical TPM:

TPMphysicaltarget=TPMdeliveredtarget×ISL(1htarget)+OSLISL+OSL\text{TPM}_{\text{physical}}^{\text{target}} = \text{TPM}_{\text{delivered}}^{\text{target}} \times \frac{\text{ISL} \cdot (1 - h_{\text{target}}) + \text{OSL}}{\text{ISL} + \text{OSL}}

9. 一句话总结

KV cache hit 修正以 prefill chip-time 为核心:计算侧按 trace/阶段模型随 hit 缩短(attention 按 1h21-h^2,FFN 按 1h1-h),KV load 侧按 hit 增长并显式进入 TTFT,再通过 overlap ratio 描述传输和计算的重叠程度。最终和 decode chip-time 组合得到 Delivered TPM 与 Physical TPM。

相关页面

修改历史2 次提交