KV 缓存与请求调度
解释持续批处理、分页缓存、前缀复用、失效与缓存量化的条件。
调度单位如何改变浪费
固定批次等待一组请求共同处理,变长输入可能需要 padding,较短生成结束后槽位也可能空闲,整体完成受最长请求影响。持续批处理按模型迭代重新选择活跃请求:结束或取消的请求退出,资源允许时新请求加入。变长内核、token 预算与公平策略决定如何落实;调度每步发生,也增加主机与设备协调。
按请求数限制批量还不够。两个请求各含 100 token,与两个各含 100000 token 的内存和工作量不同。实际调度需要考虑本轮 token 数、已驻留 KV、最大输出、优先级和等待时间。新请求的长 prefill 可能阻塞已有 decode,预留 decode 工作或切块 prefill 可缓解。
缓存为何能复用
因果模型中,过去位置只依赖当时可见的前缀。保持模型参数、适配器、位置、掩码和输入表示一致时,追加后缀不会改变已算过去位置的 K/V。缓存避免下一轮重算这些张量,但仍需读取它们完成注意力。
常规载荷为 ,各符号依次表示层数、驻留序列数、缓存长度、键值头数、头维度和元素字节。滑动窗口、潜表示、多模态分支、量化元数据及物理分配会改变实际账。长度由全部被缓存位置决定,可能含提示、视觉输入和生成内容。
跨请求前缀复用比单请求追加要求更多。缓存键需要识别从起点开始的完整 token 前缀以及会改变计算的模型、LoRA、位置、掩码、多模态数据和预处理配置。只比较某个块的 token 内容会忽略其更早上下文;同一句后缀在不同历史下的高层 KV 通常不同。
构造例子:两个请求以同一系统说明开头,后续用户消息不同。公共前缀可复用,分叉之后分别计算。修改系统说明中的一个早期 token,会影响后面的可复用范围。即使文本相同,换掉图片或适配器也可能使缓存失效。多租户还需按授权隔离,避免通过命中时延或共享状态泄漏信息。
前缀缓存主要跳过重复 prefill;新生成 token 的 decode 工作仍存在。缓存占用与活跃会话争夺容量,低复用率负载可能得不偿失。驱逐策略、有效身份、锁定活跃块和冷热观测共同决定效果。
分页怎样控制分配
预留一整段连续 KV 空间可能造成过度预留、内部空余和外部碎片。分页将缓存切成固定大小物理块,为每个序列维护逻辑块到物理块映射,按需要增长。空闲块可以分散,尾部不足一块的空间仍会浪费。PagedAttention 讨论了相应访问与共享设计。
多个序列共享已算前缀块,用引用计数保持生命周期;若需要改变共享块,则复制后写入。引用计数、查表、非连续内存内核和并发管理都有代价。块大小在元数据与尾部空余之间取舍,具体默认值属于引擎版本。
基数树可以按公共前缀组织检索,分块哈希可以按缓存块匹配。逻辑匹配粒度与底层分配/可复用粒度未必相同;只见树结构不能推出所有实现都支持任意单 token 复用。引擎的缓存键、分配器和调度器需要一起核对。SGLang 论文
KV 量化的质量账
降低 K/V 元素位宽减少载荷与部分带宽。K 的误差进入注意力打分,V 的误差进入加权结果;softmax、层间传播和重复使用会改变影响。某些维度或位置对误差敏感,但误差不会在所有序列上必然单调放大,K 也没有无条件比 V 更敏感的定律。
量化尺度可以按张量、头、通道或块组织,粒度越细通常需要更多元数据与计算。校准语料、位置长度、离群值处理和反量化内核影响质量与速度。容量节省可以容纳更多请求,也可能被反量化和通信开销抵消。应测长上下文、精确回忆与实际任务,同时记录吞吐和尾部延迟。
最后更新于