ALBert
- ALBERT就是为了解决模型参数量大以及训练时间过长的问题。
ALBERT最小的参数只有十几M, 效果要比BERT低1-2个点,最大的xxlarge也就200多M。可以看到在模型参数量上减少的还是非常明显的,但是在速度上似乎没有那么明显。最大的问题就是这种方式其实并没有减少计算量,也就是受推理时间并没有减少,训练时间的减少也有待商榷。
整个模型的结构还是依照了BERT的骨架,采用了Transformer以及GELU激活函数。
具体的创新部分应该有三个:
- 一个是将embedding的参数进行了因式分解
- 然后就是跨层的参数共享
- 最后是抛弃了原来的NSP(next sentence predict)任务,现在使用SOP(sentence order predict)任务
这三个更新前两个的主要任务就是来进行参数减少的,第三个更新这已经算不上什么更新了,之前已经有很多工作发现原来BERT中的下一句话预测这个任务并没有什么积极地影响。根据文章的实验结果来看似乎参数共享对参数降低的影响比较大,同时也会影响模型的整体效果。后面就来详细的说一下这三个改动。
Factorized embedding parameterization
原始的BERT模型以及各种依据transformer来搞的预训练语言模型在输入的地方我们会发现它的E是等于H的,其中E就是embedding size,H就是hidden size,也就是transformer的输入输出维度。
- 这就会导致一个问题,当我们的hidden size提升的时候,embedding size也需要提升,这就会导致我们的embedding matrix维度的提升。
- 所以这里作者将E和H进行了解绑,具体的操作其实就是在embedding后面加入一个矩阵进行维度变换。E是永远不变的,后面H提高了后,我们在E的后面进行一个升维操作,让E达到H的维度。这使得embedding参数的维度从 O ( V × H ) O(V×H) O(V×H)到了 O ( V × E + E × H ) O(V×E + E×H) O(V×E+E×H), 当E远远小于H的时候更加明显。
Cross-layer parameter sharing
之前transformer的每一层参数都是独立的,包括self-attention 和全连接,这样的话当层数增加的时候,参数就会很明显的上升。
之前有工作试过单独的将self-attention或者全连接进行共享,都取得了一些效果。
- 这里作者尝试将所有的参数进行共享,这其实就导致多层的attention其实就是一层attention的叠加。同时作者通过实验还发现了,使用参数共享可以有效地提升模型的稳定程度。实验结果如下图:
Inter-sentence coherence loss
这里作者使用了一个新的loss,其实就是更改了原来BERT的一个子任务NSP, 原来NSP就是来预测下一个句子的,也就是一个句子是不是另一个句子的下一个句子。
-
这个任务的问题出在训练数据上面,NSP正例就是用的一个文档里面连续的两句话,但是负例使用的是不同文档里面的两句话。这就导致这个任务包含了主题预测在里面,而主题预测又要比两句话连续性的预测简单太多。
-
新的方法使用了
sentence-order prediction(SOP)
, 正例的构建和NSP是一样的,不过负例则是将两句话反过来。实验的结果也证明这种方式要比之前好很多。但是这个这里应该不是首创了,百度的ERNIE貌似也采用了一个这种的。
Embedding的size影响:
-
对于参数不共享的版本,随着E的增加,效果是不断提升的。
-
但是在参数共享的版本似乎不是这样的,效果最好的版本并不是E最大的版本。同时我们也可以发现参数共享对于效果可能带来1-2个点的下降
Roberta
模型主要贡献:
- 模型更大,batch-size更大,数据更多:training the model longer, with bigger batches,over more data;
- 去除NSP任务:removing the next sentence prediction objective;
- 更长的Sequence_length:training on longer sequences;
- 动态的改变训练数据的mask: dynamically changing the masking pattern applied to the training data.
- We also collect a large new dataset (CC-NEWS) of comparable size to other privately used datasets, to better control for training set size effects.
Dynamic Masking
static masking: 原本的BERT采用的是static mask的方式,就是在create pretraining data中,先对数据进行提前的mask,为了充分利用数据,定义了dupe_factor,这样可以将训练数据复制dupe_factor份,然后同一条数据可以有不同的mask
。
注意这些数据不是全部都喂给同一个epoch
,是不同的epoch,例如dupe_factor=10, epoch=40, 则每种mask的方式在训练中会被使用4次。
The original BERT implementation performed masking once during data preprocessing, resulting in a single static mask. To avoid using the same mask for each training instance in every epoch, training data was duplicated 10 times so that each sequence is masked in 10 different ways over the 40 epochs of training. Thus, each training sequence was seen with the same mask four times during training.
- dynamic masking: 每一次将训练example喂给模型的时候,才进行随机mask。
No NSP and Input Format
NSP: 0.5:从同一篇文章中连续的两个segment。0.5:不同的文章中的segment
- Segment+NSP:bert style
- Sentence pair+NSP:使用两个连续的句子+NSP。用更大的batch size
- Full-sentences:如果输入的最大长度为512,那么就是尽量选择512长度的连续句子。如果跨document了,就在中间加上一个特殊分隔符。无NSP。实验使用了这个,因为能够固定batch size的大小。
- Doc-sentences:和full-sentences一样,但是不跨document。无NSP。最优。
Text Encoding
BERT原型使用的是 character-level BPE vocabulary of size 30K
RoBERTa使用了GPT2的 byte BPE 实现,使用的是byte而不是unicode characters作为subword的单位。
SpanBert
主要的点:
- 提出了更好的 Span Mask 方案,也再次展示了
随机遮盖连续一段字要比随机遮盖掉分散字好
; - 通过加入 Span Boundary Objective (SBO) 训练目标,增强了 BERT 的性能,特别在一些与 Span 相关的任务,如抽取式问答;
- 用实验获得了和 XLNet 类似的结果,
发现不加入 Next Sentence Prediction (NSP) 任务,直接用连续一长句训练效果更好
。
Span Mask
- 参考文章:https://zhuanlan.zhihu.com/p/75893972
对于原始的 BERT:token mask (subword level)
训练时,会随机选取整句中的最小输入单元 token 来进行遮盖。因为用到 Byte Pair Encoding (BPE)技术,所以也可以把这些最小单元当作是子词(subword),比如说superman,分成 super+man 两个子词。
但这样会让本来应该有强相关的一些连在一起的字词,在训练时是割裂开来的。
WWM模型:连续mask一个完整词的字词(word level)
- 能不能遮盖掉这样连在一起的片段训练呢?。
首先想到的做法,既然现在遮盖子词,那能不能直接遮盖整个词,比如说对于 super + man,只要遮盖就两个同时遮盖掉,这便是 Google 放出的BERT WWM 模型
所做的。
ERNIE :整个实体连续mask掉(phase level)
于是能不能进一步,因为有些实体是几个词组成的,直接将这个实体都遮盖掉。因此百度在 ERNIE 模型中,就引入命名实体(Named Entity)外部知识,遮盖掉实体单元,进行训练。
但这两种做法会让人认为,必须得引入类似词边界信息才能帮助训练
。
-
但前不久的 MASS 模型,却表明可能并不需要,
随机遮盖
可能效果也很好 -
如何随机Mask:根据几何分布,先随机选择一段(span)的长度,之后再根据均匀分布随机选择这一段的起始位置,最后按照长度遮盖。
- 文中使用几何分布取 p=0.2,最大长度只能是 10,10以上的直接丢弃,利用此方案获得平均采样长度分布。
SBO
Span Boundary Objective 是该论文加入的新训练目标,希望被遮盖 Span 边界的词向量,能学习到 Span 的内容。或许作者想通过这个目标,让模型在一些需要 Span 的下游任务取得更好表现,结果表明也正如此。
- 具体做法是,在训练时取 Span 前后边界的两个词,值得指出,这两个词不在 Span 内,然后用这两个词向量加上 Span 中被遮盖掉词的位置向量,来预测原词(
将词向量和位置向量拼接起来,过两层全连接层
)。
最后预测 Span 中原词时获得一个新损失,就是 SBO 目标的损失,之后将这个损失和 BERT 的 Mased Language Model (MLM)的损失加起来,一起用于训练模型。
对于为什么 NSP 没有用,这里,SpanBERT 作者们给出了下面两个解释:
- 相比起两句拼接,一句长句,模型可以获得更长上下文(类似 XLNet 的一部分效果);
- 在 NSP 的负例情况下,基于另一个文档的句子来预测词,会给 MLM 任务带来很大噪音。
- 于是 SpanBERT 就没采用 NSP 任务,直接一句长句,然后 MLM 加上 SBO 任务来进行预训练。
XLnet
- XLNet引入了自回归语言模型以及自编码语言模型的提法
自回归语言模型(Autoregressive LM)
在ELMO/BERT出来之前,大家通常讲的语言模型其实是根据上文内容预测下一个可能跟随的单词,就是常说的自左向右的语言模型任务,或者反过来也行,就是根据下文预测前面的单词,这种类型的LM被称为自回归语言模型。
- GPT 就是典型的自回归语言模型。ELMO尽管看上去利用了上文,也利用了下文,但是本质上仍然是自回归LM,这个跟模型具体怎么实现有关系。ELMO是做了两个方向(从左到右以及从右到左两个方向的语言模型),但是是分别有两个方向的自回归LM,然后把LSTM的两个方向的隐节点状态拼接到一起,来体现双向语言模型这个事情的。所以其实是两个自回归语言模型的拼接,本质上仍然是自回归语言模型。
自回归语言模型有优点有缺点
-
缺点是只能利用上文或者下文的信息,不能同时利用上文和下文的信息,当然,貌似ELMO这种双向都做,然后拼接看上去能够解决这个问题,因为融合模式过于简单,所以效果其实并不是太好。
-
优点,其实跟下游NLP任务有关,比如生成类NLP任务,比如文本摘要,机器翻译等,在实际生成内容的时候,就是从左向右的,自回归语言模型天然匹配这个过程。而Bert这种DAE模式,在生成类NLP任务中,就面临训练过程和应用过程不一致的问题,导致生成类的NLP任务到目前为止都做不太好。
自编码语言模型(Autoencoder LM)
自回归语言模型只能根据上文预测下一个单词,或者反过来,只能根据下文预测前面一个单词。
相比而言,Bert通过在输入X中随机Mask掉一部分单词,然后预训练过程的主要任务之一是根据上下文单词来预测这些被Mask掉的单词,如果你对Denoising Autoencoder
比较熟悉的话,会看出,这确实是典型的DAE的思路。那些被Mask掉的单词就是在输入侧加入的所谓噪音。类似Bert这种预训练模式,被称为DAE LM
。
这种DAE LM的优缺点正好和自回归LM反过来,它能比较自然地融入双向语言模型,同时看到被预测单词的上文和下文,这是好处。
- 缺点是啥呢?主要在输入侧引入[Mask]标记,导致预训练阶段和Fine-tuning阶段不一致的问题,因为Fine-tuning阶段是看不到[Mask]标记的。
- DAE吗,就要引入噪音,[Mask] 标记就是引入噪音的手段,这个正常。
XLNet的出发点就是:能否融合自回归LM和DAE LM两者的优点。就是说如果站在自回归LM的角度,如何引入和双向语言模型等价的效果;如果站在DAE LM的角度看,它本身是融入双向语言模型的,如何抛掉表面的那个[Mask]标记,让预训练和Fine-tuning保持一致。当然,XLNet还讲到了一个Bert被Mask单词之间相互独立的问题,我相信这个不太重要,原因后面会说。当然,我认为这点不重要的事情,纯粹是个人观点,出错难免,看看就完了,不用较真。
- 具体怎么做才能让这个模型:看上去仍然是从左向右的输入和预测模式,但是其实内部已经引入了当前单词的下文信息呢?
XLNet在模型方面的主要贡献其实是在这里。
- 那么XLNet是怎么做到这一点的呢?
其实思路也比较简洁,可以这么思考:XLNet仍然遵循两阶段的过程,第一个阶段是语言模型预训练Pretrain阶段;第二阶段是任务数据Fine-tuning阶段。
它主要希望改动第一个阶段,就是说不像Bert那种带Mask符号的Denoising-autoencoder的模式,而是采用自回归LM的模式。就是说,看上去输入句子X仍然是自左向右的输入,看到Ti单词的上文Context_before,来预测Ti这个单词。但是又希望在Context_before里,不仅仅看到上文单词,也能看到Ti单词后面的下文Context_after里的下文单词,这样的话,Bert里面预训练阶段引入的Mask符号就不需要了,于是在预训练阶段,看上去是个标准的从左向右过程,Fine-tuning当然也是这个过程,于是两个环节就统一起来。当然,这是目标。剩下是怎么做到这一点的问题。
那么,怎么能够在单词Ti的上文中Contenxt_before中揉入下文Context_after的内容呢?
- XLNet是这么做的,在预训练阶段,引入Permutation Language Model的训练目标。什么意思呢?
就是说,比如包含单词Ti的当前输入的句子X,由顺序的几个单词构成,比如x1,x2,x3,x4四个单词顺序构成。我们假设,其中,要预测的单词Ti是x3,位置在Position 3,要想让它能够在上文Context_before中,也就是Position 1或者Position 2的位置看到Position 4的单词x4。可以这么做:假设我们固定住x3所在位置,就是它仍然在Position 3,之后随机排列组合句子中的4个单词,在随机排列组合后的各种可能里,再选择一部分作为模型预训练的输入X。比如随机排列组合后,抽取出x4,x2,x3,x1这一个排列组合作为模型的输入X。于是,x3就能同时看到上文x2,以及下文x4的内容了。
这就是XLNet的基本思想,所以说,看了这个就可以理解上面讲的它的初衷了吧:看上去仍然是个自回归的从左到右的语言模型,但是其实通过对句子中单词排列组合,把一部分Ti下文的单词排到Ti的上文位置中
,于是,就看到了上文和下文,但是形式上看上去仍然是从左到右在预测后一个单词。
- 排列组合!!!
当然,上面讲的仍然是基本思想。难点其实在于具体怎么做才能实现上述思想。首先,需要强调一点,尽管上面讲的是把句子X的单词排列组合后,再随机抽取例子作为输入,但是,实际上你是不能这么做的,因为Fine-tuning阶段你不可能也去排列组合原始输入。
- 所以,就必须让预训练阶段的输入部分,看上去仍然是x1,x2,x3,x4这个输入顺序,但是可以在Transformer部分做些工作,来达成我们希望的目标.
具体而言,XLNet采取了Attention掩码的机制,你可以理解为,当前的输入句子是X,要预测的单词Ti是第i个单词,前面1到i-1个单词,在输入部分观察,并没发生变化,该是谁还是谁。
但是在Transformer内部,通过Attention掩码,从X的输入单词里面,也就是Ti的上文和下文单词中,随机选择i-1个,放到Ti的上文位置中,把其它单词的输入通过Attention掩码隐藏掉,于是就能够达成我们期望的目标(当然这个所谓放到Ti的上文位置,只是一种形象的说法,其实在内部,就是通过Attention Mask,把其它没有被选到的单词Mask掉,不让它们在预测单词Ti的时候发生作用,如此而已。看着就类似于把这些被选中的单词放到了上文Context_before的位置了)。
具体实现的时候,XLNet是用“双流自注意力模型”实现的,细节可以参考论文,但是基本思想就如上所述,双流自注意力机制只是实现这个思想的具体方式,理论上,你可以想出其它具体实现方式来实现这个基本思想,也能达成让Ti看到下文单词的目标。
双流子注意力机制:
这里简单说下“双流自注意力机制”,一个是内容流自注意力,其实就是标准的Transformer的计算过程;主要是引入了Query流自注意力,这个是干嘛的呢?其实就是用来代替Bert的那个[Mask]标记的,因为XLNet希望抛掉[Mask]标记符号
但是比如知道上文单词x1,x2,要预测单词x3,此时在x3对应位置的Transformer最高层去预测这个单词,但是输入侧不能看到要预测的单词x3,Bert其实是直接引入[Mask]标记来覆盖掉单词x3的内容的,等于说[Mask]是个通用的占位符号。
而XLNet因为要抛掉[Mask]标记,但是又不能看到x3的输入,于是Query流,就直接忽略掉x3输入了,只保留这个位置信息,用参数w来代表位置的embedding编码。其实XLNet只是扔了表面的[Mask]占位符号,内部还是引入Query流来忽略掉被Mask的这个单词。和Bert比,只是实现方式不同而已。
Attention掩码
上面说的Attention掩码,我估计你还是没了解它的意思,我再用例子解释一下。Attention Mask的机制,核心就是说,尽管当前输入看上去仍然是x1->x2->x3->x4,但是我们已经改成随机排列组合的另外一个顺序x3->x2->x4->x1了,如果用这个例子用来从左到右训练LM,意味着当预测x2的时候,它只能看到上文x3;当预测x4的时候,只能看到上文x3和x2,以此类推……这样,比如对于x2来说,就看到了下文x3了。这种在输入侧维持表面的X句子单词顺序,但是其实在Transformer内部,看到的已经是被重新排列组合后的顺序,是通过Attention掩码来实现的。如上图所示,输入看上去仍然是x1,x2,x3,x4,可以通过不同的掩码矩阵,让当前单词Xi只能看到被排列组合后的顺序x3->x2->x4->x1中自己前面的单词。这样就在内部改成了被预测单词同时看到上下文单词,但是输入侧看上去仍然维持原先的单词顺序了。关键要看明白上图右侧那个掩码矩阵,我相信很多人刚开始没看明白,因为我刚开始也没看明白,因为没有标出掩码矩阵的单词坐标,它的坐标是1-2-3-4,就是表面那个X的单词顺序
- 通过掩码矩阵,就能改成你想要的排列组合,并让当前单词看到它该看到的所谓上文,其实是掺杂了上文和下文的内容。这是attention mask来实现排列组合的背后的意思。
XLNet起作用的,如果宏观归纳一下,共有三个因素;
-
与Bert采取De-noising Autoencoder方式不同的新的预训练目标:Permutation Language Model(简称PLM);这个可以理解为在自回归LM模式下,如何采取具体手段,来融入双向语言模型。这个是XLNet在模型角度比较大的贡献,确实也打开了NLP中两阶段模式潮流的一个新思路。
-
引入了Transformer-XL的主要思路:相对位置编码以及分段RNN机制。实践已经证明这两点对于长文档任务是很有帮助的;
-
加大增加了预训练阶段使用的数据规模;Bert使用的预训练数据是BooksCorpus和英文Wiki数据,大小13G。XLNet除了使用这些数据外,另外引入了Giga5,ClueWeb以及Common Crawl数据,并排掉了其中的一些低质量数据,大小分别是16G,19G和78G。可以看出,在预训练阶段极大扩充了数据规模,并对质量进行了筛选过滤。这个明显走的是GPT2.0的路线。
DeBerta
disentangled attention = 解绑注意力
- 在 BERT 中,每个 token 只用一个向量表示,该向量为 word (content) embedding 和 position embedding 之和
- 而 DeBERTa 则对 token embed 进行解耦,用 content 和 relative position 两个向量来表示一个 token. 对于 token i ,DeBERTa 将其表示为 H i { H _i } Hi (content) 和 P i ∣ j {P_{i∣j}} Pi∣j(relative position)
主要是说每个word / subword/ token被两个向量表示,一个是content的(内容),一个是Position的(位置);这样的话,在计算注意力权重的时候,就是通过content vector和position vector来分别计算了
score(w1, w2) =
cos(c(w1), c(w2)) +. # 内容相似度
cos(c(w1), p(w2)) + cos(p(w1), c(w2)) + # 内容和位置交叉相似度
cos(p(w1), p(w2)) # 位置相似度
- c(w)代表的是word w的content vector;p(w)代表的是word w的position vector
相对位置的计算:
这里把i-j的值的范围,设为了[-200, 200],可以看到横轴是i-j;而纵轴则是relative position的取值,可以看到其是从0到2*k=200的范围了。
- 整个是“折线”,序列左边太远距离的直接“mask”掉了,而序列右边太远距离的直接用一个最大值代替了。其他的中间的是一个单调增长的直线,相当于说,距离越近, δ ( i , j ) \delta(i,j) δ(i,j) 的取值越接近于0。
Attention的计算
相对位置编码
enhanced mask decoder 增强的解码器
解码层,加入了一个“增强版掩码解码器”(enhanced mask decoder)
- 这个解码器负责把“绝对位置信息”(absolute position information)加到BERT的解码层,从而在“预训练”阶段预测被mask掉的tokens
相当于说,我们设计,让bert知道,哪些绝对位置的词被mask掉了。
而在盘古alpha里面(gptx的预训练任务,是left-to-right的自回归解码的时候,也让模型知道目前预测的是(句子)序列中的第几个词
Why
举例子:
a new store opened beside the new mall
我们是mask掉了store和mall!
如果是基于local context(即relative positions,和surrounding words = 相对位置+周围词),那么让模型去区分store和mall是不充分的,因为两者左边都是new。
- 就是在面对相似或难区分的例子的时候,需要借助额外的参考信息(也就是绝对位置信息)
- 在Q矩阵这里加入绝对位置信息
Scale-invariant fine-tuning 对抗学习
-
主动加噪声进行对抗学习
-
但是:当模型具有数十亿参数的时候,加入的扰动的“方差”会逐渐增大,从而导致“对抗训练”的时候的”不稳定性“!
即,在标准化之后的word embeddings上增加扰动噪声,从而可以限定扰动的”方差“的值的范围不会太大,也不会太小。
具体为:
-
第一步:SiFT先把word embedding vectors标准化为随机向量;
-
第二步:在标准化之后的word embedding vectors上增加随机扰动。
DeBERTa v2
(1) 词汇表 :在v2版本中,分词器改用了一种新的、基于训练数据构建的、大小为128K的词汇表。分词器不再基于GPT2的bpe,而是现在基于sentencepiece的分词器。
(2) nGiE(nGram Induced Input Encoding): DeBERTa-v2模型使用了一个额外的卷积层,与第一个Transformer层并行,以更好地学习输入令牌的局部依赖性。
(3) 在注意力层中共享位置投影矩阵和内容投影矩阵: 基于之前的实验,这可以在不影响性能的情况下节省参数。
(4) 应用桶编码来编码相对位置: DeBERTa-v2模型使用对数桶来编码相对位置,类似于T5。
(5) 900M模型和1.5B模型 :提供了两个额外的模型大小:900M和1.5B,这显著提高了下游任务的性能。
DeBERTa v3
预训练任务
DeBERTa的预训练包括两个主要任务,旨在提升模型对语言理解的深度和广度:
-
Masked Language Modeling (MLM):这是从BERT继承来的预训练任务,模型需要预测输入序列中被掩盖掉的单词。这个任务迫使模型学习到丰富的语言表示,理解词汇、语法和上下文之间的关系。
-
Replaced Token Detection (RTD):这是DeBERTa特有的预训练任务,与ELECTRA的预训练任务类似。在RTD任务中,模型需要判断序列中的每个单词是否被一个错误的单词替换。这个任务迫使模型不仅要理解正常语言的生成规律,还要识别不符合上下文的用词,从而提高模型对语言的理解能力。