AWS Machine Learning Blog · 2026/10/20 00:03:23

vLLM 引入双向 KV 传输 优化多轮智能体首字延迟

出处作者 / 发布主体:Sunita Nadampalli原标题:Improve TTFT for multi-turn agentic workloads with bi-directional KV transfer in vLLM
78AI 研判分
核心综述

vLLM 在 Prefill-Decode 分离架构中引入双向 KV Cache 传输机制,允许 Decode 节点将生成的 Token KV 状态回传至 Prefill 节点。此举消除了多轮对话中重复计算历史响应的开销,显著降低智能体工作负载的首字延迟(TTFT)。

报道全文原始报道全文

本文目录11 个章节

多轮智能体工作负载依赖于不断累积的上下文,因为智能体在推理、调用工具并整合早期结果的过程中需要这些信息。随着每一轮新对话的产生,客户端会重新发送整个对话历史,包括系统指令、先前的提示词、工具执行结果以及模型响应,导致不断增长的上下文被反复处理。在 Prefill-decode (P-D) 分离架构中,每个请求被拆分到专门的节点上:Prefill(预填充)节点负责处理提示词并构建其键值(KV)缓存,随后 Decode(解码)节点获取这些 KV 块并生成响应。

然而,传统的分离式服务仅支持单向传输 KV 缓存:即从 Prefill 节点流向 Decode 节点。这种单向流动为多轮工作负载带来了两种低效问题。首先,在生成响应后,Decode 节点持有包含提示词和新生成 token 的 KV 缓存条目。当处理下一轮对话时,Prefill 节点无法检索这些条目,因此必须重新计算先前响应 token 的 KV 投影。其次,Decode 节点维护会话状态,而 Prefill 节点不维护,这增加了 Prefill 节点上活跃会话缓存被驱逐的概率。在完全缓存未命中的情况下,Prefill 节点必须重新计算整个对话历史的 KV 投影,包括系统指令、先前的用户请求、工具执行结果以及模型生成的响应。随着对话长度的增加,这种冗余工作消耗了更多的加速器算力,并增加了首 token 延迟(TTFT)。

在构建对话助手和智能体应用程序时,更长的交互历史可能会因重复的 Prefill 计算而导致延迟增加并消耗加速器算力。在本文中,我们将展示 双向 KV 缓存传输 如何让 Prefill 和 Decode 节点跨轮次复用之前计算的上下文,从而提高加速器利用率,并帮助应用程序在对话增长时保持灵敏的 TTFT。

在基于 Amazon Elastic Compute Cloud (Amazon EC2) P5en 实例的 1P1D(1 Prefill + 1 Decode)部署的多轮对话基准测试中,双向 KV 传输使 Qwen3-32B 的首 Token 延迟(TTFT)降低了最高 1.6 倍,使 zai-org/GLM-5-FP8 降低了最高 3.3 倍(详见“性能数据”部分)。具体结果会随工作负载和配置的不同而变化。这些实例通过 AWS Elastic Fabric Adapter (AWS EFA) 连接,这是一种低延迟的远程直接内存访问 (RDMA) 网络,用于 AWS 服务器之间的通信。在受支持的实例类型上,AWS EFA 支持 GPUDirect RDMA 和 Neuron Direct RDMA,从而可以在预填充(prefill)节点和解码(decode)节点之间直接在 GPU 或 AWS Trainium 设备内存中移动 KV 块。

我们最初在通过 EFA 连接的 AWS Trainium 实例集群上构建并验证了该功能,并将其作为加速器无关的能力贡献给了 vLLM。本文展示的结果来自配备 EFA 的 Amazon EC2 P5en GPU 集群,表明该优势同样适用于 GPU。本文将解释双向 KV 传输架构、路由器元数据流、KV 块保留与重算控制机制、性能结果以及如何复现基准测试。

双向 KV 传输

双向 KV 传输是一种机制,允许解码节点在对话的后续轮次中将先前计算好的 KV 返回给预填充节点。这避免了在预填充节点上重新计算共享上下文,并由可配置的 KV 重算阈值进行控制。它缓解了前文所述的两种计算冗余场景。为了实现这一功能,KV 必须在产生它的轮次之后继续存活,并以反向方向传输,由一个感知 KV 缓存的路由器进行协调。

NIXL KV 连接器针对双向传输的增强

我们将 NVIDIA Inference Xfer Library (NIXL) 的 KV connector 进行了扩展,使 Prefill 节点能够消费远程 KV 块,这与 Decode 节点已经能够消费由 Prefill 节点提供的 KV 块的机制类似。这一改动并非易事,因为这两类节点在架构上存在差异:Prefill 节点负责计算新 Prompt Token 的 KV 表示,并可提供完整的 Prompt KV 块;而 Decode 节点缺乏生成完整 KV 表示的能力(或效率),只能提供此前已缓存的 KV 块。因此,Prefill 和 Decode 节点仍各自保留其角色及用于计算远程和本地 KV 块元数据的逻辑。然而,实际的 KV 传输机制(即 NIXL READ)在 P->D 和 D->P 两个方向上是通用的。

