(个人论文阅读记录,新手,2025年大四,仅仅为记录,错了我会改正)
题目:Fast Distributed Inference Serving for Large Language Models
大规模语言模型的快速分布式推理服务

这个算法是整个 FastServe 系统的核心,旨在解决大语言模型推理服务中的队头阻塞问题,从而显著降低作业的排队延迟。
算法核心思想
传统的 MLFQ 在信息未知(不知道作业总执行时间)的场景下,通过让作业从最高优先级队列开始,并逐级降级来近似最短剩余时间优先调度。然而,LLM 推理是 "半信息未知" 的:
-
已知 :输入长度(因此可以准确预测第一个令牌的生成时间,即初始化阶段)。
-
未知:输出长度(因此不知道作业总共需要生成多少个令牌)。
SJ-MLFQ 的核心思想就是利用已知的输入长度信息,优化作业的初始队列放置策略,避免因初始化阶段过长而导致的无效降级和资源浪费。
算法组件与工作流程解析
1. 初始化与数据结构
-
输入:一组优先级队列 Q1,Q2,...,QnQ1,Q2,...,Qn,其中 q1<q2<...<qnq1<q2<...<qn 是每个队列对应的时间配额。新到达的作业集合 JnewJnew。
-
输出:本次迭代要执行的一个作业批次 JoutJout。
-
关键状态:每个作业维护其当前优先级 PjobPjob、饥饿时间 starveTimestarveTime 和已消耗的配额。
2. "Skip-Join" - 智能初始队列放置
这是算法最具创新性的一步。
-
问题:在传统 MLFQ 中,一个新作业(比如一个输入很长的作业)会进入 Q1Q1。但它的初始化时间 init_timeinit_time 可能远大于 q1q1,导致它刚一开始执行就必须被降级。这造成了不必要的调度开销,并且没有起到优先调度短作业的作用。
-
解决方案:当一个作业 jobjob 到达时:
-
系统通过预置的性能分析器,根据其输入长度预测出其初始化时间 init_timeinit_time。
-
算法不是将其放入 Q1Q1,而是跳过所有时间配额 qiqi 小于 init_timeinit_time 的高优先级队列。
-
它直接加入到第一个满足 qi≥init_timeqi≥init_time 的队列 QPjobQPjob 中。
-
-
伪代码对应 (Lines 6-9):
pseudocode
for job in J_in do init_time <- P.getNextIterTime(job) // 预测初始化时间 P_job <- min i, s.t. q_i >= init_time // 找到合适的初始队列 Q_{P_job}.push(job) // 跳过高端队列,直接加入 end for -
意义 :一个长作业从一开始就被识别出来,并被放置在与其计算需求相匹配的低优先级队列中,从而避免了它对高优先级队列中短作业的干扰。这本质上是一种隐式的优先级分配。
3. 迭代执行与状态更新
在每个调度周期,系统会为所有活跃作业生成一个新的输出令牌(如果它们准备好了)。
-
伪代码对应 (Line 11):
pseudocode
for job in {Q_1, Q_2, ..., Q_n} do job.outputNewGeneratedToken()这体现了 LLM 推理的自回归特性,每个作业独立推进其生成过程。
4. 完成处理与降级
-
完成处理:如果一个作业生成了结束令牌,则将其从系统中移除。
pseudocode
if job.isFinished() then Q_{P_job}.pop(job) -
降级 :如果一个作业没有完成,但已经耗尽了当前队列的配额(
job.depleteQuantum()),它就会被降级到更低优先级的队列。pseudocode
// Demote jobs. job.depleteQuantum() Q_{P_job}.pop(job), Q_{P_job + η}.push(job)-
ηη 是一个参数,控制降级的幅度。论文中提到通常设置为 1,即降到下一个优先级队列。设置 η>1η>1 可以加速长作业的降级。
-
意义:降级机制是 MLFQ 的核心。它确保那些需要长时间运行的作业(通常是输出很长的作业)不会长期霸占高优先级资源,从而保证了系统的响应能力。
-
5. 预防饥饿 - 优先级提升
这是保证公平性和控制尾延迟的关键机制。
-
问题:由于 Skip-Join 和降级,一个输入和输出都很长的作业可能会长期待在低优先级队列,永远得不到执行的机会,导致"饥饿"。
-
解决方案 :系统跟踪每个作业的等待时间(
starveTime)。当等待时间超过一个阈值 αα(例如 300ms)时,无论其当前优先级如何,都会被提升到最高优先级队列 Q1Q1。pseudocode
// Promote starved jobs. if job.starveTime >= α then Q_{P_job}.pop(job), Q_1.push(job) job.starveTime <- 0 -
意义 :这个机制在降低平均延迟 (通过优先处理短作业)和控制尾延迟(通过防止长作业饿死)之间取得了平衡。
6. 调度决策
最后,调度器从所有队列中收集准备好执行的作业,形成下一个要执行的批次。
-
它按优先级从高到低(Q1Q1 到 QnQn)扫描队列。
-
将准备好的作业加入 JoutJout,直到达到系统的最大批次大小 MaxBatchSizeMaxBatchSize。
pseudocode
for job in {Q_1, Q_2, ..., Q_n} do if job.isReady() and |J_out| < MaxBatchSize then J_out.push(job) end if end for
摘要:
大规模语言模型(LLMs)驱动了以ChatGPT为代表的新一代交互式AI应用。这类应用的交互特性要求LLM推理具备低延迟特性。现有LLM服务系统对推理任务采用运行至完成的处理模式,存在队头阻塞问题且导致延迟较高。
本文提出FastServe------一个面向LLMs的分布式推理服务系统。该系统利用LLM推理的自回归特性,实现了以单个输出令牌为粒度的抢占机制。通过采用具备跳过连接功能的多级反馈队列调度器,FastServe运用抢占式调度策略有效降低延迟。基于LLM推理特有的_半信息未知_场景,该调度器通过利用输入长度信息为每个到达任务分配合适的初始队列,并通过跳过比入驻队列更高级别队列的方式减少降级次数。我们设计了高效的GPU内存管理机制,可在LLM推理过程中主动在GPU内存与主机内存间卸载和上传中间状态。实验结果表明:在相同平均延迟和尾部延迟要求下,FastServe相比最先进的vLLM方案,吞吐量分别提升达31.4倍和17.9倍。
引言:
大语言模型(LLM)的技术进步为众多领域开辟了新可能,并催生了新一代交互式AI应用。最引人注目的当属ChatGPT[1],它使用户能够以对话方式与AI智能体交互,完成从语言翻译到软件工程等多种任务。ChatGPT令人印象深刻的能力使其成为历史上增长最快的应用之一[2]。众多机构紧随这一趋势,相继发布了LLM及类ChatGPT应用,如微软的新必应[3]、谷歌的Gemini[4]、Anthropic的Claude-3[5]、阿里巴巴的通义千问[6]等。
推理服务对于基于LLM的交互式AI应用至关重要。为了提供引人入胜的用户体验,这类应用的交互特性要求LLM推理具备低延迟。例如,用户期望其向ChatGPT输入的请求能得到即时响应。然而,LLM的规模与复杂性给底层推理服务基础设施带来了巨大压力。企业需要配置由GPU和TPU等加速器组成的庞大而昂贵的集群来处理LLM推理任务。
LLM推理具有不同于ResNet[7]等其他深度神经网络(DNN)模型推理的独特特性(§2)。DNN推理任务通常是确定性强且高度可预测的[8],即推理任务的执行时间主要取决于模型和硬件。例如,在同一GPU的同一ResNet模型上,不同输入图像的推理耗时相近。相比之下,LLM推理任务具有特殊的自回归 模式:一个LLM推理任务包含多次迭代,每次迭代生成一个输出令牌,且每个输出令牌会被追加到输入中,用于下一次迭代中生成下一个输出令牌。其执行时间既取决于输入长度,也取决于输出长度,而后者是事先未知的。
现有的推理服务解决方案(如Clockwork[8]和Shepherd[9])主要针对ResNet[7]这类确定性模型推理。它们依赖精确的执行时间剖析来调度任务,这不适用于执行时间多变的LLM推理。专为LLM推理设计的Orca[10]引入了迭代级调度,能在每次迭代结束时动态添加新任务或移除已完成任务。vLLM[11]进一步引入了PagedAttention来减少LLM推理任务中间状态的内存碎片。然而,这两者均采用先到先服务(FCFS)方式处理推理任务。一旦任务被调度,就会一直运行直至完成。由于GPU内存有限和严格的延迟要求,当前处理批次无法随意增加新到达的任务,因此长任务可能会阻塞后续任务,即队头阻塞[12]问题。该问题在LLM推理任务中尤为突出:一个大型LLM推理任务(即输入和输出长度较长)会长时间运行,阻塞后续的短任务。
图1基于真实数据集展示了该问题(详细设置见§6)。理想情况下,如果所有任务的输入和输出长度都相同,即使负载接近容量(load≈1load≈1),排队延迟也几乎为零,如图1前两列所示。然而,像ShareGPT[13]和Alpaca[14]这样的LLM数据集表明,真实工作负载是高度倾斜的。输出长度的长尾分布导致了漫长的排队延迟。图1显示,对于真实数据集,排队延迟最高可占总延迟的90%。在这种情况下,仅优化执行时间收效有限,因为它只占端到端延迟的一小部分。我们更需要优化排队延迟------它才是端到端延迟的主要构成部分。
我们提出FastServe,一个面向LLM的分布式推理服务系统。FastServe利用LLM推理的自回归特性和迭代级调度,实现了以单个输出令牌为粒度的抢占。具体来说,当一个被调度任务完成一个输出令牌的生成后,FastServe可以决定是继续执行该任务,还是抢占它并转去执行队列中的另一个任务。这使得FastServe能够通过抢占式调度来消除队头阻塞问题,并最小化延迟。
FastServe的核心是一个新颖的跳过连接 多级反馈队列(MLFQ)调度器。MLFQ是在信息未知环境下最小化延迟的经典方法[15]:每个任务首先进入最高优先级队列,若在阈值时间内未完成,则被降级至下一优先级队列。LLM推理与经典场景的关键区别在于它是半信息未知的------虽然输出长度事先未知,但输入长度是已知的。由于LLM推理的自回归模式,输入长度决定了生成第一个输出令牌的执行时间,该时间可能远大于后续令牌的生成时间(§4.1)。对于长输入、短输出的任务,首个输出令牌的执行时间占据了整个任务耗时的绝大部分。我们利用这一特性,通过"跳过连接"扩展了经典MLFQ:每个到达的任务并非总是进入最高优先级队列,而是通过比较其首个输出令牌的执行时间与各队列的时间配额,直接加入一个合适的队列,从而跳过更高优先级的队列以减少降级次数。
抢占式调度会引入额外的内存开销,以维护已开始但未完成任务的时间状态。LLM为每个Transformer层维护一个键值缓存来存储中间状态(§2.2)。在FCFS中,缓存只需存储处理批次内已调度任务的中间状态(受最大批次大小限制)。但在MLFQ中,更多任务可能已启动但被降级至低优先级队列,缓存必须为MLFQ中所有已启动但未完成的任务维护中间状态。考虑到中间状态的大尺寸和GPU有限的内存容量,缓存可能溢出。若简单地选择在缓存满时暂停启动新任务,则会再次引入队头阻塞。为此,我们设计了主动式GPU内存管理机制:当缓存接近满载时,主动将低优先级队列中任务的中间状态换出至主机内存;当这些任务即将被调度时,再将其状态换回。我们采用流水线和异步内存操作来提升效率。
对于单个GPU无法容纳的大模型,FastServe利用张量并行[16]和流水线并行[17]等并行化策略,在多个GPU上执行分布式推理服务(§4.3)。调度器以流水线方式并发运行多个任务批次,以最小化流水线气泡。键值缓存管理器在多个GPU间划分键值缓存,并以分布式方式处理GPU内存与主机内存之间的数据交换。
我们实现了FastServe的系统原型,并集成了PagedAttention[11]等多种优化技术。我们在真实LLM推理工作负载下,针对不同配置的LLM评估了FastServe。特别地,我们在16个NVIDIA A100 GPU上评估了FastServe服务OPT-175B[18](一个与最大GPT-3模型相似的开源LLM)的端到端性能。实验表明,与最先进的解决方案vLLM[11]相比,在相同的平均延迟和尾部延迟要求下,FastServe分别将吞吐量提升了高达31.4倍 和17.9倍。
2 背景与动机
2.1LLM推理与应用
LLM推理。LLM系列模型[18,19,20]建立在Transformer[21]架构之上。LLM推理以自回归方式运行:输入(通常称为提示)被作为令牌序列处理,随后模型会为待选择的下一个令牌生成概率分布。
每次输出令牌的处理和选择机制被称为一次迭代。经过海量语料库训练后,LLM能够执行高质量的语言任务。
例如,给定输入"knowledge is",模型分配给"power"的概率会高于"apple"。第一个输出令牌会被追加到初始提示后,并输入LLM以生成后续令牌。该过程持续进行,直到生成表示序列结束的独特<EOS>令牌,或达到预设的最大输出长度。这种推理过程与ResNet等其他模型存在显著差异------后者的执行时间通常是确定且可预测的[8]。虽然LLM模型中每次迭代的执行保持这些特性,但迭代次数(即输出长度)是可变的,导致总推理任务执行时间不可预测。
LLM应用。LLM的核心使命是为输入提示预测下一个令牌。利用提示工程[19],下游NLP任务可以被重新表述为基于LLM的生成任务。具体而言,对于翻译任务,可以在原文前添加"将以下英文文本翻译成法文"作为提示开头。通过这种方式,可以引导LLM生成所需的法文翻译文本。
ChatGPT[1]是基于LLM的典型应用。通过在原始GPT模型[19]上对对话任务进行监督微调,并结合基于人类反馈的强化学习进行对齐后,ChatGPT实现了与AI智能体的交互式对话,使用户能够处理广泛的任务。这些任务包括翻译、问答、摘要,以及更复杂的情感分析、创意写作和领域特定问题解决等。尽管能力卓越,但ChatGPT的交互特性给底层推理服务基础设施带来了巨大压力。由于需要快速响应,保持低延迟对于确保类ChatGPT交互应用的性能至关重要。
2.2推理服务系统
大多数现有推理服务系统(如TensorFlow Serving[22]和Triton Inference Server[23])对DNN模型不可知。它们作为底层执行引擎之上的抽象层,对到达任务进行排队,将任务分派给可用计算资源,并将结果返回给客户端。为充分利用GPU,它们通常将任务批量组合进行并行处理。通过批处理,多个任务的输入张量被拼接后整体送入模型。尽管利用率更高,但批处理的缺点是内存开销更大。LLM的巨大规模和海量中间状态限制了LLM推理的最大批处理大小[11]。
随着LLM的迅速普及,推理服务系统已演进至包含针对LLM独特架构和迭代生成模式的优化。LLM架构的主要部分是一系列Transformer层,如图2所示。在Transformer层中,掩码自注意力模块是将其与CNN等其他架构区分开的核心组件。在LLM推理的每次迭代中,注意力算子需要每个令牌的前序令牌的键 和值 。一种简单的无状态实现总是在每次迭代中重新计算所有前序键和值。为避免这种重新计算开销,fairseq[24]建议在迭代间将键和值保存在键值缓存 中。该优化将推理过程划分为两个不同阶段:初始化阶段 和解码阶段 。图3展示了两个阶段中键值缓存的使用。在对应于第一次迭代的初始化阶段 ,LLM为输入提示中的每个令牌生成键值缓存。在随后的解码阶段,LLM只需计算新生成令牌的查询、键和值,并利用预计算的键值缓存逐步推进过程。因此,解码阶段迭代的执行时间通常小于初始化阶段(即第一次迭代)。值得注意的是,其他基于Transformer的系统(如HuggingFace[25]和FasterTransformer[26])也采用了该优化技术,从而提高了推理效率。
另一项重要优化是Orca[10]提出的迭代级调度。简单的任务级调度会执行一个任务批次直至所有任务完成。提前完成的任务无法立即返回给客户端,而新到达的任务必须等待当前批次处理完成。然而,通过迭代级调度,执行引擎每次仅对批次执行单次迭代,为每个任务生成一个输出令牌。每次迭代后,已完成的任务离开批次,新到达的任务可以加入。尽管如此,GPU内存容量限制了最大批处理大小,而交互式应用的严格服务等级目标也在确定合适批处理大小中发挥作用。vLLM[11]通过引入PagedAttention进一步提升了LLM推理效率,该技术在推理过程中以块粒度逐步分配键值缓存,而非在开始时按最大输出长度分配。
2.3机遇与挑战
机遇:抢占式调度。现有LLM推理服务系统[10,26]的主要局限在于依赖简单的先到先服务调度和运行至完成执行模式。如图1所示,该方法导致严重的队头阻塞。在实际工作负载中,排队延迟最高可占总延迟的90%,显著影响LLM推理性能。为克服此挑战,可采用抢占式调度。在LLM推理中,每个任务包含多次迭代,每次迭代生成一个输出令牌。机遇在于利用这种自回归模式实现迭代级抢占,即一个任务在完成输出令牌生成后可以被抢占以执行另一个任务。借助抢占能力,调度器可以采用抢占式调度策略来预防队头阻塞并优化平均延迟。然而,抢占式调度给现有LLM推理系统带来了两大挑战。
挑战一:可变任务规模。最短剩余处理时间[27]是广泛用于最小化平均延迟的抢占式调度策略。然而,由于LLM的迭代特性,将SRPT应用于LLM推理存在挑战。与图像分类等一次性预测任务不同,LLM推理涉及多次迭代。虽然单次迭代(生成一个输出令牌)的执行时间可根据模型架构和硬件确定,但总迭代次数(即输出序列长度)仍然未知且难以预测,因为它取决于任务的语义。从与LLM对话收集的真实数据集(如ShareGPT[13]和Alpaca[14])显示出输出长度和输入长度的长尾分布[11]。因此,SRPT无法直接用于LLM推理以最小化平均延迟。
挑战二:GPU内存开销。与仅需为进行中任务维护键值缓存的运行至完成FCFS不同,抢占式调度策略在LLM推理中引入了额外的GPU内存消耗。抢占式调度必须为所有处于挂起状态的被抢占任务在GPU内存中保留键值缓存,以供未来令牌生成使用。这些键值缓存消耗大量GPU内存,带来潜在挑战。例如,一个输入序列长度为512的OPT 175B任务至少需要2.3 GB内存用于键值缓存(§4.2)。由于GPU内存容量稀缺,键值缓存的大小成为影响抢占式调度策略效力的关键因素。先前研究已提出键值缓存的内存节约技术。多查询注意力[28]和组查询注意力[29]通过注意力头间共享键值张量来减少内存消耗,但可能损害LLM能力,且内存消耗仍随序列长度线性增长。vLLM[11]以块粒度管理键值缓存以减少GPU内存碎片,但无法降低键值缓存本身的内存使用量。随着上下文长度增加[30],键值缓存的内存消耗成为一个难题且日益重要。
3 FastServe 概述
3.1期望特性
LLM具有独特特性,对分布式计算和GPU内存消耗构成挑战。我们的目标是开发满足以下三个要求的高效LLM推理服务系统:
-
低延迟与高吞吐量。我们专注于交互式LLM应用,用户对快速响应有很高期望。为量化衡量,我们希望在特定延迟要求下实现尽可能高的最大吞吐量。
-
高效的GPU内存管理。LLM在GPU内存消耗方面带来重大挑战,需要针对模型和中间状态的有效GPU内存管理方法。
-
可扩展的分布式执行。LLM的特性要求使用多个GPU实现有效的分布式推理,这需要系统支持跨GPU服务器的可扩展分布式执行。
3.2整体架构
图4展示了FastServe的架构。任务被提交到任务池。调度器利用任务分析器的信息确定初始任务优先级,然后将任务放入跳过连接MLFQ(§4.1)以缓解队头阻塞。
执行时,调度器基于跳过连接MLFQ中的优先级选择任务,形成预定义的最大批次大小,并将批次分派给分布式执行引擎以执行一次迭代。分布式执行引擎与分布式键值缓存协作,访问和更新相应任务的键值张量。为解决有限GPU内存容量的挑战,键值缓存管理器主动在GPU内存和主机内存之间交换键值张量(§4.2)。
为支持极大型模型(如OPT-175B),FastServe采用分布式推理,同时支持张量并行和流水线并行。FastServe对调度器和键值缓存进行了扩展,以无缝支持分布式执行(§4.3)。
4 FastServe设计
本节首先介绍用于最小化延迟的跳过连接MLFQ调度器(§4.1),然后提出旨在有效改善GPU内存容量约束的主动KV缓存管理机制(§4.2),最后演示如何将这些技术应用于分布式环境(§4.3)。
4.1跳过连接MLFQ调度器
初级方案:固定优先级调度。为支持抢占式调度,需要基于优先级的调度器来决定抢占和执行哪些任务。一个简单方案是根据输入长度为每个任务分配固定优先级。当初始化阶段主导总延迟时,固定优先级调度可以近似达到与SRPT策略相当的性能。然而,该方案虽利用了初始化阶段的信息,却忽略了解码阶段的特性。许多真实数据集(如ShareGPT和Alpaca)显示的长尾分布表明,也存在输出长度较长的任务。当解码阶段主导总延迟时,固定优先级调度可能偏离SRPT的最优性能。
初级方案:朴素MLFQ。由于LLM推理的任务规模不确定,直接应用SRPT不可行。在信息未知环境下,最少已获得服务已被证明能有效近似SRPT。鉴于LAS的任务切换开销,多级反馈队列这一实用方法在各种调度系统中广受欢迎[15,31,32,33,34]。MLFQ运行多个队列,每个队列具有不同优先级。任务到达时进入最高优先级队列,若其执行时间超过时间配额则被降级至下一级队列。时间配额的值是可调参数,例如更高优先级队列通常具有更短的时间配额。
尽管MLFQ假设没有任务规模的先验知识,但它并不适合LLM服务。图5显示了OPT 2.7B在NVIDIA A100上随输入序列长度变化的迭代时间。值得注意的是,初始化阶段(即第一次迭代)时间超过解码阶段持续时间。随着输入序列长度增加,初始化阶段时间也增加。此行为可归因于键值缓存优化(§2.2)。在第一次迭代中,执行输入令牌的所有键值张量计算并缓存。在后续迭代中,仅计算一个新生成令牌的键值张量,其余从缓存中检索。
当采用原始MLFQ时,任务到达后立即被分配至最高优先级队列。然而,由于其大量的初始化阶段时间,任务可能在完成第一次迭代前耗尽时间配额。这带来了调度困境。如果调度器抢占该任务,中间激活值将被丢弃并在之后重新计算,导致宝贵计算资源和时间的浪费。另一方面,如果调度器选择不抢占该任务,则违反了MLFQ的基本设计目的,并可能再次遭受队头阻塞。
我们的解决方案:跳过连接MLFQ 。我们设计的关键洞见是利用LLM推理的半信息未知设置来解决上述初级方案的问题。虽然迭代次数(即输出长度)事先未知,但每次迭代的执行时间是可预测的。对于每次迭代,其执行类似于传统的单次DNN推理,其执行时间是高度可预测的[8,35]。轻量级剖析过程可以提前轻松收集不同硬件、模型规格和输入长度下的准确迭代时间。回顾图5,在固定硬件和模型的情况下,初始化阶段时间与输入长度呈正相关,而解码阶段的迭代时间大致恒定。
基于此洞见,我们提出了一个为LLM推理定制的跳过连接MLFQ调度器。我们的调度器以跳过连接方式高效管理任务在不同优先级队列间的移动。在MLFQ中,我们有nn个优先级队列,即Q1,Q2,...,QnQ1,Q2,...,Qn,每个队列具有不同的时间配额q1<q2<...<qsq1<q2<...<qs。传统MLFQ调度器最初将新到达任务分配给最高优先级队列,即Q1Q1。一旦任务在Q1Q1中耗尽分配的时间配额,它随后被降级至Q2Q2。如图6所示,FastServe与原始MLFQ的不同之处在于:当任务到达时,FastServe利用准确剖析预测初始化阶段时间(tinittinit),并跳过连接 任务至满足qi≥tinitqi≥tinit的最高优先级队列(qiqi)。当任务在完成前耗尽分配的时间配额时,调度器根据其当前优先级和下一次迭代时间降级该任务。
**避免永久饥饿:**需要注意的是,跳过连接和降级操作可能导致具有长输入和长输出的任务饥饿。为解决此问题,调度器定期检查饥饿任务并提升它们至最高优先级队列,即Q1Q1。这使得FastServe能够在缓解饥饿的同时解决队头阻塞问题。我们将在§6.2评估尾部延迟并展示防饥饿机制的有效性。
示例。图7展示了一个示例,演示FastServe跳过连接MLFQ调度器的有效性。在该示例中,三个任务按J1,J2,J3J1,J2,J3的顺序同时到达。T1(Ji)T1(Ji)表示任务JiJi的初始化阶段时间,T2(Ji)T2(Ji)表示解码阶段时间。我们假设跳过连接和原始MLFQ都使用四个优先级队列,时间配额值为1、2、4和8。此外,SRPT作为具有最优平均延迟的预言机。
如图7所示,FCFS、原始MLFQ、跳过连接MLFQ和SRPT的平均延迟分别为4.23、5、3.3和3。FCFS和原始MLFQ遇到队头阻塞问题,其中任务J1J1阻塞了剩余任务,导致较长平均延迟。跳过连接MLFQ通过将任务J1J1跳过连接至低优先级队列来解决此问题,实现了与最优SRPT相似的性能。通常,能够访问更多信息的算法比信息有限的算法表现更好。
算法 。算法1展示了跳过连接MLFQ调度器的伪代码。调度器拥有一组优先级队列Q1,Q2,...,QnQ1,Q2,...,Qn,其时间配额值为q1,q2,...,qnq1,q2,...,qn,并接收一组新到达任务JnewJnew。它调度一批MaxBatchSize 任务执行。跳过连接部分(图6中的❶ )对应第6-9行,降级和防饥饿部分(图6中的❷ 和❸)分别对应第16-17行和第19-21行。有两个值得注意的细节。首先,调度器根据任务的下一次迭代时间将其降级至优先级低ηη倍的队列。FastServe将低优先级队列的时间配额设置为高优先级队列的两倍,这与先前关于MLFQ的工作[34]一致。最高优先级队列的时间配额设置为最小迭代时间。第二个细节涉及调度器如何识别由参数αα控制的饥饿任务。FastServe基于用户指定的SLO调整αα,默认设置为300毫秒。
4.2主动键值缓存管理
尽管跳过连接MLFQ调度器提供了迭代级抢占以近似SRPT,从而在没有确切任务规模先验知识的情况下实现更低延迟,但它加剧了GPU内存消耗的压力。图8显示了在合成工作负载下,OPT 2.7B模型的FCFS和跳过连接MLFQ的键值缓存内存消耗。尽管我们选择相对较小的模型并将最大输出长度限制为20,但跳过连接MLFQ的峰值KV缓存内存开销可能比FCFS大7倍。当部署更大的LLM(如OPT 175B)时,GPU内存需求变得更加显著。
其背后的原因是,与现有服务系统中的运行至完成策略相比,跳过连接MFLQ提供的迭代级抢占增加了系统中进行中任务的数量。除了运行任务的键值张量,跳过连接调度器还需要为挂起状态的被抢占任务存储键值张量。与传统操作系统调度器中的进程状态不同,每个任务的中间状态(即键值张量)要大得多。形式上,对于特定的LLM推理服务任务,记输入序列长度为ss,输出序列长度为tt,Transformer的隐藏维度为hh,Transformer层数为ll。如果模型权重和所有计算使用FP16,则存储该单个任务键值缓存的总字节数为4×h(s+t)4×h(s+t)。以OPT 175B为例(l=96,h=12288)(l=96,h=12288)。给定输入序列长度s=512s=512和最小输出序列长度t=1t=1,单个任务的GPU内存开销高达2.3GB。随着生成的继续,其输出序列长度tt将增加,这会进一步增加GPU内存开销。
与此同时,部署LLM时GPU内存是稀缺资源。通常,GPU内存远小于主机内存。例如,NVIDIA A100 GPU最大拥有80 GB GPU内存。此外,大部分GPU内存被预留用于存储LLM的权重。用于存储任务键值张量的空间有限。因此,GPU内存容量约束了跳过连接MLFQ调度器的潜在收益。
初级解决方案1:延迟新到达任务 。为避免内存不足错误,一个简单方案是在GPU内存不足时简单地延迟新到达任务的执行,并继续调度当前内存中的任务直至它们完成。这种直接方案广泛用于现有服务系统,如vLLM[11]。通过这种方式,尽管新任务被分配了更高优先级,但它们被阻塞以等待空闲内存空间。在极端GPU内存受限设置下(例如,长序列推理),此方案会使MLFQ退化为FCFS,从而再次遭受队头阻塞。
初级解决方案2:终止并重新计算低优先级任务 。另一个直接方案是终止 一些低优先级任务并释放其键值缓存,为新到达的高优先级任务腾出空间。此方案有两个问题。首先,被终止的任务丢失其生成状态,需要重建其键值张量。这导致宝贵计算资源和时间的浪费。其次,它可能导致死锁。当高优先级任务到达时,正在进行的低优先级任务被终止。由于防饥饿机制,如果被终止任务的等待时间超过指定的STARVELLIMIT,它们可能被提升至最高优先级队列。在这种情况下,被提升的任务可能终止当前正在执行的任务,而该任务可能刚刚在前一步骤中终止了被提升的任务。这可能导致死锁。
我们的解决方案:主动键值缓存交换。在严格的GPU内存容量约束下,两个初级方案不得不牺牲新到达任务的性能或低优先级任务的效率。为克服此困境,我们的关键观察是:键值张量仅在其对应任务被调度时才需要保留在GPU内存中。基于此观察,FastServe将键值缓存的空间从GPU内存扩展至主机内存。FastServe将非活动任务的键值张量换出至主机内存以容纳额外的挂起任务,并为即将调度的任务将键值张量换回GPU内存。
然而,与令牌生成时间相比,交换开销不可忽略。在16个NVIDIA A100 GPU上部署OPT 175B时,一个任务的键值张量可能占用2.3 GB内存。解码阶段的令牌生成时间约为60毫秒,而在PCIe 4.0×16全带宽下在主机内存和GPU内存之间交换键值张量的时间约为36毫秒。因此,简单的反应式交换机制(顺序处理交换和推理)会引入较大开销。
相反,FastServe采用主动键值缓存交换算法来减轻交换开销的不利影响。关键洞见是将运行任务的LLM推理与挂起任务的数据传输重叠,使交换开销脱离LLM推理的关键路径。图9展示了一个示例。主动算法不是在任务J1J1被抢占或完成后才交换挂起任务J2J2的键值张量,而是提前交换J2J2的键值张量。通过这种方式,J2J2的交换开销有效地与J1J1的GPU内核执行重叠,从而实现高GPU利用率。由于换入一个任务消耗昂贵的GPU内存,任务交换顺序对GPU内存效率至关重要。
任务交换顺序。频繁换入和换出不必要的键值张量会产生额外的抖动开销。
如果频繁换入换出高优先级任务,交换开销可能会超过执行时间,导致重叠性能下降。为解决此问题,FastServe通过计算每个任务的预计下次调度时间来决定交换顺序。预计下次调度时间是指任务下次被调度执行的时间点。预计下次调度时间最大的任务将优先被换出,而预计下次调度时间最小的任务将优先被换入。通常情况下,低优先级任务会被安排稍后执行。但由于防饥饿机制,低优先级任务可能会被提升到更高优先级队列。因此,即使是低优先级任务有时也可能优先执行。
在这种情况下,对于任务ii,FastServe会同时考虑该任务的提升时间和执行所有更高优先级任务所需的时间总和。形式化地,设任务ii的提升时间阈值为Tpromote(i)Tpromote(i)。对于执行所有比任务ii优先级更高的任务所需的时间总和,我们假设这些任务在降级到任务ii的优先级队列之前不会提前完成。更高优先级的任务jj的执行时间可按如下方式计算(即任务jj从j.priorityj.priority逐级降级至i.priorityi.priority):

