DeepSpeed 模型压缩库
什么是DeepSpeed压缩: DeepSpeed压缩是一个专门构建的库,旨在使研究人员和从业者能够轻松压缩模型,同时提供更快的速度、更小的模型大小和显著降低的压缩成本。
为什么使用DeepSpeed压缩: DeepSpeed压缩提供了新颖的最先进的压缩技术,以实现更快的模型压缩,同时保持更好的模型质量和更低的压缩成本。DeepSpeed压缩还采用端到端的方法,通过高度优化的推理引擎提高压缩模型的计算效率。此外,我们的库内置了多种最先进的压缩方法。它支持这些方法和系统优化的协同组合,提供两全其美的解决方案,同时为高效的深度学习模型推理提供了一个无缝且易于使用的管道。我们强烈建议您也阅读我们的博客,以了解更多关于(从高层次上)我们为什么构建DeepSpeed压缩以及它为用户提供了哪些好处。
如何使用DeepSpeed压缩: 第一部分通用教程将介绍库支持的压缩方法。接下来的部分将描述我们的研究工作,即如何组合不同的压缩方法来执行零成本量化(ZeroQuant)和极端压缩(XTC)。除非另有说明,下面列出的实验结果基于NVIDIA A100 GPU,使用不同的GPU硬件时我们观察到略有不同的结果数字。
1. 通用教程
要使用DeepSpeed压缩库,您需要按照安装指南安装DeepSpeed >= 0.7.0。目前,DeepSpeed压缩包括七种压缩方法:通过知识蒸馏进行层减少、权重量化、激活量化、稀疏剪枝、行剪枝、头剪枝和通道剪枝。在以下小节中,我们将描述这些方法是什么,何时使用它们,以及如何通过我们的库使用它们。
1.1 层减少
什么是层减少
神经网络由输入层、输出层和隐藏层构成。例如,BERT-base语言模型包括嵌入层(输入层)、分类层(输出层)和12个隐藏层。层减少意味着在保持网络宽度不变的情况下减少隐藏层的数量(即不减少隐藏层的维度)。这种方法可以线性地减少隐藏层的推理延迟,无论硬件和/或场景如何。
何时使用层减少
如果模型非常深,您可以考虑使用此方法。在应用知识蒸馏时,它的效果会更好。层减少可以在预训练和微调阶段都应用。前者生成一个蒸馏的任务无关模型,而后者生成一个任务特定的蒸馏模型。在我们的XTC工作(paper, tutorial)中,我们还讨论了何时应用层减少。
如何使用图层减少
可以通过DeepSpeed配置JSON文件(配置详情)启用和配置层减少。用户可以通过keep_number_layer选择任何深度,并通过teacher_layer选择网络层的任何子集。此外,用户还可以通过other_module_name选择是否从给定模型(教师模型)重新初始化输入/输出层。
为了应用特定任务压缩的层减少,我们提供了一个关于如何为BERT微调进行此操作的示例。层减少涉及重置网络架构的深度和重新初始化权重参数,这发生在训练过程之前。该示例包括对客户端代码的以下更改(在DeepSpeedExamples中的compression/bert/run_glue_no_trainer.py):
(1) 初始化模型时,模型配置中的层数应与DeepSpeed配置JSON文件中的keep_number_layer相同。对于Hugging Face BERT示例,设置config.num_hidden_layers = ds_config["compression_training"]["layer_reduction"]["keep_number_layer"]。
(2) 然后我们需要根据DeepSpeed JSON配置重新初始化模型,使用从deepspeed.compression.compress导入的函数init_compression。
(3) 在训练过程中,如果不使用KD,则无需进行任何操作。否则,在计算教师和学生输出之间的差异时,需要考虑使用teacher_layer JSON配置来应用KD。
可以在DeepSpeedExamples中运行我们的层减少示例:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/layer_reduction.sh
最终结果是:
Epoch: 18 | Time: 12m 38s
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8340295466123281/0.8339096826688365
为了在任务无关的压缩中应用层减少,我们提供了一个在GPT预训练阶段如何进行的示例。
第一步:获取最新版本的Megatron-DeepSpeed。
第二步:进入 Megatron-DeepSpeed/examples_deepspeed/compression 目录。
步骤3:运行示例bash脚本,例如ds_pretrain_gpt_125M_dense_cl_kd.sh。与预训练蒸馏相关的参数是:
(1)--kd, 这启用了知识蒸馏。
(2)--kd-beta-ce,这指定了知识蒸馏系数。通常可以将其保留为默认值1,但有时调整此超参数可以获得更好的蒸馏结果。
(3)--num-layers-teacher, —hidden-size-teacher, num-attention-heads-teacher,这些参数指定了教师模型的网络配置。请确保它们与检查点中的教师模型维度匹配。
(4)--load-teacher,这是指定教师模型检查点的地方。
(5)--load,这是将要加载的学生模型的初始检查点所在的位置。默认情况下,它将加载教师模型的底层进行初始化,但你可以传递自己的检查点进行初始化。
除了上述配置外,您可能还需要修改data_options中的数据路径,以便训练器知道数据的位置。为了使事情稍微简单一些,我们提供了几个示例脚本来运行不同模型大小的蒸馏,包括350M(ds_pretrain_gpt_350M_dense_kd.sh)和1.3B模型(ds_pretrain_gpt_1.3B_dense_cl_kd.sh)。我们还通过经验发现,分阶段的KD通常会在下游任务上产生更好的预训练蒸馏模型。因此,我们建议通过在提供的脚本中不设置--kd来实现早期停止KD的简单方法(例如,在剩余的40%训练中禁用KD)。
步骤4:在蒸馏模型之后,还可以选择通过运行脚本125M-L10-Int8-test-64gpu-distilled-group48.sh进一步量化蒸馏模型,该脚本使用INT8量化器对蒸馏模型的权重和激活进行量化(权重和激活量化将在以下部分介绍)。请注意,在执行量化时需要设置-reset-iteration标志。我们在下表中提供了来自WikiText-2和LAMBADA的零样本困惑度结果。
| GPT (125M) | #层数 | wikitex2 困惑度 | LAMBADA |
|---|---|---|---|
| 未压缩 | 12 | 29.6 | 39.5 |
| 仅量化 | 12 | 29.8 | 39.7 |
| 仅蒸馏 | 10 | 31.9 | 39.2 |
| 蒸馏 + 量化 | 10 | 32.28 | 38.7 |
1.2 权重量化
什么是权重量化
权重量化将全精度权重(FP32/FP16)映射到低比特权重,如INT8和INT4。引用自这个Coursera讲座:“量化涉及将模型转换为使用较低精度的参数和计算的等效表示。这提高了模型的执行性能和效率,但通常会导致模型精度降低”。
何时使用权重量化
一方面,再次引用这个Coursera讲座:“移动和嵌入式设备的计算资源有限,因此保持应用程序资源高效非常重要。根据任务的不同,你需要在模型准确性和模型复杂性之间做出权衡。如果你的任务需要高准确性,那么你可能需要一个大型且复杂的模型。对于需要较低精度的任务,最好使用较小、较不复杂的模型。”另一方面,最近的服务器加速器,如GPU,支持低精度算术。因此,将权重量化与激活量化(在后面的部分中介绍)结合使用,可以提供更好的效率。
如何使用权重量化
权重量化可以通过DeepSpeed配置JSON文件启用和配置(配置详情)。我们想要指出的关键配置是:
(1)quantize_groups,一种分组权重矩阵量化方法:权重矩阵 W 被划分为多个组,每个组分别进行量化。更多详情请参见这篇论文。
(2)quantize_weight_in_forward 在FP32优化器训练时必须设置为true,在FP16时必须设置为false。
(3)wq1/wq2,用户可以扩展更多组,如wq3、wq4等。
(4)start_bit 和 target_bit,为了简化第一个实验,我们建议将它们设置为相同,这样一旦迭代达到schedule_offset,我们就对目标位应用量化。
客户端代码有两处更改(位于DeepSpeedExamples中的compression/bert/run_glue_no_trainer.py):
(1) 模型初始化后,使用DeepSpeed JSON配置对模型应用init_compression函数。
(2) 训练后,应用redundancy_clean函数以保存量化权重。
可以在DeepSpeedExamples中运行我们的权重量化示例,方法如下:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/quant_weight.sh
最终结果是:
Epoch: 09 | Time: 27m 10s
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8414671421293938/0.8422497965825875
1.3 激活量化
什么是激活量化
激活意味着每一层的输入。激活量化将输入从全/半精度映射到低精度。更多信息请参见此博客。
何时使用激活量化
它可以提高计算效率,类似于权重量化。
如何使用激活量化
激活量化可以通过DeepSpeed配置JSON文件启用和配置(配置详情)。其中一些组件与权重量化相同,例如schedule_offset和quantization_type。我们想要指出的关键配置是:
(1)range_calibration,用户可以选择设置为动态或静态。当使用“动态”时,激活量化组将自动设置为基于token的(对于基于Transformer的模型)和基于图像的(对于基于CNN的模型)。更多信息请参见我们的ZeroQuant论文和代码(deepspeed/compression/basic_layer.py在DeepSpeed中)。
(2)aq1/aq2,用户可以扩展更多组,例如aq3、aq4等。
客户端代码更改与权重量化相同。
可以通过以下方式在DeepSpeedExamples中运行我们的激活量化示例:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/quant_activation.sh
最终结果是:
Epoch: 02 | Time: 28m 50s
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8375955170657158/0.8422497965825875
1.4 剪枝
什么是剪枝
剪枝旨在通过移除网络连接来减少生成预测时涉及的参数和操作数量。通过剪枝,您可以降低网络中的总体参数数量(更多信息请参见这个Coursera讲座)。我们可以将剪枝策略分为两种类型:结构化和非结构化剪枝(更多信息请参见这篇论文)。
| 方法 | 类型 |
|---|---|
| Sparse pruning | 非结构化和结构化 |
| 行剪枝 | 结构化 |
| Head pruning | 结构化 |
| Channel pruning | 结构化 |
1.4.1 稀疏剪枝
什么是稀疏剪枝
稀疏剪枝意味着我们将每个权重矩阵中的一些元素设置为零值。根据用户选择的剪枝方法,零值可能具有结构化模式或非结构化模式。一种执行剪枝的方法是基于权重参数的绝对值,例如参见这篇论文。另一种执行剪枝的方法是基于权重在被屏蔽时对损失函数的影响,例如参见这篇论文。
何时使用稀疏剪枝
如果你的模型显著过参数化,你可以考虑使用稀疏剪枝。然而,要看到硬件计算效率的真正好处,密度比(剪枝后保留的权重百分比)必须相当低。
如何使用稀疏剪枝
稀疏剪枝可以通过DeepSpeed配置JSON文件启用和配置(配置详情)。我们想要指出的关键配置是:
(1)schedule_offset,我们通过经验发现,当使用method: topk时,最好将schedule_offset设置为一个较大的值,例如总训练步骤的10%。
(2)method,我们支持L1范数、topk和snip_momentum方法。欢迎用户贡献更多方法。
(3)sp1,用户可以扩展更多组,如sp2、sp3等。注意,这对于snip_momentum方法不是必需的。
(4)dense_ratio,对于非结构化稀疏剪枝,BRET-base模型的密集比率可以小于0.1,同时仍能保持良好的准确性。对于ResNet-50,密集比率可以低至0.3,同时在ImageNet上仍能保持良好的准确性。对于像snip_momentum这样的结构化稀疏剪枝,密集比率应在shared_parameters中指定,并用于计算全局稀疏比率。
(5)frequency, block_pattern 和 schedule_offset_end,它们用于指定在步骤上的剪枝频率、块状剪枝模式(NxM和M中的N),以及剪枝的结束步骤。对于snip_momentum方法,这些配置是必需的。
客户端代码更改与权重量化相同。
可以在DeepSpeedExamples中运行我们的稀疏剪枝示例,方法如下:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/pruning_sparse.sh
最终结果是:
Epoch: 02 | Time: 26m 14s
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8416709118695873/0.8447925142392189
1.4.2 行修剪
什么是行修剪
行剪枝将权重矩阵中某些行的所有元素设置为零值。如果某一行被剪枝,该行中的所有元素都将被设置为零。
何时使用行修剪
行剪枝对硬件加速有益,比稀疏剪枝效果更好(但与稀疏剪枝相比,可能会导致更大的精度损失)。这是一个为两个连续的线性层(例如,Transformer中的前馈网络)设计的功能。因此,我们建议在第一个线性层(即BERT的intermediate.dense层)使用行剪枝。减少此矩阵的行维度有助于减少后续矩阵的列(即BERT的layer.\\w+.output.dense层)。行剪枝也适用于其他类型的线性层。
如何使用行修剪
行剪枝可以通过DeepSpeed配置JSON文件(配置详情)启用和配置。我们想要指出的关键配置是:
(1)method,目前仅支持topk方法。欢迎用户贡献更多方法。
(2)rp1, 用户可以扩展更多组,例如 rp2, rp3, 等等。
(3)related_modules,正如在“何时使用行修剪”中提到的,如果我们进行行修剪,后续矩阵将受到影响。因此,需要了解模块之间的连接。
客户端代码更改与权重量化相同。
可以通过以下方式在DeepSpeedExamples中运行我们的行修剪示例:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/pruning_row.sh
最终结果是:
Epoch: 02 | Time: 27m 43s
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8440142638818136/0.8425549227013832
1.4.3 头部修剪
什么是头部修剪
头部剪枝专门设计用于具有多头注意力的网络,例如基于Transformer的模型(更多信息请参见此博客)。例如,BERT-base(BERT-large)模型有12个头(24个头)。
何时使用头部修剪
头部剪枝对硬件加速有益。此外,如这篇博客所述:“在论文中提出了令人惊讶的观察结果,即使在正常训练模型(使用所有头部)后,许多头部在测试时可以被移除,而不会显著影响BLEU分数,事实上,在某些情况下移除少量头部甚至提高了BLEU分数。”。
注意:头部剪枝是为注意力层(例如,Transformer中的多头注意力)设计的功能。目前,它只能应用于Transformer的输出矩阵(即BERT中的attention.output.dense)。剪枝输出矩阵也可能导致Query/Key/Value矩阵的剪枝。
如何使用头部修剪
可以通过使用DeepSpeed配置JSON文件(配置详情)来启用和配置头部剪枝。我们想要指出的关键配置是:
(1)num_heads: 用户需要为他们的模型提供正确的头数。
(2)modules: 模块 attention.output.dense 是专门为 Hugging Face BERT 模型设计的。目前,我们仅支持在 Query/Key/Values 是分离矩阵并后接 attention.output.dense 的情况。我们很乐意协助并欢迎对注意力模型变体的贡献。
(3)related_modules: 正如在“何时使用头部剪枝”中提到的,剪枝注意力输出矩阵也可能导致剪枝QKV矩阵。因此,这里的输入是[“self.query”, “self.key”, “self.value”]。
客户端代码更改与权重量化相同。
可以通过以下方式在DeepSpeedExamples中运行我们的头部剪枝示例:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/pruning_head.sh
最终结果是:
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8397350993377484/0.8377746135069162
1.4.4 通道剪枝
什么是通道剪枝
通道剪枝专门为卷积层和计算机视觉设计。根据wikipedia.org的说法,“图像的颜色数据存储在三个值数组中,称为通道。”例如,一个具有三个通道的图像通过ResNet-18后,在第一层之后会产生64个通道。
何时使用通道剪枝
通道剪枝是一种专为两个连续的CONV2d层(例如,ResNet中的残差连接)设计的功能。因此,我们建议在第一个CONV2d层使用通道剪枝。减少该层的输出通道数有助于减少下一层的输入通道数。通道剪枝也适用于其他类型的CONV2d层。
如何使用通道剪枝
可以通过DeepSpeed配置JSON文件启用和配置通道剪枝(配置详情)。
可以通过以下方式在DeepSpeedExamples中运行我们的通道剪枝示例:
pip install torch torchvision
DeepSpeedExamples/compression/cifar$ bash run_compress.sh
最终结果是:
after_clean
epoch 10 testing_correct: 0.7664
请注意,上述结果是在“ResNet”模型中未使用批量归一化(BN)时的情况。如果您在模型中使用BN并应用通道剪枝,清理模型后的验证将与清理前的模型不同。我们建议用户在这种情况下应用redundancy_clean后进一步微调模型。
2. ZeroQuant教程:高效且经济的训练后量化
在本节中,我们将介绍如何应用DS-Compression来执行无成本的INT8量化和轻量级的INT4/INT8混合精度量化。更多详情,请参阅我们的论文。
什么是ZeroQuant
ZeroQuant 是一种高效的训练后量化方法,它包括:(1) 一种细粒度的硬件友好量化方案,适用于权重和激活值,可以显著减少量化误差;(2) 一种新颖的、经济实惠的逐层知识蒸馏算法(LKD),即使无法访问原始训练数据也能使用;(3) 一个高度优化的量化系统后端支持,以消除量化/反量化的开销。通过这些技术,ZeroQuant 能够:(1) 将模型量化为 INT8 而无需任何成本;(2) 将模型量化为 INT4/INT8 混合精度量化,且资源需求极低(例如,BERT-base 量化仅需 31 秒)。
何时使用ZeroQuant
当你想将基于transformer的模型量化为INT8或INT4/INT8格式时,首先尝试ZeroQuant总是一个好主意,特别是当模型非常耗费资源(GPU和/或时间)来进行量化感知训练时,以及当原始训练数据不可访问时。
如何使用ZeroQuant
可以在DeepSpeedExamples中运行我们的BERT示例,方法如下:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
DeepSpeedExamples/compression/bert$ bash bash_script/ZeroQuant/zero_quant.sh
最终结果是:
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8427916454406521/0.8453010577705452
可以通过以下方式运行我们的GPT示例:
DeepSpeedExamples/compression/gpt2$ pip install -r requirements.txt
DeepSpeedExamples/compression/gpt2$ bash bash_script/run_zero_quant.sh
最终结果是:
Before converting the module COVN1D to linear and init_compression: 19.371443732303174
Before cleaning, Epoch at 0 with Perplexity: 19.47031304212775
After cleaning with Perplexity: 19.47031304212775
注意:目前,我们仅支持零成本量化。请继续关注我们即将发布的关于ZeroQuant论文中提出的逐层知识蒸馏的代码。
3. XTC教程:简单但有效的极端压缩流程
在本节中,我们将介绍如何应用DeepSpeed Compression库来执行轻量级层减少和超低比特精度(二进制/三进制)量化。特别是,我们将指导您实现XTC方法,即:
(1) 获取一个1位或2位的BERT-base(12层),带有8位激活量化。
(2) 将12层的Bert-base减少到5层,然后获得其1位或2位的对应版本。
什么是XTC
XTC(eXTreme Compression的缩写)是我们新开发的简单而高效的方法,通过轻量级层减少和鲁棒的二值化技术将模型压缩到极限。XTC通过简单而有效的二值化技术,将模型大小减少了32倍,同时在GLUE任务上的平均得分几乎没有损失。通过结合极端的量化和轻量级层减少,我们可以进一步改进二值化模型,实现50倍的模型大小减少,同时保持97%的准确率。 更多详情,请参阅我们在我们的论文中如何推导出我们的方法,我们在论文中对当前用于极端压缩的各种技术的影响进行了系统研究。
何时使用XTC
如果你想在保持竞争力的同时显著压缩你的模型,XTC可能是一个理想的选择。它是一种简单且超参数调优友好的方法。
如何使用XTC
安装: BERT模型的XTC极端压缩示例位于DeepSpeedExamples中的compression/bert/bash_script/XTC。您需要通过以下方式安装所需的环境:
DeepSpeedExamples/compression/bert$ pip install -r requirements.txt
XTC方法的实现:
为了适应那些没有微调模型或特定任务压缩模型的用户,使用参数--model_name_or_path yoshitomo-matsubara/bert-base-uncased-${TASK_NAME},我们的Python脚本run_glue_no_trainer.py会自动从Hugging Face下载模型。用户也可以使用自己更精确的模型作为教师和学生模型的初始化。
3.1 一位或两位BERT-base(12层)与8位激活量化
有关配置,请参见DeepSpeedExamples中的compression/bert/config/XTC/ds_config_W1A8_Qgroup1_fp32.json。在我们的论文中,我们使用FP32("fp16": {"enabled": false})进行训练,同时在训练开始时直接对激活应用8位量化("bits": 8),并对注意力(查询、键、值)和前馈权重矩阵("modules": ["attention.self", "intermediate", "output.dense"])应用1位量化("start_bits": 1, "target_bits": 1)("schedule_offset": 0)。此外,我们还对word_embeddings应用1位量化作为权重量化。
可以通过以下方式运行此示例:
DeepSpeedExamples/compression/bert$ bash bash_script/XTC/quant_1bit.sh
最终结果是:
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8293428425878757/0.8396053702196908
我们想要提到的另一个重要特性是weight_quantization中的quantize_groups,这里设置为1以匹配我们的XTC论文的FP32训练设置。我们发现,在FP16训练下,较少的量化组(例如1或2)可能导致训练不稳定。因此,我们建议在FP16下使用更多的组(例如64)。DeepSpeedExamples中的compression/bert/config/ds_config_W1A8_Qgroup64_fp16.json是FP16的示例配置,其中"fp16": {"enabled": true}和"weight_quantization": {"shared_parameters": {"quantize_weight_in_forward": false}}与FP32情况不同。
通过此配置,我们对从Hugging Face下载的现有微调模型进行量化。对于2位权重量化,用户需要更新ds_config JSON文件。为了展示下载模型与我们论文中的压缩性能对比,我们在下表中收集了结果(在MNLI和QQP上使用18个训练周期的1/2位BERT)。本教程与论文之间的差异是因为它们使用了不同的检查点。TinyBERT中引入的数据增强将显著帮助较小的任务(如mrpc、rte、sst-b和cola)。更多详情请参见我们的论文。

