Prefix Cache特性介绍
Prefix Cache 即前缀缓存,是一种用于优化大语言模型(LLM)推理性能的技术,主要应用于多轮对话、系统提示等具有大量共同前缀的场景。
原理
LLM 推理计算主要包括 Prefill 阶段(Prompt 计算)和 Decode 阶段。Prefill 阶段为 Decode 阶段准备 KV Cache,通常这些 KV Cache 只为单条推理请求服务,请求结束后会被清除。但在一些场景下,多次请求的 Prompt 可能共享同一个前缀,其 KV Cache 计算结果相同,Prefix Cache 就是将这些相同前缀的 KV Cache 存储起来,供后续请求复用,避免重复计算,从而降低TTFT,提升推理计算性能。
实现方式
- 基于基数树(Radix Tree):如 vLLM 中的 Prefix Caching 使用 RadixAttention 算法,该算法基于基数树实现。基数树的节点可以是一个变长序列,能动态分裂以满足动态共享前缀的需求。vLLM 中通过 BlockSpaceManagerV1 类管理 block 分配,以 hash 码作为物理 KV Block 的唯一标识,通过 prompt 中的 token_ids 来获取 hash 值,确保不同 prompt 的 cache block 能获取唯一 hash 码,进而实现前缀缓存。
- 基于前缀树(Trie):KVCache 的存取本质类似键 - 值对数据库,可将 Trie 的每个节点代表一个 token,从根节点到某个节点的路径表示一个 token 序列,以此处理前缀匹配问题。vLLM 会先将 tokens 根据 block_size 进行分块,然后对每块进行哈希,每个 chunk 的哈希值都包含了该 chunk 前缀的信息,以此模拟前缀树的实现。
应用场景
Prefix Cache 适用于 common prefix 较多、prefill 计算占比较大的场景,例如多轮对话、system prompt、代码补全等等。在多轮对话中,每一轮对话依赖历史轮次对话的上下文,若使用 Prefix Cache,可避免历史轮次中生成对话的重复计算,降低首 Token 的耗时。
缓存管理
由于显卡显存有限,当不同的 prefix 请求较多时,之前的 prefix cache 可能会被驱逐。此时可采用 LRU、LFU 等驱逐策略,通常会从后往前驱逐,尽可能复用 prefix cache。部分框架还提供了如 prefix cache offload 功能,在显存 prefix cache 被驱逐时将其转移到 cpu 内存上,命中时再加载回 gpu 中,以加速后续相同 prefix 的请求。
昇腾
当前大语言模型推理系统普遍采用KV Cache缓存机制,但该机制存在以下两个问题:
随着LLM支持的序列长度不断增长,KV Cache所需要的显存资源也急剧增加。
KV Cache只对当前session有效,如果跨session存在重复token序列的情况下无法实现复用。
Prefix Cache通过RadixTree保留session结束后的KV Cache,新的session请求在RadixTree中查找是否存在相同的Token序列,即可复用之前计算好的KV Cache,从而实现跨session的KV Cache复用。
其优势主要包括:
更短的prefill时间:由于跨session的重复token序列对应的KV Cache可以复用,那么就可以减少一部分前缀token的KV Cache计算时间,从而减少prefill的时间。
更高效的显存使用:当正在处理的sessions相互之间存在公共前缀时,公共前缀部分的KV Cache可以共用,不必重复占用多份显存。
限制与约束
-
Atlas 800I A2 推理服务器和Atlas 300I Duo 推理卡硬件支持此特性。
-
仅Qwen2系列模型支持对接此特性。
-
当跨session公共前缀token数大于等于Page Attention中的block size,才会进行公共前缀token的KV Cache复用。
-
Prefix Cache支持的量化特性:W8A8量化与稀疏量化,其他量化特性暂不支持。
-
该特性不能和多机PD分离、Multi-LoRA、Function Call、长序列以及多机推理特性同时使用。
-
该特性可以和单机PD分离、并行解码和SplitFuse特性同时使用。
-
开启Prefix Cache特性需要配置补充参数。
效果
Prefix Cache 技术本身主要优化的是首 token 响应时间(TTFT, Time to First Token),但在特定条件下也能间接提升系统的吞吐量(Throughput)。下面从多个角度分析其影响及优化方向:
- Prefix Cache 对吞吐量的直接影响
正面影响
减少重复计算:当多个请求共享相同前缀时,Prefix Cache 避免了这些前缀的 KV Cache 重复计算,释放了计算资源(如 GPU),使系统能同时处理更多请求。
降低排队延迟:对于首 token 响应时间敏感的场景(如实时对话),更快的 TTFT 能减少请求在队列中的等待时间,从而提高整体吞吐量。
负面影响
缓存占用显存:Prefix Cache 需要额外存储 KV Cache,可能导致系统可同时处理的请求数量减少(因显存被占用)。
缓存管理开销:维护缓存(如查找、驱逐策略)可能引入额外的计算开销。 - 增大吞吐量的其他优化方法
(1)模型层面优化
量化(Quantization):如 INT8、INT4 量化减少模型参数量,降低显存占用,提高并发请求数。
模型并行:将模型分布到多个 GPU 上,提升计算能力。
FlashAttention:优化注意力计算的内存访问模式,减少显存占用。
(2)系统层面优化
批处理(Batching):将多个请求合并为一个批次处理,提高 GPU 利用率。
连续批处理(Continuous Batching):如 vLLM 的 PagedAttention 技术,动态分配 KV Cache 内存,支持请求动态加入 / 退出批次。
预取(Prefetching):提前加载热门模型或数据到显存,减少 IO 等待。
(3)调度策略优化
优先级调度:对短请求优先处理,减少长尾延迟。
资源隔离:为不同类型的请求分配专用资源(如 GPU 核心)。 - 结合 Prefix Cache 与其他技术的案例
假设使用 vLLM 框架,可同时启用 Prefix Cache 和 PagedAttention:
from vllm import LLM, SamplingParams# 初始化LLM时启用PagedAttention
llm = LLM(model="deepseek-ai/deepseek-llm-7b-chat", gpu_memory_utilization=0.9)# 对于多轮对话,系统提示会被缓存
system_prompt = "You are a helpful, creative, accurate, and harmless AI assistant."
user_prompt1 = "What is machine learning?"
user_prompt2 = "Explain deep learning in simple terms."# 首次请求(包含system_prompt)会计算并缓存前缀
sampling_params = SamplingParams(temperature=0.7)
response1 = llm.generate(f"{system_prompt}\nUser: {user_prompt1}", sampling_params)# 第二次请求共享相同前缀,直接复用缓存
response2 = llm.generate(f"{system_prompt}\nUser: {user_prompt2}", sampling_params)
通过上述代码,系统提示部分的 KV Cache 会被复用,减少了重复计算。同时,PagedAttention 技术允许高效管理 KV Cache 内存,进一步提升吞吐量。
4. 性能测试与调优建议
- 测试工具:使用框架提供的性能分析工具(如 vLLM 的 benchmark 脚本)或自定义负载测试。
- 关键指标:监控 TTFT、吞吐量(requests/second)、GPU 利用率、显存占用。
- 调优方向:
增大缓存命中率:通过调整缓存大小、驱逐策略(如 LRU)提高缓存复用率。
平衡缓存与并发:根据模型大小和显存容量,调整可缓存的最大前缀长度。
异步处理:使用异步 API(如 vLLM 的async_generate)实现非阻塞请求处理。
总结
Prefix Cache 能通过减少重复计算间接提升吞吐量,但需结合其他优化技术(如量化、批处理、高效内存管理)才能实现最大性能提升。在实际部署中,建议根据具体场景(如请求模式、模型大小)进行性能测试和参数调优。