以前理解的模型蒸馏就是模型“提纯”,这样说太宽泛了,应该说 蒸馏是“提纯”的一种手段而已。

知识蒸馏具体指:让小模型去学到大模型的知识。通俗的说,让student模型的输出接近(拟合)teacher模型的输出。知识蒸馏的重点在于拟合二字,即我们要定义一个方法去衡量student模型和teacher模型的接近程度,说白了就是损失函数。必备元素为:教师模型、学生模型、损失函数。

为什么需要知识蒸馏?

因为大模型推理慢难以应用到工业界。小模型直接进行训练又不如蒸馏得到的效果好。

相关工作介绍:

(1)Hinton在论文:Distilling the Knowledge in a Neural Network提出了知识蒸馏的方法。

损失函数:Loss = a L{soft} + (1-a) L{hard}

其中L{soft}是studentModel和TeacherModel的输出的交叉熵,L{hard}是studentModel输出和真实标签的交叉熵。L{soft},我们直到TeacherModel的输出是经过softmac处理的,指数e拉大来各个类别之间的差距,最终输出结果特别像one-hot向量,这样不利于studentModel的学习,因此我们希望输出更加软一些。因此我么我们需要修改一些softmax函数:

深度学习--知识蒸馏介绍

显然T越大输出越软。这样改完之后,对比原始softmax,梯度相当于乘了1/T^2,因此L{soft}需要再乘以T^2来与L{hard}在一个数量级上。

最后再放一张这个算法的整体框架图:

深度学习--知识蒸馏介绍

(2)TinyBert

首先说到对Bert的蒸馏大家肯定会想到就用微调好的Bert作为TeacherModel去训练一个StudentModel,没错目前就是这么干的。那么下面的问题就是我们选取什么模型作为StudentModel,这个已经有一些尝试了,比如有人使用BiLSTM,但是更多的人还是继续使用了Bert,只不过这个Bert会比原始的Bert小。在TinyBert中,StudentModel使用的是减少embeddingsize、hidden size和num hidden layers的小bert。

那么新的问题又来了,我们怎么初始化StudentModel?

最直接的解决方案就是随机化,模型不都是这么训练的吗?但是这种效果真的好吗?我看未必,如果没问题那么为啥那么多人用预训练模型?所以啊,我们需要一个比较好StudentModel的参数,确切说,我们需要一个与训练的studentModel,那么怎么获取一个预训练的StudentModel,TinyBert给出的答案就是咱们再用预训练好的Bert蒸馏出一个预训练好的StudentModel。(是不是很绕,感觉等于没说,要想弄明白,还是要实践,实践出真知

Ok,TinyBert基本讲完了,简单总结下,TinyBert一共分为两步:

1、用pretrained bert蒸馏一个pretrained TinyBert

2、用fine-tuned bert蒸馏一个fine-tuned TinyBert(它的初始参数就是第一步里pretrained TinyBert)

深度学习--知识蒸馏介绍

在进行蒸馏的时候,会先进行隐层蒸馏(即m<=M),然后再执行m = M+1时的蒸馏。

总结一下,TinyBert在蒸馏的时候,不仅要让StudentModel学到最后一层的输出,还要学到中间几层的输出。换言之,studentModel的某一隐层可以学到TeacherModel若干隐层的输出。感觉蒸馏的力度比较细,我觉得可以叫做LayerBasedDistillation.

(3)BERT-OF-Theseus

这个准确的来说不是知识蒸馏,但是它确实减小了模型体积,而且思路和TinyBERT、DistillBERT都有类似。这个思路非常优雅,它通过随机使用小模型的一层替换大模型中若干层来完成训练。举一个例子:假设大模型是

input->tfc1->tfc2->tfc3->tfc4->tfc5->tfc6->output,然后再定义一个小模型input->sfc1->sfc2->sfc3->output。再训练过程中还是要训练大模型,只是在每一步中,会随机的将(tfc1, tfc2),(tfc3,tfc4),(tfc5,tfc6)替换sfc1, sfc2, sfc3,而且随着训练的进行,替换的概率不断变大,因此最后就是在训练一个小模型。

深度学习--知识蒸馏介绍

方式优雅,作者提供了源码,强烈推荐大家用一用。

(4)MiniLM

1、先用TeacherModel蒸馏一个中等模型,再用中等模型蒸馏一个较小的StudentModel。只有在StudentModel很小的时候才会这么做。

2、只对最后一个隐层做蒸馏,作者认为这样可以让StudentModel有更大的自由空间,而且这样对StudentModel架构的要求就变得宽松了。

3、对于最后一个隐层主要是对attention权重做学习。

 

 

相关库的使用见如下链接:

https://www.cnblogs.com/SuperDun/p/12442919.html

后期会增加这一部分的实战介绍。