DualPath: Breaking the Storage Bandwidth Bottleneck in Agentic LLM Inference

  • 文章标题: DualPath:打破 Agentic LLM 推理中的存储带宽瓶颈
  • 作者/机构: Yongtong Wu, Shaoyuan Chen, Yinmin Zhong, Rilin Huang, Yixuan Tan, Wentao Zhang, Liyue Zhang, Shangyan Zhou, Yuxuan Liu, Shunfeng Zhou, Mingxing Zhang, Xin Jin, Panpan Huang
  • 所属机构: 1. 北京大学计算机学院; 2. 清华大学; 3. DeepSeek-AI

A1 主要贡献

本文研究的核心问题是,在多轮、代理式(agentic)大语言模型(LLM)推理中,其性能越来越多地受到 KV-Cache 存储 I/O 而非计算的限制。在流行的分离式(disaggregated)架构中,从外部存储加载巨大的 KV-Cache 会产生一个根本性的不平衡:预填充(prefill)引擎上的存储网卡(NIC)带宽饱和,而解码(decoding)引擎上的存储网卡却处于空闲状态。这种不对称性严重制约了整个系统的吞吐量。

为了解决这一瓶颈,本文提出了 DualPath,一个通过引入双路径 KV-Cache 加载来打破该瓶颈的推理系统。除了传统的“存储到预填充”路径外,DualPath 还启用了一条新颖的“存储到解码”路径,其中 KV-Cache 被加载到解码引擎,然后通过计算网络上的 RDMA 高效地传输到预填充引擎。DualPath 将这一优化的数据路径——其本身避免了网络拥塞和对延迟关键型模型执行通信的干扰——与一个动态平衡预填充和解码引擎负载的全局调度器相结合。


图 1: 现有瓶颈(左)与 DualPath(右)。

本文的主要贡献如下:
* 我们识别了多轮、代理式 LLM 工作负载的 I/O 密集型特性,并证明在现代 LLM 推理架构下,KV-Cache 加载主导了系统性能。
* 我们提出了 DualPath,一个引入双路径 KV-Cache 加载并通过利用解码引擎带宽来解决预填充端瓶颈的推理系统。
* 我们设计并评估了一种工作负载感知的调度算法,该算法动态平衡计算和网络资源,显著改善了在现实工作负载下的平衡性。

A3 背景知识

2.1 LLM 推理初步

LLM 推理的构成。目前流行的大语言模型主要采用仅解码器(decoder-only)的 Transformer 架构,由堆叠的块组成,每个块包含注意力层和前馈网络(FFN)。注意力层负责处理请求内 token 之间的交互,而 FFN 则独立地处理每个 token。模型基于前面的 token 预测后续的 token,并将注意力机制中的键(keys)和值(values)作为 KV-Cache 存储在 HBM 中,以避免重复计算。

预填充-解码分离式推理 (PD-disaggregated Inference)。预填充-解码(PD)分离架构【【37,Splitwise: Efficient Generative LLM Inference Using Phase Splitting,ISCA 2025】,【58,DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving,OSDI 2024】】将预填充阶段和解码阶段分开,并将它们分别分配给专用的预填充引擎(PEs)和解码引擎(DEs)。这两个阶段表现出不同的计算和内存模式:预填充是计算密集型的、可批处理的,而解码是内存带宽密集型的、对延迟敏感的。通过 PD 分离,PEs 加载命中的 KV-Cache 并执行预填充;然后,它们将 KV-Cache 传输给 DEs,DEs 再进行自回归解码。这种设计减少了两个阶段之间的干扰,使得可以针对不同阶段进行特定优化,并提高了可扩展性,使其成为现代 LLM 服务的实际标准架构。为了支持多轮对话,KV-Cache 通常存储在分布式存储中以便跨轮次重用。

分层预填充 (Layerwise Prefill)。长上下文的预填充受限于 HBM 容量,因为整个批次的激活值和 KV-Cache 都必须驻留在 HBM 中,这迫使批处理大小受限,导致 GPU 利用率低下。LayerKV【【50,LayerKV: Optimizing Large Language Model Serving with Layer-wise KV Cache Management,arXiv 2024】】和 PrefillOnly【【17,PrefillOnly: An Inference Engine for Prefill-only Workloads in Large Language Model Applications,SOSP 2025】】通过利用预填充计算中的强局部性来解决这个问题:每一层仅需要其自身的特定于该层的 KV-Cache。因此,KV-Cache 可以按层进行分配和释放,GPU 仅需为前向批次保留一层的 KV-Cache。这使得有效批处理大小(以 token 计)大约增加了层数的倍数,从而提升了预填充吞吐量。

2.2 LLM 的代理式应用

代理式应用的多轮交互特性。LLM 越来越多地为代理式应用提供支持,这些应用在长会话中执行多轮推理并与环境(例如,通过终端命令、代码执行或请求人类反馈)进行交互。如图 2 所示,在典型的一轮中,模型接收由先前上下文和一些新追加的 token(通常是工具输出或用户输入)组成的提示,并生成下一个动作或响应。单个代理运行是一个包含数十甚至数百轮的轨迹:上下文逐轮增长,最长可达一百万个 token【【4,Introducing Claude Opus 4.6,Anthropic 2026】,【11,Gemini 3 Pro,Google DeepMind 2026】】。由于大部分上下文(在我们的追踪数据中通常 >95% 的 token)在轮次间被重用,每轮中绝大多数 token 都能命中 KV-Cache;只有新追加的上下文需要预填充计算。由于代理轨迹的极端长度,基于 DRAM 和 HBM 的 KV-Cache 存储方案如 Mooncake【【38,Mooncake: Trading More Storage for Less Computation — A KVCache-centric Architecture for Serving LLM Chatbot,FAST 2025】】只能存储一小部分 KV-Cache,因此必须使用更大但更便宜的基于外部 SSD 的 KV-Cache 存储【【13,3FS,DeepSeek-AI 2025】】。


图 2: 代理轨迹示例。

代理式 LLM 训练中的 I/O 压力。代理式 LLM 推理工作负载在代理 LLM 训练中也很普遍,后者通常采用强化学习(RL)方法。在典型的 RL 训练循环中,代理 LLM 首先经历一个“展开”(rollout)阶段,在此阶段它被提示生成大量的多步代理轨迹。然后,这些轨迹由一个单独的奖励模型进行评分。最后,LLM 的参数被更新,以增加高分输出的可能性并减少低分输出的可能性。在展开阶段,大量数据(如奖励模型和优化器状态)被卸载到主机的 DRAM 中,进一步限制了可用于 KV-Cache 的 DRAM。这加强了对能够高效容纳长代理展开上下文的外部、高容量 KV-Cache 存储的需求。

