首页 > 其他分享 >无干扰推理:混合下游工作负载的 分解LLM 推理

无干扰推理:混合下游工作负载的 分解LLM 推理

时间:2024-07-02 09:30:25浏览次数:23  
标签:负载 请求 填充 解码 调度 实例 LLM 推理

24年1月来自中科院和华为云的论文“Inference without Interference: Disaggregate LLM Inference for Mixed Downstream Workloads”。

基于 Transformer 的大语言模型 (LLM) 推理服务现已成为许多云服务的骨干。LLM 推理包括预填充阶段和解码阶段。然而,现有的 LLM 部署实践往往忽视了这些阶段的不同特点,从而导致严重的干扰。为了减轻干扰,根据推理请求的特点仔细调度和分组推理请求。通过三大支柱,在 TetriInfer 中实现了这个想法。首先,它将提示分成固定大小块,加速器总是接近其计算饱和极限。其次,它分解预填充和解码实例,以便每个实例都可以独立运行。最后,它用一个智能两级调度算法并增强预测资源使用情况,避免解码调度热点。结果表明,TetriInfer 在性能/美元方面大幅提高了第一个token时间 (TTFT)、作业完成时间 (JCT) 和推理效率,例如,它使用的资源减少了 38%,同时平均 TTFT 和平均 JCT分别降低了 97% 和 47% 。

自 ChatGPT 以来,基于大语言模型 (LLM) 的服务已在日常生活中发挥着至关重要的作用。要运行推理请求,LLM 模型将首先获取用户输入以生成第一个 token(称为预填充阶段),然后以自回归方式逐个 token 生成输出(称为解码阶段)。

有多种方式可以与 LLM 交互,从简单的聊天到更复杂的下游任务,例如文档摘要、内容创建等。因此,支持 LLM 的服务可处理具有截然不同属性的推理请求,这些属性可分为两个维度:预填充阶段的输入提示长度和解码阶段的生成 token 长度。如图所示,摘要任务具有较长的输入提示和较短的生成tokens,而上下文创建任务则相反。不同下游任务的tokens长度可能相差两个数量级以上。

请添加图片描述

鉴于来自各种下游任务的 LLM 推理请求存在显著差异,第一个研究的问题是,这些推理请求在一起运行时的表现如何?为了回答这个问题,大量测试混合了不同长度的 LLM 预填充和解码请求。不幸的是,所有组合都存在严重干扰。例如,混合预填充请求可能导致速度减慢 10 倍,组合预填充和解码请求可能导致速度减慢 5 倍,而混合不同长度的解码请求可能会导致 16% 的吞吐量损失。避免干扰的一个简单解决方案是静态地为每个下游任务配置资源。

鉴于 LLM 服务基础设施的高成本,这种解决方案是不切实际的。为此,第二个研究的问题是,如何构建一个最小化干扰的分布式 LLM 推理服务系统?

LLM 推理,是根据输入提示生成输出tokens序列的过程。此过程包含两个阶段:预填充和解码。预填充阶段输出第一个token并生成K-V缓存以供将来解码 [21]。解码阶段使用之前的 KV 缓存以自回归的方式逐步生成新tokens。通常,预填充阶段受计算限制,而解码阶段受内存限制 [33]。如图所示,实验结果表明,一旦加速器在一定数量的tokens上达到饱和(称为加速器饱和阈值),预填充阶段的吞吐量就会保持平稳。解码阶段的吞吐量会随着批次大小的增加而继续增加,但一旦内存带宽饱和就会达到稳定水平。

请添加图片描述

为什么存在干扰?根本问题在于,当前的 LLM 部署实践没有考虑到 LLM 预填充和解码阶段所表现出的不同特征。具体来说,预填充阶段类似于计算繁重的批处理作业,其计算量与输入提示长度成二次方关系。解码阶段类似于内存密集型、延迟-关键型任务,其资源使用量与生成的tokens长度成亚线性关系 [33]。

在测试中观察到的干扰,是经典的系统问题。运行预填充请求,会导致严重的减速,因为这是在饱和的硬件继续添加计算繁重的作业。结合预填充和解码请求会对两者造成损害,因为系统在同时运行批处理和延迟关键型作业。混合解码请求会导致吞吐量下降,因为不知道内存带宽和容量使用情况,从而导致争用和队头(head-of-line)阻塞。

