<!--StartFragment-->
在实际的生产环境中,[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)的部署和微调都面临很多挑战,以下是对大多数模型推理优化技术的简要概述。
对模型优化的方法可以在硬件和软件层面上进行。为了帮助有志于在大模型领域深入耕耘研究的开发者,可以更好地了解该领域的最新知识结构,本文梳理了针对在软件层面的优化策略和最新行业进展,如下图所示:
![640.png](https://dev-media.amazoncloud.cn/dd9aff6a4f2f480a8a941be05ff2cc4b_640.png "640.png")
对这一话题有兴趣的开发者也可以关注我和王宇博老师下周在 [2023 亚马逊云科技 re:Invent](https://mp.weixin.qq.com/s?\\__biz=Mzg4NjU5NDUxNg==\\&mid=2247557010\\&idx=1\\&sn=903b8671c3d2df9d2f99ca1998de0f12\\&scene=21#wechat_redirect?trk=cndc-detail) 上分享的演讲(详细的演讲信息请见文末):
![640 (1).png](https://dev-media.amazoncloud.cn/64f7cc6c47b842f9b907c7a967debf28_640%20%281%29.png "640 (1).png")
### **1 模型模型编(Model Compilation)**
现代的模型编译技术(例如,算子融合、常量折叠等)可以在不影响模型精度的情况下提高性能。
例如,[Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Neo 会自动优化[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)模型,以便在云实例和边缘设备上进行推理,从而以更快的速度运行而不会损失准确性。首先,选择一个已使用 PyTorch、TensorFlow 等深度学习框架构建,并在其他任何地方训练过的[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)模型。然后选择目标硬件平台,该平台可以是 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 托管实例,也可以是基于 ARM、Intel、Nvidia 或 Qualcomm 等处理器的边缘设备。
[Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Neo 可以用于优化和编译云端推理模型,并与亚马逊云科技的 Neuron 集成,在自定义芯片 Inferentia 和 Trainium 上运行深度学习模型。
以下分别简述算子融合(Operator Fusion)、常量折叠(Constant Folding)等基本概念。
#### **1.1. 算子融合(Operator Fusion)**
算子融合(Operator Fusion)常用于深度学习和其他计算密集型任务中,其基本操作就是将多个连续的操作或算子合并成一个单一的算子,以减少计算和内存开销。使用算子融合有助于提高执行效率,减少数据传输和临时存储的需要,以及提高缓存利用率。以下举例说明。
例如在深度学习的卷积层后,常常会紧跟着一个激活函数,比如:ReLU 激活函数。将这两个算子融合,可避免额外的内存访问。示例代码如下:
```
output = my_relu(conv3d(input, weights))
```
我在 2023 年初发表过一篇技术博客[《机器学习洞察|一文带你“讲透”JAX》](https://mp.weixin.qq.com/s?\\__biz=Mzg5Mzg1NDc2NQ==\\&mid=2247484633\\&idx=1\\&sn=b1159155a751911abf284209dedbdac0\\&scene=21#wechat_redirect?trk=cndc-detail),其中谈到 JAX 通过 jax.jit 将源代码编译成 HLO (High Level Optimized)代码,代表高级的优化代码,提供给 XLA 进行读取。XLA 在获取编译的 HLO 代码之后,会分配到对应的 CPU、GPU、Inferentia、Trainium 或者 ASIC,也是类似原理。有兴趣的读者,可以参考我这篇博客进行深度阅读。
#### **1.2. 常量折叠(Constant Folding)**
常数折叠(Constant folding)是一个在编译时期简化常数的一个过程,常数在表示式中仅仅代表一个简单的数值,就像是整数 6,若是一个变数从未被修改也可作为常数,或者直接将一个变数被明确地被标注为常数,例如下面的描述:
i = 320 * 200 * 32;
多数的现代编译器不会真的产生两个乘法的指令再将结果储存下来,取而代之的,他们会辨识出语句的结构,并在编译时期将数值计算出来(在这个例子,结果为 2,048,000),通常会在中间表示(IR,Intermediate Representation)树中进行。
对常量折叠有兴趣的读者,可以参考维基百科的“Constant folding”条目做深入探究。
* 《维基百科的“Constant folding”条目》 \
https\://en.wikipedia.org/wiki/Constant_folding?trk=cndc-detail
### **2 模型压缩(Model Compression)**
模型压缩是一种使研究人员和从业人员可以轻松压缩模型的方法,同时提供更快的速度、更小的模型大小并显著降低压缩成本。究其具体理论方法,可大致分为以下三种:
1. 量化(Quantization)
2. 修剪(Pruning)
3. 蒸馏(Distillation)
以下分别做一些简述。
#### **2.1. 量化(Quantization)**
量化(Quantization)涉及将模型转换为使用较低精度的参数和计算的等效表示。你可以执行权重并激活量化,将全精度权重 (FP32/FP16) 映射到低位权重,如 INT8 和 INT4。这提高了模型的执行性能和效率,但通常会导致模型精度降低。
具体而言,模型量化是一种压缩网络参数的方式,它将神经网络的参数(weight)、特征图(activation)等原本用浮点表示的量值换用整型表示,在计算过程中,再将整型数据反量化回浮点数据,最终得到输出结果。
在深度神经网络上应用量化有两种常用方法:
**1)训练后量化 (PTQ: Post-Training Quantization)**:首先对模型进行收敛训练,然后我们无需进行更多训练即可将其权重转换为较低的精度。与训练相比,实施起来通常相当便宜。
**2)量化感知训练 (QAT: Quantization-Aware Training)**:在预训练或进一步微调期间应用量化。QAT 能够获得更好的性能,但需要额外的计算资源和对额外训练数据的访问权限。
PyTorch 对上述量化方式都提供了相应的 API,有兴趣的同学可参考以下文档:\
https\://pytorch.org/blog/introduction-to-quantization-on-pytorch/?trk=cndc-detail
目前市场上具有真实场景落地的量化实践方法有 QLoRA、GPTQ 等,不同的量化实践方法各有特点和优势。例如, QLoRA 同时结合了模型量化 Quant 和 LoRA 参数微调,而 GPTQ 则是对某个 block 内的所有参数逐个量化。
在这个博客系列的[《Generative AI 新世界 | Falcon 40B 大模型微调和量化实践》](https://mp.weixin.qq.com/s?\\__biz=Mzg5Mzg1NDc2NQ==\\&mid=2247489020\\&idx=1\\&sn=236165ff3f5f3292a7118cb4920aed97\\&scene=21#wechat_redirect?trk=cndc-detail)一文中,我们曾经详细地以微调 Falcon 40B 大模型为例,运用 QLoRA 和 4-bits 的 bitsandbtyes 量化技术原理,在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 上使用 Hugging Face PEFT 来微调 Falcon 40B 大模型。有兴趣深究的读者,可以参考我的这篇博客做深度研究和亲自来动手实践。
#### **2.2. 修剪(Pruning)**
修剪(Pruning) 是在模型容量保持不变的情况下,通过修剪不重要的模型权重或网络连接,从而减少生成预测所涉及的参数和操作的数量,最终削减模型大小。其在实现上目前可以使用 DeepSpeed 或 HuggingFace Optimum library 等来完成。
构建修剪后的精简网络(Pruned Network)的常规工作流程分为三个步骤:
1. 训练密集网络(Dense Network)直到收敛;
2. 修剪网络以移除不需要的结构;
3. (可选)重新训练网络,使用新的权重恢复性能。
通过网络修剪发现密集模型中的稀疏结构(Sparse Structure),而稀疏网络(Sparse Network)仍然可以保持相似的性能。
修剪(Pruning)理论最早来自《The Lottery Ticket Hypothesis》这篇来自 MIT 的 2019 年论文。这篇有趣的论文提出一个鼓舞人心的发现:即只有一部分网络参数会影响模型性能,使网络不会过拟合。论文如下所示。
* 《The Lottery Ticket Hypothesis》 \
https\://arxiv.org/abs/1803.03635?trk=cndc-detail
![640 (2).png](https://dev-media.amazoncloud.cn/ee442dd385284859bfe45dd73efeed51_640%20%282%29.png "640 (2).png")
Source: https\://arxiv.org/pdf/1803.03635.pdf?trk=cndc-detail
该论文为解释和解析深度神经网络结果开辟了一个新的视角,许多有趣的后续工作正在进行中。对修剪(Pruning)理论感兴趣的开发者,可以参考以上论文做进一步研究学习。
#### **2.3. 蒸馏(Distillation)**
蒸馏(Distillation)也称为知识蒸馏(Knowledge Distillation),是训练小 “学生模型” 模仿更大的 “教师模型” 的过程,通过将技能从预先训练的昂贵模型(“教师模型”)转移给学生来加快推理速度。其在实现上目前可以使用 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Training 和 HuggingFace DLC 等来完成。
![640 (3).png](https://dev-media.amazoncloud.cn/a3de97cd8ad54c3bb4eada728698a2e8_640%20%283%29.png "640 (3).png")
The generic framework of teacher-student knowledge distillation training (source: Gou et al. 2020)
比较出名的蒸馏领域论文例如 DistilBERT。根据论文阐述,它能够将 BERT 的参数减少 40%,同时在微调的下游任务上保持 BERT 的 97%的性能,运行速度提高 71%。
* 《DistilBERT》 \
https\://arxiv.org/abs/1910.01108?trk=cndc-detail
蒸馏还可以轻松地与量化、修剪或稀疏化(sparsification)等技术相结合,其中,教师模型是原始的全精度密集模型,对学生模型进行量化、修剪或修剪以获得更高的稀疏度水平。
### **3 模型分片(Model Sharding)**
模型分片(或模型并行度)是一种将模型分成分区,每个分区托管在单独的加速器内存中的技术。当大型模型即使在遵循模型压缩技术后也无法放入单个加速器的内存时,这将非常有帮助。在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 上有经验地使用开源 DeepSpeed、Parallelformers 库,可以实现最终的模型输出准确度不会降低。这些库将自动对模型进行分区,并将兼容的高性能内核注入大模型并高效管理 GPU 之间的通信。
大模型通常有数十到数千亿个参数,这使得它们无法容纳在单个 GPU 卡中。大模型领域目前已有多个训练分布式计算的开源库,例如:Neuron,DeepSpeed,FT,HF 等。你可以在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 中使用 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 分布式训练库,这些库已经针对亚马逊云进行了优化,可提供更简单的开发体验。
为了提供更好的分布式训练性能和可用性,[Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Training 提出了几种专有扩展来扩展 TensorFlow 和 PyTorch 训练代码。在真实场景里,大型语言模型的训练通常以多维度并行(3D-parallelism)的方式在进行:
* **数据并行(data parallelism)**:可拆分训练小批次并将其馈送到模型的多个相同副本,以提高处理速度
* **流水线并行(pipeline parallelism)**:将模型的各个层归因于不同的 GPU 甚至实例,以便将模型大小扩展到单个 GPU 和单个服务器以外
* **Tensor 并行(tensor parallelism)**:将单个层拆分为多个 GPU,通常位于同一服务器内,以将单个层扩展到超过单个 GPU 的大小
在这个博客系列的[《Generative AI 新世界|大型语言模型(LLMs)概述》](https://mp.weixin.qq.com/s?\\__biz=Mzg5Mzg1NDc2NQ==\\&mid=2247486827\\&idx=1\\&sn=8c54d985613a020d6119f837608b6e24\\&scene=21#wechat_redirect?trk=cndc-detail)中,我们曾经探讨过大模型训练的并行化(Training Parallelism)这个前沿话题。有兴趣对模型分片(Model Sharding)做进一步详细探究的读者,可以通过以上博客做深度阅读。
### **4 批量推理(Batching)**
由于大量 GPU 内存占用量和[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)(LLM)的计算成本,推理成本在大多数现实世界的生成式 AI 应用的计算成本中占主导地位。[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)工程师通常将 LLM 视为 “黑匣子”,认为只有通过量化和自定义 CUDA 内核等内部更改才能对其进行优化。但情况并非完全如此。
由于 LLM 需要不间断地生成输出结果,而且由于 LLM 推理瓶颈主要是内存容量而非计算资源,因此如果进行合理的系统级别批处理优化,将可以有效地使实际工作负载提升 10 倍甚至更多。在提供吞吐量的同时,优化批量推理还可以有效地减少延迟,从而提升客户体验。
行业最新的批量推理优化实践之一是连续批处理(Continuous Batching),也称为动态批处理(Dynamic Batching)。以下将对比静态批处理和连续批处理的实现效率,简述如下。
#### **4.1. 静态批处理(Static Batching)**
![640 (4).png](https://dev-media.amazoncloud.cn/40274d74a606456097553de1a85207a3_640%20%284%29.png "640 (4).png")
Source:https\://www\.anyscale.com/blog/continuous-batching-llm-inference?trk=cndc-detail
静态批处理如上图所示。
使用静态批处理完成四个序列。在第一次迭代中(左),每个序列从提示标记(黄色)中生成一个标记(蓝色)。经过几次迭代(右),每个完成的序列都有不同的大小,因为每个序列在不同的迭代中都会发出其序列结束标记(红色)。尽管序列 3 在两次迭代后完成,但静态批处理意味着在批处理中的最后一个序列完成生成之前,GPU 将得不到充分利用(在本示例中,序列 2 在六次迭代之后)。
#### **4.2. 连续批处理(Continuous Batching)**
![640 (6).png](https://dev-media.amazoncloud.cn/dbc7f34279c74670878c31287ef673f2_640%20%286%29.png "640 (6).png")
Source:https\://www\.anyscale.com/blog/continuous-batching-llm-inference?trk=cndc-detail
连续批处理如上图所示。
使用连续批处理完成七个序列。左侧显示单次迭代后的批次,右侧显示多次迭代后的批次。一旦序列发出序列结束标记,就会在其位置插入一个新序列(即序列 S5、S6 和 S7)。这可以实现更高的 GPU 利用率,因为 GPU 不会等待所有序列完成后才开始新的序列。
#### **小结**
作为开发者的你可能在担心:这么多先进的[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)理论和优化实践方法,光是简述就写了这么多,实际应用在[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)的部署和微调代码实践,将会是一个更加艰难的挑战吧?
别担心!
这其中的难度主要集中在以上分享的这些先进理论和论文方法的介绍。在引入 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 等亚马逊云科技的服务之后,你会发现实践起来真的很简单,只需要参考亚马逊云科技提供的文档示例,按照你不同的业务需要做些配置即可。
这就是我和宇博老师将在下周四下午(太平洋时间 11 月 30 日 14:00),今年美国拉斯维加斯 [2023 亚马逊云科技 re:Invent ](https://mp.weixin.qq.com/s?\\__biz=Mzg4NjU5NDUxNg==\\&mid=2247557010\\&idx=1\\&sn=903b8671c3d2df9d2f99ca1998de0f12\\&scene=21#wechat_redirect?trk=cndc-detail)这一盛会中,分享“开源[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)部署和微调的优化实践”这样一个热点话题的意义:
![640 (5).png](https://dev-media.amazoncloud.cn/cc2873a0c81a45ec96b59c6055f10f07_640%20%285%29.png "640 (5).png")
生成式 AI 和[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)的变革力量正在彻底改变全球各行各业,我们希望通过这场分享,和世界各地的开发者们一起探讨[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)的模型部署和微调优化领域,在模型编译、模型压缩、模型分布式训练、模型推理批处理等方面的行业最新论文和发展趋势,以及通过两个实际代码演示 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 如何高效简化[大语言模型](https://aws.amazon.com/cn/what-is/large-language-model/?trk=cndc-detail)的部署和微调流程。
期待下周在拉斯维加斯现场和全球开发者分享我们的内容,一起加入讨论。遗憾不能到场的开发者也不用担心,我们将在大会之后提供视频回放,敬请期待!
请持续关注 Build On Cloud 微信公众号,了解更多面向开发者的技术分享和云开发动态!
![640.gif](https://dev-media.amazoncloud.cn/edbcd422578e4c4582a65309bb8917b7_640.gif "640.gif")
<!--EndFragment-->