2.3 现代 AI 数据中心架构

计算与存储网络分离。现代 AI 数据中心是为处理大规模生成式 AI 训练和推理工作负载而专门构建的逻辑超级计算机。例如,在标准的 NVIDIA DGX SuperPOD【【32,SuperPOD: Next Generation Scalable Infrastructure for AI Leadership,NVIDIA 2023】】中,每个节点配备 8 个通过高速 NVLink 互连的 Hopper GPU。每个 GPU 配备一个专用的 400 Gbps 计算网卡(CNIC,也称为东西向网卡),以最大化节点间通信带宽。独立于计算网络,每个节点还配备一个高达 400 Gbps 的存储网卡(SNIC,也称为南北向网卡),用于快速访问数据集、模型检查点和磁盘上的 KV-Cache。

网络隔离的重要性。该架构的一个基本原则是计算网络和存储网络相互隔离【【55,Insights into deepseek-v3: Scaling challenges and reflections on hardware for ai architectures,ISCA 2025】】。这种分离对于最大化存储和应用性能至关重要。通过将 GPU 之间的高强度东西向计算流量与存储流量隔离,该架构防止了它们之间的干扰,并显著降低了计算通信延迟。这种设计还确保了即使在执行数据密集型任务(如读取大型数据集或写入数TB的模型检查点)时,GPU 间的通信也能保持高度可靠和可预测。

A3 关键 Observation 与设计动机

我们在代理式推理任务中观察到严重的 GPU 未充分利用现象。我们的调查显示,由于每个节点上单个存储网卡的带宽有限,KV-Cache 的加载速度成为瓶颈。分析表明,三个决定性因素共同导致了这一瓶颈。

因素一:代理式工作负载的高 I/O 与低计算比。代理式工作负载天然具有长上下文、短追加、多轮次的特点。在每一轮中,GPU 需要从持久存储中读取整个上下文的 KV-Cache,并为追加的 token 执行预填充计算。我们从代表性的编码任务中收集的追踪数据显示,平均轮次为 157 轮,表明 LLM 倾向于进行多轮交互。平均上下文长度为 32.7k,而平均追加长度仅为 429,这意味着 KV-Cache 命中率高达 98.7%。在这种场景下,“缓存-计算比”(即需要加载的 KV-Cache 与所需计算量的比率)对于 DeepSeek-V3.2【【16,DeepSeek-V3.2: Pushing the Frontier of Open Large Language Models,DeepSeek-AI 2025】】来说约为 22 GB/PFLOP,这对存储带宽构成了显著的瓶颈。值得注意的是,DeepSeek MLA 模型的 KV-Cache 大小已经高度优化;对于 KV-Cache 更大的模型(见表 1),情况更为严重。DeepSeek-V3.2 的比率高于 DeepSeek-V3【【15,DeepSeek-V3 Technical Report,DeepSeek-AI 2025】】,这得益于其稀疏注意力设计,降低了计算需求。

表 1: 在追加长度为 429 的情况下,不同上下文长度(16k–64k)的缓存-计算比。KV-Cache 数据类型默认为 FP8,除非另有说明。

因素二:硬件发展趋势不适应代理式推理。近年来,网络带宽和 HBM 容量的增长落后于 GPU FLOPS 的增长,这导致我们在代理式工作负载下面临内存和通信瓶颈。如图 3 所示,从 NVIDIA Ampere 到 Blackwell,I/O-计算比下降了 14.4 倍。低网卡带宽限制了 KV-Cache 的加载速度,使得 GPU 处于空闲状态。此外,较小的 HBM 容量限制了 GPU 内核【【10,FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning,ICLR 2024】,【14,DeepGEMM,DeepSeek-AI 2025】,【27,FlashMLA: Efficient Multi-head Latent Attention Kernels,Jiashi Li and Shengyu Liu 2025】,【54,FlashInfer: Efficient and Customizable Attention Engine for LLM Inference Serving,arXiv 2025】】能够同时计算的 token 批次大小,从而妨碍了计算单元(如 Tensor Core)的充分利用【【17,PrefillOnly: An Inference Engine for Prefill-only Workloads in Large Language Model Applications,SOSP 2025】】。

因素三:现有系统在不同引擎类型间存在严重的存储网络利用不平衡。在流行的 PD 分离系统中,命中 token 的 KV-Cache 仅由预填充引擎直接从远程存储加载。这种设计将所有存储 I/O 压力集中在预填充端的 SNIC 上,而解码引擎上的 SNIC 则基本处于空闲状态。因此,总的存储网络带宽无法得到充分利用。

设计动机。以上分析表明,在 PD 分离架构上进行代理式推理的根本性能问题是 KV-Cache 检索的高 I/O 需求和推理引擎间存储网络带宽利用的不平衡。同时,我们观察到,计算网络的网络流量(其总带宽远大于存储网络)呈现出间歇性模式:模型推理中使用的集合操作(collective operations)以亚毫秒级的间隔爆发。因此,一个机会自然出现:我们可以利用解码节点的 SNIC 带宽从存储中加载 KV-Cache,并利用更快的计算网络的空闲带宽将其传回预填充节点。


图 3: 左:NVIDIA GPU 的硬件趋势。右:不同请求批次大小下的相对 token 吞吐量(每个请求有 30K 上下文和 300 个 token 追加)。

A2 方法细节

4 DUALPATH 系统概览

为了打破预填充端的存储 I/O 瓶颈,我们提出了一种双路径加载架构,它从根本上重新思考了在 PD 分离推理中如何检索 KV-Cache。基于此架构,我们设计并实现了 DualPath。DualPath 采用了两种在 §2 中论证的广泛应用的技术:(1) PD 分离【【37,Splitwise: Efficient Generative LLM Inference Using Phase Splitting,ISCA 2025】,【58,DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving,OSDI 2024】】,它将提示和解码处理分开以提高效率。(2) 分层预填充,它避免了 LayerKV【【50,LayerKV: Optimizing Large Language Model Serving with Layer-wise KV Cache Management,arXiv 2024】】和 PrefillOnly【【17,PrefillOnly: An Inference Engine for Prefill-only Workloads in Large Language Model Applications,SOSP 2025】】在预填充引擎上遇到的 HBM 瓶颈,并提高了 GPU 利用率。

