Helix:突破GPU集群瓶颈,高效加速大型语言模型服务

技术

picture.image

Abstract

本文介绍了Helix,一个在异构GPU集群上用于高吞吐量、低延迟大型语言模型(LLM)服务的分布式系统。Helix背后的一个关键思想是将异构GPU和网络连接上的LLM推理计算公式化为一个有向、加权图的最大流问题,其中节点代表GPU实例,边通过它们的容量捕捉GPU和网络异质性。Helix然后使用混合整数线性规划(MILP)算法发现高度优化的策略来服务LLM。

这种方法使得Helix能够联合优化模型放置和请求调度,这两个在异构LLM服务中高度纠缠的任务。

作者在从24到42个GPU节点的几个异构集群设置上的评估显示,与现有的最佳方法相比,Helix将服务吞吐量提高了2.7倍,将提示和解码延迟分别降低了2.8倍和1.3倍。

1 Introduction

生成式大型语言模型(LLM),如GPT-4 [1]和LLaMA-3 [20],已经在包括聊天机器人[25]、编程助手[19, 30]和任务自动化[11]在内的多种应用领域中展示了其生成自然语言文本的卓越能力。然而,现代LLM日益增长的模型大小和高计算需求使得在现有云平台上以低成本和高效的方式提供服务变得具有挑战性。特别是,现今大多数LLM服务系统(例如,Orca [46]和vLLM [16])针对的是同构GPU集群[21],其中所有GPU类型相同,具有相同的内存容量和计算资源。由于模型大小的增长,使用同构GPU服务LLM需要越来越多的GPU,如表1所示。此外,服务业界使用的最先进的LLM需要甚至更多的资源。作者观察到,在单个云区域内分配如此数量的GPU几乎是不可能的,这也得到了其他近期研究[36, 45]的认同。

picture.image

由于GPU架构设计的进步以及它们随时间的增量部署,现代云平台越来越多地由多种GPU类型组成。这些异构GPU实例分布在全世界的数据中心,并且总体上提供的内存容量和计算资源远大于单个GPU类型,使得LLM服务变得更加可达和可扩展。同样,也有一种趋势是使用志愿者消费者的GPU来解决GPU短缺问题[7, 32, 47]。然而,与同构GPU实例相比,在地理分布式异构实例上部署LLM需要适应各种GPU设备和网络条件。

之前的工作已经介绍了几种在异构设备[49, 26]或地理分布式环境[31, 12]上运行机器学习(ML)计算的系统。但它们大多数是为长时间运行的训练工作负载设计的,不能适应具有实时推理请求的大语言模型(LLM)服务场景。例如,与作者最相关的工作是Petalas [4],它使用流水线模型并行性将LLM划分为多个阶段,并采用贪心算法以循环方式将这些阶段分配给异构GPU。这种优化吞吐量的设计对长时间运行的任务有效,但缺乏交互式LLM应用(如需要快速响应的聊天机器人)所需的响应性。为了利用异构GPU资源进行LLM服务,作者提出了Helix,这是一个分布式系统,可以在异构GPU上实现高吞吐量、低延迟的LLM服务。Helix背后的关键思想是将异构GPU和网络上的LLM服务执行制定为在多种GPU计算能力、内存容量以及复杂的GPU间连接约束下的数据流问题。据作者所知,Helix是第一个为地理分布式异构GPU设计的 服务系统。接下来,作者将介绍Helix必须解决的关键挑战以及Helix对它们的解决方案。

首先,由于LLM的大小不断增加,在现代GPU上服务它们需要采用张量[35]和流水线[26, 13]模型并行性将LLM划分为多个阶段,并将这些阶段放置在不同的GPU上,作者称这项任务为模型放置。同构服务系统(例如Orca [46])将LLM划分为大小相等的阶段并将它们分配给GPU。这种方法导致高性能GPU的利用率次优,因为它适应了较低性能GPU的内存和计算限制。现有的异构感知服务系统(如Petalas [4])依赖于不同的启发式方法将模型划分为阶段并将它们分配给GPU。现有的启发式方法没有同时考虑GPU和网络异构性。

Helix将模型放置制定为一个有向加权图的最大流问题,其节点代表GPU实例,边通过它们在最大流问题中的容量捕获GPU和网络异构性。然后,Helix使用混合整数线性规划(MILP)算法发现高度优化的模型放置策略,这些策略在很大程度上优于之前工作[4]中使用的启发式方法。

Helix必须解决的第二个挑战是请求调度。为了服务LLM请求,Helix需要选择一系列GPU实例的流水线以计算LLM的所有层。现有的系统通常使用一组固定的流水线,并以轮询的方式将这些请求分配给这些流水线。使用固定流水线不足以适应异构的计算和网络条件,并且经常导致资源利用率低下。相反,Helix引入了按请求定制的流水线,每个请求都分配有它自己的流水线。结果是,潜在的总流水线数量等于在集群的图表示中从源点到汇点的路径数量,这为Helix提供了足够的灵活性以最大限度地利用GPU实例及其之间的网络连接的全部容量。

作者在vLLM [16]的基础上实现了Helix,并在三个异构集群上进行评估,这些集群从24到42个节点不等,最多有7种不同的节点类型。作者评估的模型包括LLaMA 30B和70B。与考虑异构性的 Baseline 相比,Helix将服务吞吐量提高了最多2.7倍,同时将平均提示和解码延迟分别降低了最多2.8倍和1.3倍。

总之,本文做出了以下贡献:

(1) 在异构GPU上实现高吞吐量、低延迟LLM服务的首个系统;

(2) 针对LLM服务提出了一种最大流公式和一个MILP算法以优化模型放置;

(3) 通过按请求定制流水线来最大化GPU利用率;

(4) 作者技术的实现以及在各种LLM基准上的评估。作者将在论文评审后发布Helix,以促进未来的研究。

LLM Architecture and Serving

当今大多数的LLM采用解码器式的Transformer架构[29, 5],首先将自然语言 Query 转换为一串标记。模型然后将每个标记转换为隐藏状态向量,其大小被称为模型的隐藏大小。Transformer模型由输入和输出嵌入以及一系列相同的Transformer层组成,每个层包括一个自注意力块和一个前馈块。自注意力块计算每对标记之间的“亲和力”,并根据此上下文相关性得分更新每个标记的隐藏状态。前馈块通过非线性函数独立修改每个标记的隐藏状态。

给定一个输入序列,Transformer模型计算下一个标记的概率分布,并从这个概率分布中进行采样。因此,模型应用自回归范式来生成整个输出序列:给定一个_input prompt_,模型进行多次迭代。在第一次迭代中,也就是所谓的_prompt phase_,模型处理所有提示标记并生成第一个输出标记。在后续迭代中,也就是_decode phase_,模型结合提示和之前生成的标记来预测下一个输出标记。当模型产生特殊的句子结束信号时,此迭代过程停止。由于生成输出是不可预测的,确切的迭代次数在序列完全生成之前是不确定的。

除了不可预测的执行迭代之外,LLM服务还有一个特点是高内存需求。自注意力块需要所有先前标记的隐藏状态作为输入。为了存储新生成标记的隐藏状态(称为KV缓存),随着生成过程,内存需求不断增加。

为了解决这些挑战,Orca [46]提出了迭代 Level 的调度,它在每次迭代时更新一个批次,以避免在请求完成但同一批次中的其他请求需要更多迭代时的资源保留;vLLM [16]引入了PagedAttention,用相同的页面管理KV缓存的内存,并且仅在请求用完其所有页面时分配新页面;multi-query [33]和group-query attention [3]修改了自注意力机制,以减少为每个标记存储的KV缓存的大小。

Distributed Model Serving

开源的LLM现在包含多达数千亿个参数,远远超过了单个GPU的内存容量。因此,服务一个LLM需要多个GPU并行运行。张量并行(TP)[35]将每个操作符的权重在多个GPU之间划分,通过AllReduce/AllGather操作在每个设备上收集部分结果。然而,TP对网络条件非常敏感。对于每个Transformer层,它需要两次通信。因此,在延迟较高的网络中,TP的开销很大,只在节点内的GPU之间使用。

相反,流水线并行(PP)[13]在不同的GPU上分配不同的操作符(通常是多层),创建多个流水线阶段。然后它将输入分割成微批次,通过流水线运行它们。PP只在流水线阶段的边界传输激活张量。因此,PP对网络的敏感性要低得多。然而,完美地划分模型和输入批次是具有挑战性的,这导致了流水线中的气泡。结果,PP在流水线气泡时设备空闲,需要精心安排才能提高性能[2]。

传统数据中心设置通常假设同构的集群:具有统一带宽的统一节点。因此,模型被均匀地划分为流水线阶段并分配给每个设备。然而,随着待服务的LLM的大小增长以及最新一代GPU的短缺,使用异构设备服务LLM成为一个关键需求,这在先前的努力中并没有得到很好的研究。

在异构GPU上服务LLM需要考虑硬件和网络方面的异构性。例如,均匀划分模型层可能会使能力更强的设备利用不足。此外,节点可能位于多个区域。不同区域之间的带宽差异也必须考虑。

为了应对这些挑战,petals[4]引入了贪婪设备分配和请求路由。它关注去中心化设置,允许设备的即插即用。对于设备放置,它将新设备分配给效率最低的流水线阶段。对于网络拓扑,它通过优先选择低延迟网络来路由每个请求。然而,这种在异构集群场景中的贪婪在线方法并不是最优的,因为所有节点的信息是预先已知的。SWARM[31]关注异构集群中的模型训练。它将模型均匀地划分为流水线阶段。在将请求路由到下一个流水线阶段时,它根据每个候选者的实时吞吐量选择副本。

3 Optimization Formulation in Helix

图1:次优模型放置和请求调度的示例。(a)本例中的所有GPU和网络条件。计算能力的顺序是:A100 > L4 > T4;(c)通过统一划分模型,然后按平衡计算能力分配设备的模型放置;(b)共同优化模型划分和设备放置以使计算能力更加平衡;(d)共同优化模型划分、设备放置和请求调度。

picture.image

图2:给定模型放置的3节点集群的图抽象。图1(b)中边上的数字代表它们的容量,即每秒可以通过边的 Token 数量。源和汇之间的最大流等于集群的最大服务吞吐量。

picture.image

本节首先为LLM服务系统提供了一种数学抽象。基于这种表述,作者将异构LLM服务建模为一个最大流问题。最后,作者应用混合整数线性规划(MILP)来搜索具有最高最大流的模型放置策略。

LLM服务的表述