TetriInfer 是一个旨在对抗干扰的 LLM 推理服务系统。如图展示其工作流和架构图:(a) 比较现有系统和 TetriInfer 的执行时间线,现有系统有两个节点运行混合预填充和解码,TetriInfer 将预填充和解码实例分开,这允许在不同的按需解码实例之间对长解码任务进行负载平衡;每个时间线包含四轮(R1 到 R4),预填充和解码框的长度表示它们的序列长度,解码框的宽度表示其资源使用情况;更宽的解码框表示存在较长的生成tokens,从而导致更大的资源使用率和解码延迟;(b) 显示 TetriInfer 的架构,其中突出显示了四个核心模块:集中控制平面、预填充实例、解码实例和长度预测模型。

请添加图片描述

集中控制平面。它由一个全局调度程序和一个集群监视器组成。全局调度程序根据负载将请求发送到预填充实例,并接收来自解码实例的流输出。集群监视器从预填充和解码实例收集统计信息,并定期将负载信息广播到预填充实例。它添加、删除和翻转预填充或解码实例。

预填充实例。它们仅运行 LLM 推理请求的预填充阶段。每个预填充实例都有一个本地调度程序、一个长度预测器、主 LLM 引擎和一个调度程序。所有请求都经过四个步骤。1)本地预填充调度程序根据预定义的策略对请求进行排序。2)长度预测器运行预测模型来推测请求的解码长度,然后使用它们来估计解码阶段的资源使用情况。3)主 LLM 引擎将所有请求划分为固定块。4)对于每个请求,调度程序运行解码间负载平衡算法来选择一个解码实例,然后将生成的 KV 缓存转发给它。

解码实例。它们实际上与预填充实例分离,并且仅运行 LLM 推理请求的解码阶段。每个解码实例都可以接收来自任何预填充实例的请求。它运行一个本地调度程序,该调度程序具有三个预定义策略,用于选择要在主 LLM 引擎中运行的解码请求。

长度预测模型。预测模型是一个小型 LLM 模型,经过离线微调,用于预测 LLM 推理请求的生成长度。TetriInfer 的预填充调度程序和解码实例的本地调度程序利用推测的信息来调度解码实例并避免测量热点。预测模型很小,部署在所有预填充实例上。

预填充实例的调度程序对于改善预填充阶段的延迟和吞吐量至关重要。调度程序维护一个原始请求队列,该队列存储来自全局调度程序的请求,以及一个存储排序请求的调度队列。在这项工作中,实现了三种调度程序策略:先到先服务 (FCFS)、最短作业优先 (SJF) 和最长作业优先 (LJF)。

如图是预填充调度程序策略。左侧显示四个原始推理请求(R1 至 R4)。右侧显示使用 FCFS、SJF 和 LJF 的调度请求。这种分块版说明了切片和合并(C1 至 C4)。具体而言,FCFS 保持原始请求到达顺序。提示tokens按顺序划分并合并为块。此策略最容易实现,并且最适合具有相似提示长度的推理请求。但是,当请求具有较长的提示时,FCFS 可能导致队头阻塞和较高的平均作业完成时间 (JCT)。这是有问题的,因为 LLM 推理请求之间的长度差异超过三个数量级。

请添加图片描述

如图是预填充预测模型的微调和预测流程。目标模型是想要预测其解码行为的模型。预测模型是训练的模型,不涉及在线微调。在此过程中,训练预测模型(以红色表示)以推测特定目标模型(以蓝色表示)的解码行为。预测模型的微调涉及三个关键步骤。首先,组装一个从公共数据集继承的仅提示训练数据集、一个大型目标 LLM 模型(例如 OPT-13B)和一个用于预测模型的分类模型(例如 125M OPTForSequenceClassification [16])。其次,向目标 LLM 模型发送训练提示,该模型生成响应。随后,将生成的响应分类到具有选定粒度的固定大小存储桶中。例如,使用粒度 100,token长度在 0 到 200 之间的响应 tokens 类别为 0,在 200 到 400 之间的响应 tokens 类别为 1,依此类推。这些标签与训练提示配对以创建新的数据集。最后,将新数据集划分为训练部分和评估部分,然后继续使用该数据集训练和评估预测模型。