系统组件。我们的系统由以下组件构成:
* 推理引擎。每个引擎管理一个 GPU。引擎分为用于预填充的预填充引擎(PEs)和用于解码的解码引擎(DEs)。
* 流量管理器 (§5)。每个引擎包含一个流量管理器,用于执行 (1) 主机-设备内存拷贝 (H2D & D2H),(2) PEs 和 DEs 之间的 KV-Cache 传输,以及 (3) 通过存储网卡从存储中读/写 KV-Cache。我们采用以 CNIC 为中心的流量管理方法(详见 §5),以防止 KV-Cache 流量影响模型推理中的通信。
* 请求调度器 (§6)。一个中央调度器,接收客户端请求并将其分发到各个引擎。它还负责在两条路径之间动态分配数据流量(图 4)。

4.1 双路径加载

核心机制。除了传统的“存储到预填充”路径,DualPath 引入了一条新颖的“存储到解码”路径,允许 KV-Cache 先被加载到解码引擎,然后通过计算网络上的高带宽 RDMA 传输到预填充引擎。通过动态地在两条路径间分配负载,系统汇集了所有引擎(包括原本空闲的解码端网卡)的存储网卡带宽,并消除了限制现有系统的非对称带宽饱和问题。这种方法将存储 I/O 从单一瓶颈资源转变为一个全局池化和可调度的能力。双路径的具体数据流如下所述。


图 4: 双路径加载示意图。调度器动态地在两条路径之间分配数据流量。

数据流实现。为了实现双路径加载,DualPath 在每个 PE 和 DE 上分配了少量 DRAM 作为缓冲区,分别称为 PE 缓冲区和 DE 缓冲区。

预填充 PE 读取路径。首先,命中 token 的 KV-Cache 从持久存储读入 PE 缓冲区(如图 4a 中的标签 1 和 2 所示)。在计算一个注意力层之前,该层的 KV-Cache 被传输到 PE HBM(3 和 4),用于计算缓存未命中(cache-miss)的提示 token 的 KV-Cache。然后,所有命中和未命中 token 的 KV-Cache 被传输到 DE 缓冲区,以形成完整的提示 KV-Cache(5-7)。这个过程(3-7)会重复 $N_{layers}$ 次。在预填充前向传播过程中,传输与计算是重叠的。

预填充 DE 读取路径。命中 token 的 KV-Cache 首先被读入 DE 缓冲区(如图 4b 中的标签 1 和 2 所示)。在 PE 预填充期间,相应层的 KV-Cache 从 DE 缓冲区读出,同样与计算重叠(3-5)。这个过程重复 $N_{layers}$ 次。在一层的计算完成后,只有未命中 token 的 KV-Cache 被传输到 DE 缓冲区,并与已有的命中 token KV-Cache 合并。

解码阶段。在 DE 缓冲区接收到完整的提示 KV-Cache(包括通过 PE 读取路径加载的 KV-Cache 和新追加 token 的 KV-Cache)后,解码阶段开始。DE 首先分配 HBM 并执行主机到设备(H2D)的传输(图 4a 中的标签 8 和 9;图 4b 中的标签 6 和 7),然后在开始解码前释放 CPU 内存。DE 缓冲区的设计给 DRAM 和 CNIC 带来了带宽压力(一次额外的 H2D),这本可以通过 GPU Direct RDMA 直接绕过来避免。然而,由于在这种场景下生成长度通常较短,首 token 时间(TTFT)占总端到端请求时间的不可忽略部分。引入 DE 缓冲区有助于减少 GPU 内存使用。在解码期间,每当累积满一个 token 块(例如 64 个 token)时,它会立即被持久化到磁盘。

不同的块布局。我们采用两种不同的块布局:全块(Full Block)和层块(Layer Block),它们分别包含所有层和单层。详细布局可在 §A.5 中找到。对于所有与存储的交互,我们采用全块。在 PE 读取情况下,KV-Cache 加载到 PE HBM 和传输到 DE 缓冲区的过程是以分层流式方式进行的,两者都使用层块。类似地,对于 DE 读取路径,从 DE 缓冲区到 PE HBM 的传输使用层块。

4.2 无瓶颈分析

分析前提。我们证明,在大多数合理的 P/D 比率下,系统可以完全饱和所有存储网卡,而不会引入计算网卡或 DRAM 瓶颈。我们假设 PCIe 拓扑配置良好(每对 GPU-NIC 都在同一个 PCIe 交换机下),任务调度负载均衡,计算网络无拥塞,并且存储读取带宽被充分利用。

符号定义。令 $P$ 和 $D$ 分别表示预填充和解码节点的数量。每个节点有 $g$ 个 GPU,每个 GPU 有一个带宽为 $B$ 的计算网卡。每台机器的存储带宽为 $s \times B$(由该机器上的所有引擎共享);$M$ 是每台机器的内存带宽。

每个 PE-DE 对的流量。我们假设存储读取带宽被充分利用,并且任务调度是负载均衡的。在负载均衡下,存储网卡带宽被均匀共享。对于 PE 读取路径(图 4a 中的所有步骤),每对的流量为 $T_p = Bs/(Pg^2)$;对于 DE 读取路径(图 4b),流量为 $T_c = Bs/(Dg^2)$。链路流量是所有使用该链路的对的流量总和。

PE CNIC 带宽分析。对于 PE CNIC,存在环回流量(即不经过交换机的 H2D 和 D2H),因此无论读写操作,PCIe 侧的总流量总是大于或等于交换机方向的流量。因此,我们只需要计算 PCIe 侧的压力。读取操作包括 PE 路径 (3) 和 (5),所有对的总流量为:

$$2 \times T_{p} \times Dg = 2Bs/g \le B$$


由于在实践中 $s \leq g$ 总是成立,因此读取方向总是无瓶颈的。写入操作包括 PE 路径 (4) 和 DE 路径 (5),总流量为:

$$(T_p + T_c) \times Dg = Bs/g \times (1 + D/P) \le B$$
然后,我们得到:
$$P/D \geq \frac{s}{g-s}$$

DE CNIC 带宽分析。对于 DE CNIC,读取操作包括 PE 路径 8 和 DE 路径 3/6,流量为:

$$(T_p + T_c \times 2) \times Pg = s/g \times (P/D + 2) \times B \leq B$$


然后,我们得到:

$$P/D \leq \frac{g-2s}{s}$$
写入操作包括 PE 路径 7/9 和 DE 路径 7,流量为:
$$(2T_{p}+T_{c})\times Pg \le B$$
这意味着:
$$P/D \leq \frac{g-s}{2s}$$

DRAM 压力分析。DRAM 是半双工的,所以我们对读写压力求和。对于 PE MEM,压力是 $2T_p$,通常不会超过内存带宽。对于 DE MEM,遵循类似的分析,我们可以得到压力是 $(3 + 2P/D)T_c$。要求 DE MEM 压力小于或等于 $M$,我们得到:

$$P/D \leq \frac{M/Bs-3}{2}$$

总结。结合以上所有分析,我们有:

