Bonsai-demo Prompt-Cache 性能揭秘:多轮对话首 Token 延迟优化完整指南
【免费下载链接】Bonsai-demoBonsai Demo项目地址: https://gitcode.com/GitHub_Trending/bo/Bonsai-demo
Bonsai-demo 是 PrismML 开源的 Bonsai / Ternary-Bonsai 本地大模型演示项目。本文面向新手,揭秘它的 prompt-cache(KV 前缀缓存)如何让多轮对话的首 token 延迟(TTFT)大幅下降,并给出 4 个开箱即用的优化技巧与一个必须避开的"坑"。
一、Prompt-Cache 是什么?为什么它决定首 token 延迟
先建立一个直觉:模型每回合收到的是"全部历史 + 你的新消息"。如果没有缓存,每一轮都要把整段对话重新预填(prefill)一遍——对话越长,第一字越慢。
prompt-cache 的作用:llama.cpp 服务把已算过的 KV 前缀留在显存里,下一轮只有"新增的那一小段"需要真正预填。于是——
同一张图的追问"近乎瞬时",同一话题的多轮对话首 token 越来越快。
这正是 Bonsai-demo 文档里反复强调的体验。
Bonsai 系列还能在 0.25 GB 级体积上取得 70 分以上的平均基准分,27B 更支持262,144 token的长上下文——而 KV 缓存只占 64 KiB/token,100K 上下文也只需约 6.3 GiB。体积小 + 缓存友好,是它多轮对话体验好的两大前提。
二、零配置开启:一行命令获得缓存加速
Bonsai-demo 的启动脚本默认就开启了缓存路径(flash attention + 多槽位服务),你不需要任何特殊开关:
./scripts/start_llama_server.sh # 打开 http://localhost:8080服务默认 4 个并发槽位(--parallel),多个用户同时对话互不干扰。启动脚本见 scripts/start_llama_server.sh。
验证缓存是否生效
每个 API 响应都带timings对象,其中prompt_ms就是"编码 + 预填"耗时——第二轮同话题提问时,这个数值会明显小于第一轮。验证命令见 AGENTS.md。
三、多轮对话首 Token 延迟优化:4 个实用技巧
技巧 1:保持系统提示前缀稳定
缓存命中的前提是"前缀逐字相同"。系统消息(含工具 schema)放在对话最前面,只要前缀不变,后续每轮直接复用缓存。
- 在聊天界面 Settings 里设置固定的 System message(给模型一个稳定的"Bonsai 身份");
- 不要在不同对话间反复开关 MCP 工具服务器——启用集合(含顺序)一变,前缀失效,整段重新预填。
工具 schema 大约 2,600–2,900 token(见 AGENTS.md),这个"一次性成本"被缓存后,之后每轮都免费。
技巧 2:图片只编码一次,追问免费
27B 是视觉模型:一张图会被编码成上千个 vision token,是典型的首轮成本。但 prompt-cache 让"同一张图的追问近乎瞬时"——因为图片 token 已缓存在前缀里(详见 VISION.md)。
慢硬件上建议保留默认的图片 token 上限(1024),需要 OCR 细小时再用BONSAI_IMAGE_MAX_TOKENS=0全量精度。
技巧 3:长上下文用 4-bit KV,多轮不崩内存
多轮对话的本质是"越来越长的前缀"。默认 FP16 KV 每 token 64 KiB,100K 上下文约 6.3 GiB;开启 4-bit KV 缓存后降到约 18 KiB/token(100K 仅需约 1.8 GiB,省约 3.5 倍):
BONSAI_KV4=1 ./scripts/start_llama_server.sh注意它是省内存工具,不是提速工具:解码比 FP16 略慢,适合"内存紧张 + 超长多轮"的场景。可选用./scripts/make_kv_bias.sh生成校准偏置来弥补 4-bit 量化精度损失,完整说明见 KV-CACHE.md。
同时用BONSAI_CTX控制上下文档位(默认按内存自动分配 8K–131K,避免 OOM),详见 environment_variables.md。
技巧 4:Mac 上选对后端:llama.cpp 有缓存,MLX 没有
这是最容易踩的坑:
| 后端 | 跨请求 prompt-cache | 多轮体验 |
|---|---|---|
| llama.cpp(默认) | ✅ 有,前缀复用 | 后续轮次首 token 快 |
| MLX | ❌ 无,每轮重算整段对话 | 多轮明显变慢 |
文档明确建议:交互式多轮对话优先用默认的 llama.cpp 后端(OPENWEBUI.md、AGENTS.md)。MLX 的图像编码器本身有缓存,但语言模型的 LM 预填每轮重来,所以长对话下首 token 延迟差距会随轮数拉大。
四、避坑:推测解码会关掉 prompt-cache
BONSAI_SPECULATIVE=1能让解码提速 1.8–2.4 倍(CUDA 上),但它强制每个请求重新预填完整历史、并锁定单槽位(-np 1),即关闭了跨请求 prompt-cache 复用——多轮对话的"首 token"反而变慢。
所以官方策略是:推测解码只开在独立聊天服务器上,而依赖缓存的 agentic 路径(Open WebUI)保持普通缓存路径。代码里这段注释写得很直白(scripts/start_llama_server.sh):
It disables prompt-cache reuse and forces a single slot (-np 1), so it is off by default...
给新手的决策口诀:
- 🎯 单发长代码/数学题、追求生成速度 → 开
BONSAI_SPECULATIVE=1(CUDA 优先) - 💬 多轮聊天、追问、agent 工具循环 → 保持默认,靠 prompt-cache 压低 TTFT
- 权衡细节见 SPECULATIVE.md
五、常见问题(FAQ)
问:怎么知道这一轮到底省了多少延迟?看响应里的timings.prompt_ms(编码 + 预填耗时)。同话题第二轮通常显著低于首轮;首轮慢是正常的"建缓存"成本。
问:开缓存会不会占更多显存?会。KV 缓存随上下文增长,这正是 27B 混合注意力把它压到 64 KiB/token 的价值所在;内存吃紧时用BONSAI_KV4=1,或调小BONSAI_CTX。
问:换模型/换工具集后缓存会失效吗?前缀一变就失效(换模型、改系统消息、改 MCP 启用集合都会重建)。保持"稳定前缀 + 可变后缀"是 TTFT 优化的核心心法。
六、总结
| 场景 | 推荐做法 |
|---|---|
| 多轮聊天 | 默认 llama.cpp + 稳定系统提示(零配置) |
| 图片追问 | 保持默认图片上限,利用"图只编码一次" |
| 超长对话 | BONSAI_KV4=1+ 按需BONSAI_CTX |
| Mac 多轮 | 别用 MLX 后端,选 llama.cpp |
| 纯生成提速 | CUDA 上才考虑BONSAI_SPECULATIVE=1 |
Bonsai-demo 把 prompt-cache 做成了"默认行为":你只需保证前缀稳定,多轮对话的首 token 延迟就会被缓存默默吃掉大部分。配合 README.md 的 Quick Start,两条命令即可上手体验。
【免费下载链接】Bonsai-demoBonsai Demo项目地址: https://gitcode.com/GitHub_Trending/bo/Bonsai-demo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考