每 token KV 心算是什么
把 KV 缓存公式压成「每 token 字节数」,方便上线前做量级心算:每 token 的 KV 字节数约等于 2 乘以层数乘以 KV 头数乘以头维度乘以每元素字节数,其中 2 表示 K 与 V 各一份。乘上窗口长度得到单序列占用,再乘以并发就是总量。用 GQA 模型的 KV 头数计算,而不是注意力头数,否则结果会高估数倍。
基本信息
| 公式 | 每 token ≈ 2 × 层数 × KV 头数 × 头维度 × 每元素字节数 |
|---|---|
| 2 的含义 | K 与 V 各存一份 |
| fp8 KV | 每元素 1 字节,总量相对 fp16 减半 |
| 取值来源 | 模型 config.json 的层数、KV 头数与隐藏维度 |
| 用途 | 上线前的量级判断与并发上限粗算 |
典型使用场景
- 上线前粗算:一个请求在目标窗口下要占多少显存,能不能和权重一起装进卡里
- 判断窗口能开多大:并发目标固定时,反推可承受的最长上下文
- 反推最大并发:显存预算扣除权重与开销后,除以单序列占用
- 评估 fp8 KV 是否值得:显存吃紧时先算清减半能换来多少并发
- 横向比较模型:层数与 KV 头数不同的模型,KV 效率差异很大
算例:80 层 / 8 KV 头 / 128 维 / FP16
算例:80 层 / 8 KV 头 / 128 维 / FP16
每 token:2 × 80 × 8 × 128 × 2 B ≈ 320 KiB
8K 窗口:320 KiB × 8192 ≈ 2.5 GiB / 序列
16 并发:≈ 40 GiB
(KV 用 fp8 存储时字节数减半)
换成 4K 窗口或 32 并发,用同一算式即可得到另一张表:先心算再上机验证参数的取值来源
| 参数 | 从哪里取 | 易错点 |
|---|---|---|
| 层数 | config.json 中的隐藏层层数 | 把 MoE 的专家层数算进来 |
| KV 头数 | config.json 的 KV 头数字段 | 缺失时误用注意力头数 |
| 头维度 | 隐藏维度除以注意力头数 | 直接拿隐藏维度当维度 |
| 每元素字节 | fp16 取 2、fp8 取 1 | 忽略量化后的实际存储格式 |
不同模型的 KV 效率差别很大:层数与 KV 头数是量级决定因素,MQA 类模型的每 token KV 可以很小,长上下文能力因此更便宜。
心算只用于量级判断:实际占用还受块对齐、碎片与框架开销影响,最终要按引擎报告的实际 KV 池容量核对。