$$\frac{s}{g-s} \leq P/D \leq \min \left\{ \frac{g-2s}{s}, \frac{g-s}{2s}, \frac{M/Bs-3}{2} \right\}.$$


对于 ($g=8, s=1$) 且 $M \approx 500$ GB/s 和 $B_s \approx 50$ GB/s 的情况,无瓶颈的范围是 $1 \leq P/D \leq 7$,这覆盖了大多数实际配置。

4.3 实践挑战

双路径架构从根本上重塑了数据移动方式:KV-Cache 可以直接从存储加载到预填充引擎,也可以间接地通过解码引擎加载,从而汇集了所有引擎的存储带宽,打破了预填充端的 I/O 瓶颈。然而,在一个实际系统中实现这一高层设计会引入三个相互关联的挑战。我们简要概述这些挑战,并请读者参阅相应章节获取详细信息。

细粒度数据传输 (§5)。分层执行范式虽然对于克服 HBM 容量限制至关重要,但它将 KV-Cache 分割成大量细粒度的块【【37,Splitwise: Efficient Generative LLM Inference Using Phase Splitting,ISCA 2025】】。在存储、主机 DRAM 和 GPU HBM 之间传输这众多细粒度数据块必须以最小的开销,并与计算无缝重叠,才能实现吞吐量的提升。

流量隔离 (§5)。DualPath 中复杂的数据路径在计算网络和 PCIe 链路上引入了额外的 KV-Cache 传输流量。一个主要担忧是,这种流量可能会干扰模型执行所必需的、对延迟敏感的现有集合通信操作——例如专家并行中的 AllToAll【【56,DeepEP: an efficient expert-parallel communication library,DeepSeek-AI 2025】】以及张量/上下文并行中的 ReduceScatter/AllGather。由于这些集合通信对端到端推理延迟至关重要,一个关键挑战在于如何在不降低模型推理性能的情况下利用空闲的 I/O 带宽。

动态负载均衡 (§6)。由于我们采用两种不同的路径进行 KV-Cache 加载,系统必须迅速决定每个请求使用哪条路径。一个简单的策略可能会使一条路径过载,重现原始的瓶颈。流量调度器必须实时平衡多个因素:存储网卡队列长度、GPU 上的计算负载以及请求的工作负载特征。

5 以 CNIC 为中心的流量管理器

现有数据传输技术的局限性。现代 LLM 推理系统采用一系列先进的数据传输技术——例如片上 CUDA 拷贝引擎和 GPUDirect Storage【【34,GPUDirect Storage Overview Guide,NVIDIA 2026】】——来高效地在存储、主机内存和 GPU HBM 之间移动数据。然而,所有这些机制都可能在模型执行期间干扰对延迟敏感的集合通信(例如,EP AllToAll)。这主要是由于两个原因:(1) 这类传输技术通常在不与计算网络共享相同 QoS 控制的独立路径上运行,以及 (2) 现有 GPU 不支持 PCIe QoS【【39,Resolving Performance Interference in SR-IOV Setups with PCIe Quality-of-Service Extensions,DSD 2016】】,这使得难以将模型推理通信与其他争用 PCIe 带宽的流量隔离开来。此外,由于集合通信以快速的、亚毫秒级的突发形式发生,依赖基于软件的流量整形器在这些高优先级流量窗口之间插入低优先级 I/O 操作是不切实际的。

CNIC-centric 方法。为了解决这个问题,我们提出了一种以 CNIC 为中心的数据传输方法,这在我们的生产部署中被广泛采用:所有进出 GPU 的数据流量,包括本地的 H2D/D2H 拷贝,都必须通过 GPU 配对的 CNIC 使用 GPUDirect RDMA【【33,Developing a Linux Kernel Module using GPUDirect RDMA,NVIDIA 2026】】数据路径。通过将所有流量整合到计算网络上,我们可以利用计算网络的原生 QoS 功能来实施严格的流量区分。

5.1 流量隔离

基于 InfiniBand 的实现。对于基于 InfiniBand 的网络,我们利用虚拟通道(Virtual Lanes, VLs)【【5,InfiniBand Architecture Specification Volume 1, Release 1.2.1,InfiniBand Trade Association 2007】】来强制隔离不同类别的流量。所有模型推理通信流量被分配到一个专用的高优先级 VL,而所有其他流量,包括 KV-Cache 传输,被映射到一个单独的低优先级 VL。我们将所有网络交换机和 NIC 的 VL 仲裁器配置为加权轮询策略,为高优先级 VL 保留大约 99% 的总带宽。剩余的带宽分配给低优先级 VL 以防止饥饿。这种配置确保了模型执行流量几乎不受 KV-Cache 传输的影响,同时仍允许 KV-Cache 流量机会性地利用计算网络中其他时候的空闲带宽。详细配置在 §A.1 中描述。

扩展到其他互联技术。尽管我们的实验是在基于 InfiniBand 的网络上进行的,但相同的设计原则自然可以扩展到其他互连技术。DualPath 可以在 RDMA over Converged Ethernet (RoCE) 上实现,通过利用流量类别(Traffic Class, TC)和差分服务代码点(Differentiated Services Code Point, DSCP)标记【【6,Differentiated services in the Internet,Proc. IEEE 2002】,【20,RDMA over Commodity Ethernet at Scale,SIGCOMM 2016】】结合硬件数据包队列。新兴技术如 UnifiedBus【【1,UnifiedBus,2026】】和 Ultra Ethernet【【9,Ultra Ethernet Specification v1.0.2,Ultra Ethernet Consortium 2026】】也正在趋向于为异构流量提供 QoS 机制,这些机制可以直接支持 DualPath 的要求。

5.2 CNIC 辅助的 KV-Cache 拷贝

现有方法的挑战。现有的 GPU 数据传输技术包括 GPUDirect Storage【【34,GPUDirect Storage Overview Guide,NVIDIA 2026】】,它将 KV-Cache 从存储后端加载到 GPU HBM,以及 CUDA 拷贝引擎,它通过 PCIe 直接将主机 DRAM 拷贝到 GPU。然而,这些方法无法将 KV-Cache 流量与模型执行中的高优先级、延迟敏感的集合通信隔离开来,从而严重降低了推理性能。

CNIC 辅助的数据路径。为了解决现有方法的局限性,我们采用了一种 CNIC 辅助的 H2D/D2H 数据路径。对于 KV-Cache 加载,我们首先将 KV-Cache 从存储后端读入主机 DRAM。然后,我们向 GPU 配对的 CNIC 提交一个 RDMA Write 请求,以执行本地 H2D 拷贝。存储新生成的 KV-Cache 遵循一个对称的过程:它首先通过 CNIC 传输到主机 DRAM,然后通过存储网络持久化到存储后端。这种设计将 CNIC 确立为所有 GPU PCIe 流量的中央 QoS 调度器,允许其 VL 仲裁器优先处理推理通信流量,并使用空闲的 PCIe 带宽执行 KV-Cache 传输。

