Update README.md
本仓库在 llama.cpp 的 Host Prompt Cache 基础上增加了 Radix Tree 后端,用于在多个请求、会话和并发 Slot 之间保存并复用共享前缀的 KV Cache。本文面向部署和使用该功能的用户,说明如何构建、启动、调用并验证 Radix Tree Prompt Cache。
llama.cpp
原版 llama.cpp 的项目介绍、模型支持和通用使用说明保留在 README-UPSTREAM.md。通用构建选项请参阅 docs/build.md,完整的 llama-server API 请参阅 tools/server/README.md。
llama-server
传统 Host Prompt Cache 以完整 Prompt 状态为单位保存 KV Cache。多个 Prompt 即使拥有相同前缀,也会分别保存对应状态。Radix Tree 后端按照 Token 前缀组织缓存,将公共前缀只保存一次,并在分叉处保存各自的后缀。
一次请求的主要处理流程如下:
输入 Prompt -> Token 化并查找最长公共前缀 -> 从 Host Radix Tree 直接恢复命中的 KV 片段 -> 仅 Prefill 未命中的后缀 -> Slot 空闲后保存新增 KV -> 按共享前缀分裂 Radix 边并更新节点
该实现具有以下特点:
--cache-ram
该功能主要适用于 System Prompt、工具定义、RAG 文档或多轮历史较长,并且后续请求会从这些内容继续分叉的工作负载。
本仓库保留了上游基线、早期开发过程和当前发布版本三个分支:
master
feature/prompt-cache-radix-tree
radixTree
本文中的构建、启动和测试命令均以 radixTree 分支为准。
Radix Tree 的发布代码位于 radixTree 分支:
git clone -b radixTree https://gitee.com/frankPointer/llama.cpp-radix-tree.git cd llama.cpp-radix-tree
如果已经克隆仓库,请先确认当前分支:
git switch radixTree git status --short --branch
先安装 CMake、C/C++ 编译器和与设备匹配的 CANN Toolkit,并加载 CANN 运行环境。set_env.sh 的位置取决于本机安装目录:
set_env.sh
source /path/to/ascend-toolkit/set_env.sh
使用 Release 模式构建 llama-server:
cmake -S . -B build \ -DGGML_CANN=on \ -DCMAKE_BUILD_TYPE=Release cmake --build build --target llama-server -j
构建产物位于 build/bin/llama-server。启动日志中出现 CANN0 model buffer size 和模型层卸载信息,表示模型已使用 CANN 后端。
build/bin/llama-server
CANN0 model buffer size
Radix Tree Prompt Cache 位于 llama-server 层,不限定模型计算后端。CPU、CUDA、Metal 等后端仍按上游 构建文档 编译。例如 CPU Release 构建:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --target llama-server -j
下面的示例使用 4 个 Slot、Unified KV 和 4096 MiB Host Prompt Cache。请根据模型上下文长度、并发量和主机内存调整参数:
MODEL=/path/to/model.gguf ./build/bin/llama-server \ --model "$MODEL" \ --alias local \ --host 0.0.0.0 \ --port 8080 \ --ctx-size 8192 \ --parallel 4 \ --kv-unified \ --n-gpu-layers 99 \ --batch-size 2048 \ --ubatch-size 512 \ --cache-ram 4096 \ --cache-radix-prompt on \ --log-file /tmp/llama-server-radix.log
服务启动后可以检查健康状态:
curl http://127.0.0.1:8080/health
日志中应包含以下信息:
prompt cache radix backend is enabled by --cache-radix-prompt idle slots will be saved to prompt cache and cleared upon starting a new task
--cache-radix-min-restore-tokens 不需要额外设置。默认值为 0,表示不启用最小恢复长度阈值。默认的空闲 Slot 保存与清理逻辑已经能够驱动 Host Cache 生命周期,也不需要增加其他保留空闲 Slot 的参数。
--cache-radix-min-restore-tokens
0
以下三个启动组合可用于部署或对照测试:
--cache-ram 0 --cache-radix-prompt off
--cache-ram 4096 --cache-radix-prompt off
--cache-ram 4096 --cache-radix-prompt on
--cache-radix-prompt on 只有在 --cache-ram 非零时才会生效。修改缓存后端需要重启服务器;缓存保存在当前服务器进程的主机内存中,服务器退出后不会保留。
--cache-radix-prompt on
Radix 后端默认关闭,因此不传 --cache-radix-prompt on 时仍保持 Legacy 行为。严格的 No Cache 对照还应在请求中设置 "cache_prompt": false,仓库内的 Benchmark 已自动完成这项设置。
"cache_prompt": false
Radix Tree 不改变 llama-server 的 OpenAI 兼容 API。下面的请求显式启用请求级 Prompt Cache:
curl http://127.0.0.1:8080/v1/chat/completions \ -H 'Content-Type: application/json' \ -d '{ "model": "local", "messages": [ { "role": "system", "content": "You are a document assistant. Always answer from the supplied context." }, { "role": "user", "content": "Summarize document A." } ], "cache_prompt": true, "temperature": 0, "max_tokens": 32 }'
后续请求保持较长的 System Prompt、工具定义或文档前缀不变,只修改末尾问题,即可复用已保存前缀。cache_prompt 默认为 true,示例中显式填写是为了说明缓存行为。需要强制当前请求执行完整 Prefill 时可将其设置为 false;需要完全关闭 Host Prompt Cache 时,应在服务器启动时使用 --cache-ram 0。
cache_prompt
true
false
--cache-ram 0
响应 timings 中与缓存相关的主要字段为:
timings
cache_n
prompt_n
prompt_ms
predicted_n
predicted_ms
当相同或共享前缀请求中的 cache_n > 0 时,说明请求复用了已有 KV。该字段也可能包含活动 Slot 中的前缀复用;确认 Host Radix Restore 时,还应检查服务器日志中的 Radix loads 是否增加。日志会周期性输出 Radix 终止节点数、Host Cache 占用、unique tokens、logical tokens、保存/加载次数、淘汰次数和错误回退次数。
cache_n > 0
loads
unique tokens
logical tokens
--parallel
--kv-unified
--ctx-size
项目新增的测试按实现层、真实模型层和 HTTP 服务层组织:
tests/test-server-prompt-cache-radix.cpp
tests/test-server-prompt-cache-direct-roundtrip.cpp
tools/server/tests/radix/test_radix_lifecycle.py
tools/server/tests/radix/test_qwen_cann_smoke.py
tools/server/tests/radix/test_radix_http_token_equivalence.py
tools/server/tests/radix/test_radix_http_fallback.py
详细说明位于 tools/server/tests/radix/README.md。
cmake --build build --target \ llama-server \ test-server-prompt-cache-radix \ test-server-prompt-cache-direct-roundtrip \ -j python3 -m pip install -r tools/server/tests/requirements.txt
测试使用本地 GGUF 模型,不会自动下载模型,也不在代码中保存机器相关路径:
export LLAMA_TEST_MODEL_FILE=/path/to/model.gguf
运行 CPU 结构、Direct KV 和生命周期测试:
tools/server/tests/radix/run_correctness.sh cpu
在上述测试基础上增加 CANN 部署和 HTTP Token 等价性测试:
tools/server/tests/radix/run_correctness.sh cann
异常回退测试使用独立的故障注入构建。故障注入默认不进入正常 Release 二进制:
cmake -S . -B build-radix-fault \ -DGGML_CANN=on \ -DCMAKE_BUILD_TYPE=Release \ -DLLAMA_SERVER_RADIX_TEST_FAULT_INJECTION=on cmake --build build-radix-fault --target \ llama-server \ test-server-prompt-cache-radix \ test-server-prompt-cache-direct-roundtrip \ -j LLAMA_TEST_BUILD_DIR="$PWD/build-radix-fault" \ tools/server/tests/radix/run_correctness.sh fault
测试的完整日志、HTTP JSON 和 JUnit XML 默认写入 /tmp/llama-radix-correctness-<UTC timestamp>/。可以通过 LLAMA_TEST_EVIDENCE_DIR 指定其他输出目录。
/tmp/llama-radix-correctness-<UTC timestamp>/
LLAMA_TEST_EVIDENCE_DIR
tools/server/radix-bench/ 提供独立冷启动的 No Cache、Legacy 和 Radix 对照工具。每次运行分为 Warmup、默认 Slot Cleanup 和 Measurement 三个阶段,只有 Measurement 请求进入 TTFT 和吞吐统计。
tools/server/radix-bench/
主实验使用 Qwen3 8B Q8_0 时,可以执行:
MODEL=/path/to/Qwen3-8B-Q8_0.gguf \ MODES="no-cache legacy radix" \ REPEATS=5 \ ./tools/server/radix-bench/run_suite.sh \ tools/server/radix-bench/scenarios/shared-prefix-main.json
默认结果保存在 tools/server/radix-bench/results/。该目录保存本地完整 JSON 和服务器日志,并已从 Git 跟踪中排除。
tools/server/radix-bench/results/
现有场景包括:
shared-prefix-main.json
exact-reuse.json
no-sharing.json
prefix-512/1024/2048/4096.json
concurrency-1.json
concurrency-4.json
capacity-lru-512.json
Benchmark 自身的纯 Python 单元测试不需要模型或 NPU:
python3 -m pytest tools/server/radix-bench/test_rag_bench.py -q
更完整的场景、指标和单场景运行方式见 tools/server/radix-bench/README.md。
仓库保留了 Qwen3 8B Q8_0、Ascend 910B3 环境下的精简参考证据。它们用于证明测试路径和结果可复查,不代表所有模型和硬件上的固定性能。
正确性参考运行包括:
参考证据位于:
共享前缀主实验在 4 Slot、4 路客户端并发下执行 5 次独立冷启动,以下为运行级中位数:
该结果只对应仓库中的固定共享前缀工作负载。评估其他部署时,应使用同一模型、相同服务器配置和独立冷启动重复实验重新测量。
tools/server/server-prompt-cache-radix.h/.cpp
tools/server/server-task.h/.cpp
tools/server/tests/radix/
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802047560号
llama.cpp Radix Tree Prompt Cache
本仓库在
llama.cpp的 Host Prompt Cache 基础上增加了 Radix Tree 后端,用于在多个请求、会话和并发 Slot 之间保存并复用共享前缀的 KV Cache。本文面向部署和使用该功能的用户,说明如何构建、启动、调用并验证 Radix Tree Prompt Cache。原版
llama.cpp的项目介绍、模型支持和通用使用说明保留在 README-UPSTREAM.md。通用构建选项请参阅 docs/build.md,完整的llama-serverAPI 请参阅 tools/server/README.md。功能概述
传统 Host Prompt Cache 以完整 Prompt 状态为单位保存 KV Cache。多个 Prompt 即使拥有相同前缀,也会分别保存对应状态。Radix Tree 后端按照 Token 前缀组织缓存,将公共前缀只保存一次,并在分叉处保存各自的后缀。
一次请求的主要处理流程如下:
该实现具有以下特点:
--cache-ram上限时按 LRU 淘汰终止节点,并保留仍被其他分支引用的公共前缀。该功能主要适用于 System Prompt、工具定义、RAG 文档或多轮历史较长,并且后续请求会从这些内容继续分叉的工作负载。
分支说明
本仓库保留了上游基线、早期开发过程和当前发布版本三个分支:
masterllama.cpp基线,不包含本项目的 Radix Tree Prompt Cache 实现。feature/prompt-cache-radix-treeradixTree本文中的构建、启动和测试命令均以
radixTree分支为准。获取代码
Radix Tree 的发布代码位于
radixTree分支:如果已经克隆仓库,请先确认当前分支:
构建
Ascend CANN
先安装 CMake、C/C++ 编译器和与设备匹配的 CANN Toolkit,并加载 CANN 运行环境。
set_env.sh的位置取决于本机安装目录:使用 Release 模式构建
llama-server:构建产物位于
build/bin/llama-server。启动日志中出现CANN0 model buffer size和模型层卸载信息,表示模型已使用 CANN 后端。其他计算后端
Radix Tree Prompt Cache 位于
llama-server层,不限定模型计算后端。CPU、CUDA、Metal 等后端仍按上游 构建文档 编译。例如 CPU Release 构建:启动服务
下面的示例使用 4 个 Slot、Unified KV 和 4096 MiB Host Prompt Cache。请根据模型上下文长度、并发量和主机内存调整参数:
服务启动后可以检查健康状态:
日志中应包含以下信息:
--cache-radix-min-restore-tokens不需要额外设置。默认值为0,表示不启用最小恢复长度阈值。默认的空闲 Slot 保存与清理逻辑已经能够驱动 Host Cache 生命周期,也不需要增加其他保留空闲 Slot 的参数。缓存模式
以下三个启动组合可用于部署或对照测试:
--cache-ram 0 --cache-radix-prompt off--cache-ram 4096 --cache-radix-prompt off--cache-ram 4096 --cache-radix-prompt on--cache-radix-prompt on只有在--cache-ram非零时才会生效。修改缓存后端需要重启服务器;缓存保存在当前服务器进程的主机内存中,服务器退出后不会保留。Radix 后端默认关闭,因此不传
--cache-radix-prompt on时仍保持 Legacy 行为。严格的 No Cache 对照还应在请求中设置"cache_prompt": false,仓库内的 Benchmark 已自动完成这项设置。调用接口
Radix Tree 不改变
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应覆盖并发 Slot 的实际上下文需求。长共享前缀场景需要为多个同时恢复的请求预留足够 KV 容量。当前边界
llama-server进程内有效,不在不同服务器实例之间共享,也不持久化到磁盘。正确性测试
项目新增的测试按实现层、真实模型层和 HTTP 服务层组织:
tests/test-server-prompt-cache-radix.cpptests/test-server-prompt-cache-direct-roundtrip.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 模型,不会自动下载模型,也不在代码中保存机器相关路径:
运行 CPU 结构、Direct KV 和生命周期测试:
在上述测试基础上增加 CANN 部署和 HTTP Token 等价性测试:
异常回退测试使用独立的故障注入构建。故障注入默认不进入正常 Release 二进制:
测试的完整日志、HTTP JSON 和 JUnit XML 默认写入
/tmp/llama-radix-correctness-<UTC timestamp>/。可以通过LLAMA_TEST_EVIDENCE_DIR指定其他输出目录。性能与内存测试
tools/server/radix-bench/提供独立冷启动的 No Cache、Legacy 和 Radix 对照工具。每次运行分为 Warmup、默认 Slot Cleanup 和 Measurement 三个阶段,只有 Measurement 请求进入 TTFT 和吞吐统计。主实验使用 Qwen3 8B Q8_0 时,可以执行:
默认结果保存在
tools/server/radix-bench/results/。该目录保存本地完整 JSON 和服务器日志,并已从 Git 跟踪中排除。现有场景包括:
shared-prefix-main.jsonexact-reuse.jsonno-sharing.jsonprefix-512/1024/2048/4096.jsonconcurrency-1.jsonconcurrency-4.jsoncapacity-lru-512.jsonBenchmark 自身的纯 Python 单元测试不需要模型或 NPU:
更完整的场景、指标和单场景运行方式见 tools/server/radix-bench/README.md。
参考测试结果
仓库保留了 Qwen3 8B Q8_0、Ascend 910B3 环境下的精简参考证据。它们用于证明测试路径和结果可复查,不代表所有模型和硬件上的固定性能。
正确性参考运行包括:
参考证据位于:
共享前缀主实验在 4 Slot、4 路客户端并发下执行 5 次独立冷启动,以下为运行级中位数:
该结果只对应仓库中的固定共享前缀工作负载。评估其他部署时,应使用同一模型、相同服务器配置和独立冷启动重复实验重新测量。
目录索引
tools/server/server-prompt-cache-radix.h/.cpptools/server/server-task.h/.cpptests/test-server-prompt-cache-radix.cpptests/test-server-prompt-cache-direct-roundtrip.cpptools/server/tests/radix/tools/server/radix-bench/