Skip to content
🔗 分享本题
查看我的学习进度 →

共享前缀 KV 复用、Radix Tree 最长前缀匹配和缓存治理图

🧠 记忆锚点:前缀必须 token 完全一致才能复用;Radix 树找最长共享路径,命中省 Prefill,缓存仍要隔离与淘汰。

💡 答案要点

问题背景:

传统推理:每个请求的 Prompt 完全独立
实际场景:大量请求共享相同前缀

例子:
请求A: "你是一个法律顾问,帮助分析以下合同:\n[5000字合同内容]\n问题1..."
请求B: "你是一个法律顾问,帮助分析以下合同:\n[5000字合同内容]\n问题2..."
请求C: "你是一个法律顾问,帮助分析以下合同:\n[5000字合同内容]\n问题3...

→ 5000字的系统指令+合同内容 被重复计算了3次!

Prefix Caching(前缀缓存)的核心原理:

KV Cache 的复用:
┌─────────────────────────────────────────────┐
│ Shared Prefix(共享前缀)                    │
│ "你是一个法律顾问,帮助分析以下合同:\n..."   │
│  → 只需计算一次,结果被所有请求复用            │
└─────────────────────────────────────────────┘

┌─────────────────────────────────────────────┐
│ Request-specific suffix(请求特定后缀)       │
│ "问题1..." / "问题2..." / "问题3..."        │
│  → 每个请求独立计算                         │
└─────────────────────────────────────────────┘

效果:共享前缀越长,节省越多
- 共享前缀5000 tokens:节省 60-70% 计算量
- 共享前缀10000 tokens:节省 80-90% 计算量

RadixAttention(SGLang 的实现):

python
# SGLang 的 RadixAttention 自动管理前缀缓存
from sglang import sgl

@sgl.function
def legal_advisor(s, question):
    # 系统前缀 + 合同内容 → 自动进入 RadixAttention 缓存树
    s += sgl.system_prompt  # 共享前缀
    s += contract_text       # 共享中间内容
    
    # 用户问题 → 独立计算
    s += question
    s += sgl.gen(max_tokens=512)

# RadixAttention 内部结构
# (sglang/runtime/internal/tree_manager.py)
RadixTree:
  "/" → system_prompt tokens → KV_cache_node
       → contract_text tokens → KV_cache_node
          → question_1 → response_1  (叶节点)
          → question_2 → response_2  (叶节点)
          → question_3 → response_3  (叶节点)

Prefix Caching vs 传统 KV Cache 的关键区别:

维度传统 KV CachePrefix Caching
缓存单位整个请求(独立)请求前缀(可共享)
共享能力无(每个请求独立)有(相同前缀自动复用)
适用场景完全不同的请求共享系统指令/RAG 上下文
计算节省030-90%(取决于前缀长度)
管理复杂度高(需要 LRU/树结构)

为什么长上下文场景"必须"用 Prefix Caching:

长上下文场景的共享前缀特征:
1. 系统指令(500-2000 tokens)→ 100% 共享
2. RAG 检索上下文(2000-8000 tokens)→ 经常共享
3. 长文档(5000-50000 tokens)→ 同一文档多次查询

没有 Prefix Caching:
- 每次请求都重新计算共享部分
- 长上下文请求的 Prefill 延迟高(3-10秒)
- 显存利用率低(大量重复 KV 计算)

有 Prefix Caching:
- 共享部分只算一次
- Prefill 延迟降低 60-90%
- 显存利用率提升(复用已计算的 KV)

实测数据(SGLang on 8xA100):
                    无Prefix Caching  有Prefix Caching
Prefill延迟(16K):      2.3s              0.4s
吞吐(QPS):              45               180
显存占用:              78GB             62GB

vLLM vs SGLang 的前缀缓存策略对比:

维度vLLM(0.5)SGLang(0.4)
前缀缓存实现自动前缀缓存(APCache)RadixAttention(树结构)
缓存粒度Block 级别Token 级别(更细)
共享效率~75%~90%
适用场景通用场景长上下文 + 共享系统指令
多模态支持支持支持

面试话术:

"Prefix Caching 复用完全相同的 token 前缀所对应的 KV Cache,适合共享 system prompt、工具定义或固定文档前缀的请求。收益取决于可复用 token 数、命中率、缓存容量和淘汰开销;动态权限内容还要防止跨租户复用。vLLM、SGLang 等框架都在演进相关能力,不能只凭是否共享前缀直接决定框架。"

📚 参考:SGLang:RadixAttention 与 Prefix Caching(原论文)