3.2 将12层的BERT-base压缩为1位或2位的6/5层BERT
本节包括两部分:(a) 我们首先进行轻量级的层减少,(b) 基于(a)中的模型,我们进行1位或2位量化。
3.2.1 轻量级层减少
compression/bert/config/XTC/ds_config_layer_reduction_fp16.json 在 DeepSpeedExamples 中是将12层的BERT-base减少到6层的示例配置。学生的层从教师的第i层初始化,i= [1, 3 ,5 ,7 ,9 ,11](注意层从0开始),这在我们XTC论文中称为Skip-BERT_5。此外,学生的模块包括嵌入、池化和分类器也从教师初始化。对于5层的减少,需要将ds_config_layer_reduction_fp16.json中的配置更改为"keep_number_layer": 5,"teacher_layer": [2, 4 ,6, 8, 10](如compression/bert/config/ds_config_TEMPLATE.json中所示)。
可以通过以下方式运行此示例:
DeepSpeedExamples/compression/bert$ bash bash_script/XTC/layer_reduction.sh
最终结果是:
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8377992868059093/0.8365541090317331
值得注意的是,当使用单阶段知识蒸馏(--distill_method one_stage)时,教师模型和学生模型的输出之间的差异(att_loss 和 rep_loss)也需要与初始化保持一致。请参见 compression/bert/util.py 中 forward_loss 下的 _kd_function 函数。
对于mnli/qqp,我们设置了--num_train_epochs 36,--learning_rate 5e-5,并使用上述的JSON配置。结果如下(我们也包括了fp16训练的结果)。使用fp32显然比fp16带来更稳定的性能,尽管fp16可以加快训练时间。

3.2.2 6层(5层)BERT的一位或两位量化
在准备好上述层减少模型后,我们现在继续使用1/2位量化来压缩模型。DeepSpeedExamples中的compression/bert/config/XTC/ds_config_layer_reduction_W1Q8_fp32.json是一个示例配置,我们在compression/bert/config/XTC/ds_config_W1A8_Qgroup1_fp32.json的基础上将层减少设置为true。除了配置外,我们还需要在脚本compression/bert/bash_script/XTC/layer_reduction_1bit.sh中使用--pretrained_dir_student更新学生模型的路径。用户可以通过添加--pretrained_dir_teacher来使用不同的教师模型进行训练。
可以通过以下方式运行此示例:
DeepSpeedExamples/compression/bert$ bash bash_script/XTC/layer_reduction_1bit.sh
最终结果是:
Epoch: 18 | Time: 18m 11s
Clean the best model, and the accuracy of the clean model is acc/mm-acc:0.8140601120733572/0.8199755899104963
通过上述命令,现在可以获得1位6层模型的结果。下面我们列出了更多2位/1位6层/5层模型的结果。请注意,我们用于以下压缩的检查点来自3.2.1节中的上述表格。

