点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

编者荐语

近年来,BERT 系列模型成了应用最广的预训练语言模型,随着模型性能的提升,其参数规模不断增大,推理速度也急剧提升,导致原始模型必须部署在高端的GPU 显卡上,甚至部分模型需要多块显卡才能正常运行。

转载自丨博文视点Broadview


前言

在移动智能终端品类越发多样的时代,为了让预训练语言模型可以顺利部署在算力和存储空间都受限的移动终端,对预训练语言模型的压缩是必不可少的。本文将介绍针对BERT(以Transformer Block 堆叠而成的深度模型)的压缩方法。

01

BERT模型分析

想要深度压缩BERT,必须对模型各部分有更为深入的了解,前面的文章已经详细介绍过Transformer 和BERT 的结构,此处不再解释各模块的具体功能。

BERT 的结构拆分如图1 所示,根据具体的实现逻辑,可以分为Embedding 层、Linear before Attention 层、Multi-Head Attention 层、Linear after Attention 层和Feed Forward 层,后4 层属于Transformer Block 内的模块,所需存储空间和推理耗时都会随着层数的增多而增多。

图1 BERT 的结构拆分

BERT 的大小可以用3 个超参数来衡量,即LH 和A,其中L 表示Transformer Block 的层数,H 表示隐层向量的维数(等于Embedding 层输出向量的维数),表示Self-Attention 层的头数。

通过这3 个超参数,可以基本知晓BERT 的各模块大小,决定了模型的宽度和深度,A决定了模型Attention 的多样性。以  为例分析3 个超参数,其中L 为12,H 为768,A 为12,模型各层所占存储空间和算力,如图2所示。

图2 BERTBASE 各层所占存储空间和算力

显然,在数据存储空间方面,Feed Forward 层占据了约一半的空间,Embedding层和Linear before Attention 层分别占据约四分之一的空间,而最核心的Multi-Head Attention 层几乎不占存储空间,这里所谓的存储空间可以等效为模型参数的数量。

在推理计算量方面,Feed Forward 层消耗了超过一半的计算资源,而Embedding 层几乎不需要算力。

通常,参数越多,所需算力越大,此处较为特殊的是Embedding 层和Multi-Head Attention 层,前者是因为Embedding 操作本质上是查表操作,所以占据较大的存储空间,却不需要算力,而后者是因为计算不同词的   矩阵乘积,没有用到模型的权重矩阵,所以不需要存储空间,但需要一定的算力。其余层(多为普通的全连接层)的参数量级计算过程并不复杂,读者可自行计算。

理论计算所需的运行耗时和实际推理时间并不完全一致,在英伟达Titan X GPU 上运行  ,利用TensorFlow 工具可以得到模型各层的推理所占时间,如图3所示。

图3 BERTBASE 推理所占时间分析

实际推理时间大致与各层所需算力正相关,但Multi-Head Attention 层所需的实际运行耗时远大于其理论值,这是因为  在计算时需要先求  和  的乘积,使用Softmax 函数后再与  求乘积,这个串行的计算过程消耗了不少时间。

通过分析   所占存储空间、所需理论算力及模型实际运行时间,明确了BERT 各模块的特性与瓶颈,这将帮助读者理解BERT 模型压缩的各类方法。

02

量化

模型量化是指将模型权重参数用更少的比特数存储,以此来减少模型的存储空间和算力消耗。

例如,BERT 原本是以fp32 精度(float precision 32bit,单精度4 字节浮点数)运行的,若转换成fp16 精度(float precision 16bit,半精度2 字节浮点数),则存储空间立刻减少一半,在针对fp16 精度优化的运算设备上(如英伟达T4/V100 GPU 或FPGA 平台),运行速度也可以得到显著提升。

量化是一种通用的压缩方法,适用于几乎所有的深度模型,学术界已经证实,全连接层是对量化操作十分友好的结构,而BERT 中大部分模块都由全连接层组成,因此BERT 对于量化操作是比较友好的。

值得注意的是,Embedding 层(并不属于全连接层)对于量化操作较为敏感,在实际操作中应避免对Embedding 层做量化操作。

数据精度降低之后,模型的质量肯定也会有所下降,一般可以通过量化后训练(Quantization Aware Training,QAT)来缓解。