用于服务LLM的集群通常包含一个协调节点和一组计算节点。每个计算节点具有一个计算吞吐量和给定的GPU VRAM大小。集群中节点之间的网络连接具有给定的吞吐量和延迟。基于集群信息,LLM服务需要找到一种将模型层放置到计算节点的方法,以最大化服务性能。模型放置函数将计算节点作为输入,并返回模型的一个(通常是连续的)子集。一种广泛使用的评估模型放置的指标[4, 31]是具有最低计算能力的流水线阶段的性能,它汇总了为单层服务的所有实例的计算能力。正如作者下面将展示的,仅考虑计算能力会导致异构集群的次优模型放置。

基于模型放置,LLM服务需要一个能够有效服务集群中请求的请求调度策略。请求调度策略将请求作为输入,并输出形成执行LLM所有层的完整流水线的计算节点序列。

在作者深入研究异构LLM服务的最大流表述之前,作者首先使用一个示例来说明为什么需要在最大流问题中共同优化模型划分、设备放置和请求调度。

在这个示例中,设备如图1(a)所示。两个区域之间的带宽较低。区域1有一个强大的A100 GPU,而区域2有一个较弱的L4 GPU和三个T4 GPU,但区域内具有高带宽。成对的带宽是独立的。如果作者遵循常见的做法,首先划分模型,然后将设备分配给每个分区,那么放置计划将如图1(b)所示。在这个计划中,尽管最后一个流水线阶段有一个T4和一个L4 GPU,但其吞吐量受限于前一个阶段的输出吞吐量,而该阶段只有2个T4 GPU。这表明有必要共同优化流水线分区计划和流水线阶段的放置。

然而,即使每个流水线阶段都具有完美的平衡计算能力,如图1(c)所示,解决方案仍然可能不是最优的。在这个解决方案中,它将强大的A100分配给单独服务某些层,而其他GPU则以数据并行方式运行其余层。然而,一个流水阶段到另一个的通信成为瓶颈。对于每个请求,其中间状态通过低带宽从区域1发送到区域2。这最终在A100的发送端造成了拥塞。相反,图1(d)将两个T4 GPU与A100并行分配。这将在A100 GPU和两个T4 GPU之间分割工作量,以减少慢链路上的通信量。

Heterogeneous LLM Serving as Max-Flow

为了优化模型放置,Helix需要一种方法来确定不同模型放置的最大服务吞吐量。为此,作者将分配了模型层的计算节点集群转换为一个带边界的有向图。边容量表示计算节点和网络连接每秒可以处理和传输的 Token 数量。图中源点和汇点之间的最大流,代表协调节点,给出了当前模型放置下集群的最大服务吞吐量。下面作者展示了在给定模型放置情况下集群图抽象的正式构建。

对于一个具有协调节点的计算集群和模型放置,作者可以将集群中的实体转换为其图抽象的元素,如下所示。图2展示了一个具有给定模型放置的集群图抽象示例。

计算节点。 对于每个计算节点,作者在图中用两个连接的顶点表示它。作者将这两个顶点命名为和。有向边的容量表示该节点在一秒内可以处理的最大 Token 数。这是节点计算能力和网络吞吐量的最小值。Helix执行一次性的性能分析,以测量所有计算节点的吞吐量。

协调节点。 作者将协调节点在图中表示为源点和汇点。

网络连接。 在给定集群中,一个节点可能与其他任何节点进行通信,在节点之间创建可能的有向网络连接。然而,只有基于以下模型放置描述的连接子集是有效的。

一个有效连接应满足以下三个条件中的一个:

(1) 该连接是从协调节点到计算节点,且持有模型的第一层;

(2) 该连接是从计算节点到协调节点,且持有模型的最后一层;

(3) 该连接是从一个计算节点到另一个计算节点,且在上进行推理后立即需要的模型层。

对于前两种情况,作者分别用有向边和表示该连接,其容量等于连接带宽除以 Token 的传输大小(几字节)。对于第三种情况,作者用有向边表示该连接,其容量等于连接带宽除以激活的传输大小(几十千字节)。这模拟了不同节点间网络连接速度对吞吐量的限制。作者用表示所有可能网络连接的完整集合。

构建了集群的等价图抽象后,作者运行preflow-push算法[6]来获取源点和汇点之间的最大流。这里的流的一个单位代表一秒内可以通过计算节点或网络连接的一个 Token 。因此,最大流给出了当前模型放置下集群可能的最大服务吞吐量。

Optimal Model Placement with MILP

上一节介绍了获取集群在给定模型部署下的最大服务吞吐量的方法。在本节中,作者提出了一种基于混合整数线性规划(MILP)的方法来寻找最大化流量的模型部署,从而最大化服务吞吐量。MILP公式具有与计算节点数量和网络连接数量成线性关系的变量和约束条件。

解决的关键挑战包括:

(1)将系统级约束表述为需要满足的线性条件;

(2)使用线性数量的变量表达这些条件;

(3)使用辅助变量线性化每个条件,具体来说,每个约束条件最多用三个线性约束以及最多两个辅助变量来表达。变量和约束的概述分别显示在表2和表3中。

picture.image

picture.image

节点变量。 为了表示每个计算节点上的模型部署,作者在MILP公式中引入了两组变量。假设模型总共有层,每个计算节点持有模型的连续子集。对于每个计算节点,作者引入一个整数变量来表示持有的第一层。假设计算节点在其GPU上最多可以持有层,作者进一步引入个二进制变量来表示节点持有的层数(如果持有层,则)。作者选择用个二进制变量(而不是一个整数表示层数)来表达模型部署,因为这种表述有助于如下所述的表达推理吞吐量约束。计算节点的_结束层索引_可以表示为。因此,持有在范围内的层。

