使用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

posted @ 2022-02-08 10:46  deephub  阅读(155)  评论(0编辑  收藏  举报