目录

AgentTierFlow:面向智能体的内存管理系统设计与实现

image-20260730104649844

AgentTierFlow:面向多轮交互、工具调用和多Agent协同场景的分层KV Cache管理系统。

一、项目简介

在Agent工作流中,模型推理通常与任务规划、工具调用、分支执行和结果汇总交替进行。与传统线性生成请求相比,此类工作负载具有上下文持续增长、缓存生命周期较长、执行路径动态分支以及工具中间数据规模较大等特点,容易造成KV Cache重复计算、显存占用增长和频繁数据迁移。

本项目设计并实现了Agent生命周期感知的跨推理框架分层KV Cache管理系统AgentTierFlow。系统通过生命周期感知调度、动态分支共享、工具上下文压缩和GPU—CPU—外部存储三级缓存,降低长上下文及多分支任务中的状态存储与迁移开销。同时,系统采用逐层异步迁移机制,将KV Cache恢复、模型计算和缓存保存重叠执行,以降低分层存储产生的I/O延迟。

项目基于llama.cpp、SGLang进行源码级扩展,并面向LangGraph、AutoGPT、AutoGen及自定义Agent应用提供接入能力。在保证推理结果正确性和任务成功率的前提下,系统重点优化有效GPU显存占用、缓存复用效率、并发任务承载能力和端到端推理时延。

二、核心特性

  • Agent生命周期感知调度

    结合离线工作流Trace与在线状态观测,预测未来多个执行步骤中的Agent调用及KV Cache复用价值,并生成保护、预取、下沉和回收优先级。

  • 动态分支共享与写时复制 多个Agent分支共享公共Token前缀,仅为分叉后的增量内容分配独立缓存;发生内容分歧时按需复制,降低并行分支产生的缓存冗余。

  • 工具上下文压缩

    对工具描述、调用参数和返回结果进行清洗、去重、相关性排序和预算截断,并通过外部Artifact Store保存原始结果,减少冗余内容进入后续推理上下文。

  • GPU—CPU—外部存储三级KV Cache

    通过Logical Cell统一表示不同存储层级中的缓存数据,将KV Cache的逻辑身份与物理位置解耦,使上层执行过程无需直接感知缓存所在层级。

  • 逐层异步迁移流水

  • 通过Disk→CPU、CPU→GPU、GPU→CPU和CPU→Disk四条数据通道,将缓存恢复、模型计算与缓存保存重叠执行,降低跨层迁移对推理关键路径的影响。

  • 跨框架、模型与硬件适配

  • 支持llama.cpp、SGLang,已完成Qwen2.5、DeepSeek-R1-Distill-Qwen、openPangu-Embedded、和GLM等模型适配,并在openEuler及多种GPU、NPU和边缘设备上完成部署验证。

三、系统架构

系统采用机制与策略分离、控制决策与数据迁移分离的设计。控制侧负责采集Agent工作流状态、组织上下文、评估KV Cache未来复用价值并生成调度提示;数据侧负责缓存映射、跨层迁移、并发同步和物理空间管理。缓存预测仅影响资源调度效率,不直接参与模型计算结果的判定。

image-20261007032822089

系统主要由以下四个模块组成:

  1. Agent工作流状态建模模块:统一接入异构Agent应用,建立任务、Agent、请求和缓存之间的关联,并采集模型执行、工具等待、协同等待和任务完成等状态。
  2. 上下文压缩与缓存复用模块:构建当前推理上下文,压缩工具状态,并识别公共前缀和动态分支中可共享的KV Cache。
  3. 生命周期预测与缓存价值评估模块:融合离线工作流先验与在线运行观测,预测缓存未来复用价值,生成保护、预取与回收等调度提示。
  4. 分层KV Cache运行时模块:通过Logical Cell统一管理GPU、CPU和外部存储中的缓存,并执行恢复、保存、迁移、淘汰和回收。

上层Agent应用向系统提供推理请求、生命周期状态和工具事件。控制侧生成缓存调度提示,运行时结合缓存位置、容量、版本和引用状态执行具体操作,并将缓存命中、预取效果、迁移开销和推理时延等信息反馈至后续预测过程。

四、技术创新

4.1 生命周期感知的缓存价值预测