性能优势。尽管这种方法与 GPUDirect Storage(直接将 KV-Cache 读到 GPU HBM)和 CUDA 拷贝引擎(直接将主机内存拷贝到 GPU HBM)相比似乎绕了路,但据我们所知,这是目前唯一能确保 KV-Cache 加载/存储不降低关键模型执行通信性能的实用方法。

小数据块传输的开销优势。我们还观察到,在处理大量小数据块时,CNIC 辅助的 H2D 和 D2H 性能优于 CUDA 拷贝引擎。我们的测量显示,通过 cudaMemcpyAsync 提交单个拷贝操作会产生约 5-7μs 的延迟开销。由于 CUDA 驱动程序的闭源特性,我们无法进一步分解此开销。相比之下,提交一个 RDMA Write 工作请求仅涉及在用户空间向 NIC 寄存器进行几次 mmio 写入,耗时仅约 1μs。此外,通过利用 doorbell batching【【25,Design guidelines for high performance RDMA systems,USENIX ATC 2016】】,RDMA 工作提交的开销可以被显著摊销。

6 自适应请求调度器

尽管我们的理论分析显示了有希望的结果,但不平衡的负载会降低硬件利用率,在这种情况下,我们需要同时考虑两个维度的平衡:(1) NIC 流量,和 (2) GPU 的利用率平衡。我们将调度分为两个级别:引擎间调度,它将请求分配给一个 (PE, DE) 对,并为每个请求选择读取路径(PE 或 DE);以及引擎内调度,它决定每个前向批次中包含哪些请求进行计算。

6.1 引擎间调度

引擎分组与负载信息。我们将引擎组织成组以减少调度器的压力。只有引擎 rank 0,称为领导引擎(Leader Engine),与调度器交互。一个组中的所有引擎要么全是 PE,要么全是 DE。同一节点上的所有引擎保证在同一个组内。一个组中的所有引擎会定期主动地一起获取任务。在获取新请求时,每个引擎 $e$ 报告 (1) $n_e$,分配给它但尚未完成的请求数量;(2) 这些 $n_e$ 个请求的总 token 数 $tok_e$;以及 (3) 引擎 $e$ 所属节点 $n(e)$ 的磁盘读取队列长度 $disk_q_{n(e)}$。GPU 负载、磁盘读取负载和网络负载都与 token 数量强相关。因此,我们使用 token 数量作为代理,并旨在平衡各个引擎的 token 数量。


图 5: 引擎间 PE 调度示意图。所有八个 GPU 都在同一个 PE 引擎组中,调度器将选择最佳的一个。

PE 调度算法。所有到达调度器的请求进入一个等待队列,并按 FIFO 顺序调度。当一个 PE 组发起获取请求时,调度算法被调用。引擎间调度过程的示意图如图 5 所示。我们定义两个常数,短读取队列阈值 $\alpha$,和未完成 token 上限 $\beta$,以 token 为单位。所有引擎被分为三类:(1) 过载引擎,其中 $tok_e > \beta$;(2) 位于磁盘读取队列较短的节点上的引擎,其中 $disk_q_{n(e)} \leq \alpha$ 且 $tok_e \leq \beta$;以及 (3) 位于磁盘读取队列较长的节点上的引擎,其中 $disk_q_{n(e)} > \alpha$ 且 $tok_e \leq \beta$。我们不向过载引擎分配新请求。第二类引擎优先于第三类引擎,因为它们所在的节点磁盘读取队列较短,缺乏后续请求容易导致存储网卡利用率不足。

PE 分配逻辑。我们把当前请求分配给第二类中 $tok_e$ 最小的 PE(如果非空),否则分配给第三类中 $tok_e$ 最小的 PE(如果非空)。分配后,我们更新所选 PE 的 $tok_e$,然后处理等待队列中的下一个请求。如果两类都为空,我们终止此次获取请求,并将已分配的请求返回给领导引擎。

Data: Waiting queue Q, PE group G_PE, load metrics (disk_q_n(e), tok_e) reported by each engine e, where n(e) denotes the node that engine e belongs to, constants α and β
Result: Assigned requests to PEs
Each engine e reports (disk_q_n(e), tok_e);
Classify all PEs into three categories:;
C1 ← {e ∈ G_PE : tok_e > β};
C2 ← {e ∈ G_PE : disk_q_n(e) ≤ α ∧ tok_e ≤ β};
C3 ← {e ∈ G_PE : disk_q_n(e) > α ∧ tok_e ≤ β};
while Q is not empty do
    r ← head of Q;
    if C2 ≠ ∅ then
        pe* ← arg min_{e∈C2} tok_e;
    else if C3 ≠ ∅ then
        pe* ← arg min_{e∈C3} tok_e;
    else
        Terminate this fetch request;
        Return assigned requests to Leader Engine;
        break;
    end
    Assign request r to PE pe*;
    Update tok_{pe*} ← tok_{pe*} + tokens(r);
    Remove r from Q;
end

DE 调度阶段 1:跨组调度。DE 调度是两级的,不保证全局 FIFO。有一个全局等待队列和每个 DE 引擎组一个私有队列。进入的请求首先进入全局队列。当一个 DE 组获取任务时,组级调度会清空全局队列,并将每个请求分配给其总 $tok_e$(组内所有引擎之和)最小的组;这可以平衡各组间的 token 数量,从而平衡 NIC 和 GPU 负载。

DE 调度阶段 2:组内调度。然后,我们计算组内所有 DE 的剩余 HBM 总和,并从私有队列的头部开始遍历,计算在不考虑 HBM 碎片的情况下可以调度多少个请求。这些请求构成集合 $S$。这是一个可以调度的上限。然后,我们计算一个高 token 阈值 $H = 1.05 \times (\sum_{r \in S} \text{tokens}(r) + \sum_{e \in G} \text{tok}_e) / |G|$。

DE 分配逻辑。接下来,我们尝试弹出私有队列的头部并将其调度到一个 DE。在有足够剩余 HBM 的 DE 中,我们将它们分为 (1) 高 token DE,其中 $tok_e + \text{len}(r) > H$,和 (2)其余的 DE。我们优先选择类别 (2) 以保持 token 数量平衡;类别 (1) 的 DE 已经有较高的 GPU 和 NIC 压力。在类别 (2) 中,我们选择 $n_e$ 最小的 DE 来平衡请求数量;如果类别 (2) 为空,我们选择类别 (1) 中 $tok_e$ 最小的 DE,以减少 HBM 耗尽和抢占风险。如果没有 DE 有足够的 HBM,获取结束,已分配的请求被返回。