连接变量。 作者引入两组变量来约束可以通过集群中每个网络连接的推理请求的数量。对于计算节点和之间的网络连接,作者引入一个实数变量来表示在图抽象中从到的流量。作者进一步引入一个二进制变量来表示网络连接是否有效(如第3.2节定义)。下面介绍的约束条件将使用来确保请求只能通过有效的连接传输。对于协调节点与计算节点之间的网络连接,作者同样引入上述两个变量,但用源/汇替换。

约束-1:模型部署。 为了确保MILP求解器找到的模型部署是有效的,作者需要对每个计算节点施加以下两个约束。首先,应该只有一个有效的模型部署,这意味着。此外,持有的第一层和最后一层必须在层的范围内,这意味着0s_i<l0\leq s\_{i}<le_ile\_{i}\leq l。<="" p="">

约束-2:流量守恒。 对于每个计算节点,流入的流量之和必须等于流出的流量,因为需要遵守流量守恒。这个约束可以表示为,其中和枚举所有除了之外的节点。

约束-3:推理吞吐量。 对于计算节点 ,流经 的流量不应大于其最大推理吞吐量。作者可以用以下不等式施加这个约束:。这里, 是一个常数,表示持有 层时节点 每秒能处理的最大 Token 数,这是通过一次性能分析过程获得的。

约束-4:传输吞吐量。 作者只允许流量通过有效的网络连接,并且流经的流量不应大于连接的最大传输吞吐量。为了实施这个约束,作者将 作为MILP问题的一个约束添加进去。 是可以通过网络连接传输的最大 Token 数,可以通过性能分析并使用第3.2节中提到的方法计算得出。

优化目标。 MILP问题的目标是找到一个满足所有约束并且为集群产生最高最大流量的模型放置。这个优化目标可以表达为最大化来自源的流量之和,即最大化 。

MILP解决方案编排。 在MILP求解器找到一个满足所有约束的解决方案后,作者可以将其编排成一个模型放置计划,并构建集群的图抽象。对于计算节点 , 和 告诉作者模型层 应该加载到其GPU中。

Analyzing and Speeding up MILP

如表2和3所示,MILP问题中的变量数量和约束与计算节点数量和网络连接数量成线性关系。对于拥有超过40个节点的大型集群,MILP求解器可能需要数小时才能给出一个合理的好解。为了加快大型集群的MILP求解过程,作者引入了三种优化方法。首先,作者剪除了集群中一些较慢的网络连接。第5.8节的评估显示,这样做可以有效减小问题规模,而不会牺牲太多性能。其次,作者用启发式方法找到的解来提示MILP求解器。由于问题具有指数级的解空间,MILP求解器在有限的求解时间预算内只能覆盖一小部分。使用启发式方法得到的解作为MILP问题的起点,可以加快优化过程,特别是对于大型集群。第5.8节显示了对于大型集群,从启发式解出发的必要性。最后,作者注意到集群的最大服务吞吐量总是受到所有计算节点计算吞吐量总和除以层数量的限制。MILP求解器将此作为提前停止的标准,并在找到接近这个上限的解时停止。

图3:Helix概览。在Helix中,协调器计划模型放置,如第3.3节所述。作者只需要对每个集群运行一次模型放置。当一个新请求到达时,协调器节点运行Helix调度器为它分配一个每个请求的流水线,并将请求发送到流水线的第一个节点。流水线中的每个计算节点对其负责的层上的请求进行推理,并将请求(输出)发送到流水线中的下一个节点。当流水线中的最后一个节点完成对其层的推理时,它会将请求的输出 Token 发送给协调器(Worker Finished)。协调器使用相同的流水线安排生成请求的下一个 Token 。

picture.image

加快MILP问题的一种常见方法是将其放松为线性规划(LP),通过将整数变量放松为线性变量,并使用诸如对结果线性变量进行四舍五入的方法来获得原始问题的有效解。作者指出,这种方法对于上述模型放置的MILP问题不可行。这是因为从LP得到的解不能很容易地转换为原始问题的有效解。模型放置的变量(和)决定了边缘有效性变量,这进而决定了流变量。在放松解中四舍五入模型放置的非整数变量可能会使一些或所有网络连接无效,从而极大地改变集群的最大流。## 4 Helix运行时

本节讨论Helix中的请求运行时调度。当协调器节点收到一个新请求时,它会运行Helix的请求调度器为请求分配一个每个请求的流水线,作者将在4.1节中介绍。然后协调器节点将请求发送到流水线的第一个计算节点。当一个计算节点收到请求时,它使用在该流水线中负责的层对请求进行推理,并将请求发送给后续的计算节点。图3显示了Helix的概览。

Scheduler Design: Per-Request Pipelines

为了在集群中推理请求,调度器需要为请求分配一个“流水线”。该流水线包含一系列阶段,每个阶段指定一个计算节点以及在计算节点上推理的层。一个有效的流水线在顺序执行阶段时必须按正确顺序推理模型的每个层。在Helix中,与之前的工作[15, 4]将请求分配给一组固定的流水线不同,作者提出了一种按请求分配流水线的方法,即每个请求都有自己的流水线。可能存在的流水线总数等于集群图抽象中从源点到汇点的可能路径数。大量的流水线使得调度可以更好地适应计算节点和网络连接的容量。作者的最大流公式使作者能够创建按请求的流水线。