系统将 Agent 工作流状态引入 KV Cache 调度,通过离线工作流 Trace 构建状态转移先验,并结合在线运行观测动态更新转移概率。设 Agent 由状态 sis_i 转移至状态 sjs_j,其后验转移概率表示为:

Pt(sj∣si)=αij+Nijoff+Nijon(t)∑k(αik+Nikoff+Nikon(t))P_t(s_j \mid s_i) = \frac{\alpha_{ij} + N_{ij}^{\mathrm{off}} + N_{ij}^{\mathrm{on}}(t)}{\sum_{k} \left( \alpha_{ik} + N_{ik}^{\mathrm{off}} + N_{ik}^{\mathrm{on}}(t) \right)}

其中,αij\alpha_{ij} 为平滑先验,NijoffN_{ij}^{\mathrm{off}} 和 Nijon(t)N_{ij}^{\mathrm{on}}(t) 分别表示离线 Trace 与在线运行中观测到的状态转移次数。

在获得未来状态分布后,系统结合缓存块与工作流状态之间的访问关系,计算缓存块 bb 的未来复用价值:

Vt(b)=∑h=1Hγh−1∑s∈SP(st+h=s∣Ht)R(b,s)V_t(b) = \sum_{h=1}^{H} \gamma^{h-1} \sum_{s \in \mathcal{S}} P(s_{t+h} = s \mid \mathcal{H}_t) R(b, s)

其中,HH 为预测窗口,γ\gamma 为时间衰减系数,R(b,s)R(b,s) 表示缓存块 bb 在状态 ss 下被访问的关联程度。

该数值用于缓存块之间的相对排序,而不直接表示概率。复用价值较高的缓存将获得更高的保护或预取优先级;复用价值较低,或所属任务已经完成的缓存,则优先下沉或回收。通过上述机制,系统能够识别工具等待、协同等待等暂时不活跃但仍可能再次使用的缓存,降低仅依据历史访问时间进行淘汰所产生的误判。

4.2 动态分支共享与写时复制

针对多Agent协同和多路径推理场景,系统允许不同分支共享分叉前的公共KV Cache,仅保存各分支新增的Token缓存。当某一分支的内容与公共区域发生分歧时,运行时仅复制对应的局部缓存单元,其他分支仍引用原有数据。

image-20260730103840726

该机制使并行分支的缓存开销由“公共上下文重复存储”转变为“公共前缀共享与少量增量存储”,避免缓存占用随分支数量快速增长。

4.3 工具上下文压缩

系统对代码文件、检索文档、网页内容、执行日志和结构化数据等工具结果进行清洗、去重、相关性排序和Top-K截断,并在条目数、字符数和Token数量等预算约束下生成紧凑表示。

压缩后的内容保留任务目标、关键结果、异常信息和必要依赖,原始结果存储在外部Artifact Store中,并通过引用按需恢复有限原文片段,从源头减少输入Token数量及后续KV Cache的存储和迁移开销。

image-20260730103804092

4.4 Logical Cell三级缓存抽象

系统在GPU显存、CPU主存和外部存储物理池之上引入Logical Cell,将缓存的逻辑身份与物理副本位置解耦。上层计算通过稳定的逻辑标识访问缓存,缓存发生恢复或下沉时仅更新逻辑单元与各层副本之间的映射关系。

该抽象统一了三级存储中的KV Cache表示,使缓存查找、恢复、保存和回收过程无需改变上层请求的访问方式。

image-20260730103917889

4.5 逐层异步流水与细粒度同步

系统将KV Cache迁移细化至模型层,并构建Disk→CPU、CPU→GPU、GPU→CPU和CPU→Disk四条异步数据通道。在当前层执行Attention计算时,后续层可以同步完成缓存恢复,已完成计算的层则可以向低层存储保存。

image-20260730103947974

运行时通过设备事件、版本信息、引用计数和缓存状态标记控制数据访问顺序。计算算子仅在当前层KV Cache就绪后执行,正在迁移或仍被其他请求引用的缓存不会被提前覆盖和回收。

五、性能对比

5.1 测试环境

