DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving
这篇论文是北大Xin Jin组和USD合作的,已经被OSDI‘24接收。主要思路是将一个推理请求的prefill和decoding分解进行batch,从而最优化goodput。
摘要
DistServe 通过分解预填充和解码计算来提高大型语言模型 (LLM) 服务的性能。 现有的 LLM 服务系统将两个阶段colocate,并批量计算所有用户和请求的预填充和解码。 我们发现这种策略不仅会导致强烈的预填充解码干扰,而且还会耦合两个阶段的资源分配和并行计划。 LLM 应用程序通常强调每个阶段的单独延迟:预填充阶段的第一个token时间 (TTFT) 和解码阶段每个请求的每个输出token时间 (TPOT)。 在存在严格的延迟要求的情况下,现有系统必须优先考虑一种延迟而不是另一种,或者过度配置计算资源来满足这两种延迟。
DistServe 将预填充和解码计算分配给不同的 GPU,从而消除预填充和解码干扰。 考虑到应用程序的 TTFT 和 TPOT 要求,DistServe 共同优化为每个阶段量身定制的资源分配和并行策略。 DistServe 还根据服务集群的带宽来colocate两个阶段,以最大程度地减少因分解而导致的通信。 因此,DistServe 在每个 GPU 上的 TTFT 和 TPOT 限制内可提供的最大速率方面显着提高了 LLM 服务性能。 我们的评估表明,在各种流行的 LLM、应用程序和延迟要求上,与最先进的系统相比,DistServe 可以服务 4.48 倍以上的请求或 10.2 倍更严格的 SLO,同时将超过 90% 的请求保持在延迟限制内。
Contributions:
- 识别现有 LLM 服务系统中的预填充-解码干扰和资源耦合问题,并建议分解预填充和解码阶段。
- 设计一种新的placement算法来自动选择预填充和解码instances的goodput最佳模式。
- 使用真实的workloads对DistServe做了一个全面的实验验证。
2.Background and Motivation
LLM 服务遵循客户端-服务器架构:客户端将文本序列作为请求提交给服务器; 服务器在 GPU 上托管 LLM,对请求运行推理,并将生成结果响应(或流式传输)回客户端。 如第 1 节中所述,由于独特的预填充解码过程,LLM 服务可能会对 TTFT 和 TPOT 施加激进的服务级别目标 (SLO),具体取决于应用程序的需求。 服务系统必须满足两个 SLO,同时最大限度地降低与昂贵 GPU 相关的成本。 换句话说,我们希望服务系统能够最大限度地提高每秒服务的请求数,并遵循每个配置的 GPU 的 SLO 实现目标——最大限度地提高每个 GPU 的吞吐量。 接下来,我们详细介绍 LLM 推理计算(第 2.1 节)并讨论 LLM 服务的现有优化(第 2.2 节)。
2.1 LLM inference
现代LLMs [32, 43] 在给定输入序列的情况下预测下一个token。 该预测涉及计算序列中每个token的隐藏表示。 LLM 可以采用可变数量的输入token并并行计算其隐藏表示,并且其计算工作量随着并行处理的token数量而超线性增加。 无论输入token数量如何,计算都需要大量 I/O 将 LLM 权重和中间状态从 GPU 的 HBM 移动到 SRAM。 此过程对于不同的输入大小是一致的。
预填充步骤处理新序列,通常包含许多token,并同时处理这些token。 与预填充不同,每个解码步骤仅处理上一步生成的一个新令牌。 这导致两个阶段之间存在显着的计算差异。 当处理不简短的用户prompt时,预填充步骤往往受计算限制。 例如,对于 13B LLM,计算 512 个token序列的预填充会导致 A100 计算受限。 模型越大,将预填充步骤转为计算限制所需的序列就越短(请参阅第 3.1 节)。 相比之下,解码阶段尽管每步仅处理一个新令牌,但会产生与预填充阶段类似水平的 I/O,从而使其受到 GPU 内存带宽的限制。
在这两个阶段中,每个token位置都会生成中间状态,称为 KV cache [28],在后续解码步骤中再次需要这些状态。 为了避免重新计算它们,它们被保存在 GPU memory中。 由于在memory中共享 LLM 权重和 KV 缓存,大多数 LLM 推理引擎选择colocate预填充和解码阶段到GPU,尽管它们具有独特的计算特性。
2.2 LLM Serving Optimization
在实时在线服务中,会出现多个请求,并且必须在 SLO 内提供服务。 批处理和并行化计算是实现 GPU 低延迟、高吞吐量和高利用率的关键。
**Batching.**当前的服务系统 [8,28,45] 使用称为连续批处理的批处理技术。 此方法通过对正在进行的请求进行解码来批量预填充新请求。 它提高了 GPU 利用率并最大限度地提高了整体系统吞吐量——所有用户和请求每秒生成的tokens。 然而,正如第 1 节中提到的以及稍后第 2.3 节中详细阐述的,这种方法会导致 TTFT 和 TPOT 之间的权衡。 连续批处理的高级变体 [8] 试图通过分段预填充和附加解码作业来平衡 TTFT 和 TPOT,以避免超出 GPU 性能限制 - 但本质上,它是用 TTFT 换取 TPOT。 总之,批量预填充和解码总是会导致 TTFT 或 TPOT 的妥协。
Model parallelism. 在LLM服务中,模型并行性通常分为算子内并行性和算子间并行性[29,39,50]。 两者都可以用于支持更大的模型,但可能会以不同的方式影响服务性能。 算子内并行性将计算密集型算子(例如矩阵乘法)划分到多个 GPU 上,从而加速计算,但会导致大量通信。 它减少了执行时间,从而减少了延迟,特别是对于预填充阶段的 TTFT,但需要 GPU 之间的高带宽连接(例如 NVLink)。 运算符间并行性将 LLM 层组织为多个阶段,每个阶段在 GPU 上运行以形成管道。 由于级间通信,它会适度增加执行时间,但会随着每个添加的 GPU 线性扩展系统的速率容量。 在本文中,我们揭示了模型并行性的另一个好处:通过缩短执行时间来减少预填充和解码阶段的排队延迟。 我们将在第 3 节中进一步探讨这一点。 除了模型并行性之外,复制模型实例(无论其模型并行性配置如何)都会线性扩展系统的速率容量。
这些并行策略创建了一个复杂的优化空间,需要根据应用程序的延迟要求进行仔细权衡。
2.3 Problems and Opportunities
与现有系统一样,对预填充和解码计算进行colocate和批处理以最大化整体系统吞吐量,这对于服务提供商来说是具有成本效益的。 然而,在存在 SLO 的情况下,由于下面讨论的问题,当前的方法很难保持高服务质量和低成本。
Prefill-decoding interference. 如图 2 所示,向一批解码请求添加单个预填充作业会显着减慢这两个过程,从而导致 TTFT 和 TPOT 显着增加。 具体来说,批次中的解码任务必须等待更长的预填充作业完成,从而延长了TPOT;