使用DistilBERT 蒸馏类 BERT 模型的代码实现
机器学习模型已经变得越来越大,即使使用经过训练的模型当硬件不符合模型对它应该运行的期望时,推理的时间和内存成本也会飙升。为了缓解这个问题是使用蒸馏可以将网络缩小到合理的大小,同时最大限度地减少性能损失。
我们在以前的文章中介绍过 DistilBERT [1] 如何引入一种简单而有效的蒸馏技术,该技术可以轻松应用于任何类似 BERT 的模型,但没有给出任何的代码实现,在本篇文章中我们将进入细节,并给出完整的代码实现。
学生模型的初始化
由于我们想从现有模型初始化一个新模型,所以需要访问旧模型的权重。本文将使用Hugging Face 提供的 RoBERTa [2] large 作为我们的教师模型,要获得模型权重,必须知道如何访问它们。
Hugging Face的模型结构
可以尝试的第一件事是打印模型,这应该让我们深入了解它是如何工作的。当然,我们也可以深入研究 Hugging Face 文档 [3],但这太繁琐了。
运行此代码后得到:
在 Hugging Face 模型中,可以使用 .children() 生成器访问模块的子组件。因此,如果我们想使用整个模型,我们需要在它上面调用 .children() ,并在每个子节点上调用,这是一个递归函数,代码如下:
这样获得了如下输出
看起来 RoBERTa 模型的结构与其他类似 BERT 的模型一样,如下所示:
复制教师模型的权重
要以 DistilBERT [1] 的方式初始化一个类似 BERT 的模型,我们只需要复制除最深层的 Roberta 层之外的所有内容,并且删除其中的一半。所以这里的步骤如下:首先,我们需要创建学生模型,其架构与教师模型相同,但隐藏层数减半。只需要使用教师模型的配置,这是一个类似字典的对象,描述了Hugging Face模型的架构。查看 roberta.config 属性时,我们可以看到以下内容:
我们感兴趣的是numhidden -layers属性。让我们写一个函数来复制这个配置,通过将其除以2来改变属性,然后用新的配置创建一个新的模型:
完整文章:
https://www.overfit.cn/post/6583351575974a5993a4ebd98b51088e