配置项 测试环境
操作系统 openEuler
CPU Intel Core i7-12700K
GPU NVIDIA GeForce RTX 5060 Ti,16 GB显存
系统内存 32 GB
存储空间 1 TB
推理框架 llama.cpp / SGLang
模型 Qwen2.5-7B、DeepSeek-R1-Distill-Qwen-7B、openPangu-Embedded-7B、GLM-4.6V-Flash
KV Cache精度 FP16
最大上下文长度 32K
Agent应用 Deer-Flow、PairCoder、OWL

5.2 测试场景

应用类别 代表应用 数据集 主要工作流特征
深度研究 Deer-Flow Deep Research Bench 多轮检索、文档解析、内容归纳与报告生成
代码开发 PairCoder HumanEval、MBPP 代码生成、编译测试、错误定位与迭代修复
复杂任务 OWL GAIA-text 任务规划、工具调用、协同执行与结果反思

5.3 核心结果

5.3.1 显存降低和任务成功率

image-20261007032904207

5.3.2 多级缓存命中率

image-20261007033031419

5.3.3 平均TTFT延迟

image-20261007033131979

5.3.4 不同并发下的TTFT和请求延迟

image-20261007033239119

六、赛题完成情况

赛题要求 完成情况
KV Cache 生命周期管理 ✔,包括一定创新
分支推理内存共享 ✔,已支持
工具调用与上下文压缩 ✔,已支持
分层内存与异构存储优化 ✔,三级存储
异构AI加速硬件支持 ✔,支持昇腾、NVIDIA硬件
支持多模型或多任务推理场景 ✔,支持4模型3任务
适配不同模型规模或不同推理框架 ✔,支持2框架
实现一个支持智能体推理流程的系统 ✔,已完整实现
保证任务成功率基本不下降 ✔,成功率平均降低了1.25%
实现显存占用的有效降低 ✔,平均降低36.32%
实现推理延迟优化 ✔,平均TTFT延迟降低了79.33%
缓存命中率优化 ✔,多级缓存命中率平均提高了2.22x

七、部署文档

1. 安装环境

需要 Linux、Bash、支持 C++17 的编译器、CMake 3.18 及以上版本、Python 3.10 及以上版本,以及 NVIDIA 驱动和 CUDA Toolkit。容器内运行时,需要由宿主机向容器提供 GPU 设备。

检查基础环境

cmake --version
c++ --version
python3 --version
nvcc --version
timeout 8s nvidia-smi

nvidia-smi 应能显示 GPU 和驱动;nvcc --version 用于确认实际 CUDA 编译器版本。若 nvcc 不在 PATH,编译前通过 CUDACXX 指定它的绝对路径。

2. 环境

进入提交包根目录,并将下载、编译和运行目录放在包外:

export PROJECT_ROOT="$(pwd)"
export DEPLOY_ROOT=/workspace/agenttierflow-runtime
export BUILD_DIR="$DEPLOY_ROOT/build"
export MODEL_DIR="$DEPLOY_ROOT/models/qwen2.5-7b-instruct-q4_k_m"
export HF_HOME="$DEPLOY_ROOT/huggingface"
mkdir -p "$BUILD_DIR" "$MODEL_DIR" "$DEPLOY_ROOT/runs"

python3 -m venv "$DEPLOY_ROOT/venv"
export PYTHON="$DEPLOY_ROOT/venv/bin/python"
"$PYTHON" -m pip install --upgrade pip
"$PYTHON" -m pip install \
  'huggingface_hub>=1.0,<2' 'PyYAML>=6.0.1,<7' 'httpx>=0.27,<1'

提交包和部署目录可以放在其他位置,将上面的路径替换为实际值即可。后续命令在同一终端中按顺序执行,保持这些环境变量有效。

3. 下载模型

模型来自 Qwen 官方 GGUF 仓库。下面使用 Hugging Face CLI 下载 Q4_K_M 的两个分片,只下载指定的模型文件:

"$DEPLOY_ROOT/venv/bin/hf" download Qwen/Qwen2.5-7B-Instruct-GGUF \
  qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf \
  qwen2.5-7b-instruct-q4_k_m-00002-of-00002.gguf \
  --local-dir "$MODEL_DIR"

下载完成后应有:

qwen2.5-7b-instruct-q4_k_m/
├── qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf
└── qwen2.5-7b-instruct-q4_k_m-00002-of-00002.gguf