Helix中的调度器使用集群的图抽象以及来自MILP的模型放置解决方案和其最大流解决方案来指导请求调度。调度器在协调节点上运行,并使用交错加权轮询(IWRR)[37]来执行请求调度。IWRR调度接收一个候选者列表及其权重作为输入。在 Query 调度时,它会按照其权重比例选择一个候选者。使用IWRR使作者能够按照集群的最大流进行请求调度,而不会产生突发。下面作者详细介绍了基于最大流的IWRR调度过程。

集群中的每个节点(包括协调节点)在Helix的调度器中由一个IWRR实例表示。每个IWRR实例的候选者包含与相应节点通过有效网络连接连接的所有节点。每个候选者的权重等于第3.3节中获得的集群最大流解决方案中相应网络连接的流量。当一个新请求到达时,调度器从代表协调节点的IWRR实例开始调度。它 Query IWRR实例并获得一个计算节点,该节点将托管第一个流水线阶段。由于请求尚未推理任何层,第一个流水线阶段将推理持有的所有层。对于第二个流水线阶段,调度器将使用代表的IWRR实例来确定托管第二个流水线阶段计算节点。由于第3.3节提到的部分推理,和持有的层可能会有部分重叠。因此,调度器将检查重叠,并且只在第二个阶段对之前未推理的层进行推理。调度器重复此过程,直到形成一个有效的流水线。根据作者在第3节构建集群图抽象的方式,调度器总是可以为集群构建一个有效的流水线。图4中的示例展示了使用Helix请求调度器调度两个请求的过程。

picture.image

KV-Cache Estimation

在为LLM服务时,每个GPU在推理过程中有有限的VRAM来存储请求的KV缓存。如果GPU上并发运行的请求所需的KV缓存超过了这个限制,执行引擎就必须将一些请求卸载到主内存中,这会显著降低吞吐量。因此,在调度器中,作者维护了所有计算节点KV缓存使用的估计,并在运行交错加权轮询时屏蔽那些超过高水位线的计算节点。只有当一些当前在这些节点上运行的请求完成后,作者才能调度更多请求到这些计算节点。这个屏蔽确保了作者不会过度订阅GPU的KV缓存。

5 Evaluation

在本节中,作者旨在回答以下问题。

图4:每个边上的数字表示集群图抽象中的最大流过该边的流量。Helix的请求调度程序使用这些数字作为权重,以执行交错加权轮询调度,以形成每个请求的 Pipeline 。用于调度请求1和2的 Pipeline 显示在右侧。

  • Helix在不同设置下是否能够提供比现有系统更高的吞吐量(第5.3节)?
  • Helix是否为了获得高吞吐量而牺牲延迟(第5.3节)?
  • 网络异构性如何影响Helix的性能(第5.4节)?
  • 异构程度如何影响Helix的性能(第5.5节)?
  • Helix为何能够比现有系统实现更好的性能(第5.6节和第5.7节)?### 实现

Helix原型 作者用Python(1.5k行代码)和C++(1.7k行代码)实现了一个多副本 Pipeline 并行系统。对于模型执行引擎,作者采用了最新版本的vLLM [16](0.4.0post1),以避免重新实现基本的LLM推理优化,如迭代级调度和PageAttention。由于请求可能只执行节点中所有本地层的子集,作者实现了一个对所有本地层统一的页面池。对于节点间的通信,作者使用ZeroMQ [38] 来传输元数据和中间张量。作者使用Gurobi [10] 作为MILP的求解器。

模拟器 除了原型系统之外,作者还构建了一个基于事件的模拟器,用于在异构集群中进行分布式LLM推理,用Python编写了14k行代码。作者使用从原型系统收集的剖析数据调整模拟器,以达到高保真度。运行模拟比真实系统快得多,所需的计算量也更少。它还允许作者探索更多样化的网络条件、机器异构性和集群规模设置。作者在第5.3节中测试了模拟器与原型系统的保真度。

Experiment Setup

模型。 作者在LLaMA [40, 41] 上评估Helix,这是一个代表性且流行的开源Transformer模型家族。具体来说,作者使用LLaMA 30B和LLaMA 70B研究不同规模模型上的系统性能。作者使用半精度(FP16)运行模型推理。

集群设置。

作者使用三种集群设置进行评估:

(1) 单集群,(2) 分布式集群和(3) 高GPU异构性。

在 单集群设置 中,作者在Google云的一个区域内创建了一个异构集群,包含4个A100节点,8个L4节点和12个T4节点。作者的评估侧重于单GPU节点,因为多GPU节点在云上难以分配 [39],同时作者的实现也适用于多GPU节点,通过在相同节点上的GPU之间利用张量模型并行性,正如vLLM [16] 所支持的。机器之间的平均传输带宽为10 Gb/s,平均延迟小于1ms。分布式集群设置 包含三个集群,分别包含4个A100节点,2个L4节点+8个T4节点,以及6个L4节点+4个T4节点。集群内部网络条件与单集群设置相同。集群间通信的平均带宽为100 Mb/s,平均延迟为50 ms(根据作者在Google Cloud上的分析结果)。在用于模拟的 高GPU异构性 集群中,集群包含4个A100节点,6个V100节点,8个L4节点,10个T4节点,4个2L4节点,6个2T4节点和4个4 T4节点。多GPU节点为其分配的层运行张量并行。

