展开文章目录
这篇实验笔记只做一件事:把 KV Cache 容量算到可以复核。默认参数取 32 层、8 个 KV heads、head 维度 128、FP16、8K 上下文和 16 路并发。
计算
每个 token 的 KV 字节:
整批缓存:
这个结果还没有算模型权重、激活、allocator 和临时 workspace。它说明长上下文服务不能只按“模型能否装进显存”判断并发上限。
分页的尾部
若块大小为 16 token,8K 恰好整除,尾部浪费为零。把上下文改成 8,001 token,则需要 501 个块,最后一块只使用 1 个 token:
单个请求的浪费不大,但当块更大、序列更短、并发更高时,累计开销会变得可见。分页的价值更多在外部碎片和共享,而不是消灭块内浪费。
运行实验
打开 KV 容量账本,调整 GQA 的 KV heads、上下文和并发。观察两个问题:
- 把 KV heads 从 32 降到 8,容量是否按比例下降?
- 把并发翻倍,尾延迟风险为什么不能只用容量是否“还装得下”回答?
模型结果只作为量级估计。真实服务要用目标框架的显存报告和压力测试校准。
公式与默认参数
实验使用的基本公式是:
其中 是每个 token 的缓存字节数, 为层数, 为 KV heads, 为 head 维度,系数 2 对应 K 和 V, 是每个元素的字节数。总容量再乘以上下文长度与并发数:
默认的 32 层、8 个 KV heads、128 维、FP16、8K 上下文和 16 并发会得到约 16 GiB 的缓存。这个数字只包含 KV,不包含权重、激活、块表、对齐和临时 buffer,因此不能把它当作模型的完整显存需求。
怎么读指标
页面给出的三个指标对应三个决策:
- 每 token 缓存:模型结构和精度决定的下限,改变并发不会改变它。
- 总缓存:上下文与并发的乘积,服务容量规划更需要这个数。
- 每 MiB 可存 token:把容量换算成直观的 token 数,便于比较不同模型。
把 KV heads 从 32 改成 8,每 token 字节数应按 4 倍下降;把上下文从 8K 改成 16K,总缓存应约翻倍;把并发翻倍,总缓存也约翻倍。若界面结果偏离这些比例,通常是输入或单位理解错了。
什么时候模型会骗人
这是一个纯预算模型,无法告诉你 GPU 上真实的吞吐、allocator 碎片或 kernel 延迟。它也不模拟块共享、prefix caching、KV 驱逐和量化误差。对于使用 PagedAttention 的服务,实际容量可能因为块大小和请求长度分布而低于理论值;对于使用量化 KV 的服务,每个元素字节数变化还需要考虑反量化成本。
如果要用它做面试或方案评审,建议先算一个下限,再用目标框架测量一个上限。两者之间的差距,才是分页、调度和缓存策略能发挥作用的空间。把估算值直接写成“实测显存占用”会误导读者,也会掩盖真正的工程问题。
一个灵敏度练习
先固定 8K 上下文和 8 个 KV heads,把层数从 16 提到 64,观察缓存如何线性变化;再把 head 维度从 64 提到 256,体会为什么“模型看起来不大”不代表 KV 压力小。最后保持总 token 数不变,交换并发和上下文,看总缓存相同但尾延迟风险是否相同。答案是否定的:长序列请求更难调度,块池回收也更慢。
这个实验的目的不是给出另一个固定公式,而是训练一种预算直觉:每当你准备增加上下文或并发时,先问需要多少字节、这些字节放在哪个内存层、当请求失败时系统如何回收它们。
把结果写进设计文档
一份可评审的 KV 预算至少应包含模型结构、精度、上下文上限、并发目标、每 token 字节数、总容量和保留余量。若总容量接近目标显存,应明确降级顺序:降低并发、缩短上下文、切换更低精度 KV、启用分页共享,还是拒绝新请求。不同降级对质量和用户可见行为的影响不同,不能只留下一个“可能 OOM”的模糊结论。
还要区分平均与尾部。平均请求长度 2K 不代表 32K 请求不会出现;长请求会在块池中驻留更久,并拖慢回收。用 P95/P99 上下文和并发做预算,比用平均值更接近真实服务。预算模型的价值在于提前暴露这种差距,而不是给出一个看似精确的单一数字。
如果预算结果刚好接近上限,不要把它当成“可以通过”。至少给块表、对齐、临时激活和流量突发留出余量;在压测中观察拒绝率与 GC/释放行为,而不是只相信理论公式。一个安全的容量设计会明确在超限时限制上下文、降低并发还是延迟新请求。
在团队评审中,可以把“每 token 128 KiB”当作一个可验证断言:检查层数、KV heads、头维度和类型,手算一次,再用实验页复算。如果两个结果不一致,优先检查是否把注意力头总数当成 KV heads,或把字节数和 bit 数混在一起。这个简单的算术检查能提前发现大量容量规划错误。
最后把容量预算与成本预算分开记录:显存够不够是一回事,单位 token 的成本能不能覆盖业务是另一回事。两者都通过,服务才具备可持续性。
这条记录也应随模型版本和框架配置一起更新,不能沿用上一版估算。
把估算过程写进设计文档,后来的人才能知道容量数字从何而来,并在模型升级时快速重新计算。
这张表也应随着并发目标和上下文策略一起变更。
- 01请求token 序列
- 02逻辑块连续编号
- 03块表映射物理页
分页把连续上下文需求与物理显存分配解耦,收益由请求长度分布和块大小共同决定。
证据清单
来源与适用范围
- 论文
- 文档
限定条件:本地确定性预算模型;不包含 GPU 实测,也不模拟 allocator 元数据和临时激活。