指定第一个分片作为模型入口,并检查两个分片均已保存:

export MODEL="$MODEL_DIR/qwen2.5-7b-instruct-q4_k_m-00001-of-00002.gguf"
test -s "$MODEL"
test -s "$MODEL_DIR/qwen2.5-7b-instruct-q4_k_m-00002-of-00002.gguf"

两个分片必须放在同一目录并保留原文件名,引擎会从首个分片加载其余分片。下载中断时可重新执行下载命令。CLI 下载参数见 Hugging Face 文档。

已有兼容的 GGUF 模型时,可以跳过下载,直接将 MODEL 设为实际模型文件的绝对路径;分片模型同样指定首个分片。当前部署入口使用模型的文本推理能力。

4. 编译

先指定 CUDA 编译器。下面使用常见安装位置,请按实际安装路径调整:

export CUDACXX=/usr/local/cuda/bin/nvcc
test -x "$CUDACXX"

使用提交包自带的构建脚本编译:

cd "$PROJECT_ROOT"
CUDA_ARCH=120 JOBS=2 bash demo/build.sh --build-dir "$BUILD_DIR"
export SERVER="$BUILD_DIR/bin/llama-server"
test -x "$SERVER"

CUDA_ARCH=120 对应 RTX 5060 Ti;其他 GPU 改为其实际架构值。JOBS=2 为编译并行度,可按主机内存调整。脚本完成 CMake 配置后构建 llama-server,所需共享库也输出在构建目录中,运行时保留整个构建目录。

构建配置为 Release、CUDA 后端,关闭 CUDA Graph、Web UI 下载和 OpenSSL。只检查配置、暂不编译时使用:

CUDA_ARCH=120 bash demo/build.sh --build-dir "$BUILD_DIR" --configure-only

此命令只生成构建文件;服务程序仍需通过前面的完整构建命令生成。

5. 启动服务

5.1 LRU 模式

cd "$PROJECT_ROOT"
PYTHON="$PYTHON" bash demo/start_server.sh \
  --server "$SERVER" \
  --model "$MODEL" \
  --strategy LRU \
  --port 38081 \
  --run-root "$DEPLOY_ROOT/runs"

该命令在前台运行,保持终端打开。模型加载完成后,终端打印 READY http://127.0.0.1:38081,表示服务已就绪。每次启动会在 DEPLOY_ROOT/runs 下创建独立运行目录和缓存文件。

5.2 Queue 模式

先停止上一实例,再切换为 Queue:

PYTHON="$PYTHON" bash demo/start_server.sh \
  --server "$SERVER" \
  --model "$MODEL" \
  --strategy QUEUE_WINDOW \
  --port 38081 \
  --run-root "$DEPLOY_ROOT/runs"

该入口同时管理服务和一个 Queue 策略进程,无需另外启动策略进程。

5.3 启动参数

参数 用途 默认值或约束
--server 本包编译生成的服务程序 指定 BUILD_DIR/bin/llama-server
--model 本地 GGUF 模型 分片模型指定首个分片
--strategy 简易入口启动的缓存策略 LRU 或 QUEUE_WINDOW
--port 本机监听端口 不指定时自动选择空闲端口
--run-root 包外运行和缓存目录 建议设为 DEPLOY_ROOT/runs
--l1 L1 容量 默认 8192 token cells
--l2 L2 容量 默认 8192 token cells
--l3 L3 容量 默认 32768 token cells
--startup-timeout 等待模型加载和服务就绪的时间 默认 90 秒,上限 300 秒

例如显式设置容量和启动等待时间:

PYTHON="$PYTHON" bash demo/start_server.sh \
  --server "$SERVER" --model "$MODEL" --strategy LRU \
  --port 38081 --run-root "$DEPLOY_ROOT/runs" \
  --l1 8192 --l2 8192 --l3 32768 --startup-timeout 180

当前启动脚本固定使用第一张 GPU、总上下文 32768 tokens、两个并行槽位和 FP16 KV。统一 KV 模式下并发请求共享总上下文容量。各层容量可设为 1 到 32768 token cells,但不会增加模型的总上下文。模型权重和运行所需内存须能容纳在当前设备中。

服务监听 127.0.0.1。在本机或容器内使用第六节的地址访问;从宿主机外访问时,需要另外配置端口转发。

