叮咚 看了苏剑林老师的博客,真心觉得大佬们的思路顶呱呱。 当然,建立大家直接去看原文,链接均给出。本文偷懒,搬运了要点而已。
《LST: Ladder Side-Tuning for Parameter and Memory Efficient Transfer Learning》——“过墙梯”
https://spaces.ac.cn/archives/9138 看模型大致就可以看明白了,蓝色表示参数固定,绿色则是更新参数,红色虚线表示反向更新参数。 这里插入苏老师给出的解释: 对于Adapter来说,它在每一层后面都插入了一个小规模的层,虽然其余参数都固定了,只有新插入的层可训练,但每一层都新层,所以反向传播要传到输入层;对于P-tuning来说,本质上它是只有在Embedding层中有少量可训练参数,但Embedding层是输入层,因此它的反向传播也要贯穿整个模型。因此,这两种方案能提升的训练效率并不多。
至于LST,它是在原有大模型的基础上搭建了一个“旁支”(梯子),将大模型的部分层输出作为旁枝模型的输入,所有的训练参数尽在旁枝模型中,由于大模型仅提供输入,因此反向传播的复杂度取决于旁枝模型的规模,并不需要直接在原始大模型上执行反向传播,因此是可以明显提升训练效率的。
LST新增的“梯子”分支的初始化问题,如果完全随机初始化的话,可能会有训练上的困难,效果效果会不理想。这一点原论文也提到了,它提供了一个截取大模型矩阵权重来作为小模型矩阵初始化的方案,从而提升了LST的最终效果
《BERT-of-Theseus: Compressing BERT by Progressive Module Replacing》——BERT-of-Theseus
https://kexue.fm/archives/7575
模型压缩常见技术: 常见的模型压缩技术可以分为两大类:1、直接简化大模型得到小模型;2、借助大模型重新训练小模型。这两种手段的共同点是都先要训练出一个效果比较好的大模型,然后再做后续操作。
第一类的代表方法是剪枝(Pruning)和量化(Quantization)。剪枝,顾名思义,就是试图删减掉原来大模型的一些组件,使其变为一个小模型,同时使得模型效果在可接受的范围内;至于量化,指的是不改变原模型结构,但将模型换一种数值格式,同时也不严重降低效果,通常我们建立和训练模型用的是float32类型,而换成float16就能提速且省显存,如果能进一步转换成8位整数甚至2位整数(二值化),那么提速省显存的效果将会更加明显。
第二类的代表方法是蒸馏(Distillation)。蒸馏的基本想法是将大模型的输出当作小模型训练时的标签来用,以分类问题为例,实际的标签是one hot形式的,大模型的输出(比如logits)则包含更丰富的信号,所以小模型能从中学习到更好的特征。除了学习大模型的输出之外,很多时候为了更进一步提升效果,还需要小模型学习大模型的中间层结果、Attention矩阵、相关矩阵等,所以一个好的蒸馏过程通常涉及到多项loss,如何合理地设计这些loss以及调整这些loss的权重,是蒸馏领域的研究主题之一。 模型
回到BERT的压缩,现在假设我们有一个6层的BERT,我们直接用它在下游任务上微调,得到一个效果还不错的模型,我们称之为Predecessor(前辈);我们的目的是得到一个3层的BERT,它在下游任务中效果接近Predecessor,至少比直接拿BERT的前3层去微调要好(否则就白费力气了),这个小模型我们称为Successor(传承者) 在BERT-of-Theseus的整个流程中,Predecessor的权重都被固定住。6层的Predecessor被分为3个模块,跟Successor的3层模型一一对应,训练的时候,随机用Successor层替换掉Predecessor的对应模块,然后直接用下游任务的优化目标进行微调(只训练Successor的层)。训练充分后,再把整个Successor单独分离出来,继续在下游任务中微调一会,直到验证集指标不再上升。
BERT-of-Theseus的主要特点是:简洁。BERT-of-Theseus还有一个特别的优势:很多的蒸馏方法都得同时作用于预训练和微调阶段,效果才比较突出,而BERT-of-Theseus直接作用于下游任务的微调,就可以得到相媲美的效果
|