docs(AI): MNN prefix KV cache 调研 — setPrefixCacheFile 可用,建议 W6 量化后接入
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
41
docs/research/mnn-kv-cache-prefix.md
Normal file
41
docs/research/mnn-kv-cache-prefix.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# MNN 前缀 KV Cache 调研(2026-06-10)
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
当前打包的 MNN.xcframework 已暴露 prefix cache 能力,技术上可以把每个场景**固定的
|
||||||
|
system prompt + few-shot 模板**的 prefill 结果缓存到磁盘,二次调用跳过这部分 prefill。
|
||||||
|
**建议 W6 polish 阶段、用性能自检卡量化 prefill 占比之后再决定是否接入**;当前瓶颈在
|
||||||
|
decode 而非二次 prefill,优先级低于 C1/C2/Live Activity。
|
||||||
|
|
||||||
|
## 依据(`Frameworks/MNN.xcframework/ios-arm64/MNN.framework/Headers/llm/llm.hpp`)
|
||||||
|
|
||||||
|
| API | 行号 | 含义 |
|
||||||
|
|---|---|---|
|
||||||
|
| `bool setPrefixCacheFile(const std::string& filename, int flag = 0)` | :161 | 指定前缀缓存文件;配套私有成员 `mPrefixCacheMode` / `mPrefixLength` / `mIsPrefixFileExist` / `completePrefixWrite()`(:250-255)印证:命中时 prefill 只算增量部分 |
|
||||||
|
| `bool reuse_kv()` | :171 | 读 config 开关 `reuse_kv`,多轮对话内复用 KV(同一会话增量 prefill) |
|
||||||
|
| `void syncPromptCache(const ChatMessages&)` | :176 | decode 结束后同步缓存文本——注释明确说明 cache 在 generate() 后自更新,此接口供做过后处理(如 deleteThinkPart)的调用方提供更准确版本 |
|
||||||
|
| `void setKVCacheInfo(size_t add, size_t remove, ...)` / `eraseHistory(begin, end)` | :158-160 | 更底层的 KV 区间管理,可做部分历史擦除 |
|
||||||
|
|
||||||
|
## 对本项目的适用性
|
||||||
|
|
||||||
|
- 我们所有调用都是「固定模板前缀 + 可变数据后缀」的单轮 `response()`,与 prefix cache
|
||||||
|
的模型吻合。
|
||||||
|
- 模板体量(估):报告识别 ~900 tok、导出报告 ~700 tok、意图抽取 ~300 tok。
|
||||||
|
按性能自检卡实测的 prefill 速率推算,每次调用预计省 **1~3s**。
|
||||||
|
- 多场景共用一个 cache 文件是否支持多前缀未知;最坏情况只对单一场景(建议选「报告识别」,
|
||||||
|
模板最长、调用最频繁)生效。
|
||||||
|
|
||||||
|
## 风险
|
||||||
|
|
||||||
|
1. `flag` 参数语义在头文件无注释,需读 MNN 源码或实验确认。
|
||||||
|
2. OMNI(多模态)分支下行为未验证——我们的 MNN 模型是 Omni 构建。
|
||||||
|
3. cache 文件与模型权重版本绑定:模型更新/重下载后必须失效,否则可能输出乱码。
|
||||||
|
4. `<img>` 标签在 prompt 前部(`analyzeImages` 把图片标签拼在最前),意味着报告识别场景的
|
||||||
|
"固定前缀" 实际不固定 —— **文本场景(导出/意图抽取)才是干净的 prefix cache 候选**。
|
||||||
|
|
||||||
|
## 建议的接入步骤(W6,如性能自检显示 prefill 占比 >30%)
|
||||||
|
|
||||||
|
1. `MNNLLMBridge` init 后调 `setPrefixCacheFile(<AppSupport>/mnn-prefix.cache)`(仅文本场景)。
|
||||||
|
2. 真机 A/B:同一导出报告各跑 3 次,对比 `LlmContext.prefill_us`。
|
||||||
|
3. 异常处理:加载失败或输出劣化时删除 cache 文件并禁用,回退现状。
|
||||||
|
4. `ModelDownloadService.importModel` / 重下载路径上顺手删除旧 cache 文件。
|
||||||
Reference in New Issue
Block a user