前缀缓存
前缀缓存(Prefix Caching / RadixAttention)
KV Cache 只在单个请求内复用历史 token 的计算结果。前缀缓存把这个思路扩展到跨请求:如果多个请求共享相同的前缀(比如同一个 system prompt),就只计算一次,KV Cache 共享给所有请求。
SGLang 实现前缀缓存的机制叫 RadixAttention——把 KV Cache 的 page 组织成 radix tree,按 token 序列的前缀自动归并和复用,不需要手动标记共享前缀。
收益和前缀长度正相关
这是实验里最重要的发现:前缀缓存的价值取决于"省掉的 prefill 有多贵"。
| 前缀长度 | SGLang 缓存加速比(vs vLLM 无缓存) | 说明 |
|---|---|---|
| ~500 tokens | ~1x | prefill 太快(~20ms),固定开销淹没收益 |
| 8K tokens | 13.4x | 0.475s → 0.036s |
| 32K tokens | 35.3x | 1.841s → 0.052s |
反直觉的地方:缓存命中后的 TTFT(0.03-0.05s)和前缀长度几乎无关——因为命中后只需要处理新增的几十个 token,不管前缀有多长。
在 Agent 场景下的复合收益
Agent 场景里前缀缓存有双重收益:
- 共享 system prompt 的 KV Cache:多个 Agent 会话共用一份,内存效率大幅提升
- 会话内增量 prefill:每轮只处理新增的 user message,不重新算整个历史
实验七数据(16个并发 Agent 会话,6轮工具调用):SGLang 总耗时 19.9s,vLLM 44.7s,差 2.2 倍。而且 SGLang 从 4 个会话扩到 16 个,总耗时几乎不变(20.3s → 19.9s)——共享缓存让 GPU 有充裕余量。
500 token 看不出效果的原因
TTFT 的下限不是 prefill 时间,而是整条链路的固定延迟(HTTP 往返、调度、流式 SSE 首包)。4090 处理 500 token prefill 只需要 ~20ms,这点时间完全淹没在几十毫秒的固定开销里。缓存确实在工作(SGLang 服务端日志 #cached-token: 992),只是在 TTFT 指标上量不出来。
相关来源
- llm-inference-tutorial:第3章(KV Cache 与 PagedAttention)
- inference-experiments-2026-04:实验二、五、七、九详细测量了不同前缀长度的缓存收益