痕迹。 作者使用的痕迹来自Azure Conversation数据集 [27]。图5显示了该数据集的长度分布和到达率。作者移除了输入长度超过2048或输出长度超过1024的请求,以适应作者使用的GPU。修剪后的数据集包含16657个请求,平均输入长度为763,平均输出长度为232。作者有两个到达率的设置。对于 在线设置 ,作者使用Azure Conversation数据集的真实到达率。作者将平均到达率缩放至集群峰值吞吐量的75%,以避免请求激增导致系统内存不足。对于 离线设置 ,作者允许请求以充分利用集群的速度到达。这模仿了在数据集上运行离线推理。作者将这两个设置称为 在线 和 离线服务。

picture.image

实验持续时间。 对于在线设置,作者预热集群30s,测试30分钟。对于离线设置,作者预热集群1分钟,测试10分钟。这段时间足以进行作者的评估,并且作者不运行更长时间以减少不必要的实验成本。

Helix设置。 作者允许MILP求解器搜索是否进行部分推理以及是否进行集群剪枝。作者还提示MILP求解器使用Petals / Swarm /独立 Pipeline 的解决方案。当MILP求解器在10分钟内找不到更好的解决方案时,求解时间会超时。每个集群设置的总搜索预算为在14核CPU上4小时。

就作者所知,目前没有适用于作者设置的可应用于模型放置和调度的异构LLM服务系统。因此,作者采用了来自异构LLM训练系统Swarm [31] 的想法来构建一个有竞争力的异构 Baseline 。作者还构建了另一个基于同构 Pipeline 的 Baseline ,该 Baseline 为每种类型的机器运行一个独立 Pipeline 。作者将这两个 Baseline 称为Swarm和独立 Pipeline (SP)。对于Swarm,作者在作者的系统中实现该方法,因为原始系统是针对训练设计的,不能直接用于推理。作者的实现确保提示和译码阶段的请求始终遵循同一路径,这对于推理的正确性至关重要。作者将 Pipeline 阶段的数量设置为允许集群中最弱的GPU持有其VRAM一半的一个阶段层的最小值。这最小化了 Pipeline 深度并在GPU上留有足够的VRAM用于KV缓存,这两者对性能都至关重要。对于独立 Pipeline ,每个 Pipeline 服务一个模型的副本,并且层在 Pipeline 内的机器之间平均分配。

指标。 对于离线服务,作者报告平均 译码吞吐量,即每秒生成的 Token 数。对于在线服务,作者进一步报告平均 提示延迟 和 译码延迟,即解析用户输入和生成新 Token 的平均延迟。

Single Cluster

真实系统评估。 本节评估了Helix原型系统在单一集群设置下的表现。作者针对在线和离线服务评估了LLaMA 30B和LLaMA 70B,形成了四组实验。每种方法对在线和离线服务使用相同的模型放置计划。不同方法在离线和在线服务中解码吞吐量的比较如图6所示。在线服务中不同方法的提示和解码延迟比较如图7所示。

picture.image

picture.image

离线服务。 对于LLaMA 30B,每种类型的计算节点都能够独立服务一个单独的 Pipeline 。在这种情况下,Helix模型放置规划器找到的最佳模型放置包含三个独立的 Pipeline 。尽管由于第4.2节中的KV缓存估计启用的KV缓存更好利用而带来的小性能增益,Helix的整体性能与独立 Pipeline 非常接近。Swarm的模型放置计划引入了瓶颈并且未充分利用A100节点,作者将在5.6节中详细讨论这一点。因此,与Swarm相比,Helix在解码吞吐量上实现了2.14倍的提升。

对于LLaMA(70B),情况大不相同。当每种类型的机器服务一个 Pipeline 时,大部分GPU VRAM将被用于模型参数,没有足够的空间用于KV缓存,这大大限制了解码吞吐量。在这种情况下,独立 Pipeline 的解码吞吐量显著下降。与LLaMA 30B情况类似,Swarm在其模型放置计划中引入了瓶颈,导致A100和L4节点的利用不足。因此,与Swarm和独立 Pipeline Baseline 相比,Helix分别实现了1.94倍和1.86倍的解码吞吐量。

在线服务。 对于LLaMA 30B,Helix与独立 Pipeline Baseline 的提示和解码延迟相似,因为模型放置是相同的。另一方面,Swarm的提示延迟比Helix高47%,解码延迟比Helix高13%,尽管其吞吐量只是Helix的一半(图5(a))。原因是Swarm未充分利用A100节点,导致大部分计算在较慢的L4和T4 GPU上进行,作者将在5.6节中用一个例子详细讨论这个问题。对于LLaMA 70B,运行独立 Pipeline 会产生最低的提示和解码延迟。原因是8个L4和12个T4节点受到KV缓存容量的严重限制(太多VRAM用于参数)并且服务吞吐量非常低。大多数请求由4个A100节点服务,这些节点的延迟非常低。然而,这导致了L4和T4节点计算能力的严重浪费,因此如图5(b)所示,吞吐量较低。

模拟器保真度评估。 作者还在第5.1节提到的模拟器中进行了相同实验的单集群设置,然后将结果与真实机器实验的结果进行比较。图5(a)和5(b)显示,对于在线服务实验,在集群以75%峰值吞吐量运行时,模拟与真实评估结果的平均解码吞吐量差异小于1%。图7显示了在线服务实验的提示和解码延迟比较。作者发现对于所有方法,LLaMA 30B和70B的常量差异约为150ms。经过分析,作者确定这种差异是由于模拟器中没有建模的CPU-GPU数据传输开销。由于所有方法之间的差异是一致的,因此它不影响它们之间的比较。对于离线服务实验,图5(c)和5(d)显示模拟器报告了所有方法的持续较高吞吐量。这个差距也是由于未建模的恒定CPU-GPU传输开销造成的。由于不同方法之间的差异是一致的,因此模拟器仍然有价值,因为它达到了比较不同方法性能的目的。

