가입 후 초대 링크를 공유하면 동영상 재생 및 초대 보상을 받을 수 있습니다.

meng shao
@shao__meng
追踪 AI 前沿,精选解读一手技术资料 分享 Agent 构建与 AI Coding 实践,拆解 Agent 工程架构和细节、技术选型与企业应用案例 前 CTO|AI 技术顾问 · 企业培训 公众号 / 小红书:AI 启蒙小伙伴 合作请私信 📮
가입 November 2023
1.1K 팔로잉 중    34.4K 팬
解码 Prompt Caching:从 PagedAttention 原理到 10 倍降本增效 @dejavucoder 这篇文章深入剖析了 Prompt Caching(提示词缓存)的底层原理,特别是基于 @vllm_project PagedAttention 技术。作者结合自己在开发中的“踩坑”经历,纠正了许多开发者对于缓存机制的常见误解,提供了极具实操性的优化建议。 核心误区与真相:缓存是全局的,不是私有的 · 误区:作者(和咱们很多人一样)最初认为,Prompt Caching 是基于“用户会话”的。也就是说,只有同一个用户在同一个对话框里的后续发言,才能利用之前的缓存。 · 真相:Prompt Caching 是基于内容的,而非基于用户。 · 核心逻辑:只要你的系统提示词或工具定义是完全一致的文本,那么 用户 A 产生的缓存,完全可以被 用户 B 复用。 · 意义:这意味着在高并发场景下,只要前缀一致,系统可以实现“全局复用”,极大降低重复计算。 为什么需要缓存?(成本与速度) LLM 的推理过程分为两个阶段,理解这个区别是理解缓存价值的关键: · 预填充阶段:处理你输入的一大段提示词,计算出它们的 KV Cache。这个过程是 计算密集型 的,非常消耗算力。 · 解码阶段:逐个生成回复的 token。这个过程是 内存带宽密集型 的。 · 如果没有缓存:每次请求进来,即便前面 90% 的 Prompt 都是一样的,模型都要重新算一遍 Prefill,既慢又贵。 · 命中缓存:可以直接跳过繁重的 Prefill 计算,输入 token 的成本可降低 10 倍,且首字生成速度显著提升。 技术揭秘:PagedAttention 传统的 KV Cache 管理非常低效,必须预先分配一大块连续显存,容易造成碎片化浪费。vLLM 引入了操作系统管理内存的思路——分页。 · 分块(Blocks): 系统不再分配连续大内存,而是将 KV Cache 切分成固定大小的“块”。这些块在物理显存里可以是分散的,不连续的。 · 哈希链(Block Hashing)——缓存生效的关键: 系统如何知道“这段话以前算过”?它会计算块的哈希值。 · 父块依赖:一个块的哈希值,不仅取决于它自己的内容,还取决于前一个块的哈希值。 · 连锁反应:这就像区块链一样。只有当“从头开始的所有内容”都完全一致时,当前的哈希值才会匹配。这保证了因果关系的正确性——你不能只复用中间的一段,必须是前缀完全匹配。 · 全局查找: 新请求进来时,系统计算其提示词的块哈希,去全局哈希表中查找。如果命中,直接指向已有的显存块,完全不需要计算。 给开发者的实操建议:如何“骗”过系统命中缓存? 为了最大化缓存命中率,你需要让系统认为不同的请求是“一样”的。文章给出了几条黄金法则: · 保持前缀稳定(Stable Prefix) 将所有静态内容(系统提示词、工具定义、示例文本)放在 最前面。 · 反例:如果你把“当前时间”或“用户名”放在提示词的开头,那么整个哈希链从一开始就断了,后面的内容即使一样也无法复用缓存。 · 确定性序列化(Deterministic Serialization) 在使用 JSON 格式传递数据时(例如工具调用),必须保证键的顺序固定。 · 技巧:在 Python 中使用 json.dumps(..., sort_keys=True)。因为 { "a": 1, "b": 2 } 和 { "b": 2, "a": 1 } 虽然语义相同,但生成的字符串不同,会导致缓存未命中。 · 仅追加模式(Append-only) 在维护多轮对话历史时,尽量只在末尾添加新内容。不要去修改或截断中间的历史记录,一旦中间变了,后面的缓存链就全失效了。 · 警惕工具定义的变化 工具定义通常被模型拼接在系统提示词附近。如果你动态地为不同用户开启/关闭不同的工具,会导致前缀发生变化,从而导致缓存失效。 总结 Prompt Caching 的本质不是“记忆”,而是“复用计算结果”。理解了底层的 分块 和 哈希链 机制,开发者就能明白为什么“前缀”如此重要。 一句话总结:把所有不变的东西(系统指令、背景文档、工具列表)永远放在最前面,把变化的东西(用户提问、动态变量)放在最后面。 阅读原文
더 보기