大模型推理加速概述

半年前我开始了一份新工作,干的就是让现有业务的大模型跑得更快。我从一开始的懵懵懂懂到现在的初窥门径,感觉跌跌撞撞浪费了不少时间。如果半年前我能读到一些提纲挈领性的文章,整个进程会不会加快一些?这就是本文的初衷,写给半年前对推理加速懵懂无知的自己。

现如今几乎所有人都会认可,以Transformers为基础的大模型技术将会是不远将来通用人工智能的基石。大模型技术分为训练会推理,其中训练的重要性不言而喻,毕竟训练直接决定了模型的能力有多强。而推理的重要性也日渐受到关注。原因有很多,最直接的原因是,模型推理才是我们每天在业务中用到的技术。模型推理更快,单位时间输出的token更多,我们就能以更低的成本服务更多用户,也就是赚到更多钱。这一点对于强推理(reasoning)模型来说更加重要——推理(inference)过程中能输出更多token,就越可能给出高质量答案——当然也就耗时间,更需要进行加速。用户对于速度和成本的追求是无止境的,我们永远都有优化的活要干。

指标

大模型推理加速,一句话来说就是让模型推理更快。然而,对于“快”却可以有不同的定义,衍生出不同的衡量指标。

  • 时延(Latency):简单来说,时延是指从系统开始处理一个prompt到处理完这个prompt所用的时间。这个指标又可以继续分解:
    • 首token时延:这是指大模型从开始处理一个prompt到输出第一个token所需要的时间,其实就是指prefill阶段的处理时间。这个指标对于实时交互应用,比如角色陪聊或者支持客服尤其重要,因为用户不希望说完一句话然后等上个几秒才看到
    • 增量token时延:这是指大模型每个输出的每一个token之间的时间,也就是decode阶段每个token的生成时间。这个指标对于长文本输出的应用,尤其是像强推理模型或者agent这样的应用就有位重要。
  • 吞吐(Throughput):单位时间内系统能生成多少个token,通常用 XXX tokens/s来表示

理想状态下,我们既想要低时延,又想要高吞吐。然而对于一个大模型服务系统,当并发量变大的时候,时延和吞吐就会需要权衡了。有的优化手段可以优化时延,却会劣化吞吐;反之。

除了快之外,又是还有其他因素需要纳入综合考量:

  • 每秒请求数 系统每秒钟处理完多少个请求,这个肯定跟业务强相关的,取决于平均的请求长度,以及业务的性质
  • 显存占用 这是除了时延和吞吐之外最常考虑的指标,毕竟内存总是不够用的。而且显存占用与吞吐量息息相关。如果一个技术手段可以在不影响时延的情况下减少显存占用,比如说,那么必然可以提升吞吐量。
  • 功耗 这个指标尤其见于要在端侧跑的模型,比如要在手机或者笔记本电脑里运行的模型,为了续航时间照相,功耗将会是一个不得不考虑的指标。

技术

如其他众多事物一样,大模型推理加速技术也是一堆技术的集合,但至少可以分成几个方面:

  • 系统层:当我们部署模型用于生产环境时,GPU、CPU、存储等资源是有限的,而我们要同时服务来自许多用户的不同请求。因此,我们需要从系统层面考虑用怎样方式来部署这个模型才能最大化使用我们有限的资源,并达到一定的目标,比如平均每秒输出多少token,每一个请求的处理时间之类的。vllm、sglang、Dynamo等部署系统(serving system)就是能解决这些问题的,都会用到并行推理、PD分离、PagedAttention等技术。
  • 算子层:大模型所有的计算,归根到底都是要在GPU(或其他计算卡)上完成的。我们写的一个简单矩阵乘指令torch.matmul(A, B),在GPU上都可以有无数种具体的执行方式,这其中有的快,有的慢。GPU具体的计算操作就是由算子去定义的,我们写的python代码吗最终都会调用算子。如果我们发现大模型的计算环节某些算子的执行逻辑可以优化得更快,或者说几个算子可以融合在一起来减少GPU得启动开销,就可以加速模型的运行。FlashAttention就是通过减少GPU和显存之间数据搬运的时延来加速推理的。写算子是一个高难度的工作,通常要使用Cuda C语言来写,甚至更底层的PTX指令。不过OpenAI也涉及了Triton这样基于python的高级编程框架来降低算子的开发门槛。
  • 模型层:系统层关注高层级的资源和请求调度,算子层关注底层级的计算和搬运,模型层则直接对大模型本身动手,或改变其结构、或改变其逻辑。这个改变可大可小。量化技术,就是把模型的参数和计算过程的中间结果从较高精度的数据格式转化成较低精度的格式,比如从fp32bf16,甚至fp4;模型剪枝则是试图发现大模型中一些冗余参数,直接删掉它们;GQA是把大模型注意力机制中的KV头数目进行削减。不同于系统层和算子层的技术,一般来说,模型层的加速手段都会影响模型的准度,毕竟模型的结构和计算过程与原始模型已有所不同,因此少不得要做些后训练工作,但也有像投机解码这样可以在数学原理上保证模型能力不变的加速手段。

