大模型(LLM)部署框架对比篇
来源:AiGC面试宝典 作者:宁静致远 日期:2024年03月31日
一、为什么需要对大模型推理加速?
大模型推理加速的目标是高吞吐量和低延迟。
- 吞吐量:一个系统可以并行处理的任务量。
- 延迟:指一个系统串行处理一个任务时所花费的时间。
📝通俗解释:想象餐厅厨房做菜,吞吐量就像同时能炒多少道菜,延迟就像端出一道菜需要多长时间。大模型推理加速就是既要能同时处理很多请求(高吞吐量),又要让每个请求尽快得到结果(低延迟)。
二、大模型(LLM)部署框架对比总览
| 框架 | llama.cpp | rtp-llm | vLLM | TensorRT-LLM | LMDeploy | fastllm |
|---|---|---|---|---|---|---|
| 语言 | C++ | Python | Python | C++/Python | Python | C++ |
| 维护者 | ggerganov | Alibaba | vllm-project | NVIDIA | InternLM | ztx16 |
| 特点 | 1、纯C++推理引擎,无任何额外依赖 2、F16和F32混合精度 3、支持4bit量化 4、无需GPU,可只用CPU运行 | 1、高性能的CUDA Kernel 2、支持Paged Attention、Flash Attention 3、KV Cache量化 | 1、PagedAttention 2、高性能的CUDA Kernel | 1、高性能CUDA Kernel 2、量化 3、TensorRT优化 | Continuous Batching、Blocked KV Cache、动态拆分和融合、张量并行、高性能Kernel等。推理性能是vLLM的1.8倍。可靠的量化支持(权重量化和KV量化) | 1、纯C++实现 2、FP32/FP16/INT8/INT4加速 3、多卡部署,支持GPU+CPU混合部署 4、并发计算、动态拼Batch、全平台支持 |
| 多模态支持 | √(LLaVA、MobileVLM等) | √(LLaVA、Qwen-VL) | × | × | √(InternLM、Qwen-VL) | × |
| 多平台支持 | √ | × | × | × | × | √ |
| KV Cache | √ | √ | √ | √ | √ | √ |
| 量化方法 | INT8、INT4等 | KV Cache量化、Weight Only INT8 | GPTQ、AWQ、SqueezeLLM、FP8 KV | INT4/INT8 Weight-Only、SmoothQuant、GPTQ、AWQ、FP8 | INT4权重量化、KV量化、W8A8 | INT8、INT4 |
| 高性能CUDA Kernel | √ | √ | √ | √ | √ | √ |
| Flash Attention | √ | √ | √ | √ | √ | √ |
| Paged Attention | √ | √ | √ | √ | √ | × |
| Continuous Batching | √ | √ | √ | √ | √ | √ |
| Speculative Decoding | √ | √ | √ | √ | × | × |
| Medusa | √ | √ | × | √ | × | × |
三、大模型(LLM)部署优化策略
3.1 大模型(LLM)部署优化策略——量化
3.1.1 介绍一下大模型(LLM)量化方法?
大模型量化将16位、32位浮点数的模型参数或激活量化为4位或8位整数,能够有效降低模型存储空间和计算资源需求,同时加速推理速度。
📝通俗解释:就像把高清照片压缩成小尺寸图片——原本需要很大空间存储的照片,压缩后虽然画质略有损失,但体积小了很多,查看速度也更快。量化就是这个道理,把高精度数字"压缩"成低精度的,模型变小、推理变快。
3.1.2 一般会对大模型(LLM)中哪些模块进行量化?
量化对象包含权重、激活、KV Cache量化:
- 仅权重量化:如W4A16、AWQ及GPTQ中的W4A16、W8A16(权重量化为INT8,激活仍为BF16或FP16)
- 权重、激活量化:如SmoothQuant中的W8A8
- KV Cache INT8量化:LLM推理时,为了避免冗余计算,设计了KV Cache缓存机制,本质上是空间换时间。由于KV Cache的存在,对于支持越长文本长度的LLM,KV Cache的显存占用越高,KV Cache的量化也很有必要。
📝通俗解释:权重量化就像把房间里的家具缩小(只缩小体积,不改变功能);激活量化就像把正在加工的半成品也缩小;KV Cache量化则像是把仓库里暂存的东西也压缩存放。三个一起做效果最好,但实现也更复杂。
3.1.3 大模型(LLM)量化方法
常见的量化方法包括:Weight Only INT8、KV Cache量化、INT4量化、INT8量化。
📝通俗解释:INT4就是用4个二进制位表示一个数字(16种可能),INT8用8个二进制位(256种可能)。数字越低,压缩越厉害,但精度损失也可能越大。
3.2 大模型(LLM)部署优化策略——KV Cache
3.2.1 介绍一下大模型(LLM)KV Cache方法?
KV Cache采用以空间换时间的思想,复用上次推理的KV缓存,可以极大降低内存压力、提高推理性能,而且不会影响任何计算精度。
📝通俗解释:就像做阅读理解时,不需要每次都重新读一遍前面的内容,而是把已经理解的内容记在脑子里,下次直接用。KV Cache就是让计算机"记住"之前计算过的内容,避免重复计算。
3.2.2 为什么需要大模型(LLM)KV Cache方法?
以GPT为代表的一个token一个token往外生成的AIGC大模型为例,里面最主要的结构就是Transformer中的Self-Attention结构的堆叠,实质是将之前计算过的Key-Value以及当前的Query来生成下一个token。LM用于推理的时候就是不断基于前面的所有token生成下一个token,每一轮用上一轮的输出当成新的输入让LLM预测,一般这个过程会持续到输出达到提前设定的最大长度或者是LLM自己生成了特殊的结束token。其中存在很多重复计算,比如token的Key Value的计算。一个方法就是将过去token得到的Key Value存起来,Query不需要存,Q矩阵是依赖于输入的,因此每次都不同,无法进行缓存,因此Q矩阵通常不被缓存。
📝通俗解释:想象你在写一句话,每写下一个字都要回头看一遍前面所有写过的字。随着句子越来越长,你回头看的时间也越来越长。KV Cache就像是给你一个笔记本,记录之前写过的内容,下次直接查笔记本,不用再重新看一遍了。
3.3 大模型(LLM)部署优化策略——Flash Attention
3.3.1 介绍一下大模型(LLM)Flash Attention方法?
当输入序列(sequence length)较长时,Transformer的计算过程缓慢且耗费内存,这是因为Self-Attention的Time和Memory Complexity会随着sequence length的增加成二次增长。
GPU中存储单元主要有HBM和SRAM:GPU将数据从显存(HBM)加载至on-chip的SRAM中,然后由SM读取并进行计算,计算结果再通过SRAM返回给显存。HBM容量大但是访问速度慢,SRAM容量小却有着较高的访问速度。
普通的Attention的计算过程如下,需要多次访问HBM,Flash Attention的目的就是通过分片+算子融合(矩阵乘法和Softmax)减少对HBM的访问。
标准Attention实现流程:
- 从HBM加载Q、K,计算S = QK^T,将S写回HBM
- 从HBM读取S,计算P = softmax(S),将P写回HBM
- 从HBM加载P和V,计算O = PV,将O写回HBM
将矩阵分片运算,矩阵乘法可以直接拆分计算,但是Softmax算子分片计算出来的结果不是最终的。Flash Attention通过引入额外的统计变量,将Softmax优化成一个可以分片运算的算子。
📝通俗解释:想象你要整理一堆文件,普通方法是把文件从仓库(显存HBM)搬到桌子(快速存储SRAM)整理完再搬回去,来来回回跑很多趟。Flash Attention就像直接在仓库里分区处理,减少了来回搬运的次数,自然就快很多。
3.4 大模型(LLM)部署优化策略——Paged Attention
3.4.1 介绍一下大模型(LLM)Paged Attention方法?
PagedAttention是对KV Cache所占空间的分页管理,是一个典型的以内存空间换计算开销的手段。虽然KV Cache很重要,但是KV Cache所占的空间也确实大且有浪费的,所以出现了PagedAttention来解决浪费问题。
KV Cache大小取决于seqlen,然而这个东西对于每个batch里的seq来说是变化的。毕竟不同的人输入不同长度的问题,模型有不同长度的答案,KV Cache统一按照max seq len来申请,造成现有decoder推理系统浪费了很多显存。
PagedAttention将每个序列的KV缓存分成多个块,每个块包含固定数量的标记的键和值。在注意力计算过程中,PagedAttention Kernel高效地识别和获取这些块,采用并行的方式加速计算。
PagedAttention的核心是一张表,类似于OS的page table(这里叫block table),记录每个seq的KV分布在哪个physical block上。通过把每个seq的KV Cache划分为固定大小的physical block,每个block包含了每个句子某几个tokens的一部分KV,允许连续的KV可以不连续分布。在attention compute的时候,PagedAttention CUDA kernel通过block table拿到对应的physical block序号,然后CUDA线程ID计算每个seq每个token的offset从而fetch相应的block,拿到KV,继续做attention的计算。
📝通俗解释:想象图书馆(显存)要存放很多书(KV Cache),但每本书长度不一样。如果按照最长那本书来安排书架,会浪费很多空间。PagedAttention就像把书分成若干章存放,可以灵活拼凑空间,不用的章节就不占地方,需要时再拼起来。
3.5 大模型(LLM)部署优化策略——Continuous Batching
3.5.1 介绍一下大模型(LLM) Continuous Batching方法?
静态批处理:在第一遍迭代中,每个序列从提示词(Prompt)中生成一个标记(Token)。经过几轮迭代后,完成的序列具有不同的尺寸,因为每个序列在不同的迭代结束时产生不同的结束标记(EOS)。尽管某些序列已经完成,但静态批处理意味着GPU必须等待批处理中的最后一个序列完成才能处理下一批。
Continuous Batching(连续批处理):动态批处理,一旦批中的一个序列完成生成,就可以在其位置插入一个新的序列,从而实现比静态批处理更高的GPU利用率。
📝通俗解释:静态批处理就像一桌人一起点菜,必须等到最后一个人吃完才能收拾桌子换下一桌;连续批处理就像快餐店,有人吃完立刻有人补上座位,桌子利用率更高。
3.6 大模型(LLM)部署优化策略——Speculative Decoding
3.6.1 介绍一下大模型(LLM) Speculative Decoding方法?
原始方法:
- 用户问题:上海有什么好玩的地方?
- 流程:大模型逐个token进行预测(上 -> 海 -> 有 ... 民 -> 广 -> 场 -> 等)。这是一个串行的过程,每次只预测一个字。
- 模型回答:上海有很多好玩的地方,其中一些最受欢迎的景点包括外滩、黄浦江、南京路和人民广场等。
投机采样(Speculative Decoding):
- 用户问题:上海有什么好玩的地方?
- 流程:
- 小模型预测:小模型快速连续预测多个token(上 -> 海 -> 有 ... 民 -> 广 -> 场 -> 等)
- 大模型验证:大模型对小模型预测的片段进行并行验证,决定是否接受小模型的预测
- 模型回答:上海有很多好玩的地方,其中一些最受欢迎的景点包括外滩、黄浦江、南京路和人民广场等。
投机采样的关键在于利用小模型多次推理单个token,让大模型进行多token预测,从而提升整体推理效率。每次小模型的单token推理耗时远远小于大模型,因此投机采样能够有效地提高推理效率。这种方法的优势在于,通过蒸馏学习和投机采样,可以在减小模型规模的同时保持较高的预测效果和推理速度,从而在实际部署中获得更好的性能优化。
📝通俗解释:就像让一个实习生(小模型)先快速起草一份草稿,然后专家(大模型)审核修改。实习生写得快,专家审核也快,比专家自己从头写要省时间。这叫"小模型打草稿,大模型来把关"。
3.7 大模型(LLM)部署优化策略——Medusa
3.7.1 介绍一下大模型(LLM) Medusa方法?
一次生成多个词,相对于投机采样使用一个小模型一次生成多个词,主要思想是在正常的LLM的基础上,增加几个解码头,并且每个头预测的偏移量是不同的。比如原始的头预测第i个token,而新增的Medusa Heads分别为预测第i+1、i+2...个token。
Medusa的工作流程:
- 多头Medusa预测:记录logits
- 树形注意力验证:预测的token组合输入大模型,token的组合太多了,每个分别输入大模型判断耗时太长。Medusa提出了树形注意力机制,预测的所有token可以同时输入进大模型,输出logits概率进行判别是否接受以及接收长度
- 选择最优:重复步骤1
Tree Mask注意力机制:
- 左侧结构展示了树状生成的层级结构,Root节点指向Head 1,Head 1包含多个token,Head 1指向Head 2
- 右侧矩阵展示了Key与Query之间的注意力掩码(Attention Mask)矩阵,不同的Query只能关注特定的Key
📝通俗解释:就像一个团队同时想多个后续情节发展(多个头),然后大家一起评估哪个情节最合理,选最好的那个继续发展。比一个一个想再一个个验证要快得多。
需要注意的问题:
- 随着Medusa头数量增加,top-k的树状分支将以指数增长,造成庞大的计算开销
- 许多基础和微调模型并没有开放其训练数据集,因此多头Medusa面临的另一大问题是使用什么数据来训练Medusa头
总结
大模型部署优化主要从以下几个方向入手:
| 优化策略 | 核心思想 | 效果 |
|---|---|---|
| 量化 | 压缩模型精度(FP32→INT8→INT4) | 减少显存占用,加快计算 |
| KV Cache | 缓存已计算的Key和Value | 避免重复计算 |
| Flash Attention | 分片计算+减少HBM访问 | 降低内存复杂度 |
| Paged Attention | 分页管理KV Cache | 减少显存浪费 |
| Continuous Batching | 动态批处理 | 提高GPU利用率 |
| Speculative Decoding | 小模型打草稿,大模型验证 | 加速自回归生成 |
| Medusa | 多头并行预测 | 一次生成多个token |
📝通俗解释:这些优化技术就像给一辆跑车(LLM)做改装:量化是减轻车身重量,KV Cache是减少重复刹车,Flash Attention是优化发动机效率,Paged Attention是合理安排油箱空间,Continuous Batching是让发动机尽量满负荷运转,Speculative Decoding是找助手先帮忙处理,Medusa是一次多踩几个油门。这些改装一起用,才能让LLM跑得更快、更省资源。