prompt cache radix backend is enabled by --cache-radix-prompt
resident KV sharing enabled: N = ...
idle slots will be saved to prompt cache and cleared upon starting a new task
缓存组合
以下启动组合可用于部署或对照测试:
模式
启动参数
行为
No Cache
--cache-ram 0 --cache-radix-prompt off
关闭 Host Prompt Cache
Legacy
--cache-ram 4096 --cache-radix-prompt off
使用原有完整状态缓存
Radix
--cache-ram 4096 --cache-radix-prompt on
使用 Radix Tree Prompt Cache
Radix + Resident
--cache-ram 4096 --cache-radix-prompt on --kv-unified --cache-kv-share on
同时使用 Host Radix Tree 和 Resident KV Sharing
--cache-radix-prompt on 只有在 --cache-ram 非零时才会生效。修改缓存后端需要重启服务器;缓存保存在当前服务器进程的主机内存中,服务器退出后不会保留。
Radix 后端默认关闭,因此不传 --cache-radix-prompt on 时仍保持 Legacy 行为。严格的 No Cache 对照还应在请求中设置 "cache_prompt": false,仓库内的 Benchmark 已自动完成这项设置。
llama.cpp Radix Tree Prompt Cache and Resident KV Sharing
本仓库在
llama.cpp的 Host Prompt Cache 基础上增加了 Radix Tree 后端和 Unified KV 中的 Resident KV Sharing(显存 KV 共享),用于在多个请求、会话和并发 Slot 之间保存并复用共享前缀的 KV Cache。本文面向部署和使用这些功能的用户,说明如何构建、启动、调用并验证 Host Radix Tree 与 Resident KV Sharing。原版
llama.cpp的项目介绍、模型支持和通用使用说明保留在 README-UPSTREAM.md。通用构建选项请参阅 docs/build.md,完整的llama-serverAPI 请参阅 tools/server/README.md。缓存功能概述
本项目包含两个可以分别启用的缓存优化:Host 侧的 Radix Tree Prompt Cache,以及 Unified KV 中的 Resident KV Sharing(显存 KV 共享)。前者减少重复的 Host KV 保存和恢复,后者让多个请求复用同一份设备 KV Cell。
Host Radix Tree Prompt Cache(主机缓存)
传统 Host Prompt Cache 以完整 Prompt 状态为单位保存 KV Cache。多个 Prompt 即使拥有相同前缀,也会分别保存对应状态。Radix Tree 后端按照 Token 前缀组织缓存,将公共前缀只保存一次,并在分叉处保存各自的后缀。
一次请求的主要处理流程如下:
该实现具有以下特点:
--cache-ram上限时按 LRU 淘汰终止节点,并保留仍被其他分支引用的公共前缀。该功能主要适用于 System Prompt、工具定义、RAG 文档或多轮历史较长,并且后续请求会从这些内容继续分叉的工作负载。
Resident KV Sharing(显存 KV 共享)
--cache-kv-share on启用 Resident KV Sharing,让多个独立请求共享 Unified KV 中同一份公共前缀 K/V:只给已有 Cell 增加归属,不复制 K/V。来源请求结束或 Slot 被其它任务复用后,公共前缀仍由 Resident KV Sharing 的缓存条目保留。该功能默认关闭,关闭时服务行为与原有 Unified KV 一致。支持条件(任一不满足会在启动时说明原因并拒绝启用,不会静默降级):
--kv-unified的 KV cache:不含 SWA、循环或混合内存,位置为一维连续;--context-shift关闭且--cache-reuse 0;参数与默认值:
--cache-kv-share on|offoff--cache-kv-share-min-tokens N32--cache-kv-share-max-entries N0(auto)auto = min(64, 可用缓存 ID 数)--cache-kv-share-cells N0(auto)auto = C/2(C 为预分配 KV Cell 总数)--cache-kv-share-headroom N0(auto)auto = min(n_ubatch, max(1, C/8))--cache-kv-share-route longest|sharelongest选路规则:
longest:在 A(目标 Slot 自己已验证的前缀)、S(Resident KV 索引)、H(Host Radix 可恢复前缀)中取最长可执行前缀,等长优先 A、S、H;share:A/S 有效候选时取两者最长(等长取 A),没有 A/S 才使用 H;M-1重算,产生一份末尾私有 KV,不覆盖共享 Cell。记录、保留与回收:
[0,M)与成功恢复的 Host 前缀[0,H)各自最多自动记录一次为可共享前缀;当前不支持“Resident KV 前缀 + Host Radix 后缀”的混合恢复(
append/mixed)。Resident KV Sharing 的收益口径是池内物理 Cell 占用与搬运减少,公共前缀只保留一份 K/V,不等同于整卡 HBM 占用下降。
/metrics中的kv_cache_used_cells、kv_cache_owner_cells、kv_cache_owner_only_cells、kv_cache_business_logical_cells和kv_share_path_{a,s,h,prefill}_*可用于区分物理占用与请求路径。启用 Resident KV Sharing 的最小启动示例:
分支与版本
本仓库保留了上游基线、早期开发过程、当前定版和后续开发四个分支:
masterllama.cpp基线,不包含本项目的 Radix Tree Prompt Cache 实现。feature/prompt-cache-radix-treeradixTreedev本文中的构建、启动和测试命令均以
radixTree分支为准。获取代码
项目发布代码位于
radixTree分支:如果已经克隆仓库,请先确认当前分支:
构建 llama-server
Ascend CANN
先安装 CMake、C/C++ 编译器和与设备匹配的 CANN Toolkit,并加载 CANN 运行环境。
set_env.sh的位置取决于本机安装目录:使用 Release 模式构建
llama-server:构建产物位于
build/bin/llama-server。启动日志中出现CANN0 model buffer size和模型层卸载信息,表示模型已使用 CANN 后端。其他计算后端
Host Radix Tree 位于
llama-server层,不限定模型计算后端;Resident KV Sharing 还要求启用受支持的 Unified KV。CPU、CUDA、Metal 等后端仍按上游 构建文档 编译。例如 CPU Release 构建:启动缓存服务
下面的示例同时启用 Host Radix Tree Prompt Cache 和 Resident KV Sharing,使用 4 个 Slot、Unified KV 和 4096 MiB Host Prompt Cache。请根据模型上下文长度、并发量和主机内存调整参数:
服务启动后可以检查健康状态:
日志中应包含以下信息:
缓存组合
以下启动组合可用于部署或对照测试:
--cache-ram 0 --cache-radix-prompt off--cache-ram 4096 --cache-radix-prompt off--cache-ram 4096 --cache-radix-prompt on--cache-ram 4096 --cache-radix-prompt on --kv-unified --cache-kv-share on--cache-radix-prompt on只有在--cache-ram非零时才会生效。修改缓存后端需要重启服务器;缓存保存在当前服务器进程的主机内存中,服务器退出后不会保留。Radix 后端默认关闭,因此不传
--cache-radix-prompt on时仍保持 Legacy 行为。严格的 No Cache 对照还应在请求中设置"cache_prompt": false,仓库内的 Benchmark 已自动完成这项设置。Resident KV Sharing 的参数和行为见缓存功能概述;“缓存组合”表格同时列出 Host Prompt Cache 的模式和两项功能的联合模式。两个功能可以单独开启,也可以同时开启。
调用接口与缓存观测
这些缓存功能不改变
llama-server的 OpenAI 兼容 API。下面的请求显式启用请求级 Prompt Cache:后续请求保持较长的 System Prompt、工具定义或文档前缀不变,只修改末尾问题,即可复用已保存前缀。
cache_prompt默认为true,示例中显式填写是为了说明缓存行为。需要强制当前请求执行完整 Prefill 时可将其设置为false;需要完全关闭 Host Prompt Cache 时,应在服务器启动时使用--cache-ram 0。响应
timings中与缓存相关的主要字段为:cache_nprompt_nprompt_mspredicted_npredicted_ms当相同或共享前缀请求中的
cache_n > 0时,说明请求复用了已有 KV。该字段也可能包含活动 Slot 中的前缀复用;确认 Host Radix Restore 时,还应检查服务器日志中的 Radixloads是否增加。日志会周期性输出 Radix 终止节点数、Host Cache 占用、unique tokens、logical tokens、保存/加载次数、淘汰次数和错误回退次数。参数与容量建议
--cache-ram的单位为 MiB,限制的是 Host Prompt Cache。容量应结合主机内存和预期工作集设置。--parallel和--kv-unified。默认空闲 Slot 清理依赖 Unified KV 与非零 Host Cache。--ctx-size决定总池容量,--cache-kv-share-cells只限制 resident owner 覆盖的物理 Cell,并不会单独分配第二个池。kv_cache_used_cells、kv_cache_owner_cells和kv_cache_owner_only_cells,不要用整卡 HBM 占用替代 Cell 统计。--ctx-size应覆盖并发 Slot 的实际上下文需求。长共享前缀场景需要为多个同时恢复的请求预留足够 KV 容量。功能边界
llama-server进程内有效,不在不同服务器实例之间共享,也不持久化到磁盘。正确性与验证
项目新增的测试按实现层、真实模型层和 HTTP 服务层组织:
tests/test-server-prompt-cache-radix.cpptests/test-server-prompt-cache-direct-roundtrip.cpptests/test-server-kv-resident-cache.cpptools/server/tests/radix/test_radix_lifecycle.pytools/server/tests/radix/test_qwen_cann_smoke.pytools/server/tests/radix/test_radix_http_token_equivalence.pytools/server/tests/radix/test_radix_http_fallback.py详细说明位于 tools/server/tests/radix/README.md。
构建与运行测试目标
测试使用本地 GGUF 模型,不会自动下载模型,也不在代码中保存机器相关路径:
其中
test-server-kv-resident-cache是不依赖模型的 Resident KV 索引单元测试;索引元数据位于 Host 侧,可以单独运行,或与其它目标一起通过 CTest 执行。