下图首先以蓝色展示了现有的流程:Router 将请求发送给 Prefill 节点,Prefill 节点计算 Prompt KV 并返回其块元数据,随后 Router 将请求和元数据转发给 Decode 节点,执行标准的 P→D NIXL READ。图中编号为红色的路径展示了双向 KV 传输的新增功能:(1) Decode 节点在生成结束后保留符合条件的 KV 块,(2) 在流式响应中返回这些块的元数据,以及 (3) Router 缓存该元数据以供下一次 Prefill 请求使用。接着,Prefill 节点会 (4) 在应用本地缓存匹配后检查可复用的远程 KV,(5) 当可复用 Token 数量达到阈值时发起异步接收队列,以及 (6) 在计算剩余后缀之前执行 D→P NIXL READ。

Flow diagram contrasting the standard prefill-to-decode KV path (blue) with the bi-directional additions numbered one through six (red)

图 1:标准 Prefill-to-Decode 流程(蓝色)与双向 KV 传输新增功能(红色)

KV-Cache-Aware Router

vLLM 在 Connector 端提供了对双向 KV 传输的支持,但要在多轮对话中协调 KV 复用,则需要一个具备 KV-Cache 感知能力的 Router。vLLM GitHub 提供了一个 示例代理,实现了本文所述的流程,可根据你的环境进行适配。

KV 缓存感知路由器是一个轻量级、有状态的控制平面组件,位于客户端、预填充(prefill)节点和解码(decode)节点之间。它维护一个内存映射,将客户端提供的 conversation_id 与解码节点的 kv_transfer_params 关联起来。路由器仅存储块位置元数据,而不存储 KV 张量本身,并且这些元数据是从响应流中获取的,无需单独查询解码节点。

下图展示了路由器如何在多轮对话中管理 KV 元数据。在第一轮对话中,缓存查找未命中,请求遵循标准的 P→D 流程。随后,路由器从响应流中保存解码节点的元数据。在后续轮次中,路由器使用 conversation_id 检索该元数据,以便预填充节点能够复用来自解码节点的 KV 缓存。生成完成后,路由器会刷新元数据以供下一轮使用。

跨轮次的 KV 缓存感知路由器元数据流

图 2:跨对话轮次的 KV 缓存感知路由器元数据流

块保留 TTL

通常,解码实例会在生成结束后立即释放请求所占用的块。但在双向 KV 传输模式下,它会以可配置的生命周期(decoder_kv_blocks_ttl,默认为 480 秒)保留这些块,并发布其位置和过期时间。这样,对话的 KV 缓存(包括提示前缀和生成的响应)将在下一轮对话中保持可用。如果在 TTL 到期之前到达新一轮对话,预填充节点将复用 KV 缓存;如果晚于 TTL 到期,则回退到正常的预填充流程。由于此 TTL 是固定的且不会续期,因此需要根据预期的轮次间隔时间来调整该值,以平衡 KV 复用率与加速器内存占用。一个自然的下一步改进是将心跳续租机制扩展到解码端。这样一来,当对话空闲时,解码实例可以立即回收块,而不是等待固定计时器结束。

KV 重算阈值

KV 复用并不总是比本地重算更快。对于较短的可复用前缀,互连和协调开销可能会超过重新计算这些 token 所需的时间。kv_recompute_threshold 设置(默认为 64 个 token)控制着这一决策。当需要计算的 token 数量低于该阈值时,Prefill 节点会进行重算;当达到或超过该阈值时,则从 Decode 节点拉取 KV 缓存。部署可以根据模型计算时间、KV 大小以及互连性能来调整此值。

性能数据

在评估中,我们在采用 EFA 连接的 Amazon EC2 P5en 实例上,使用 Qwen3-32B 和 GLM-5-FP8 模型进行了 1P1D 部署测试。为了模拟 Prefill 节点已驱逐其本地缓存,或者路由器选择了没有该对话 KV 块的不同 Prefill 节点的场景,我们在 Prefill 节点上通过 --no-enable-prefix-caching 禁用了前缀缓存。

