用块哈希复用 prompt 前缀
把上下文身份编码进块哈希,让重复请求共享已经计算的 KV cache。
相关概念
工程问题#
相同系统提示词不断被重新计算;仅比较当前块 token,又会混淆不同前文产生的 KV。
实际实现#
V1 将父块哈希、本块 token 与 LoRA/多模态附加信息组合为键,通过映射寻找完整缓存块。
处理流程#
- 按块切分请求 token
- 递推计算包含前文的哈希
- 查找连续命中的完整块
- 引用可复用块,计算剩余或必须重算的 token
源码片段#
固定版本 · 原文摘录vllm/v1/core/kv_cache_utils.pyv0.8.5 · V1 · L413–L420
413 if not parent_block_hash:414 parent_block_hash = NONE_HASH415416 curr_block_token_ids_tuple = tuple(curr_block_token_ids)417 return BlockHashType(418 hash_function(419 (parent_block_hash, curr_block_token_ids_tuple, extra_keys)),420 curr_block_token_ids_tuple, extra_keys)hash_block_tokens
父块哈希把此前上下文纳入身份;本块 token 与 extra_keys 一起参与哈希。返回的 BlockHashType 还保留本块 token 和附加键,因此索引键不是一个裸哈希整数。此函数只构造键,完整块筛选、命中查找和生命周期由上层管理。
PYTHONApache-2.0
收益与取舍#
工程分析带来的收益
- 减少重复 prefill 计算
- 多个请求可共享同一缓存块
付出的代价
- 此版本仅缓存完整块,尾部不足一块无法按此机制复用
- 哈希计算有成本,键设计和碰撞处理影响正确性
可比较的选择
Radix Tree 前缀索引显式表达前缀分支,但需维护树节点及拆分逻辑。
版本与适用范围#
核验基线为 v0.8.5 V1 文档;不把 2023 年 PagedAttention 论文中的预定义共享前缀等同于这里的自动哈希缓存。
参考来源#
源码、官方文档与原始论文相关实现与比较#
4 个相关案例QEMU TCG 用 QHT 保存 TranslationBlock 索引,帮助复用与当前客体执行状态一致的翻译结果。
附源码片段 · 缓存与复用
libvirt 为 Domain 对象维护 UUID 与名称两个哈希索引,两个入口指向同一个对象。
附源码片段 · 索引与查找
将逻辑连续的 token 缓存映射到分散的物理块,减轻显存碎片与重复存储。
附源码片段 · 内存管理
Redis 有序集合既要按成员查分数,也要按分数和名次遍历;较大集合通过两种索引服务这些访问方式。
附源码片段 · 索引与查找