具体而言,在对模型参数进行直接量化操作或精度截断之后,用训练数据继续训练量化后的模型,以缓解量化造成的精度损失,这是常见的量化压缩流程。

正常的均匀量化可以通过TensorFlow Lite Toolkit 或其他量化工具实现。

除此之外,还可以通过  均值聚类等量化操作获得更大的压缩比。读者可自行搜索相关文献或开源代码。

03

剪枝

模型剪枝是指去除模型参数中冗余或不重要的部分,这个过程与哺乳动物幼年神经突触消失的过程极为相似。

剪枝是提高推断效率的方法之一,它可以高效地生成规模更小、内存利用率更高、能耗更低、推断速度更快的模型。

就BERT 的剪枝而言,可以大致分为以下两类:元素剪枝(Elementwise Pruning,EP)和结构剪枝(Structured Pruning,SP)。

元素剪枝又被称为稀疏剪枝,聚焦于模型单个参数元素。

若单个参数元素绝对值过小或对模型不重要,则可以通过将其置为0 元素来减小存储空间,缩短推理时间。

对模型不重要的定义可以是对目标函数影响小,也可以是对梯度更新影响小等自定义的客观衡量标准。

元素剪枝对全连接层相对友好,因此BERT 使用元素剪枝可以获得不俗的压缩比,同时可以保证一定的精度。

结构剪枝聚焦于去除模型结构的冗余,以精简模型结构来减小模型的存储空间,满足算力需求。

结构剪枝更具有针对性,不同于元素剪枝适用于所有模型,对于不同的模型结构,结构剪枝可以设计不同的剪枝策略。以BERT 为例,一般有两种结构剪枝策略:Attention 头剪枝和层剪枝。

(1)Attention 头剪枝:BERT 的Multi-Head Attention 层在推理时间中占比排第二。有研究表明,Multi-Head Attention 层存在较大的冗余,因此BERT 的12-Head Attention 可以通过剪枝变为4-Head 甚至更少,这样的剪枝操作可以大大缩短Multi-Head Attention 层的推理时间。

(2)层剪枝:BERT 是由多层Transformer Block 堆叠而成的,层数越多,模型所需的存储空间越大,推理时间也越长。训练时常用的Dropout 操作有助于模型收敛得更稳定,故通过删除个别不重要的层来减少模型参数,加速推理是完全可行的。不重要的层可以通过比较目标函数值大小和L1 正则化值的大小等方法来定位。

剪枝操作也会对模型带来精度损失。

一般而言,根据剪枝流程的位置,可以将剪枝操作分为两种:训练时剪枝和后剪枝。

训练时剪枝其实和训练时使用Dropout 操作较为类似,训练时剪枝会根据当前模型的结果,删除不重要的结构,固化模型再进行训练,以后续的训练来弥补部分结构剪枝带来的不利影响,避免模型因为剪枝操作而造成的精度陡降。

后剪枝则是在模型训练完成后,根据模型权重参数和剪枝测试选取需要剪枝的部分,比较粗暴,但与训练时剪枝所需的额外计算量和控制流程相比,后剪枝是较为简单的做法。

Keras 模型的剪枝操作可以通过2019 年发布的Tensor-Flow Model Optimization Toolkit 工具实现。PyTorch 模型的剪枝操作可以通过torch.nn.utils.prune 工具实现。

04

蒸馏

量化和剪枝是最常用的模型压缩方法,有成熟的配套工具,但为了保证一定精度,其压缩比一般较小,还不足以让BERT 在移动设备的芯片上运行。

蒸馏的全称为知识蒸馏(Knowledge Distillation,KD),是2015 年由深度学习开山鼻祖Hinton 提出的一种模型压缩方法,是一种基于教师-学生网络思想的训练方法。

蒸馏已经成为压缩模型的主流方法之一,可以与量化和剪枝叠加使用,达到可观的压缩比。

在知识蒸馏使用的教师-学生(Teacher-Student)网络中,教师模型是“知识”的输出者,学生模型是“知识”的接受者,整个过程分为两个阶段。