在这两个模型上,开启双向 KV 传输均减少了多轮对话中的 Prefill 计算量,且随着提示词长度的增加,收益通常也会扩大。如果关闭该功能,Prefill 实例每轮都会重新计算整个增长后的上下文,导致 TTFT(首 Token 延迟)急剧上升。Qwen3-32B 的 TTFT 从 2k 长度时的 158 ms 上升至 24k 长度时的 778 ms,而 GLM-5-FP8 则从 2k 长度时的 500 ms 上升至 20k 长度时的 2,334 ms。开启该功能后,Decode 实例保留的 KV 会被复用而非重新计算,从而使 TTFT 保持相对平稳。在相同范围内,Qwen3-32B 仅从 122 ms 上升至 460 ms(在最长提示词下约有 1.6 倍的降低),而 GLM-5-FP8 从 358 ms 上升至 702 ms,在长提示词下比纯重算路径快多达 3.3 倍。Prefill 耗时分解揭示了其中的原因。

双向传输增加了少量的 KV 传输时间(Qwen3-32B 约为 30 ms 至 130 ms;GLM-5-FP8 约为 29 ms 至 110 ms),但它所节省的 Prefill 计算时间远远超过了这部分 KV 传输开销。因此,开启传输后的总 Prefill 持续时间(Qwen3-32B:128 ms 至 414 ms;GLM-5-FP8:316 ms 至 541 ms)始终显著低于纯重算路径(Qwen3-32B:153 ms 至 744 ms;GLM-5-FP8:500 ms 至 2,331 ms)。更大的 GLM-5-FP8 模型显示出更大绝对值和相对差距,因为其较高的单 token 重算时间使得随着模型规模和上下文的扩展,KV 复用的收益更加显著。

Qwen3-32B

下图绘制了 Qwen3-32B 的 TTFT 随提示词长度变化的曲线,对比了双向 KV 传输开启与关闭的情况。

Qwen3-32B 启用和禁用双向 KV 传输时,首 Token 延迟(TTFT)与提示词长度的折线图

图 3:Qwen3-32B 在启用和禁用双向 KV 传输时的 TTFT 与提示词长度对比

下一张图表将相同运行条件下的预填充(prefill)耗时分解为重计算(recompute)和 KV 传输两个组成部分。

Qwen3-32B 预填充耗时分解为重计算和 KV 传输组件的柱状图

图 4:Qwen3-32B 预填充耗时分解为重计算和 KV 传输组件

综合这两张图表可以看出,当该功能开启(ON)时,TTFT 几乎保持平稳;而当功能关闭(OFF)时,随着上下文增长,TTFT 急剧上升。这是因为少量的 KV 传输时间远小于其消除的重计算开销。

zai-org/GLM-5-FP8

GLM-5-FP8 也展示了相同的两种视图。第一张图绘制了该功能开启与关闭时,TTFT 随提示词长度变化的曲线。

zai-org/GLM-5-FP8 启用和禁用 KV 复用时的 TTFT

图 5:zai-org/GLM-5-FP8 启用和禁用 KV 复用时的 TTFT

第二张图将预填充耗时分解为重计算和 KV 传输组件。

zai-org/GLM-5-FP8 预填充耗时分解

图 6:zai-org/GLM-5-FP8 预填充耗时分解

与 Qwen3-32B 相比,GLM-5-FP8 显示出更大的差距,在长提示词下 TTFT 降低高达约 3.3 倍。这是由于其每 token 的重计算时间更高,使得随着上下文长度增加,KV 复用的收益更加显著。

如何运行基准测试

要复现我们的 1P1D 基准测试配置(即一个预填充节点和一个解码节点,使用配备 EFA 的 Amazon EC2 P5en 实例),请按照 Reproducing our results guide 中的分步说明进行操作。该指南涵盖了环境设置、启动 vLLM 预填充和解码服务器、运行基准测试以及收集结果等内容。此功能可以在其他受支持的配置上运行,但性能结果会因硬件、模型、工作负载和网络配置的不同而有所差异。

结论

在本文中,我们展示了双向 KV Cache 传输如何在智能体对话历史增长时降低 TTFT(首 Token 延迟)。在 P-D 分离式部署中,该功能允许预填充节点复用解码节点在多轮对话间保留的 KV 块,从而减少重复计算。可配置的块保留和重算阈值决定了何时发生复用。在使用通过 EFA 连接的 Amazon EC2 P5en 实例的 1P1D 部署中,在我们测试的最长提示长度下,我们观察到 Qwen3-32B 的 TTFT 降低了 1.6 倍,zai-org/GLM-5-FP8 的 TTFT 降低了 3.3 倍。结果取决于具体的工作负载和部署配置。要在你的环境中实现这一功能,请使用支持 NixlConnector 的 vLLM v0.21.0 或更高版本,在预填充和解码服务器上均启用 bidirectional_kv_xfer,使用具备 KV Cache 感知能力的路由器,并遵循 GitHub 复现指南。

致谢

感谢 vLLM 社区为维护此功能提供的支持。