Distributed Clusters

在本节中,作者在模拟环境中用分布式集群设置评估了Helix。与单集群实验类似,作者针对在线和离线服务评估了LLaMA 30B和70B模型。图8展示了解码吞吐量的对比。对于LLaMA 30B,与单集群设置相比,所有方法的解码吞吐量下降了10-20%。对于LLaMA 70B,所有方法的解码吞吐量下降了一半。这源于集群间网络连接较慢,较大模型受到的影响更大,因为它们需要一个更深的 服务流水线。对于受到慢网络严重影响 的LLaMA 70B,作者发现Helix的模型放置最大流水线深度比Swarm短了28%,因为Helix的MILP模型放置规划器找到了更好的放置策略,将更多层加载到L4和A100机器中以减少网络通信。通过比较Helix在单集群和分布式集群设置下为LLaMA 70B的模型放置(仅在网络条件上有所不同),分布式集群的模型放置将流水线深度减少了19%。这表明Helix的模型放置考虑了网络条件,这比Swarm和独立流水线分别提高了2.0和1.5的效率。

picture.image

图9展示了在线服务中的提示和解码延迟对比。对于LLaMA 30b,Helix与独立流水线具有相似的延迟,因为在这种情况下两种方法都使用了相同的模型放置。另一方面,Swarm的延迟要高得多,原因与第5.3节相同。对于LLaMA 70B,独立流水线具有最低的延迟,因为12个较慢的T4节点受到内存限制,只贡献了总吞吐量的四分之一。T4的计算能力未充分利用将解码延迟改善了28%,但代价是解码吞吐量下降了45%。对于Swarm,当集群以峰值吞吐量运行时,作者观察到严重的拥塞。平均提示延迟达到了70秒,是Helix的7.5。作者将在第5.7节通过一个案例研究进一步讨论Swarm的拥塞问题。

picture.image

Cluster Heterogeneity

本节在增加集群异质性的情况下评估了Helix,在由42个节点和7种节点类型组成的模拟集群中对LLaMA 70B进行离线服务。图8(e)展示了解码吞吐量的对比。在这个集群中,V100、T4和T42节点本身无法形成单独的流水线。作者报告了在没有这些机器的情况下单独流水线的吞吐量 Baseline 。作者还尝试使用这些机器构建混合流水线,并将混合流水线的结果报告为单独流水线+。结果显示,与Swarm、单独流水线和单独流水线+相比,Helix分别实现了1.38、2.72和2.11的吞吐量。

Model Placement Deep Dive

在本节中,作者分析了不同的模型放置方法对集群服务吞吐量的影响。作者使用LLaMA 70B在单集群和分布式集群设置中进行离线服务测试。作者将Helix的模型放置规划器与Swarm的以及Petals的[4]进行了比较,后者是一个去中心化的异构LLM推理系统。作者在这里与Petals进行比较,因为它只有一个模型放置策略,没有集中的调度方法,因此在端到端的评估中不直接适用。Swarm将模型层划分为等长的阶段,并为每个阶段分配节点,使得每个阶段具有相等的计算量。而Petals则允许节点承载不同数量的层。它旨在实现去中心化的LLM服务,因此逐个节点地决定模型放置,并贪心地选择涵盖计算量最少层的放置策略。为了避免不同调度方法的影响,以便隔离模型放置的效果,作者为所有方法使用了Helix的请求调度器。图10左图显示,在单集群设置中,Helix相对于Petals和Swarm分别实现了1.23倍和2.10倍的解码吞吐量。这与作者在原型系统中的观察结果相匹配。对于分布式集群设置,Helix的相对吞吐量分别为Petals和Swarm的1.34倍和2.49倍。作者通过一个案例研究来解释为什么Helix的模型放置方法能实现最佳性能。

picture.image

案例研究:LLaMA 70B - 单集群。 图10右图显示了在单集群设置中为LLaMA 70B提供服务时,每种方法的模型放置的GPU计算利用率。Swarm找到的模型放置在其 Pipeline 末端存在瓶颈,即4个T4节点各自服务4层。这个瓶颈导致A100和L4节点的GPU利用率不足,显著降低了服务吞吐量。对于Petals的模型放置,没有明显的瓶颈。然而,该放置仍然未能充分利用8个T4节点和1个L4节点,对服务吞吐量产生了负面影响。对于Helix找到的放置策略,几乎所有节点都得到了充分利用。计算节点的有效使用使得Helix能够超越 Baseline ,吞吐量最高达到2.10倍。

Request Scheduling Deep Dive

在本节中,作者分析了不同的请求调度方法对集群服务吞吐量的影响。作者使用离线服务在单集群和分布式集群设置中测试了LLaMA 70B。作者将Helix的请求调度器与以下方法进行了比较:(1) Swarm,该方法按照吞吐量成比例选择下一级节点;(2) 随机调度,在调度时随机选择下一个节点。为了消除模型放置的影响,所有方法都使用Helix找到的模型放置计划。图11左图显示,对于单集群设置,使用Helix的调度可以使服务吞吐量提高23%。对于分布式集群设置,Helix的吞吐量提高了12%。单集群设置下的改进与作者在原型系统中的观察相符。此外,运行时监控显示Swarm和随机调度存在严重的拥塞。作者将在一个案例研究中进一步说明这一点。

