之前写过BERT,不了解BERT的同学可以看这个:【翻译】图解BERT、ELMo等
最近在面试,陆陆续续也收到了一些offer,但都不是很满意。还在继续找,所以闲着没事也会回顾一些基础知识。今天就说一下ALBERT。
ALBERT的英文全称为A Lite BERT,顾名思义,就是BERT模型的精简版。
ALBER的核心目标是: 在不损失性能的前提下,极大地减少 BERT 的参数量,提高模型训练效率。
技术改进
与BERT相比,ALBERT的参数更少,它主要引入了以下两个关键技术:
1. 词嵌入矩阵因式分解(Factorized Embedding Parameterization)
BERT 使用的是一种叫 WordPiece 的子词(subword)分词方法。
比如:
输入句子:"我爱自然语言处理"WordPiece 分词器 → ["我", "爱", "自然", "语言", "处理"]再加上特殊标记:[CLS], [SEP]最终 → ["[CLS]", "我", "爱", "自然", "语言", "处理", "[SEP]"]
WordPiece分词出来的词表大小为30000。在 BERT 中,词嵌入矩阵和隐藏层维度一样大。
分词之后就是Token Embedding,bert-base为例,隐藏层维度是768。所以bert-base中,一个词向量的长度是768,词表长度是30000,所以BERT 的 Token Embedding 层的形状是:
[V × H] = 30000 × 768
所以词表越大,嵌入层参数越多,模型就越重。
WordPiece 嵌入来自嵌入矩阵(Embedding Table),它的作用是把一个 token 的 one-hot 向量(词表大小维度)映射为一个低维稠密向量。这个嵌入是固定的、无上下文信息的
由于 WordPiece 嵌入是静态的,仅起到“初始化”作用,即使我们将嵌入维度从 768 降到 128,只要后续的编码器足够强大,也能恢复语义信息。这就是 ALBERT 用因子分解降低 Embedding 维度的核心思想。
当然有人要问隐藏层维度能不能变,隐藏层的维度(如 768)直接决定了整个模型的语义建模能力、注意力表示能力、以及最终的下游任务表现,是不可轻易压缩的关键部分。
ALBERT 将词嵌入矩阵拆分为两个较小的矩阵:
从词表独热编码向量投射到低维嵌入空间 V
× E
低维嵌入到隐藏层维度E
×H
。
不是直接映射从 V × H
将其分解为 V × E
和 E × H
,这样大大减少了嵌入层参数。
接着上边BERT-base的例子,ALBERT设置的token Embedding嵌入大小为128,词表的大小为30000那词嵌入维度就是V × E = 30000 × 128
。接着,将WordPiece嵌入的大小投射到隐藏层中, E × H = 128 × 768
。
ALBERT 引入 嵌入层因子分解 的意义就是即便词表长度 V
很大,通过降低嵌入维度 E
,仍然能显著减少参数。
2. 跨层参数共享(Cross-Layer Parameter Sharing)
传统 BERT 每层 Transformer 模块都有自己独立的参数,而 ALBERT 将所有层的 Transformer 参数共享,减少模型规模。
展开详细说就是:BERT所有编码器层的参数将通过训练获得。但在跨层参数共享的情况下,不是学习所有编码器层的参数,而是只学习第一层编码器的参数,然后将第一层编码器的参数与其他所有编码器层共享。
参数共享方式可以有:
- 全共享:其他编码器的所有子层共享编码器1的所有参数。共享前馈网络层:只将编码器1的前馈网络层的参数与其他编码器的前馈网络层共享。共享注意力层:只将编码器1的多头注意力层的参数与其他编码器的多头注意力层共享。
默认情况下,ALBERT使用全共享选项。
比如BERT-base是12个编码器组成的:
训练方法
和 BERT数据集一样,ALBERT 也是用英文维基百科和多伦多图书语料库来进行预训练的。BERT 的预训练有两个主要任务:一个是“掩码语言模型”(Masked Language Model, MLM),另一个是“下句预测”(Next Sentence Prediction,NSP)。
ALBERT 同样保留了掩码语言模型这个任务,但它不再使用下句预测,而是换成了一个新任务,叫做句序预测(Sentence Order Prediction,SOP) 。
那为什么要换任务。研究人员发现,其实下句预测并没有我们想象中那么有用。
- NSP本身不算一个很难的任务;它把“主题是否相关”和“句子是否连贯”两个问题混在了一起,反而容易让模型学偏。
所以ALBERT 的作者设计了 SOP 任务,专门让模型学会判断两个句子顺序是否合理,而不是单纯判断它们是不是相关。
SOP 还是一个二分类任务,但它的判断逻辑更侧重在“两个句子的先后顺序是否正常”。
举个例子:
- 句子1:优弧送了我1000w矿石句子2:我马上用矿石换了个switch
这两个句子读起来是连贯的,顺序也自然,所以这是一个正例。
但如果我们调换顺序:
- 句子1:我马上用矿石换了个switch句子2:优弧送了我1000w矿石
就显得有点怪了,其实本山东人读起来没啥问题,这就是一个负例。
模型要做的,就是学会判断:这两个句子顺序是不是被调换过。
这种任务能更好地帮助模型理解句子之间的逻辑关系。
和BERT对比
经过ALBERT不懈努力,参数量大大减少。
上图是ALBERT论文中的表格,比较了BERT和ALBERT的不同配置。我们可以看到,BERT-large有3.4亿个参数,而ALBERT-large只有1800万个参数。