6. 检查服务并发送请求

保持启动终端运行,在另一个终端执行:

export SERVER_URL=http://127.0.0.1:38081
curl --fail --max-time 10 "$SERVER_URL/health"
curl --fail --max-time 10 "$SERVER_URL/v1/models"
curl --fail --max-time 10 "$SERVER_URL/kv/stats"

若启动时使用其他端口或自动选端口,将 SERVER_URL 改为终端打印的实际地址。

发送一次短文本请求:

curl --fail --max-time 60 "$SERVER_URL/completion" \
  -H 'Content-Type: application/json' \
  --data '{
    "prompt": "The capital of France is",
    "n_predict": 16,
    "temperature": 0,
    "stream": false,
    "cache_prompt": true
  }'

正常情况下接口返回 JSON,其中 content 为生成文本。应用可使用 OpenAI 兼容接口,配置 base_url 为 http://127.0.0.1:38081/v1,模型名称使用 /v1/models 返回的实际 id。

需要进一步确认服务和前缀复用时,在新终端中执行:

export DEPLOY_ROOT=/workspace/agenttierflow-runtime
"$DEPLOY_ROOT/venv/bin/python" -B demo/smoke.py \
  --base-url "$SERVER_URL" --timeout 30

通过时输出 PASS_TWO_REQUEST_PREFIX_SMOKE。若调整了提交包或部署目录,以上路径也应同步调整。

7. Bayes 工作流

Bayes 使用 src/TestAgent/scripts/run_bayes.sh,需要三类应用的生命周期输入。启动前准备 DeerFlow、PairCoder 和 OWL 的应用源码及各自依赖、应用输入、所需工具服务,以及与当前模型匹配的 Trace 和 tokenizer helper。上述应用和输入不包含在源码包中。

安装 Agent 接入所需的附加依赖并复制配置:

cd "$PROJECT_ROOT"
"$PYTHON" -m pip install 'datasets>=2.16.1' 'langchain-core>=1.0,<2'
cp src/TestAgent/configs/local.example.yaml "$DEPLOY_ROOT/config.yaml"

编辑 DEPLOY_ROOT/config.yaml,至少按实际部署填写:

配置项 填写要求
runtimes.harness、deep_research、paircoder、owl 各环境实际的 Python 启动命令;使用虚拟环境时可写为 ["/绝对路径/venv/bin/python"]
paths.sources_dir、deer_flow、deep_research_bench、paircoder、owl 已准备的应用源码目录,建议使用绝对路径
paths.runs_dir、paths.data_dir 包外运行目录和应用数据目录
deep_research.query_file、owl.local_jsonl、owl.cache_dir 实际输入和缓存路径
deep_research.searx_host、owl.searx_host 可用的搜索服务地址
web_search.policy 启用工具上下文压缩时设为 summary_v1

模型及 tokenizer 服务地址由该启动入口根据本次 server 端口设置。应用自身的其他依赖按对应源码版本安装到 runtimes 指定的环境中。

设置外部输入路径后启动:

export TRACE_ROOT=/data/agent-traces/current-model
export TOKENIZER_HELPER=/data/tools/llama_tokenize_batch
export PYTHONPATH="$PROJECT_ROOT/src/AgentTierFlow:$PROJECT_ROOT/src/TestAgent"
test -d "$TRACE_ROOT"
test -x "$TOKENIZER_HELPER"

PYTHON_BIN="$PYTHON" SERVER_BIN="$SERVER" MODEL="$MODEL" \
TRACE_ROOT="$TRACE_ROOT" TOKENIZER_HELPER="$TOKENIZER_HELPER" \
bash src/TestAgent/scripts/run_bayes.sh \
  "$DEPLOY_ROOT/config.yaml" \
  "bayes-$(date -u +%Y%m%dT%H%M%SZ)-$" \
  "$DEPLOY_ROOT/results"

此入口自行启动和管理 server 及策略进程,运行前停止第五节的实例。Trace 需具备入口要求的清单和请求数据,且模型、chat template 和 helper 身份须匹配清单;仅填写一个普通 Trace 目录不能替代这些输入。简易服务入口不直接启动 BAYES_LIFECYCLE。

关于
214.4 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号