picture.image

案例研究:LLaMA 70B - 分布式集群。 图11右图显示了Helix的模型放置规划器为分布式集群设置中的LLaMA 70B生成的模型放置计划。该模型计划尽可能避免使用缓慢的跨集群网络连接,但仍然有一些计算节点通过低带宽连接。当使用Swarm或随机调度来调度请求时,作者观察到图中所标记为“拥塞”的三条链路上的严重拥塞——提示阶段请求在这些链路上平均排队5至16秒才能传输。作者找到了造成拥塞的责任节点,并在图中将它们标记为橙色。令人惊讶的是,作者发现其中一个拥塞是由距离三个节点远的节点的不良调度引起的。这证实了需要一种能同时考虑网络和计算的全局调度方法的必要性。作者还观察到,在分布式集群设置中,Swarm在其为LLaMA 70B找到的模型放置上运行请求调度时也存在类似的拥塞情况。

Ablation Study on Optimization

本节对第3.4节中引入的两个MILP优化进行了消融研究。作者使用第5.4和5.5节的LLaMA 70B设置进行消融实验。作者将其称为24节点和42节点设置。

簇剪枝。 当启用簇剪枝时,作者会剪除网络连接,使得每个节点的平均度数为12。正如作者下面所讨论的,这个连接数对于LLM推理系统来说已经足够。这对于24节点设置剪除了50%的网络链接,对于42节点设置剪除了72%的网络链接。表4显示,剪枝分别将两个设置的问题规模减少了大约40%和50%。作者还比较了在启用与不启用簇剪枝的情况下,找到的最佳模型放置的离线解码吞吐量。图11(a)的结果显示,对于这个问题实例,在两个设置中启用剪枝后,Helix的性能分别提高了16%和4%。作者注意到,实现的加速程度会根据手头MILP问题的具体实例而有所不同。原因是,在LLM服务中,所使用的网络连接非常稀疏——通常每个节点只与少数其他节点通信。此外,有许多等效的模型放置可以实现相同的吞吐量。剪枝簇很可能使其中一些放置仍然有效。这使得在有限的优化时间内寻找这些放置更容易,因为问题规模(和解空间大小)减少了。

picture.image

初始值。 作者比较了从启发式方法的解和默认值开始运行Helix的模型放置规划器的性能。由于两种方法找到的最佳模型放置是相同的,因此作者比较了找到放置的墙钟时间。图11(b)显示,对于这个问题实例,在两种设置中,从启发式解运行MILP所需的时间分别多了43%和8%。作者注意到,实现的加速程度会根据手头MILP问题的具体实例而有所不同。结果表明,从启发式解开始加快了Helix中的模型放置。

6 Related Work

picture.image

机器学习模型服务 有大量关于服务机器学习模型的工作,讨论的方面包括系统实现[23, 24],模型放置,以及请求调度。然而,由于LLM独特的自回归执行范式,这些方法未能有效地服务LLM。相反,许多最近的特定于LLM的系统解决了LLM服务中不可预测的执行时间和高内存消耗问题。Orca [46] 提出了迭代级调度,一旦请求完成就释放资源。vLLM [16] 引入了PageAttention,通过分配确切的页数来进一步减少每个请求的内存消耗。Speculative Inference 应用一个小型模型来预测多个输出标记,并在单一迭代中验证它们。Splitwise [27] 和 DistServe [50] 发现,将提示和解码阶段分解可以提高吞吐量,因为这两个阶段有不同的工作负载特征。Sarathi [2] 引入了分块预填充,为提示阶段分配预算以使每个微批处理的工作负载平衡,最小化流水线气泡。以上所有工作与作者的工作正交,并且可以整合到作者的系统中,因为作者的重点是集群异质性。

异构集群上的ML工作负载 几种方法探索了利用异构GPU进行ML任务的潜力。其中一些方法[14, 26] 共同设计模型分割和放置在异构集群上,但假设有统一的网络带宽。Learninghome [32] 和 DeDLOC [7] 研究了在去中心化集群上的网络感知路由,但只单独考虑了数据或流水线并行。SWARM [31],如第2.1节所述,优化了异构网络中的流水线通信。然而,它仅通过下一阶段的元数据来进行调度,缺乏全局视图。还有一些努力使用近似方法来减少网络通信[42]或同步[12]。它们大多数关注模型训练。在模型推理中,尤其是LLM,使用异构和地理分布式GPU的服务还没有得到很好的研究。SkyPilot [45] 和 Melange [8] 为请求选择最佳的GPU类型,但每个请求仅由单一GPU类型服务。Petals [4],如第2.1节所述,研究了一种去中心化的流水线并行设置。它为动态设备组设计了贪心模型分配和请求调度,失去了对固定设备组的优化机会。

7 Conclusion

这篇论文介绍了Helix,这是首个针对异构GPU集群的高吞吐量、低延迟的大规模语言模型服务引擎。Helix将层放置和请求调度公式化为一个最大流问题,并加以解决。与现有解决方案相比,Helix在吞吐量和延迟方面实现了显著改进。

参考

[1].Helix: Distributed Serving of Large Language Models via Max-Flow on Heterogeneous GPUs.

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
云原生数据库 veDB 核心技术剖析与展望
veDB 是一款分布式数据库,采用了云原生计算存储分离架构。本次演讲将为大家介绍火山引擎这款云原生数据库的核心技术原理,并对未来进行展望。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论