用了一个月sglang最大问题,一直无法得到有效解决。
-
4090D-48G-QWEN3.8-27B-SGLANG从0.5.15-0.5.17,速度是真快,显存占用也是真高。
唯独有一个问题,一个客户端,一个客户的情况下,超过70k后就容易prefill。
后面提一个问题就全量prefill。一次。。。默认是开启的缓存的。
这个问题一直没得到解决,甚至都去修改了prefill触发代码,想着改源码来解决这个频繁prefill的问题。。
结果很明显,没解决,所以想问问用sglang大家伙儿。你们是咋解决频繁prefill的?根因:hermes 会后台运行,打断sglang kvcache前缀。导致前缀失效造成频繁prefill。
解决方法及其简单。 -
楼主这个"70k 之后每问一句就全量 prefill"大概率不是缓存没生效,而是前缀缓存命中失效的问题。先花两分钟定位是哪种情况,再动手,比改源码快得多:
先拿证据(不用改源码):
- 启动参数加
--log-requests,看每轮请求日志里的 hit len(前缀命中长度); - 或者加
--enable-metrics,盯sglang:prefix_cache_hit_rate这个指标; - 顺手确认一下启动参数里没有
--disable-radix-cache(0.5.x 前缀缓存默认是开的)。
情况 A:70k 前 hit len ≈ 全部历史,过 70k 后突然掉到 0,之后每轮都全量重算
这是 KV cache 池满了:单用户长对话在 RadixAttention 里是一条超长前缀链,池子装不下时 LRU 淘汰会从链最老的开头踢,下一轮请求的前缀从淘汰点起全部重算。解决(按性价比):--mem-fraction-static0.88 → 0.90~0.92。单用户并发低,余量足够(TID:1193 里 Che 的配置就是 0.90);- 如果现在 KV 是 FP16,加
--kv-cache-dtype fp8_e4m3,池容量直接翻倍; - 或者反过来把
--context-length压到池容量以内(比如 96k/128k),让整条对话装得下,不触发淘汰; - 治标:
--chunked-prefill-size 2048+--enable-mixed-chunk-prefill,真 miss 时 prefill 分块执行,不会整段卡死。
情况 B:hit len 从一开始就只有几百 token(≈ system prompt 长度),跟 70k 无关
这是客户端每次请求的前缀对不上,不是服务端缓存问题:网关(new-api 之类)或客户端做了滚动窗口截断(中间历史删掉只留头尾)、往 system prompt 里注入会变的内容(时间戳/会话变量)、或续写时continue_final_message/add_generation_prompt前后不一致。这种要查客户端,服务端怎么调都没用。另外 0.5.15~0.5.17 都是老版本了,条件允许可以试试 0.6.x,前缀缓存和淘汰策略改进不少;但先按上面定位,大概率一个参数就解决,不用动源码。
- 启动参数加