(1)教师模型训练:教师模型一般为参数量巨大,结构相对复杂的待压缩的模型,简称为Model-T。教师模型一般由大量数据训练而成,性能指标高于蒸馏后的学生模型。

(2)学生模型训练:学生模型一般为参数量很小,结构相对简单的模型,简称为Model-S,其训练过程以学习Model-T 为主,而不是学习数据的真实标签。

根据学生模型学习的目标,可以将BERT 的蒸馏方法分为以下三类:基于输出概率蒸馏、基于隐层蒸馏和基于Attention 层蒸馏。

下面通过两个经典的BERT 蒸馏模型讲解蒸馏的思想和具体实现。

1. Distilled BiLSTM

Distilled BiLSTM是一个从BERT 蒸馏得到的双向LSTM 模型,即教师模型为精调后的  ,学生模型仅为一个轻量级的单层双向LSTM 模型。

具体模型结构根据任务类型分为两种:输入为单句文本的模型(如图4 所示)和输入为句对文本的模型(如图5 所示)。

图4 Distilled BiLSTM 的模型结构

图5 Distilled BiLSTM 的模型结构2

由于BERT 和LSTM 的模型结构差异太大,只能通过基于输出概率蒸馏的方法进行知识传递,具体公式如下:

其中,  表示输出类别概率,  是输入Softmax 层的向量,定义蒸馏误差  为教师模型和学生模型的  均方差,则BiLSTM 的最终目标函数可以由真实标签的交叉熵  和蒸馏误差  加权构成。

其中,  为类别  的One-hot 标签,  是学生模型的最终输出概率,两者相乘便是真实标签的交叉熵  ,而  是权重常系数。采用交叉熵和蒸馏误差的加权和作为目标函数的好处是,学生模型不仅可以从教师模型学到知识,还可以根据下游任务的训练数据进行无教师监督学习,只需要调整超参数  ,即可在交叉熵和蒸馏误差之间切换。

从结果看,在BERT 和LSTM 的模型结构差异过大的情况下,用LSTM模型作为学生模型来蒸馏BERT 的知识,取得了不错的效果,在下游任务的表现上远超用BiLSTM 直接训练得到的模型,说明蒸馏模型学会了浅层模型不容易学会的拟合泛化能力。

虽然Distilled BiLSTM 相较于BERT 有不少性能损失,但是其模型体积相较于BERT 压缩了约99.7%,推理速度快了400 倍,压缩力度之大远超想象。

2. MobileBERT

一般的知识蒸馏都会使用与教师模型结构相似的学生模型,模型结构不是变浅就是变窄,MobileBERT就是把BERT 变窄,作为学生模型的经典模型之一。

MobileBERT 采用和  一样的层数,通过在每一层Transformer Block 中添加bottleneck(瓶颈)层,让每一层变得更窄。

由于原始的BERT 不存在bottleneck 层,为了顺利进行知识蒸馏,需要先通过训练得到一个特殊设计的教师模型,即一个包含Inverted-bottleneck 结构的  ,称之为  。

随后,将训练得到的  教师模型迁移到学生模型MobileBERT 中,三个模型的结构如图6 所示。

图6 三个模型的结构

bottleneck 层本质上就是一个变换特征向量维度的全连接层,结合图6,很容易理解MobileBERT 的模型结构,如表1所示,body 模块中的Linear 层就是新增的bottleneck 层,其余部分与BERT 一致。

表1 几个模型的参数规模对比

从参数规模上看,  比  略小,而MobileBERT 在  的基础上,模型体积压缩了90%。

训练MobileBERT 这样既深又窄的深度网络是很困难的任务。为了让蒸馏训练更稳定,MobileBERT 采用了阶梯式层级训练法,如图7所示。

图7 MobileBERT 的阶梯式层级训练法

先自下而上逐层训练学生模型,当学生模型的每一层输出都与教师模型接近时,才训练下一层。逐层蒸馏根据训练目标的不同也分为基于隐层蒸馏和基于Attention 层蒸馏。

具体而言,基于隐层蒸馏被称为特征映射迁移(Feature Map Transfer,FMT),将MobileBERT 的每一层Transformer Block 的输出都与  对齐,目标函数为