这是从大体上对模型加速技术的分类。如果说我现在被安排到一个使用了大模型的业务里,要着手优化业务中的模型,我们能用到哪些技术手段?一个原则是,首先上简单的、无损的、不用后训练的技术,在考虑复杂的,会对模型本身造成影响的,需要后训练的手段。

  • 一般来说部署一个模型都不会单跑一个模型实例,而是会抱一个部署系统,然后在此基础上部署模型。最著名的就是vllm。那么其中集成的一些系统层优化技术,如减少显存碎片的PagedAttention、prefix cache、、chuncked prefill等技术,就肯定是能用就用的。
  • 鉴于大模型推理过程中预填充(prefill)阶段和解码(decode)阶段的计算特性很不同,PD分离也是要考虑的。哪怕只有一张计算卡,也可以试试部署多个模型实例,分别做prefill和decode,试验各种调度策略、更何况还有SemiPD这样对一张GPU里不同计算核心调度的细粒度调度算法。
  • 如果我们有多张计算卡,除了考虑PD分离以外,必定会考虑做并行推理——数据并行、张量并行、流水线并行等,如果业务里的大模型还是混合专家架构(MoE),专家并行是必须考虑的。
  • 对于像ChatBot这样的多轮对话应用,把用户的历史对话对应的KVCache缓存起来是必须做的。然而我们的显存资源是有限的,总得丢弃一些旧的缓存。但如果用户一段时间后在原有对话基础上继续对话,那就不得不重新计算之前所有对话的KVCache。因此,KVCache的管理和调度策略也是一个优化重点,而如果能把GPU显存以外的存储资源也利用起来,组成一个多级缓存池,就可以扩大KVCache的容量。
  • 模型量化技术虽然是会改变模型参数的技术,然而经验表明量化技术的效果很好很稳定,哪怕是从fp32降到fpp8,对很多模型来说也不会造成显著的模型能力损失。现在,W8A8量化(权重参数weight和计算的中间结果activation都使用8比特的数据格式)已经成为基本的加速手段之一。更低精度的量化技术,比如W4A8,W4A4,以及对KVCache和其他参数的量化,也在火热研究中。

以上这些技术都是简单、稳定、且有成熟工具可用的技术。在一个加速项目的初期,应当首先考虑。以下的加速技术,则需要考虑合适的使用场景,或者要在模型的准度和速度之间权衡。

  • 如果说业务中输出的文本很长,也就是增量token很多,那么投机解码技术也是必须考虑的选项。投机的主要原理是用低成本的方式快速生成一段候选token,然后用大模型一次推理验证哪些token可以保留。这个技术的关键难点在于怎么生成高质量的候选token,如果一直生成垃圾候选,那么反而会拖慢整个推理过程。另外,如果模型的输出token不多,每次只说几个token就完事了,那么投机解码的收益也不大。
  • 通常模型的输入并非每一个token都是重要的。如果我们在处理输入前能够用低成本的方法预测出哪些token不重要,提前识别出来直接丢掉,那就可以加速模型推理。这种token裁剪方法不会改变模型的结构和参数,但改变了输入,因此也会有准度下降的风险。
  • 如果说在一项也无力大模型的应用场景相对单一,比如说只会做角色扮演陪聊,或者说只作为一个出行规划应用的的核心大脑,而其他像编程、做数学题、百科知识等能力基本不用考虑,那么可以考虑裁剪掉大模型中的部分权重参数,然后使用特定场景的数据集对裁剪后的模型做微调。业务场景越是单一和特化,可以裁剪掉的模型参数也就越多,加速效果越好。同理,可以考虑蒸馏技术,把一个32B模型对特定领域的知识和对特定问题的能力迁移到一个7B模型中去,有可能获得一个比14B模型快且好的模型。
  • 如果说业务是翻译一个长文档,或者对一份长文档做摘要,其中要处理的文本序列很长,长到10k甚至100k,那么大模型的注意力模块就会成为瓶颈,因为其他模块的计算复杂度都是\(O(n)\),而注意力机制的的复杂度是\(O(n^2)\)。但是对于这么长的文本,在处理某一个token时并不是每个之前的token都很重要。因此,应用稀疏注意力技术就可以只选择部分token作为注意力机制的输入,把注意力机制的\(n\)降低,从而实现几倍甚至十几倍的加速。
  • 对于RAG等在输入中带有多个相对独立文本块的应用场景,一个简单的想法是预先把RAG中的文本快的KVCache预先计算好存起来,需要用到的时候直接提取使用,无需现场计算。但因为预先计算的文本快KV值没有考虑位置编码,而实际上文本快之间也并非完全独立,因此肯定会需要对模型微调或在推理过程中重计算部分KV。LMCache中的CacheBlend技术便是代表。
  • 如果对算子层的执行时间分析,发现有些算子的时间太长,而恰好又有相对应的高兴能算子可以直接替换,那是最好的。但如果在用的算子已经是当前可用的最好的算子,就需要亲自编写优化算子了。

以上就是现阶段学界研究较多,业界使用较多的大模型推理加速技术。针对更具体的业务场景,往往可以提出更加有针对性的加速方案。

posted @ 2025-07-06 15:45  zrq96  阅读(370)  评论(0)    收藏  举报