请添加图片描述

一旦主 LLM 完成其预填充阶段,预填充的 KV 缓存就会在加速器的内存(例如 GPU 的 HBM)中生成。目标是将此缓存传输到所选解码实例的加速器内存,不管系统部署在哪个硬件平台上。这很有挑战性,因为预填充和解码实例之间存在多个物理数据链路,每个链路都需要不同的软件堆栈。

将现有的物理数据链路分为三类,如图所示。第一种称为Direct,其中加速器具有直接连接的高速链路,例如 NVLink [40] 或 HCCS [13]。可以使用低层内存复制原语 [14, 26] 或收集库 [28] 通过这些链路传输数据。第二种称为 Direct-NIC,其中加速器通过其配套 NIC 进行通信。可以使用定制库 [27] 通过 PCIe 和以太网(或 Infiniband)传输数据。第三种称为Indirect,没有直接链接,加速器必须通过其配套的 CPU DRAM 反弹数据,从而产生额外的内存复制。图中还将利用上述数据链接的网络堆栈分为单侧和双侧,类似于 RDMA 的分类。GPU 或 NPU 等加速器可以进行单侧内存访问,因为它们具有低级原语,例如设备之间的直接内存复制 [14, 26]。为了导航复杂的物理数据链接并确保 TetriInfer 在部署后始终能够使用性能最高的链接,设计一个统一的网络传输抽象来利用图中列出的不同网络堆栈选项。堆栈公开发送、接收、读取、写入等 API。调度程序调用这些 API 将 KV 缓存传输到远程解码实例。

请添加图片描述

在解码实例中,一旦选择了实例,将执行图中所示的步骤。要翻转预填充实例,全局调度程序会停止转发请求,然后向其发送翻转请求。预填充实例将等到所有排队的请求都耗尽。然后,翻转实例。翻转解码实例稍微复杂一些。全局调度程序通知所有预填充实例停止将请求转发到选定的解码实例,并通知解码实例完成翻转。请注意,实际翻转快速而简单。它涉及更改内部变量,而无需重新启动流程或重新加载模型。在当前的实现中,两个实例翻转大约需要 5 到 7 毫秒,不包括动态耗尽时间。

请添加图片描述

从头开始用 Python 实现 TetriInfer 的集中控制平面。采用基于 vLLM [21] 的预填充和解码实例。除了统一网络堆栈之外,大多数核心模块都是用 Python 实现的,统一网络堆栈使用 C++ 与低级 API 和 IB Verbs 交互以进行网络传输。此外,还实现了一种基于共享内存的通信机制,可以跨 Python 和 C++ 语言快速传输命令。微调部分使用 HuggingFace Transformer [16] 提供的 Trainer API。

预填充或解码实例是一个可部署的单元,部署时由两个进程组成。对于预填充,它有一个运行调度程序、长度预测器和主 LLM 的 Python 进程,以及一个运行调度程序和网络堆栈的 C++ 进程。对于解码,它有一个用于运行调度程序和主 LLM 的 Python 进程,以及一个运行网络堆栈的 C++ 进程。

由于高端硬件可用性有限,当前的实现仅支持使用sockets的Indirect类型。为了评估 TetriInfer 在不同硬件配置下的性能,实现了一种模拟机制来模拟不同的网络带宽。该机制的工作原理如下:对于给定的一组请求,首先离线运行它们的预填充阶段以获取其预填充的 KV 缓存。在测试之前,将这些预填充的 KV 缓存加载到解码实例的本地内存中。当测试开始时,预填充实例仅将请求元数据传输到解码实例,而不传输实际的预填充 KV 缓存。随后,解码实例计算 KV 缓存传输的延迟并进行相应等待。此延迟根据特定的模型架构和要模拟的硬件带宽计算。

标签:负载,请求,填充,解码,调度,实例,LLM,推理
From: https://blog.csdn.net/yorkhunter/article/details/140116290