其中,  是层号,  是输入文本序列的长度,  是隐层特征向量的维数,  表示教师模型第  层网络第  个词的第  个位置的特征值。

同理,  表示学生模型对应位置的特征值,将教师模型和学生模型在对应位置的特征值求得的均方误差作为逐层蒸馏的目标函数。

基于Attention 层蒸馏被称为Attention 迁移(Attention Transfer,AT)。

由于BERT 最重要的结构就是Self-Attention,所以Attention 迁移能让学生模型学习教师模型的Self-Attention 层特征,从而辅助学生模型增强文本语义理解方面的能力。

在具体实现上,将MobileBERT 和  的每个Attention 头的输出特征向量的KL 散度作为目标函数,具体如下:

其中,  是层号,  是输入文本序列的长度,  是Self-Attention 的头数,  表示教师模型第  层网络第  个头的输出向量分布,  表示教师网络和学生网络输出分布的KL 散度,以KL 散度的均值作为Attention 迁移的目标函数。

MobileBERT 在逐层蒸馏的过程中使用了特征映射迁移和Attention 迁移。为了加快模型的推理速度,相比于BERT,MobileBERT 还做了以下两个改动:

(1)用线性层归一化代替原有的层归一化,即取消原有层归一化中的非线性操作,以得到加速推理的效果。

(2)用ReLU 激活函数代替GeLU 激活函数,简化激活函数换取推理加速。

总体而言,MobileBERT 作为任务无关的BERT 压缩模型,压缩比高达10 倍,配合量化可以达到40 倍,最关键的是其在多数文本理解任务上的性能与  相当。

得益于小体积和极快的推理速度,MobileBERT 可以轻松运行在各类终端移动设备上。

05

结构无损压缩

除了常见的量化、剪枝和蒸馏,还有一些与模型结构强依赖的压缩方法,这些方法不会更改模型的结构,故归为结构无损的压缩方法。

本节将简单介绍以下三类结构无损的压缩方法:参数共享、低秩分解和注意力解耦。

参数共享和低秩分解在介绍ALBERT 时已经讲解过,参数共享是指模型共享所有Transformer Block 层参数,以达到减小存储空间的目的,而低秩分解特指Embedding 层通过因式分解变成更小的Embedding 层和一个线性层,达到减小参数规模的目的,具体介绍见《预训练语言模型》一书的6.8 节。

值得注意的是,这两个方法只能减小模型的存储空间,并不能加速推理过程。

注意力解耦适用于句对任务,因为在原始的BERT 中,输入文本为两个句子时,每个词都需要与其他的词做Self-Attention 运算,即句子中的词需要与句子B 中的词做矩阵运算。这时会产生运算冗余,因为句对任务最后依赖于标签[CLS] 的输出特征,而在逐层抽象语义特征的过程中,句子A的语义抽取过程不需要与句子B 产生关联,即可以通过Self-Attention 运算的解耦达到减少运算量的目的,加快推理过程。

同样值得注意的是,Multi-Head Attention 层不占用存储空间,所以注意力解耦虽然不会减小模型体积,但是可以加快模型推理速度。

好消息!

小白学视觉知识星球

开始面向外开放啦

