SGLang 前缀缓存(RadixAttention)如何避免重复 Prefill:完整讲解

发布时间:2026/9/2 22:15:53
SGLang 前缀缓存(RadixAttention)如何避免重复 Prefill:完整讲解
SGLang 前缀缓存RadixAttention如何避免重复 Prefill完整讲解【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang做客服机器人时你会发现一天几万个请求几乎都从同一段 2000 token 的系统提示词开头。不做前缀复用每个请求都要老老实实把这 2000 个 token 的注意力 prefill 跑一遍算力消耗随 QPS 线性上涨。SGLang 的前缀缓存RadixAttention就是针对这种浪费首个请求把计算结果写进缓存后续同前缀请求直接复用现成的 KV只补算自己多出来的尾巴。一句话原理给公共前缀建一份预制品可以把它类比成中央厨房的半成品第一单客人点菜时厨师把前奏部分系统提示词做熟装进保鲜盒后面凡是同款前奏的订单直接开盒接着炒自己的配菜不用再从生料做起。SGLang 里这份保鲜盒就是挂在基数树radix tree一种按前缀共享组织的树结构上的 KV cache键值缓存索引实现位于 python/sglang/srt/mem_cache/radix_cache.py。省下的时间不是来自更快的算子而是来自这部分根本不用算。SGLang 处理一次请求的流程命中是怎么发生的把视角放在一个请求从进来到离开整个过程分四步匹配match请求 tokenize 后从树根开始逐段比对找到当前序列已缓存的最长前缀。若匹配终点落在某个节点段中间会自动执行节点分裂split node把边界切干净——这不复制数据只是重排结构。只算增量模型前向只处理没命中的那部分 token。命中 80% 的请求prefill 计算量就只剩 20%。写回insert新算出的 KV 索引挂到树上对应位置供下一个同前缀请求命中。释放与回收每个节点带lock_ref引用计数请求在飞期间前缀被锁住不受淘汰影响请求结束后锁释放节点回到可淘汰evictable集合。内存吃紧时淘汰器用堆按策略默认 LRU弹出最老的叶子释放被锁节点自动跳过。匹配用页page做对齐当page_size 1时命中长度会向下取整到页的整数倍这同时是内存对齐和碎片控制的抓手。启用 SGLang 前缀缓存的 3 个常用启动参数前缀缓存默认开启什么都不用改就已经在工作。下面 3 个参数覆盖了大多数调优场景python -m sglang.launch_server \ --model-path 模型路径 \ --page-size 16 \ --radix-eviction-policy lru # 对比实验时可显式关闭缓存 python -m sglang.launch_server --model-path 模型路径 --disable-radix-cache参数默认值作用--disable-radix-cacheFalse布尔开关关掉前缀缓存做 A/B 对比--page-size视后端而定页大小匹配/插入/淘汰的对齐粒度建议 16 这类 2 的幂--radix-eviction-policylru淘汰策略可选lru/lfu/slru/priority命中率不用翻日志服务加--enable-metrics后指标接口会暴露缓存命中率、evictable_size可回收量与protected_size被锁保护量等直接接 Prometheus 即可实现见 python/sglang/srt/observability/metrics_collector.py。性能数据前缀缓存能省多少场景基线无复用RadixAttention变化幅度多轮对话1.0x3.2x220%批量提示工程1.0x4.8x380%代码补全1.0x2.7x170%文档摘要1.0x5.1x410%数据口径说明以上为参考文章复述的对比数据以无缓存 prefill 耗时为基线做相对加速比实际数值取决于模型、序列长度与前缀重叠率规律是共享前缀占比越高收益越大四舍五入后量级约为 5 倍封顶。进阶速览分块前缀缓存与 HiCache 分层分块前缀缓存Chunked Prefix Cache长序列请求被切成多个 chunk 分块 prefill普通模式下整条前缀要等第一个请求算完才可共享。该特性让边算边共享成为可能目前面向 DeepSeek 等长序列模型短序列场景若觉得有额外开销可用--disable-chunked-prefix-cache关闭相关阈值由环境变量SGLANG_CHUNKED_PREFIX_CACHE_THRESHOLD控制。HiCache 混合缓存把 KV 从 GPU 显存扩展到主机内存形成设备端 主机端两级。设备端未命中时会先去主机端捞而不是直接重算。关键参数是--hicache-ratio主机池/设备池比值cache 模式默认 2.0和--hicache-write-policy可选write_back/write_through/write_through_selective。对前缀很长、复现间隔长到会被 LRU 淘汰的负载这一层是命中率兜底。避坑与调优命中率、锁和命名空间隔离现象原因处理KV 池紧张但缓存迟迟不释放在飞请求持有lock_ref被锁节点计入protected_size淘汰器会跳过先查 protected 占比缩短单请求上下文或降低并发热前缀多时换slru/priority策略保活长序列首个请求耗时内缓存迟迟不可复用chunked prefill 下 KV 分块写入整条前缀写完才完整可共享长序列场景依赖分块前缀缓存特性短序列负载用--disable-chunked-prefix-cache省掉开销换了 LoRA 或采样 salt 后命中率骤降RadixKey支持extra_key命名空间不同命名空间的 token 序列故意不共享节点这是设计特性而非 bug想共享就保持命名空间一致想隔离不同 adapter、不同 RAG 上下文则正该这样用高频疑问前缀缓存是默认开启的吗是。disable_radix_cache默认 False起服务即生效。想关闭只需要加--disable-radix-cache。命中率怎么查--enable-metrics启动后拉/metrics关注前缀缓存命中率以及evictable_size、protected_size两个量。命中率长期偏低且 evictable 接近 0通常说明缓存容量小于工作集考虑扩显存预算或上 HiCache。淘汰策略怎么选默认lru对多轮对话够用请求模式高度重复少数超热前缀可试lfu想给关键租户的前缀更高存活率用priority按优先级淘汰。节点分裂会不会造成 KV 重复拷贝不会。分裂只调整树上节点的边界与指针KV 索引按段切分引用不重复搬运显存数据。写在最后SGLang 的前缀缓存把重复 prefill 同一前缀从默认行为变成了可感知、可度量、可淘汰的一等公民基数树负责找前缀引用锁负责保安全页对齐负责控碎片策略化淘汰负责省显存。理解了这条链路你就有了在真实负载下调命中率和内存水位的全部抓手。接下来值得关注的是跨实例的缓存共享与量化格式 KV 的落地前缀复用正从单服务内优化走向集群级基础设施。【免费下载链接】sglangSGLang is a high-performance serving framework for large language models and multimodal models.项目地址: https://gitcode.com/GitHub_Trending/sg/sglang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考