其中i.priorityi.priority是任务ii的优先级,qkqk是优先级为kk的队列的时间配额。基于此,所有优先级高于任务ii的任务的执行时间总和定义为:

其中BB是任务的最大批次大小。最后,同时考虑防饥饿提升机制和更高优先级任务的执行,任务ii的预计下次调度时间计算如下:

该预计下次调度时间的定义旨在估算任务ii下一次被调度的预期时间。因此,使用此指标决定交换顺序,可以使活跃任务的键值张量主要驻留在GPU内存中,而非活跃任务的键值张量则更倾向于驻留在主机内存中。
处理新任务突发。主动键值缓存交换策略专为跳过连接MLFQ调度器设计。在出现大量新任务(高优先级)涌入的场景下,缓存管理系统被迫以反应式方式换出任务,从而对这些新任务的性能产生不利影响。为缓解此问题,FastServe会预留一些空闲的键值缓存槽位专门用于新任务,确保无需反应式任务交换即可立即使用。这种方法保障了新任务的性能。空闲槽位的数量基于历史任务到达模式。任务突发频率越高,所需的预留槽位就越多。
4.3对分布式LLM服务的支持
先前研究表明,LLM的有效性在经验上遵循关于模型参数数量的缩放定律[36]。但需注意,LLM的内存使用也与参数数量成正比。一个典型的例子是OPT 175B,即使以半精度存储,仅容纳其权重就需要惊人的350GB GPU内存。此外,运行时处理中间状态还需要额外内存。因此,LLM通常需要被分割成多个部分,并在多个GPU上以分布式方式服务。
张量并行[16,37]和流水线并行[17,38]是两种最广泛使用的分布式LLM服务技术。FastServe支持这两种并行技术的混合使用以服务LLM。LLM由一系列对多维张量的算子组成。张量并行将每个算子在多个设备间分割,每个设备并行执行一部分计算。分割输入和从不同GPU收集输出需要额外的通信开销。张量并行显著增加了单个任务可用的计算和内存资源,从而减少了每次迭代的时间。
流水线并行将LLM计算图的全部算子分割成多个阶段,并以流水线方式在不同GPU上执行。在推理过程中,每个阶段计算整个计算图的一部分,并并行地将中间结果传输给下一阶段。与张量并行相比,流水线并行需要的通信开销更少,同时也赋予LLM超越单个GPU内存约束的能力。由于多个处理批次在不同阶段同时处理,FastServe需要同时在分布式引擎中处理多个批次。
分布式服务中的任务调度。在传统MLFQ中,如果没有新任务到达,调度器会调度优先级最高的任务并执行直至完成或降级。然而,在流水线并行中,调度器以单个阶段为粒度进行调度。一旦任务完成其第一个阶段并将中间结果传输给后续阶段,调度器就面临一个决策点:确定下一步要启动的任务。在这种情况下,调度器不能遵循传统MLFQ持续调度同一任务直至降级的做法,因为该任务仍在进行中。为保持MLFQ的语义,FastServe仍将运行中的任务保留在优先级队列中,但会调度处于挂起状态的最高优先级任务。这样,队列中靠前的任务可以加快其时间配额的消耗完成。
分布式服务中的键值缓存管理。鉴于键值缓存占据了GPU内存的很大一部分,FastServe的键值缓存也在多个GPU上进行分区。在LLM推理中,每个键值张量由LLM的同一阶段使用。因此,FastServe根据张量并行的要求对键值张量进行分区,并将每个键值张量分配给相应的GPU,使得GPU上的所有计算只需要同一GPU上的本地键值张量。
FastServe的主动键值缓存交换机制也是分布式的。由于LLM的不同阶段同时处理不同的任务,每个阶段可以独立地换出或换入不同的键值张量。为减少冗余控制,在处理从前一阶段发送来的中间结果之前,当前阶段执行与前一阶段相同的换出或换入操作。中间结果传输和键值缓存交换并行发生,因此键值缓存交换的开销进一步降低。如图10所示,当中间结果发送到下一阶段时,下一阶段接收交换指令,并可在需要时同时交换键值缓存。键值缓存交换机制只需决定第一阶段的换出或换入操作。当使用张量并行将第一阶段分割成多个块时,一个集中式的键值缓存交换管理器会指示第一阶段的所有块换出或换入同一任务拥有的键值张量。
5 实现
FastServe是一个分布式LLM推理服务系统,具有RESTful API前端、调度器和分布式执行引擎。前端和调度器使用2.9K行Python代码实现。分布式执行引擎使用8.1K行C++/CUDA代码实现。前端支持与OpenAI API兼容的接口,客户端可指定采样参数,如最大输出长度和温度。调度器实现了跳过连接MLFQ和主动交换策略。分布式执行引擎使用Ray[39] actor实现GPU工作器,以分布式方式执行LLM推理和管理键值缓存。我们用C++实现了流行的开源LLM(如OPT),以取得比Huggingface[25]中流行的Python实现更好的性能和可扩展性。我们还实现了自定义CUDA内核以支持Orca[10]的迭代级调度和vLLM[11]的PagedAttention。
6 评估
本节首先展示FastServe相对于最先进LLM服务系统的端到端性能改进。然后,我们评估FastServe的设计选择并展示各组件的有效性。
6.1方法
测试平台。端到端实验(§6.2)使用两个AWS EC2 p4d.24xlarge实例。每个实例配置有八个通过NVLink连接的NVIDIA A100 40GB GPU、1152 GB主机内存和PCIe 4.0×16。由于预算有限,设计选择实验(§6.3)在我们自己的测试平台中使用一个NVIDIA A100 40GB GPU来验证各组件的有效性。
LLM模型。我们选择代表性的LLM系列OPT[18],该系列在学术界和工业界广泛使用。我们选择了常见的模型尺寸。表1列出了模型配置。所有实验均使用FP16精度。
工作量。 与先前关于大语言模型(LLM)服务的研究[11]类似,我们基于 ShareGPT [13] 和 Alpaca [14] 数据集生成工作负载。这些数据集包含了 LLM 服务的真实输入和输出。ShareGPT 数据集由用户分享的与 ChatGPT 的对话构成[13]。Alpaca 数据集则是由 GPT-3.5 通过自指令方法生成[14]。由于这些数据集不包含请求的到达时间,我们遵循先前的工作[11],根据泊松过程为每个请求生成到达时间,该过程由到达率参数化。
评估指标。用户感知延迟是衡量ChatGPT等交互式应用的关键指标。具体而言,与先前LLM服务的研究[10,11]类似,平均每令牌延迟的计算方式为:将每个任务的端到端延迟除以其输出长度后取平均值。此外,我们还报告P95尾部延迟。
为了进行比较,我们设定了一个延迟SLO(服务等级目标),并比较各系统在该SLO下能达到的最大吞吐量。我们遵循先前研究[40]的方法,将延迟SLO设置为解码阶段单次迭代延迟的1010倍。具体来说,根据我们的性能分析,将SLO设定为0.30.3秒。
基线系统。我们将FastServe与三种基线系统进行比较。为公平起见,所有基线系统均使用与FastServe相同的张量并行规模、流水线并行规模和批次大小,但vLLM除外------由于不支持流水线并行,其在服务OPT-175B时仅使用张量并行。表2展示了FastServe与基线系统的比较。
-
*FasterTransformer[26]:这是NVIDIA的生产级推理引擎。它同时支持张量并行和流水线并行。然而,它采用任务级调度,短任务会被同一批次中的长任务阻塞。我们使用FasterTransformer v5.3。
-
*vLLM[11]:这是最先进的LLM服务系统,支持迭代级调度[10]和PagedAttention[11]以减少键值缓存引起的内存碎片。然而,它使用简单的先到先服务调度器并采用运行至完成的执行方式,因此存在队头阻塞问题。我们使用vLLM v0.1.7。
-
*FastServe-FCFS:它使用与FastServe相同的分布式执行引擎,但未使用本文§4提出的技术。此基线有助于区分本文所提技术带来的加速与FastServe高效实现带来的加速。
6.2端到端性能
我们在OPT-30B、OPT-66B和OPT-175B模型上,针对ShareGPT和Alpaca工作负载,比较了FastServe与三个基线系统的端到端性能。
图11的第一行展示了所有系统在ShareGPT数据集下的端到端性能。尽管FasterTransformer为LLM推理实现了高度优化的GPU内核,但它不支持迭代级调度。它无法在正在处理的批次中提前返回已完成的任务,也无法将新任务加入批次以减少延迟。因此,当任务到达率较低时,FasterTransformer受严重的队头阻塞问题影响。在满足SLO的前提下,FastServe的吞吐量比FasterTransformer高出31.5-74.9倍 。作为最先进的服务系统,vLLM配备了大多数用于加速推理和减少GPU内存消耗的技术。然而,由于vLLM以先到先服务的方式调度任务,其端到端延迟的很大一部分是排队延迟。仅优化LLM推理任务的执行时间是不够的。配备了跳过连接MLFQ调度器的FastServe能够显著减少排队延迟,性能超过vLLM 2.3-18.3倍 。值得注意的是,FastServe-FCFS的性能也优于vLLM,这是因为它使用了更高效的C++实现,并将更多操作融合到更少的GPU内核中。但它仍然受队头阻塞问题影响,因此性能比FastServe慢2-4倍
图11的第二行展示了在Alpaca数据集下的实验结果。由于Alpaca数据集的作业规模小于ShareGPT数据集,即使请求速率相对ShareGPT数据集下的速率较高,所有服务系统也都能保持较低的延迟。然而,FastServe的性能增益是相似的。在没有迭代级调度的情况下,FasterTransformer是最慢的系统,FastServe的性能比它高出9.5-15.8倍。vLLM实现了比FasterTransformer更好的性能,但它仍然受到队头阻塞问题的影响。因此,FastServe的性能比vLLM高出3-31.4倍。通过我们高效的实现,FastServe-FCFS的性能也优于vLLM,但仍比FastServe慢1.6-2倍。
对尾部延迟的影响。 抢占式调度和MLFQ一个潜在的担忧是可能导致长作业饥饿,并损害尾部延迟。FastServe在其跳跃连接MLFQ调度器(§4.1)中加入了饥饿预防机制。为了证明饥饿预防机制的有效性,我们测量了在ShareGPT数据集下所有系统的95%延迟。如图12所示,在相同的尾部延迟SLO要求下,FastServe显著提高了LLM推理作业的吞吐量。例如,在服务OPT-17SB模型时,与FastServe-FCFS相比,FastServe将吞吐量提高了最多1.5倍。在服务OPT-13B和OPT-66B模型时,FastServe也比FastServe-FCFS性能高出2-2.8倍。与vLLM和FasterTransformer相比,FastServe分别实现了高达17.9倍和59.8倍的性能提升。结果表明,尽管FastServe旨在降低平均延迟,但它也能显著降低LLM推理作业的尾部延迟。使用跳跃连接MLFQ调度器优先处理短作业可以有效减少队头阻塞问题,并且不会损害尾部延迟。即使对于长作业,FastServe仍然可以通过减少它们的排队延迟来加速它们。饥饿预防机制确保了长作业能在合理的时间内被调度。
对有效吞吐量的影响。 我们进一步研究了在服务OPT-13B模型时,不同系统在不同SLO下对有效吞吐量的影响。与之前的工作[35, 41, 42]类似,我们测量了P95有效吞吐量,其定义为当95%的作业能在初始化阶段和解码阶段的SLO内完成时的吞吐量。我们将这两个阶段的SLO设置为轻负载下相应阶段延迟的5倍、10倍和20倍。如图13所示,在不同的SLO下,FastServe始终实现了最高的P95有效吞吐量。具体来说,FastServe的性能比vLLM高出4.1倍到4.7倍,比FastServe-FCFS高出1.46倍到1.64倍。这些结果表明,FastServe在不违反初始化阶段和解码阶段SLO的前提下,有效地提高了系统的吞吐量。
6.3设计选择
跳跃连接MLFQ的有效性。 为了展示跳跃连接MLFQ的有效性,我们在服务OPT-13B模型时,将其性能与FCFS、朴素MLFQ和固定优先级进行了比较。我们使用ShareGPT数据集生成作业,并在保持原始长度分布的同时,改变输入和输出长度之间的比率。这一调整反映了当前LLM中扩展输入令牌限制的行业趋势[4, 5, 42]。图14展示了改变输入输出长度比率时的结果。延迟以最慢系统为基准进行归一化。无论比率如何,由于队头阻塞问题,FCFS始终经历高延迟。朴素MLFQ在比率较小时性能良好,因为初始化阶段和解码阶段之间的差异很小。然而,随着比率增加,朴素MLFQ难以应对延长的初始化阶段。相比之下,固定优先级在比率较大时表现出色,因为此时初始化阶段主导了执行时间,但在比率较低时表现不佳,因为它在设置优先级时忽略了解码阶段。受益于半信息无关的调度策略,与FCFS、朴素MLFQ和固定优先级相比,跳跃连接MLFQ始终将性能提升了高达8.9倍、1.87倍和13.9倍。
主动键值缓存管理的有效性。 为了展示主动键值缓存管理的有效性,我们在ShareGPT数据集上服务OPT-13B模型时,将FastServe的性能与§4.2中提到的两种基线策略------重计算和被动式------进行了比较。图15(a)显示了结果。在低到达率下,GPU内存足以容纳所有作业的键值缓存,使得三种策略的性能相似。随着到达率增加,GPU内存变得不足,系统必须为其他作业抢占一些键值缓存,从而导致性能差异。
在这种情况下,重计算策略会丢弃低优先级作业的键值缓存,增加了这些作业键值缓存的重计算开销。如图15(a)所示,这种重计算开销使得主动交换策略的性能比重计算高出2.7倍。
至于被动式策略,它会在GPU内存不足时将低优先级作业交换到主机内存,并在需要时换入这些作业。数据传输处于关键路径上。后续计算必须等待这些传输完成。相反,主动交换能够预测新到达作业的内存需求,并提前抢占低优先级缓存。类似地,当检测到高优先级作业的缓存在主机内存中且GPU内存可用时,会主动将其换入GPU内存。这使得数据传输与计算重叠,并实现了比被动式方法1.7倍的性能提升。
为了进一步研究主动交换机制的开销,我们将端到端延迟分解为三个部分:排队延迟、执行时间和交换时间。交换时间是作业被主动交换机制阻塞的时间。如图15(b)所示,交换时间不到端到端延迟的5%,与执行时间和排队延迟相比可以忽略不计。原因在于主动交换机制可以将大部分交换时间与其他作业的执行时间重叠。因此,主动交换机制几乎不影响端到端延迟。
7 相关工作
抢占式调度。 许多数据中心作业调度方案使用抢占式调度。许多网络系统[18; 31; 32; 43]使用抢占式流调度来最小化流完成时间。许多针对延迟敏感数据中心工作负载的调度器,如Shinjuku[44]、Shenango[45]和Caladan[46],也使用细粒度抢占和资源重新分配来优化微秒级的尾部延迟。对于深度学习工作负载,Tiresias[34]使用MLFQ来优化分布式DL训练作业的作业完成时间。Pipeswich[47]和REEF[48]提供高效的GPU抢占,以在同一个GPU上运行延迟关键型和尽力而为型DL任务。与它们不同,FastServe针对一个新的场景,即LLM推理服务。
推理服务。 许多传统模型服务系统[8; 9; 22; 23; 49]只专注于在集群中服务相对较小的模型,没有考虑到LLM的特性。最近,提出了几种服务系统来优化基于Transformer的LLM[10; 35; 50; 51; 52]。Orca[10]和vLLM[11]考虑了LLM的自回归生成模式。然而,由于它们的FCFS策略,它们遭受严重的队头阻塞问题。VTC[52]关注LLM服务的公平性,但没有考虑抢占场景。Splitwise[53]和DisiServe[41]将预填充阶段和解码阶段解耦,以消除它们之间的干扰,从而优化执行延迟。LoongServe[42]使用弹性序列并行,为不同请求在不同阶段动态设置并行度。这些系统与FastServe是正交的。
LLM的内存优化。 由于LLM的高内存使用量,人们提出了许多技术来减少内存开销。一些工作[54; 55]针对训练场景,这与服务场景是正交的。量化[56; 57; 58; 59]在训练后将模型权重复压缩到较低精度,以减少推理期间的内存占用。SparTA[60]利用模型稀疏性来加速计算。然而,这些方法牺牲了模型精度。vLLM[11]提出了PagedAttention来减少GPU内存碎片。这与本文是正交的,并且FastServe也实现了PagedAttention。
8 结论
我们提出了FastServe,一个用于LLM的分布式推理服务系统。我们利用LLM推理的自回归模式来实现迭代级抢占,并设计了一种新颖的跳跃连接MLFQ调度器来解决队头阻塞问题。我们提出了一种主动键值缓存管理机制来处理键值缓存的内存开销,并通过计算来隐藏数据传输延迟。基于这些,我们构建了FastServe的原型。实验表明,在相同的平均延迟和尾部延迟SLO下,与vLLM相比,FastServe将吞吐量分别提高了高达31.4倍和17.9倍。
拓展:
ResNet模型的机制是什么?
ResNet(残差网络)是一种通过引入"快捷连接"来解决极深神经网络训练难题的经典模型,它使得网络可以轻松地达到前所未有的深度,从而获得极其强大的特征提取能力。
一个简单的比喻:学习骑自行车
想象一下教一个孩子骑自行车:
-
普通网络(如VGG):你告诉孩子:"双手握把,脚踩踏板,眼睛看前方,保持平衡......" 这是一系列复杂的指令。如果孩子没学会,他需要从头开始理解并调整这一整套复杂的动作,这很困难。
-
ResNet :你给孩子一辆带辅助轮 的自行车。他先尝试按照基本指令骑(学习底层特征)。如果他发现很难直接学会"保持平衡"这个高难度动作,辅助轮这个"快捷连接"可以让他绕过"平衡"问题,先确保他能前进和转向(学习更高级的特征)。之后,随着技能提升,再慢慢卸掉辅助轮,专注于学习"平衡"本身。
在这里,"辅助轮"就是ResNet中的"快捷连接",它确保了即使中间某个技能(网络层)没学好,整个学习过程(信息流动)也不会完全崩溃。
ResNet的核心机制:残差块与快捷连接
ResNet的核心创新是残差块 。传统网络层是直接学习一个目标映射 H(x),而ResNet则换了一种思路。
下图直观地展示了残差块的核心思想:

让我们来解读一下这个设计:
-
传统网络层 :
输出 = H(x)- 目标是直接学习从输入
x到理想输出H(x)的复杂映射。
- 目标是直接学习从输入
-
ResNet残差块 :
输出 = F(x) + x-
目标变化 :它不再直接学习
H(x),而是学习残差F(x) = H(x) - x。 -
快捷连接 :如图所示,输入
x直接"绕道"跳过了本层的一个或多个权重层,直接加到了这些层的输出上。 -
最终输出 :
y = F(x) + x。
-
为什么这个设计如此有效?
-
解决梯度消失/爆炸问题
-
在非常深的网络中,误差反向传播时,梯度需要经过很多层。连续乘法可能导致梯度变得极小(消失)或极大(爆炸),使得底层网络参数无法更新。
-
ResNet的解决方案:由于快捷连接的存在,梯度可以直接、无损地通过"捷径"反向传播到更早的层,就像在高速公路上开辟了一条直达通道,确保了梯度流的畅通。
-
-
避免了网络退化问题
-
即使没有梯度消失,实验发现,单纯增加网络深度,准确率也会饱和甚至下降。这不是过拟合,而是因为深网络难以学习到一个恒等映射。
-
ResNet的解决方案 :如果一个网络层是多余的(即它的最优功能是"什么都不做"),那么对于残差块来说,这是非常容易学习的------它只需要简单地将权重参数
W推向零,使得F(x) ≈ 0,那么输出y ≈ x(恒等映射)。学习恒等映射变得轻而易举。
-
-
促进了特征复用
- 网络可以自由选择是通过权重层进行特征变换,还是直接利用快捷连接保留原有特征。这使得网络能够更高效地利用不同层次的特征。
ResNet的架构
ResNet通过堆叠上述的残差块来构建整个网络。根据深度不同,有ResNet-18, 34, 50, 101, 152等变体。它通常包含:
-
初始卷积池化层:对输入图像进行初步处理。
-
4个阶段的残差块:每个阶段由多个残差块组成,在进入新阶段时,通常会通过步长为2的卷积进行下采样,以扩大感受野并降低特征图尺寸。
-
全局平均池化与全连接层:最终用于分类输出。
总结与意义
ResNet的机制 可以总结为:通过引入快捷连接,将网络层的学习目标从"学习完整映射"转变为"学习残差",从而极大地缓解了深度网络的训练难题,使得构建成百上千层的超深网络成为可能。
它的意义是革命性的:
-
实践上:使训练极深的网络变得简单可行,在ImageNet等竞赛中取得了突破性成绩。
-
理论上:启发了大量后续研究,"快捷连接"或"跳跃连接"成为了现代深度网络架构(如Transformer)的标准组件。
-
影响:不仅是计算机视觉,其思想也深刻影响了自然语言处理等其他领域。
DNN推理任务通常是确定性强且高度可预测的 这个是为什么?
-
DNN(如ResNet) :对于一个训练好的模型,其计算路径是完全确定的。无论输入什么图像,数据都会沿着完全相同的算子序列(卷积、池化、激活函数、全连接等)流动。整个计算图在模型部署时就已经固定不变。
-
LLM :计算路径是动态的 。虽然每个令牌的计算(Transformer块)是固定的,但模型需要执行多少次这种计算(即生成多少个输出令牌)是事先未知的,取决于输入和模型自身的生成结果。这是一个循环过程。
-
DNN(如ResNet) :对于一个训练好的模型,其计算路径是完全确定的。无论输入什么图像,数据都会沿着完全相同的算子序列(卷积、池化、激活函数、全连接等)流动。整个计算图在模型部署时就已经固定不变。
-
LLM :计算路径是动态的 。虽然每个令牌的计算(Transformer块)是固定的,但模型需要执行多少次这种计算(即生成多少个输出令牌)是事先未知的,取决于输入和模型自身的生成结果。这是一个循环过程。