模型压缩:量化、剪枝和蒸馏相关推荐

  1. 【嵌入式AI】CNN模型压缩(剪枝,量化)详解与tensorflow实验

    1,CNN模型压缩综述 1 模型压缩的必要性及可行性 (1)必要性:首先是资源受限,其次在许多网络结构中,如VGG-16网络,参数数量1亿3千多万,占用500MB空间,需要进行309亿次浮点运算才能完 ...

  2. 【模型压缩】关于知识蒸馏(Distill)的一次实验

    [模型压缩]关于知识蒸馏(Distill)的一次实验 1. 简介 ​ 知识蒸馏(Knowledge Distill)旨在使用一个复杂的教师网络(Teacher Net)来引导一个小的学生网络(Stud ...

  3. 模型如何压缩?使用轻量化的模型压缩技术剪枝(pruning)

    深度学习模型参数太多,本地服务器部署没有问题,但是如果部署到移动端.边缘端,像手机.树莓派等,它们的性能不能满足,所以我们要压缩模型大小,让他们可以部署到边缘端 模型压缩:使用轻量化的模型压缩技术,如 ...

  4. AI模型工业部署:综述【常用的部署框架:TensorRT、Libtorch】【常见提速方法:模型结构、剪枝、蒸馏、量化训练、稀疏化】【常见部署流程:onnx2trt】【常见服务部署搭配】

    作为深度学习算法工程师,训练模型和部署模型是最基本的要求,每天都在重复着这个工作,但偶尔静下心来想一想,还是有很多事情需要做的: 模型的结构,因为上线业务需要,更趋向于稳定有经验的,而不是探索一些新的 ...

  5. 《AI系统周刊》第4期:DNN模型压缩之剪枝(Pruning)

    No.04 智源社区 AI系统组 A I 系  统 研究 观点 资源 活动 关于周刊 AI系统是当前人工智能领域极具现实意义与前瞻性的研究热点之一,为了帮助研究与工程人员了解这一领域的进展和资讯,我们 ...

  6. ResNet压缩20倍,Facebook提出新型无监督模型压缩量化方法

    点击我爱计算机视觉标星,更快获取CVML新技术 本文经授权转自机器之心,作者立早. 怎样用量化方法解决模型压缩问题?Facebook 近日提出了一个基于向量的量化方法,无需标注数据即可对 ResNet ...

  7. Yolov5更换backbone,与模型压缩(剪枝,量化,蒸馏)

    项目地址(GitHub):https://github.com/Ranking666/Yolov5-Processing ~~~欢迎各位交流.star.fork.issues~~~ 项目介绍:     ...

  8. 《模型轻量化-剪枝蒸馏量化系列》YOLOv5无损剪枝(附源码)

    今天文章代码不涉密,数据不涉密,使用的是网上开源代码,做了修改,主要介绍如何实现的,另外,数据使用开放数据VisDrone的小部分数据来测试~ 今天的文章很短,主要附带一个视频讲解运行过程,我修改的地 ...

  9. 模型压缩之剪枝小综述

    ## 现在主流的稀疏化方法: ###  非结构化方法 1) han song提出的方法,低于某一阈值的归零,但是这种非结构化的稀疏矩阵现有的库很难处理,需要专门设置.[S. Han, J. Pool, ...

  10. 【综述】闲话模型压缩之网络剪枝(Network Pruning)

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 来自 | CSDN 地址 | https://blog.csdn.net/jinz ...

最新文章

  1. 什么是shell【TLCL】
  2. 了解下Lua 环境安装
  3. 一个框架解决几乎所有机器学习问题
  4. 数据库的UNDO和REDO
  5. 微信公众平台前端开发技巧分享
  6. apache限制php上传大小修改
  7. js Math用法jquery是否为空对象判断
  8. Java 算法 降价机器人
  9. 初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助...
  10. 代理ip如何使用_为什么在使用代理IP爬虫时会出现超时?
  11. 学习进度条 20171202
  12. SVN服务器搭建--Subversio与TortoiseSVN的配置安装(Windows)
  13. WIN10下使用VS2017的MSVC编译FFMPEG3.4.2动态静态库
  14. IOS 10 适配系列 _3_ Xcode 8 GM seed
  15. 2021年塔式起重机司机考试题库及塔式起重机司机模拟考试
  16. 安卓手机如何打开开发者模式?
  17. 影视解说短视频如何配音?三个文字转语音小技巧,配音其实也不难
  18. 成都智慧工地系统_智慧工地平台指导方案
  19. 君正平台JZ4775芯片参数详细说明,大家可以看看
  20. 【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】

热门文章

  1. 全球最动听的英文花名
  2. Android我自己的简易(秒表)计时器Chronometer
  3. linux source和.的区别,source和.命令的区别
  4. puppet部署mysql_puppet之mysql批量安装案例
  5. BootStrap使用方法为BootStrap3添加jquery.min.js文件(简单易懂)_☆往事随風☆的博客
  6. labelme的安装、批量转换方法(版本号4.5.13)
  7. 两方官宣:霍尼韦尔与剑桥量子合并!新公司预计今年年底前上市
  8. 学生手册成绩分析-以学院为单位进行划分
  9. Vue学习:事件修饰符
  10. NC外部交换平台XML使用及解析