KV-Cache 读取任务调度。在为请求选择了 PE 和 DE 之后,我们选择在读取队列较短的一侧进行读取。将请求分成两部分并从两侧同时读取可能更好,我们将其作为未来工作。

6.2 引擎内调度

调度需求。只有 PE 需要引擎内调度,因为 DE 总是将所有请求放入前向批次。引擎内调度过程的示意图如图 6 所示。数据并行在注意力层中被广泛采用,尤其是在 MLA 模型中。在这种并行配置下,每个 GPU 服务于一组不同的请求。这可能导致所有 GPU 之间的工作负载不平衡,它们必须在注意力阶段后同步,然后一起进入 FFN 阶段,导致 GPU 因等待其他对等方而产生空闲(bubbles)。因此,我们需要确保它们有相似的注意力层执行时间,以最小化等待空闲。


图 6: 引擎内调度。左:基于计算配额的批次选择。右:应用计算配额前后的 GPU 时间线。

层时间估计。我们使用 FIFO 打包来决定一个前向批次中包含多少个请求。前向批次中的每个请求由一对 $(hit_{len}, miss)$ 描述,其中 $hit_{len}$ 是已有 KV-Cache 的 token 数量(来自存储命中或之前的前向传播),而 $miss$ 是该前向批次中需要计算 KV-Cache 的 token 数量。根据这些对,我们计算注意力层的总理论计算量并估计其执行时间。理论计算量与实际时间之间的关系取决于硬件和并行配置,可以通过预先的性能剖析来拟合,如先前工作【【17,PrefillOnly: An Inference Engine for Prefill-only Workloads in Large Language Model Applications,SOSP 2025】】和【【2,Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve,OSDI 2024】】所示。

算法。我们按 FIFO 顺序不断添加请求,只要预测的注意力层执行时间不超过预定义的上限,即计算配额(compute quota)。如果添加一个请求会超过此上限,我们对该请求的 $miss$ 进行二分搜索,找到一个较小的 $miss'$ 以适应剩余的计算配额,并对该请求执行分块预填充(chunked prefill)。

A4 实验环境

7.1 实现

我们基于自研的推理框架实现了 DualPath。对于 CUDA 核,我们的自研框架采用了 FlashMLA【【27,FlashMLA: Efficient Multi-head Latent Attention Kernels,Jiashi Li and Shengyu Liu 2025】】、DeepGEMM【【14,DeepGEMM,DeepSeek-AI 2025】】和 DeepEP【【56,DeepEP: an efficient expert-parallel communication library,DeepSeek-AI 2025】】的组合,这与当前主流的开源框架【【26,Efficient Memory Management for Large Language Model Serving with PagedAttention,SOSP 2023】,【57,SGLang: Efficient Execution of Structured Language Model Programs,NeurIPS 2024】】保持一致。DualPath 的实现涉及在其基础上约 5000 行代码的修改。我们采用 3FS【【13,3FS,DeepSeek-AI 2025】】作为分布式存储,并使用类似 io_uring 的接口进行内核旁路。

7.2 实验设置

  • 硬件配置 (Testbed):

    • GPU: 集群由多个 GPU 服务器组成,每个服务器配备 8 个 NVIDIA Hopper GPU 和双处理器。
    • 网络: 节点间通过 InfiniBand 互连。每个节点配备八个 400Gbps RDMA 网卡连接到 InfiniBand 计算网络,以及一个额外的存储网卡连接到 3FS。计算和存储网络物理隔离。
    • 存储: 集群范围的 3FS 没有内部 DRAM 缓存,可以饱和存储网卡的 400Gbps 带宽。
  • 模型架构:

    • DS 660B: DeepSeek V3.2【【16,DeepSeek-V3.2: Pushing the Frontier of Open Large Language Models,DeepSeek-AI 2025】】 660B,一个采用 DeepSeek 稀疏注意力的 MoE 模型。
    • DS 27B: DS 660B 的一个 27B 缩小版模型。
    • Qwen 32B: Qwen2.5-32B【【42,Qwen2.5 Technical Report,Qwen Team 2025】】,一个采用 GQA 的稠密模型。
  • 数据集:

    • 我们从生产环境的代理式 RL 训练工作负载中收集了三个代理轨迹数据集,具有不同的最大上下文长度(MaxLen)。
    • 每个数据集包含 500 个轨迹。
    • 具体统计数据见表 2。

    表 2: 代理轨迹数据集的统计信息。

  • 软件配置与基线:

    • 我们的方案 (Ours): DualPath。
    • 基线 SGL(MC): SGLang【【57,SGLang: Efficient Execution of Structured Language Model Programs,NeurIPS 2024】】 (commit 19089aa),启用了 HiCache【【40,SGLang HiCache,SGLang 2026】】 和 Mooncake【【38,Mooncake: Trading More Storage for Less Computation — A KVCache-centric Architecture for Serving LLM Chatbot,FAST 2025】】 存储,使用 3FS 作为存储后端,并使用 Mooncake 传输引擎进行 PD 分离。
    • 基线 Basic: 我们未修改的内部推理框架(详见 §7.1)。
    • 基线 Oracle: 基于 DualPath,旁路了所有磁盘读取、D2H & H2D 传输以及 PD 间的 KV-Cache 传输,代表理论性能上限。
    • 并行策略: DS 660B 默认 2P4D(2 个预填充节点,4 个解码节点),DS 模型使用 EP 和 DP。Qwen 32B 默认 1P2D,仅使用 DP。DS 27B 默认 1P1D。SGL(MC) 对 Qwen 32B 使用 TP=8。

A4 实验结果

7.3 离线批量推理

