KV cache
大模型推理性能优化的一个常用技术是KV Cache,该技术可以在不影响任何计算精度的前提下,通过空间换时间思想,提高推理性能。
生成式generative模型的推理过程很有特点,我们给一个输入文本,模型会输出一个回答(长度为N),其实该过程中执行了N次推理过程。即GPT类模型一次推理只输出一个token,输出token会与输入tokens 拼接在一起,然后作为下一次推理的输入,这样不断反复直到遇到终止符。
其实,KV Cache 配置开启后,推理过程可以分为2个阶段:
1、预填充阶段:发生在计算第一个输出token过程中,这时Cache是空的,计算时需要为每个 transformer layer 计算并保存key cache和value cache,在输出token时Cache完成填充;FLOPs同KV Cache关闭一致,存在大量gemm操作,推理速度慢。
2、使用KV Cache阶段:发生在计算第二个输出token至最后一个token过程中,这时Cache是有值的,每轮推理只需读取Cache,同时将当前轮计算出的新的Key、Value追加写入至Cache;FLOPs降低,gemm变为gemv操作,推理速度相对第一阶段变快,这时属于Memory-bound类型计算。
通过transformer原理分析, decoding 输入的 Q 的 shape 是[b, 1, dim],而KV 的 shape 是[b, input_len + step, dim]。
参考地址:https://zhuanlan.zhihu.com/p/630832593
量化
随着以Transformer为基础语言模型规模的快速增大,对GPU显存和算力的需求越来越大,如何减少模型的存储大小,提高计算效率就显得愈发重要。
在训练时,为保证精度,主权重始终为 FP32。而在推理时,FP16 权重通常能提供与 FP32 相似的精度,这意味着在推理时使用 FP16 权重,仅需一半 GPU 显存就能获得相同的结果。那么是否还能进一步减少显存消耗呢?答案就是使用量化技术,最常见的就是 INT8 量化。
其他量化方式包括SmoothQuant、GPTQ等
NF4,非均匀的数据映射
其他关键词:向量量化(Vector-wise Quantization)
混合精度分解(Mixed-precision Decomposition)
量化校准
连续批处理
连续批处理是推理引擎(Mind Inference Engine,MindIE) 的核心特性,只适用于LLM。
由于大语言模型的输入输出长度不确定,衍生了多种处理方法,有padding input,unpadding input,static batching,continuous batching等。
- padding input:输入长度不一致,但是神经网络需要tensor对齐,将所有输入padding到相同的max_seq_length,输入使用[batch_size,max_seq_length]进行计算,有冗余计算开销。
-
unpadding input:输入长度不同,将batch中所有输入直接拼接在一起,形成Ntokens个输入,使用[ntokens]输入进行计算,无冗余计算开销。但是需要额外输入每个input在总体输入的位置偏移,用于在attention计算时分开处理不同的input。
-
static batching:输出长度不一致,将多个input组合成一个batch,执行一次推理过程,直到输出最长的推理完成,才完成一个完整的batch推理过程。
-
continuous batching:输出长度不一致,连续批处理,也称为动态批处理或者迭代级的批处理。
◈early stop:推理执行的过程中,一个batch中的一个推理请求遇到推理的结果为EOS token,或者是设定好的推理结束符,或者达到最长长度时,结束该推理请求,剩余请求可以继续推理。
◈continuous batching:当推理进行过程中,组batch的推理请求未达到batch上限时,有新请求到来,可以随时加入batch进行推理。
◈通过减小调度的间隙,提升硬件利用率,端到端吞吐率。
◈continuous batching涉及较严重的动态shape问题。
continuous batchin
参考地址:https://zhuanlan.zhihu.com/p/704408423
https://zhuanlan.zhihu.com/p/676109470
Page Attention
VLLM提出使用
推理prefill节点和decode阶段耗时接近,因为prefill阶段能够充分利用算力。
推理是 IO bound,推理吞吐主要依赖推理batch size。
GPU内存消耗正比于模型大小+sequence length。
KV cache的管理成为长序列,大batchsize的关键。
所以就提出了page attention。
- 使用paged kvcache+paged attention,细粒度管理kv cache,结合continuous
batching,最大化device内存利用率。
- paged attention将KV cache按块分布,每块包含一定数量的token的KV。 - paged kvcache:使用logical
kvcache可以随时新增或者删除,最大化kvcache空间利用率,简化continuous batching的kvcache管理。 - paged attention:使用离散physical kvcache进行attention计算
参考:https://zhuanlan.zhihu.com/p/704408423
https://zhuanlan.zhihu.com/p/697371125
https://zhuanlan.zhihu.com/p/676109470
LoRa
PEFT(Parameter-Efficient Fine-Tuning),训练LLM普遍使用的PEFT算法:LoRA(Low Rank Adaptation),顾名思义,LoRA的核心思想是基于低秩的适配器进行优化。
参考:https://zhuanlan.zhihu.com/p/663557294
流水线并行(模型并行+数据并行)
流水线并行的核心思想是:在模型并行的基础上,进一步引入数据并行的办法,即把原先的数据再划分成若干个batch,送入GPU进行训练。
以Google GPipe为代表的流水线并行范式。当模型太大,一块GPU放不下时,流水线并行将模型的不同层放到不同的GPU上,通过切割mini-batch实现对训练数据的流水线处理,提升GPU计算通讯比。同时通过re-materialization机制降低显存消耗。
参考:https://zhuanlan.zhihu.com/p/613196255
数据并行
流水线并行并不特别流行,主要原因是模型能否均匀切割,影响了整体计算效率,这就需要算法工程师做手调。因此,今天我们来介绍一种应用最广泛,最易于理解的并行范式:数据并行。
数据并行的核心思想是:在各个GPU上都拷贝一份完整模型,各自吃一份数据,算一份梯度,最后对梯度进行累加来更新整体模型
三种主流数据并行的实现方式:
- DP(Data Parallelism):最早的数据并行模式,一般采用参数服务器(Parameters
Server)这一编程框架。实际中多用于单机多卡 - DDP(Distributed Data Parallelism):分布式数据并行,采用Ring
AllReduce的通讯方式,实际中多用于多机场景 - ZeRO:零冗余优化器。由微软推出并应用于其DeepSpeed框架中。严格来讲ZeRO采用数据并行+张量并行的方式,旨在降低存储。
ZeRO是模型并行的形式,数据并行的实质。
参考地址:
https://zhuanlan.zhihu.com/p/617133971
https://zhuanlan.zhihu.com/p/618865052
视频地址:https://www.bilibili.com/video/BV1mm42137X8/?spm_id_from=333.1007.top_right_bar_window_history.content.click
张量并行
它的基本思想就是把模型的参数纵向切开,放到不同的GPU上进行独立计算,然后再做聚合。
地址:https://zhuanlan.zhihu.com/p/622212228