相关文章

  • 一文读懂“负载均衡”
    原文链接:https://blog.csdn.net/cyl101816/article/details/135195729负载均衡无处不在,无论是分布式,还是中间件,还是微服务,都需要涉及到负载均衡。一、什么是负载均衡负载均衡是一种在计算机网络和系统架构中使用的技术,用于均衡分发工作负载到多个资源,比如:服务器、计算节点或存储......
  • Windows上实现nginx的多负载,实现高可用,NLB 替代keepalived
    【转】https://blog.csdn.net/fcclzydouble/article/details/122841013NLB就是网络负载平衡,windowsServer2012中该功能允许你将传入的请求传播到最多达32台的服务器上,即可以使用最多32台服务器共同分担对外的网络请求服务。网络负载平衡,保证即使是在负载很重的情况下它们也能......
  • ​RAG与LLM原理及实践(7)--- Chroma query应用层策略及实现原理
    背景Chromaquery底层查询的 query思想是相同的,甚至在vectordb的世界中,都大同小异。如果你有看前面写的  RAG与LLM原理及实践(5)---Chromaquery源码分析应该比较清楚query的运作原理,说直白就是在memory或是disk中通过暴力查询比较与HNSW算法(NSW算法的变种,分层可导航......
  • RAG与LLM原理及实践(6)--- Chroma collection及存储逻辑分析
     背景在chromavectordb的世界中,除了对query的理解,另外就是需要深入理解chroma的运行模式,chroma运行时,提供了 local模式,server-client模式,这些在应用中固然重要,但从实现原理上说,其实就是通过http服务,在固定端口如11344上请求数据。但是在这之前,需要深入了解并理解coll......
  • RAG与LLM原理及实践(4)--- 语义相似度距离衡量的三种方式chroma示例
    语义相似度的计算是一个比较复杂的过程。今天打算先比较详细的介绍下几个相似度的距离衡量算法。相似度的排名衡量,在向量数据库vectordb的query中,被大量使用。还是直接上干货,理解下背后的逻辑和概念比较重要,后面看看源码 chromavectordb是怎么处理这个过程的。1)co......
  • LLM大模型基础入门系列之:(四)从头开始编写LLM代码
    〔更多精彩AI内容,尽在「魔方AI空间」公众号,引领AIGC科技时代〕本文作者:猫先生引言本文是LLM基础入门系列的第4篇。在本文中,我们将从头开始实现一个类GPT的transformer。将按照上一篇文章中《LLM大模型基础入门系列之:(三)Transformer架构》描述的步骤对每个部分......
  • U-KAN环境搭建&推理测试
    ​引子U-Net的鼎鼎大名,我觉得无需我多言了。图像分割和扩散概率模型的基石。作者探索了KANs在改进视觉任务Backbone网络方面的未开发潜力。作者研究、修改并重新设计已建立的U-NetPipeline,通过在标记化的中间表示上整合专用的KAN层,称之为U-KAN。严格的医学图像分割基准测试验......
  • Nginx和Tomcat负载均衡,动静分离
    Nginx和Tomcat负载均衡,动静分离目录Nginx和Tomcat负载均衡,动静分离一、反向代理1、反向代理的概念2、反向代理的优势3、Nginx四层反向代理和七层反向代理二、Nginx动静分离实现原理1、动静分离的概念2、动静分离的原理3、Nginx静态处理优势三、Nginx负载均衡调度算法(6种)1、轮询(......
  • 2029年AI服务器出货量将突破450万台,AI推理服务器即将爆发式增长
    在2020年,新冠疫情与远程办公模式的兴起推动了所有类型服务器的出货量达到峰值,随后几年里,除了AI服务器之外的所有类别都回归到了正常水平。根据Omdia的研究数据,AI服务器的出货量在2020年急剧上升,并且至今未显示出放缓的迹象,预示着AI将成为数据中心应用的主导力量。Omdia在其《......
  • Nginx实现负载均衡的4种常用方式及路径匹配规则
    一、Nginx实现负载均衡的4种常用方式为:轮询模式、IP哈希模式、权重模式、最少连接实现负载均衡需要在http模块中配置使用upstream模块定义后台的webserver的池子,名为proxy-web,在池子中我们可以添加多台后台webserver,其中状态检查、调度算法都是在池子中配置;然后在se......