本节评估离线批量推理的吞吐性能,这对应于 RL 训练中的 rollout 阶段。场景是 $N$ 个 agent 同时开始 rollout,我们测量所有请求完成时的作业完成时间(JCT)。

  • 不同 Agent 批次大小和最大 Agent 长度 (MAL) 的影响:

    • 实验内容: 在不同 Agent 批次大小和 MAL 下测试 JCT。
    • 实验结果 (图 7): DualPath 从更大的批次大小和更长的 MAL 中获益更多。在 DS 660B 上,DualPath 相较于 Basic 实现了高达 1.87 倍的性能提升,且性能接近 Oracle,表明 KV-Cache I/O 瓶颈基本被消除。在 DS 27B 上,DualPath 相较于 Basic 提升高达 1.78 倍,但仍比 Oracle 慢 1.09-1.85 倍,这是因为 1P1D 配置下存储带宽有限(图 8)。Qwen 32B 的趋势与 DS 27B 类似。SGL(MC) 在某些大型配置下出错。


    图 7: 不同 agent 数量和最大 agent 上下文长度下的离线推理性能。上:DS 27B。中:DS 660B。下:Qwen 32B。N/A 表示在完成前遇到错误。

  • 不同追加长度和生成长度的影响:

    • 实验内容: 分别缩放每轮的追加长度和生成长度,测试 JCT。
    • 实验结果 (图 9): 当追加长度或生成长度变短时,DualPath 的优势更明显。随着追加长度增加,GPU 计算压力变大,Basic 的性能逐渐接近 DualPath 和 Oracle。在不同追加长度下,DualPath 相较于 Basic 实现了 1.82-1.99 倍的加速。生成长度的趋势类似。


    图 9: 左:不同追加长度(DS 660B,64K 上下文,1024 个 agent)。右:不同生成长度(DS 660B,64K,1024 个 agent)。

  • 不同预填充-解码比率的影响:

    • 实验内容: 在 DS 27B 上使用 1P1D, 2P1D, 1P2D 的 P/D 比率进行 rollout 实验。
    • 实验结果 (图 8): 在所有比率下,DualPath 都比 Basic 有显著性能提升,平均加速 1.64 倍(最高 2.46 倍)。Basic 1P1D 与 Basic 1P2D 性能相当,DualPath 1P1D 与 Basic 2P1D 性能相当,DualPath 2P1D 与 DualPath 1P2D 性能相当。这是因为每对系统的可用存储带宽相等(Basic 只能用 PE 节点的存储带宽,DualPath 能用所有节点的),这证实了存储带宽是代理式场景下的主要瓶颈。


    图 8: 预填充-解码比率对离线推理性能的影响(DS 27B)。

7.4 在线服务

  • 方法论: 我们评估不同 Agent 到达率(APS)下的系统延迟特性。Agent 到达遵循泊松过程。SLO 设定为 TTFT ≤ 4 秒,TPOT ≤ 50ms。
  • 实验结果 (图 10): DualPath 实现了比 Basic 更高的 APS 容量(DS 27B 为 1.67 倍,DS 660B 为 2.25 倍)。DualPath 的 TTST 与 Basic 相当,而 TPOT 表明 DualPath 没有引入额外的解码开销。SGL(MC) 的 TTST 异常低,可能是实现问题。对于 DS 27B,Basic 和 DualPath 的 TPOT 都显著高于 Oracle,表明在小模型情况下基础的 P-D 传输开销相当可观。
  • 平均 JCT (图 11): 展示了两个模型的平均 JCT 随到达率的变化。
  • TTFT 分解 (图 12 左): DualPath 在不同 APS 下保持稳定的 TTFT 各项耗时,而 Basic 的排队时间由于存储带宽不足而急剧增加。


图 10: TTFT、TTST 和 TPOT 作为 agent 到达率(APS)的函数。阴影表示实验结束前最后 150 秒的波动。上:DS 27B,下:DS 660B。


图 11: 所有轨迹的平均完成时间与在线服务到达率的关系。

7.5 消融研究

  • 实验内容: 在离线推理设置下(64K MAL,1024 和 2048 Agent),逐步添加分层预填充、双路径加载和调度算法,以量化每个技术组件的贡献。
  • 实验结果 (图 12 右):
    • 与 Basic 相比,添加分层预填充平均减少 JCT 17.21%,缓解了 PE HBM 瓶颈并隐藏了传输开销。
    • 在分层预填充基础上添加双路径加载带来了主要的性能提升,与 Basic 相比平均减少 JCT 38.19%,因为它充分利用了分布式存储带宽。
    • 最后,在双路径加载基础上使用我们的调度算法来决定 KV-Cache 加载路径,获得了最佳性能,与 Basic 相比平均减少 JCT 45.62%,证明了跨存储网卡进行负载均衡调度的有效性。


图 12: 左 (§7.4): 在线服务(DS 660B)在不同 APS 下的 TTFT 分解。Sch. 表示调度,A. 表示分配,R. 表示读取 KV-cache,PF. 表示预填充。每对柱子中,第一个是 DualPath,第二个是 Basic。右 (§7.5): 离线推理消融研究结果(DS 660B,64K 上下文长度)。Layer, DPL, Sched 分别代表分层预填充、DualPath 加载和调度。

  • 负载均衡分析:
    • 存储网卡 (图 13): 我们的调度算法将存储网卡流量的最大/平均比率从轮询调度的 1.53 改善到 1.18,实现了更好的负载均衡。
    • 注意力层 (图 14): DualPath 在任务的前 5% 期间将注意力执行时间的最大/平均比率维持在低至 1.06,减少了 GPU 空闲气泡。


图 13: 存储网卡流量的负载均衡情况。


图 14: 注意力执行时间的负载均衡情况。

7.6 大规模可扩展性

  • 实验内容: 使用多达 1,152 个 GPU 进行离线和在线实验。
  • 实验结果 (表 3 和图 15):
    • 离线推理: 从 2P4D(2K agents)扩展到 48P96D(48K agents),实现了接近线性的加速,JCT 相当(3,167s vs. 3,201s)。
    • 在线服务: 44P88D 配置实现了 22 倍的吞吐量(8.8 vs. 0.4 APS),同时保持了相似的延迟。
    • 调度器开销: 在所有实验中,调度器 CPU 使用率保持在 10 核以下,证实其不是瓶颈。
    • 大规模部署的价值: 尽管没有实现额外的 JCT 或服务容量增益,但大规模部署仍然重要,因为它减少了碎片化,为微调并行度和 P/D 比率提供了更大的灵活性,并为缓解突发在线请求下的排队延迟提供了更多调度机会。

表 3: 大规模实验结果。


图 15: 48P96D 离线推理指标。1e7 是 Prompt TPS 的缩放因子。

A7 补充细节

8.1 潜在的未来工作

动态工作负载的适应性。离线推理的工作负载是高度动态的。例如,在我们的代理式 RL 任务中,工作负载在很大程度上取决于研究人员的算法设计,并且预填充阶段的压力在执行的前半部分通常远高于后半部分。同时,对这些试验性实验进行性能分析的成本很高,因为一些实验只运行有限的次数。因此,需要更具适应性和灵活性的并行度和 P/D 比率配置方法,例如模拟器或在线调整机制。

调度算法的改进。调度算法仍有改进空间,因为我们期望在大规模部署下实现更低的 TTFT 百分位数。

8.2 工作集分析

