一个引擎无关的 KV 缓存分片系统,通过 HNSW 语义检索复用注意力张量,将 Android 端 LLM 首 toke…
EdgeSync-LLM 是一个引擎无关的 KV 缓存分片系统,专为 ARM64 Android 设备(Cortex-A55/A78)上的端侧大模型推理设计,可移植到任何运行 llama.cpp、MLC-LLM 或 ONNX Runtime 的平台。该项目由个人开发者发布在 Hacker News,附带完整开源实现与基准测试脚本。
EdgeSync-LLM 并非传统意义上的「语义缓存」——后者通常只缓存响应文本字符串。该系统在应用与 LLM 引擎之间引入一层可复用的 KV 缓存层,将注意力机制中的 Key 与 Value 张量按 token 区间和层区间切分为「片段」进行持久化。下一次请求到达时,系统先由 MiniLM-L6-v2(384 维,CPU 编码约 8 ms)生成嵌入向量,经 HNSW 索引(纯 Go 实现,M=16、efSearch=50)检索出语义相近的历史片段,再将其直接注入引擎的 KV 缓存,从而跳过推理中最耗时的 prefill 阶段。
根据语义相似度阈值,请求被分为三类处理:
整体数据流为:Prompt → 嵌入模型 → HNSW 检索 → 三路路由 → KVAdapter 层 → llamacpp / mlc-llm / onnx runtime。
缓存的原子单元 KVFragment 在 cache/fragment.go 中正式定义,核心字段包括:
构造时强制校验以下不变量:Token 跨度 ∈ [64, 2048]、LayerEnd ≤ 模型总层数、TokenIDs 长度等于跨度、张量非空、LayerStride ≥ 1。
KVAdapter 接口定义了 6 个方法(ExtractFragment / InjectFragment / Generate / Tokenize / ClearKVCache / Close),三个引擎各自实现:
跨引擎复用受 CompatibleWith() 矩阵约束。最新版已加入 adapter/reshape.go,通过张量维度转置([seq, heads, dim] ↔ [heads, seq, dim])实现 llama.cpp 与 ONNX Runtime 之间的片段复用,并由 CanInjectWithReshape() 自动检测与回退。
基准测试 benchmark/runner.go 在 Snapdragon 685(Cortex-A55)上以 8 个语义提示簇、64 个唯一 prompt 各 4 种变体、共 1000 次请求进行评估,关键参数源自实测而非随机假设:
底层常数:prefill 6.8 ms/token、生成 18.4 ms/token、HNSW 搜索 3.2 ms、片段注入 0.029 ms/MB、单片段约 6 MB(128 token、12 层、Q4_K_M 量化)。
主机端可直接 go run ./benchmark/;Android ARM64 构建需启用 CGO 并链接 llama.cpp;NEON fp16 余弦相似度模块由 aarch64-linux-gnu-gcc -O3 -march=armv8.2-a+fp16 编译。项目还实现了片段去重与层配置合并(cache/compactor.go,按 ContentHash 去重并按轴 0 或按头轴 1 拼接张量)、N-gram 预取预测器(top-3 候选)以及 Android /sys/class/power_supply/ 电源监测探针(monitor/energy_android.go)。