尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

大模型推理优化:Prefill与Decode分离架构详解

大模型推理优化:Prefill与Decode分离架构详解 1. 从“一锅炖”到“流水线”为什么我们需要分离 Prefill 与 Decode如果你最近在折腾大模型推理服务特别是想把它塞进一个高并发的在线场景里比如一个需要实时对话的客服机器人或者一个千人千面的内容生成平台那你大概率已经感受到了那种“甜蜜的烦恼”。模型能力越来越强但每次请求进来服务器就像被施了定身法CPU/GPU 吭哧吭哧半天吞吐量却死活上不去延迟也居高不下。很多人第一反应是堆硬件、加机器但这成本曲线陡峭得让人心疼。问题的根源往往不在于算力绝对不足而在于我们沿用已久的“一锅炖”式推理架构已经跟不上高并发场景的节奏了。传统的 LLM 推理无论是用 Hugging Face 的pipeline还是早期的一些推理框架处理一个请求的流程大致是这样的用户输入Prompt进来模型先进行“预填充”Prefill阶段也就是把整个 Prompt 的 token 一次性读入通过自注意力机制计算出所有 token 的上下文表示并生成第一个输出 token 的 logits。紧接着就进入“解码”Decode阶段以上一个生成的 token 作为输入自回归地预测下一个 token如此循环直到生成结束。这个过程是串行且独占的一个请求必须完整走完 Prefill - Decode 的整个生命周期才能释放计算资源给下一个请求。这种模式在请求量不大、Prompt 不长、生成内容Completion也不长的时候问题不大。但一旦进入高并发场景短板就暴露无遗资源利用的“木桶效应”Prefill 阶段和 Decode 阶段对计算资源的“胃口”完全不同。Prefill 处理整个 Prompt需要巨大的计算量和显存带宽来并行处理所有 token 的注意力计算是典型的计算密集型和内存带宽密集型操作。而 Decode 阶段每次只处理一个 token或几个 token计算量小但对内存延迟极其敏感因为它需要频繁访问 KV Cache键值缓存。让同一批硬件同时处理这两种负载就像让短跑运动员和马拉松运动员在同一条赛道上比赛谁也发挥不出最佳水平。糟糕的尾部延迟和吞吐量在高并发下多个请求的 Prefill 和 Decode 阶段会混杂在一起相互抢占资源。一个耗时的长 Prompt Prefill 会阻塞后面所有请求的 Decode导致即使生成了一个 token 就能响应的请求也必须长时间等待。这直接拉高了服务的尾部延迟P99 Latency用户体验极差。同时由于资源调度不专一整体吞吐量Tokens per Second也无法最大化。批处理Batching的困境为了提高吞吐我们常使用动态批处理Dynamic Batching。但在“一锅炖”架构下批处理变得异常棘手。Prefill 希望批处理长度相近的 Prompt 以提升计算效率Decode 则希望批处理生成步调一致的请求以减少气泡Bubble。两者需求冲突导致批处理策略顾此失彼效率打折。所以“调查研究-224 Prefill 与 Decode 分离”这个标题指向的正是解决上述痛点的下一代架构思路将 Prefill 和 Decode 这两个计算特性和优化目标截然不同的阶段从物理上或逻辑上分离开让它们各司其职跑在最适合自己的硬件和调度策略上。这不仅仅是软件层面的优化更是一种面向高并发 LLM Serving 的架构范式转变。接下来我们就深入拆解这个架构的核心思想、技术实现以及它带来的深远影响。2. Prefill 与 Decode一对计算特性迥异的“孪生兄弟”要理解为什么需要分离首先得看清 Prefill 和 Decode 这对“孪生兄弟”在计算本质上的巨大差异。这不仅仅是先后顺序的区别而是从底层硬件指令到上层软件调度都需要区别对待的两类任务。2.1 Prefill 阶段计算与带宽的“重炮集群”Prefill 阶段的任务是处理用户的输入 Prompt。假设 Prompt 长度为P个 token。计算模式高度并行。模型需要对这P个 token 执行完整的 Transformer 前向计算。在注意力层需要计算一个P x P的注意力矩阵对于因果语言模型是下三角掩码矩阵。这个矩阵乘法的计算复杂度是O(P^2 * d_model)其中d_model是模型隐藏层维度。对于长 Prompt比如 8K、32K 甚至更长这个计算量是巨大的。内存访问带宽瓶颈。Prefill 需要将整个 Prompt 的 token 嵌入、以及中间激活值一次性加载到高速缓存如 GPU 的 HBM中进行处理。它大量消耗的是内存带宽因为数据吞吐量大但每个数据元素参与计算的时间相对较长计算访存比相对较高但依然受限于带宽。硬件偏好Prefill 的理想硬件是那些拥有强大浮点计算能力FLOPS和高内存带宽的处理器。例如NVIDIA 的 H100 GPU 的 Tensor Core 非常适合这种密集的矩阵运算。它的优化目标是最大化计算单元的利用率尽快“消化”掉整个 Prompt。类比就像在厨房里准备一场宴席的所有食材洗、切、腌。这是一个需要集中人力、大开大合的准备阶段讲究的是并行处理和批量效率。2.2 Decode 阶段延迟敏感的“精密流水线”Decode 阶段是自回归生成每次预测下一个 token。计算模式严格串行。每一步只处理一个或通过推测解码等技术处理少量几个新 token。计算量主要集中在对 KV Cache 的读取和更新以及最后输出层的矩阵向量乘法上。计算复杂度是O(d_model^2)量级对于每个 token远小于 Prefill。内存访问延迟瓶颈。Decode 的命脉是KV Cache。每一步生成都需要读取之前所有生成步骤的 Key 和 Value 向量大小与序列长度和注意力头数相关。随着生成长度增加KV Cache 变得巨大且访问模式具有连续性。此时从 HBM 读取这些缓存的速度内存延迟成为关键瓶颈。即使计算单元空闲也在等待数据。硬件偏好Decode 的理想硬件需要极低的内存访问延迟和高效的小规模计算核心。它更看重内存子系统如缓存层次、内存控制器的效率。一些针对推理优化的芯片如某些 AI 推理卡会在这方面做专门设计。它的优化目标是最小化每个 token 的生成延迟让流水线顺畅无阻。批处理特点Decode 阶段非常适合做大批量的推理因为多个请求的 Decode 步骤可以同步进行共享模型权重读取的开销最大化计算吞吐。但前提是这些请求的生成步调不能相差太大否则会出现“气泡”先完成的请求等待后完成的请求。类比就像宴席开始后一道接一道地上菜。每个步骤炒一个菜很快但必须严格按照顺序且对火候延迟极其敏感慢了菜就凉了。2.3 冲突与耦合传统架构的症结在传统耦合架构中一个 GPU或一个计算实例同时承担着 Prefill 和 Decode 任务。这就导致了资源竞争一个长 Prompt 的 Prefill 任务会霸占大量计算资源和内存带宽导致同一设备上其他请求的 Decode 任务陷入停滞等待数据。调度器困境调度器很难做出最优决策。是该优先调度 Prefill 以接纳新请求还是优先调度 Decode 以降低现有请求的延迟这种决策往往两难。缓存污染Prefill 阶段大量、连续的数据流会冲刷掉 GPU 缓存中 Decode 阶段急需的 KV Cache 部分导致 Decode 时缓存命中率下降进一步加剧延迟。理解了这种根本性的差异分离架构的必要性就呼之欲出了。分离的本质是让“重炮集群”去专心轰击 Prompt 这座山头让“精密流水线”去高效、稳定地输送生成的 token。3. 分离架构的三种实现范式从逻辑到物理“分离”不是一个单一的概念它可以根据分离的粒度、资源管理的维度划分为几种不同的实现范式各有其适用场景和优缺点。3.1 逻辑分离同一设备内的队列与调度优化这是最轻量、最容易落地的一种方式。它不改变物理部署而是在同一个计算设备如一台 GPU 服务器内部通过软件调度策略将 Prefill 和 Decode 任务在逻辑上区分对待。核心思想引入两个独立的任务队列Prefill 队列和Decode 队列。调度器如修改后的推理框架调度模块根据任务类型将其放入相应队列。调度策略优先级调度通常赋予 Decode 队列更高的优先级因为 Decode 任务延迟敏感且单个任务执行时间短。这样可以保证已开始生成的请求能得到快速响应避免“卡顿”。时间片轮转/混合调度调度器可以周期性地或在 Decode 队列空闲时从 Prefill 队列中提取任务执行。也可以设计更复杂的策略比如当 Prefill 队列积压到一定长度时临时提升其优先级。资源预留可以为 Decode 任务在计算单元SM或内存带宽上预留一部分“专用通道”确保其不受 Prefill 的过度干扰。技术实现这需要对现有的推理引擎如 vLLM, TensorRT-LLM, TGI的调度器进行深度定制。例如在 vLLM 中可以修改其Scheduler类不再使用单一的 FIFO 请求队列而是实现一个双队列优先级调度器。优点实现相对简单无需额外的硬件或复杂的集群管理。能有效缓解 Decode 被 Prefill 阻塞的问题显著降低尾部延迟。缺点资源竞争的根本问题仍在。Prefill 的“重炮”依然会和 Decode 的“流水线”共享同一块内存带宽和计算单元在极端高负载下优化效果有上限。这属于“软分离”。实操心得在 vLLM 的早期应用中我们尝试过一种简单的策略——将长 Prompt如超过 512 token的请求单独标记并延迟其 Prefill 的执行优先保证短 Prompt 和所有 Decode 任务的执行。虽然粗糙但在 Prompt 长度分布不均的场景下对降低平均延迟有肉眼可见的提升。这本质上就是一种手动的逻辑分离。3.2 物理分离专精化的异构计算集群这是最彻底、理论上收益最大的一种分离方式即将 Prefill 和 Decode 任务调度到不同的物理设备上运行。核心思想组建一个异构的推理集群。集群中包含两类节点或两类 pod/容器Prefill 节点配备适合计算密集型任务的高性能 GPU如 H100。这些节点专门负责接收用户请求执行耗时的 Prefill 计算生成第一个或前几个token 的 logits并初始化好该请求的 KV Cache。Decode 节点配备针对低延迟、高吞吐推理优化的硬件。这可以是推理卡如 NVIDIA L4/T4虽然它们也用于 Prefill但在 Decode 优化上更有侧重甚至是专门为自回归解码设计的 ASIC如 Groq 的 LPU。这些节点从 Prefill 节点接收“半成品”请求即已经完成 PrefillKV Cache 已就绪的请求专职进行高速、大批量的 Decode 生成。数据传递分离的关键在于KV Cache 的传递。Prefill 节点在完成计算后需要将初始化好的 KV Cache可能经过压缩通过网络通常是高速 RDMA 网络传输到指定的 Decode 节点。后续的生成步骤完全在 Decode 节点上进行。集群调度需要一个全局的调度器如基于 Kubernetes 的自定义调度器它能够感知请求的类型新请求-Prefill生成中请求-Decode并将其路由到正确的节点池。同时还需要管理 Prefill 节点和 Decode 节点之间的负载均衡和状态同步。优点资源利用率最大化每类硬件都能在其专精的任务上发挥极致性能。弹性伸缩可以根据 Prefill 和 Decode 的负载压力独立地横向扩展Scale Out相应类型的节点。例如白天用户提问多Prefill 负载重就多扩几个 Prefill 节点晚上内容生成任务多Decode 负载重就多扩几个 Decode 节点。故障隔离一个节点的故障不会影响另一类任务的进行。缺点系统复杂性剧增需要设计高效的 KV Cache 序列化、网络传输和反序列化机制。网络延迟和带宽成为新的潜在瓶颈。状态管理复杂请求的状态KV Cache在节点间迁移需要强大的状态管理和容错机制确保请求不丢失、状态一致。成本与运维门槛高需要维护两套硬件栈和更复杂的集群管理逻辑。3.3 混合分离结合模型并行的细粒度切分这是一种更激进的思路结合了模型并行Tensor Parallelism, Pipeline Parallelism的技术将 Prefill 和 Decode 阶段在模型层面分配到不同的设备上计算。核心思想不是以整个请求为单位进行分离而是在单个请求的计算过程中将 Prefill 阶段和 Decode 阶段的计算图或算子调度到不同的设备上执行。一种可能的实现利用 Pipeline Parallelism流水线并行的思想。将 Transformer 层的计算划分为多个“阶段”stages。在 Prefill 时所有 token 的数据流经过整个流水线。但我们可以设计调度器让 Decode 阶段每次一个 token的数据流只经过流水线的后半部分例如后面的若干层而前半部分专门用于处理来自 Prefill 节点的中间结果或进行其他计算。这需要编译器如 OpenAI Triton, XLA和运行时系统的深度支持。另一种思路在芯片设计层面未来的 AI 加速器可能会集成两种不同的计算核心一种针对 Prefill 的矩阵乘优化一种针对 Decode 的内存访问优化。在运行时硬件调度器自动将不同阶段的任务映射到不同的核心上。优点可以实现极致的资源利用和性能优化理论上能逼近硬件能力的上限。缺点目前这更多是一种研究方向和未来展望对软件栈、编译器、硬件的要求极高离大规模工程化落地尚有距离。通信和同步的开销管理是巨大挑战。目前工业界探索和实践的主流是逻辑分离和物理分离尤其是物理分离正随着云原生和 Kubernetes 的普及成为大型 LLM 服务提供商构建高并发服务的重点架构选项。4. 工程落地挑战、方案与踩坑实录将 Prefill/Decode 分离架构从理论搬到生产环境会遇到一系列实实在在的工程挑战。这里结合一些开源项目和业界实践聊聊关键的实现点和我们踩过的坑。4.1 核心挑战一KV Cache 的高效迁移与共享这是物理分离架构的“命门”。KV Cache 体积庞大对于 70B 模型、8K 上下文可能达到数十GB如何在 Prefill 和 Decode 节点间快速、无损地传递方案A零拷贝与 RDMA思路利用高速网络如 InfiniBand 或 RoCE的 RDMA远程直接内存访问能力实现 Prefill 节点 GPU 显存到 Decode 节点 GPU 显存的直接内存拷贝绕过 CPU 和操作系统延迟极低。实现使用 NCCL 或直接基于 UCX 库进行 GPU 到 GPU 的通信。需要将 KV Cache 在显存中组织为连续的缓冲区。坑点RDMA 配置复杂对网络环境要求苛刻。跨 NUMA 节点或跨路由器的传输性能可能下降。需要精细的内存注册和管理否则容易导致内存泄漏或访问错误。方案B压缩与量化思路在传输前对 KV Cache 进行压缩。由于 Decode 阶段对精度相对不敏感相比 Prefill可以对 KV Cache 进行量化例如从 FP16 量化到 INT8 甚至 INT4大幅减少传输数据量。实现在 Prefill 节点完成计算后调用量化 kernel 对 KV Cache 进行在线量化然后发送量化后的数据和量化参数。Decode 节点接收后可选择性地进行反量化或直接在量化状态下进行运算需要模型和 kernel 支持。坑点量化会引入误差可能影响生成质量需要仔细评估 Perplexity 的变化。在线量化会增加 Prefill 节点的计算开销。需要一套灵活的精度控制策略例如对关键的前几层保留高精度。方案C状态服务器Stateful Server思路引入一个集中的、持久化的 KV Cache 存储服务可以是基于内存的如 Redis或基于高速 SSD 的。Prefill 节点将 KV Cache 写入该服务Decode 节点从中读取。这解耦了 Prefill 和 Decode 节点的生命周期。实现需要设计高效的序列化协议如 Protobuf 压缩和缓存淘汰策略如 LRU。Decode 节点可能需要预取缓存。坑点中心化的存储服务可能成为性能和单点故障的瓶颈。网络往返延迟RTT会直接加到每个 Decode 步骤的延迟上除非 Decode 节点有本地缓存。对一致性要求高。踩坑实录我们早期尝试物理分离时采用了方案ARDMA。在实验室环境下性能提升显著。但上了生产环境后由于 Kubernetes Pod 调度和网络策略的限制并非每次 Prefill 和 Decode Pod 都能被调度到支持 RDMA 的相邻节点上。一旦 fallback 到 TCP 传输延迟激增性能反而不如单节点。教训是物理分离架构严重依赖底层基础设施的稳定性和性能一致性必须和运维团队深度协作确保网络拓扑和调度策略的亲和性。4.2 核心挑战二全局请求调度与负载均衡如何智能地将请求路由到正确的节点如何避免某些节点过载而其他节点空闲方案基于自定义调度器的服务网格组件全局调度器Global Scheduler一个独立的服务接收所有入口请求。它维护着 Prefill 节点池和 Decode 节点池的健康状态与负载情况。请求路由器Router根据调度器的决策将新请求带 Prompt转发到合适的 Prefill 节点并将已完成 Prefill 的请求转发到合适的 Decode 节点。负载均衡器在每个节点池内部实施负载均衡如 Round Robin, Least Connections。调度策略基于队列长度将请求发送到当前队列最短的节点。基于资源利用率将请求发送到 GPU 利用率或内存利用率最低的节点。基于预测根据 Prompt 长度预测 Prefill 耗时进行更智能的调度。实现可以利用 Kubernetes 的 Custom Scheduler 和 Service Mesh如 Istio来实现。调度器通过 Kubernetes API 监控各节点的 Metrics需暴露自定义指标并修改 Pod 的注解或通过 webhook 来影响路由决策。坑点调度决策本身有开销。过于复杂的策略可能得不偿失。需要防止“颠簸”一个请求在不同节点间被来回调度。对于 Decode 节点还需要考虑“请求亲和性”即同一个请求的多个生成步骤最好落在同一个 Decode 节点上以避免 KV Cache 的频繁迁移。4.3 核心挑战三容错与状态恢复在分离架构中一个请求的状态KV Cache分散在可能不同的节点上。任何一个节点故障都可能导致请求失败。方案检查点Checkpointing与副本Replication检查点定期将 Decode 节点的 KV Cache 状态持久化到共享存储如高速网络文件系统。当节点故障时可以从最近的检查点恢复但会丢失一部分生成内容。无状态 Decode 中心化状态存储这就是上文“状态服务器”方案的另一个优势。Decode 节点本身是无状态的KV Cache 存储在可靠的外部服务中。任何一个 Decode 节点故障调度器只需将请求重新路由到另一个健康的 Decode 节点并从状态服务器读取 KV Cache 即可继续。请求级副本对于非常重要的请求可以将其 KV Cache 同步复制到另一个 Decode 节点作为热备。主节点故障时备节点立即接管。但这会带来双倍资源消耗和同步开销。坑点持久化 KV Cache 开销巨大频繁检查点不可行。中心化状态存储的可用性和性能必须极高。副本方案的成本需要仔细权衡。一个实用的折中方案是对于普通请求接受一定的故障率对于付费或关键会话采用更可靠的路径例如将其调度到更稳定的节点组或启用轻量级副本。5. 性能收益评估与权衡什么时候该上分离架构分离架构不是银弹它会引入额外的复杂性和潜在开销。在决定是否采用以及采用何种分离方案前必须进行严谨的评估。5.1 关键性能指标KPIs的变化吞吐量Throughput预期收益物理分离架构下Decode 节点可以专注于大批量、高并发的 token 生成通常能显著提升Decode 吞吐量Tokens/sec。Prefill 节点也能更高效地处理长 Prompt。潜在损耗逻辑分离可能对吞吐量提升有限。物理分离中KV Cache 的网络传输会成为新的瓶颈可能抵消部分收益。需要实测验证。延迟Latency尾部延迟P99/P95 Latency这是最大的受益点。分离架构能有效防止长 Prefill 阻塞短请求大幅降低尾部延迟提升用户体验。首 Token 延迟Time to First Token, TTFT对于新请求如果 Prefill 节点负载高TTFT 可能反而增加因为需要排队等待专门的 Prefill 资源。但通过合理的负载均衡和资源预留可以控制。Token 间延迟Inter-token Latency在 Decode 节点专精化后此项延迟有望降低并保持稳定。资源利用率Resource Utilization理想情况Prefill 节点的 GPU 计算利用率Utilization和 Decode 节点的 GPU 内存带宽利用率分别接近各自的理论峰值。实际情况需要监控网络 I/O、序列化/反序列化带来的 CPU 开销以及可能出现的资源闲置如 Prefill 节点空闲时。5.2 成本模型分析分离架构可能改变成本结构硬件成本可能需要采购两种不同类型的硬件增加了采购和运维的复杂性。但通过精细化匹配负载可能降低总体的 TCO总体拥有成本。软件与运维成本架构复杂性飙升需要更专业的研发和运维团队投入。监控、告警、调试的难度都增加了。网络成本物理分离依赖高速网络这可能是一笔不小的开支。5.3 何时考虑引入分离架构你可以用下面这个简单的决策树来评估你的服务是否面临高并发100 QPS且 Prompt 长度分布差异大的场景如果是尾部延迟问题很可能已经出现。现有的单节点或逻辑优化如更好的批处理策略是否已无法满足 SLA服务等级协议特别是 P99 延迟要求。你的团队是否有足够的工程能力来驾驭分布式系统的复杂性包括网络、调度、状态管理。你的硬件基础设施是否支持或愿意投资高速网络和异构计算资源如果以上问题的答案多为“是”那么深入调研 Prefill/Decode 分离架构就是值得的。建议的路径是先从逻辑分离入手优化现有单集群的调度策略这通常能带来不错的收益且风险可控。如果性能仍不达标再逐步向物理分离演进可以先搭建一个小型试验集群用真实的流量影子复制Shadow Testing来验证效果切勿直接全量上线。分离架构是高并发 LLM Serving 走向成熟的必然阶段它标志着我们从“粗放式”的模型部署进入了“精细化”的服务运营时代。它不是一个简单的开关而是一套需要结合业务特点、技术实力和基础设施状况进行深度定制的系统工程。理解其原理看清其挑战才能让它真正为你的服务赋能在体验、成本和效率之间找到最佳平衡点。
返回列表