工作集大小估算。如图 11 所示,给定一个到达率 $\lambda$(即每秒新轨迹数)和平均 JCT $\bar{JCT}$,KV-Cache 的工作集可以近似为 $\lambda \bar{JCT} \times \text{Size}_{\text{context}}/2$。在我们对 DS 660B 服务的设置中,DualPath 的这个值从 APS 0.1 时的 69 GB 到 APS 0.45 时的 681 GB 不等。

现实世界中的挑战。在现实环境中,工作集会更大,因为我们的评估假设到达间隔时间和工具调用延迟为零。如果由于这些间隙导致 JCT 增加了 $k$ 倍,系统的 APS 容量会增加 $k$ 倍(因为间隙不给 LLM 推理带来压力),导致工作集扩大 $k^2$ 倍。这将超过可用内存,并降低分布式内存池的命中率。此类实验需要 $k$ 倍的机器小时数和 $k^2$ 倍的存储空间(成本按 $k^3$ 比例扩大),我们在有限的资源下无法承担。

A5 结论

本文介绍了 DualPath,一个针对代理式 LLM 推理的框架,它通过双路径 KV-Cache 加载解决了 PD 分离架构下 KV-Cache 读取不平衡的问题。通过采用工作负载感知的调度策略重新分配存储网络负载,DualPath 在离线推理中实现了高达 1.87 倍的吞吐量提升。在在线服务场景中,它也平均将每秒处理的 agent 运行次数提高了 1.96 倍。

A6 附录

A.1 流量隔离配置细节

InfiniBand 配置。InfiniBand QoS 机制使用高、低两个优先级仲裁器。流量在高优先级仲裁器中使用加权轮询(WRR)进行调度,然后根据 qos_high_limit 导向低优先级仲裁器;将其设置为 255 可完全禁用低优先级仲裁器。详细调度算法可在【【5,InfiniBand Architecture Specification Volume 1, Release 1.2.1,InfiniBand Trade Association 2007】】中找到。我们的配置如下:

  • qos_max_vls 4
  • qos_high_limit 240
  • qos_vlarb_high 0:192,1:192,2:0,3:192
  • qos_vlarb_low 0:192,1:192,2:64,3:192

RoCE 配置。RoCE 通过基于 DSCP 的流量分类和硬件流量类别(TC)来实施 QoS。数据包首先从 DSCP 值映射到 TC,每个 TC 都有一个专用的硬件队列(通常最多八个)。为匹配 InfiniBand 中的四个 VL 配置,我们配置了四个启用了优先级流控制(PFC)的无损 RDMA TC。通过在 NIC 和交换机上为这些 TC 分配成比例的调度权重来实现带宽隔离,为模型推理流量保留大部分带宽,同时为 KV-Cache 流量分配一小部分以防止饥饿。

A.2 27B 模型规格

模型规模参数。隐藏维度为 2560,稠密层的中间大小为 12288,隐藏层数为 30,注意力头数为 32,路由专家数为 72,MoE 中间大小为 1536,每个 token 激活的专家数为 6,共享专家数为 2,初始稠密层数为 1。

索引注意力机制参数。注意力头数为 32,头维度为 64,稀疏注意力的 topk token 数为 1024。索引器和主注意力的 Q 矩阵的 LoRA 压缩被移除。

A.3 Agent 任务结构

任务描述。为了提供数据集特征的背景,我们简要描述了 agent 的任务结构,尽管这个背景与我们的系统设计是正交的。每个 agent 在一个沙箱环境中操作,该环境包含一个带有已知 bug 和相关错误信息的代码仓库。Agent 通过 prompt 被指示诊断并修复 bug。模型具备工具使用能力,通过发出结构化输出来调用沙箱中的 bash 命令。Agent 和环境进行多轮交互,每一轮都包含一个 prompt(先前的上下文与新信息拼接而成,其中大部分是工具输出)和模型通过解码生成后续的工具调用。

轨迹生成与回放。每个轨迹是一个轮次序列;第 $i$ 轮由追加的 token $a_i$ 和生成的 token 数量 $g_i$ 组成。我们用 $G_i$ 表示在第 $i$ 轮中生成的 token,这些 token 不在我们的数据集中。我们定义 $Context_{i+1}$ 为 $a_1, G_1, a_2, G_2, ..., a_i, G_i$ 的拼接列表。在我们回放的第 $i+1$ 轮中,agent 将 prompt 拼接为 $Context_{i+1} + a_{i+1}$,然后设置适当的采样参数以确保它精确生成 $g_{i+1}$ 个 token,即 $G_{i+1}$。为了生成额外的 agent 轨迹,我们采样一个现有轨迹,并在其前面添加一个带有随机 token 作为 $a_1$ 且 $g_1 = 1$ 的合成轮次。

A.4 实验配置

配置参数。对于 DeepSeek 模型,DualPath 在每个节点上分配 80GB DRAM,而 SGL(MC) 在每个节点上总共使用 1.5TB DRAM。对于 Qwen 32B,由于 KV-Cache 较大,DualPath 分配 320GB。所有设置都禁用了推测解码。所有配置均使用 3FS 作为存储后端。短读取队列阈值 $\alpha$(在 §6 中描述)被设置为我们在 3 秒内可以读取的 token 数量,未完成 token 上限 $\beta$ 被设置为一个 GPU 在 5 秒内可以处理的 token 数量。这些值是预先分析得出的。所有 DualPath 和 Oracle 基线的计算配额阈值都设置为 300ms。

KV-Cache 命中长度计算。对于除 SGL(MC) 之外的所有系统,我们将 KV-Cache 命中限制为仅在轨迹内部发生,并且命中长度在客户端计算,因为不需要驱逐。对于 SGL(MC),命中长度是根据 HiCache 和 Mooncake Store 的缓存状态在内部计算的。

A.5 KV-Cache 块布局

设计挑战与方案。分层预填充将 KV-Cache 块大小减小到原始大小的 $1/N_{layers}$,并使块的数量增加到 $N_{layers} \times$,这对传输和存储性能构成了挑战。为了克服这一点,我们设计了两种不同的块类型:层块(Layer Block)和全块(Full Block)。

块结构。一个层块是一个形状为 [1, num_tokens, bytes_per_layer] 的字节张量,用于存储一些 token 的单层 KV-Cache。token 的数量称为 block_sizebytes_per_layer 表示每层每个 token 所需的缓存字节数。同时,一个全块的形状为 [num_layers, num_tokens, bytes_per_layer]。这种设计使我们能够通过简单地将 $L$ 个层块拼接成一个全块,从而在整个推理过程中避免手动的 KV-Cache 内存布局转换。KV-Cache 使用 trie 结构存储在分布式存储中,其中每个树节点对应一个全块。