由于各种预训练模型都有大佬的读后感,这篇文章就是各种读后感的摘抄整理等等
总览
- NLP算法面试必备!史上最全!PTMs:NLP预训练模型的全面总结 – JayLou娄杰的文章 – 知乎
- nlp中的预训练语言模型总结(单向模型、BERT系列模型、XLNet) – JayLou娄杰的文章 – 知乎
BERT 之前
从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史 – 张俊林的文章 – 知乎
- NNLM
- Word2vec:CBOW or Skip-gram
- ELMO:contextualized
- GPT:单向 transformer
BERT – 2018.10
- Attention & transformer
- bert论文解析——BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
- 放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较 – 张俊林的文章 – 知乎
算法
- 针对单向 transformer 难以捕捉句子中逆序词对的联系的问题,提出了 Masked LM,也就是双向 transformer,通过 Mask 词两边的词预测 Mask 词;
- 针对 sentence-level 的 NLP 问题,提出了 NSP (Next Sentence Prediction),把上下文句子对关系进行训练
Masked LM
bert 想要同时利用一个单词的前后文对单词进行预测,而不是仅仅利用单词的前文,并在 transformer 模型中实现了这一点。实现方法是,随机遮住句子中的一个单词(用 [Mask] token替代),用句子里前文的单词和后文的单词预测被遮住的单词。
但这样会引入新的问题,即训练集和测试集之间有偏差,因为测试集中不会出现 [Mask] token。为此,作者的解决方案是,对于以 15% 随机概率被选中的成为 [Mask] 的单词进行如下的变换:
- 80% 的概率被替换为[Mask]
- 10% 的概率被被替换为词典里的一个 random 的 token
- 10% 保持不变
NSP
bert 在 pre-training 的过程中加入了对于 sentence 之间关系的训练。具体做法是训练集中每一个句子对 (sa, sb),有 50% 的概率是前后文关系,50% 是语料库里随机的两个句子的组合,然后用句子对进行 0-1 二分类(是否是前后文对)的训练。
XLM – 2019.01
- Cross-lingual Language Model Pretraining
- 论文代码:https://github.com/facebookresearch/XLM
- 站在BERT肩膀上的NLP新秀们(PART II) – kaiyuan的文章 – 知乎
- 跨语种语言模型的预训练 – darker的文章 – 知乎
XLMs 可以认为是跨语言版的 BERT,使用了两种预训练方式
- 基于单语种语料的无监督学习
- 基于跨语言的平行语料的有监督学习
目前的词向量基本都是在单语言语料集中训练得到的,所以其 embedding 不能涵盖跨语言的语义信息。为了更好地将多语言的信息融合在一个共享的词表中,作者在文本预处理上使用了字节对编码算法(Byte Pair Encoding (BPE)),大致思想就是利用单个未使用的符号迭代地替换给定数据集中最频繁的符号对(原始字节)。这样处理后的词表就对语言的种类不敏感了,更多关注的是语言的组织结构。
Causal Language Modeling (CLM)
Transformers 简化,只保留每个 batch 中的第一个单词,而不考虑上下文。
Masked Language Modeling (MLM)
这一个预训练目标同 BERT 的 MLM 思想相同,唯一不同的就是在于模型输入。BERT 的输入是句子对,而 XLM 使用的是随机句子组成的连续文本流。此外,为了避免采样不均,对相对频繁的输出采用与频率倒数的平方根成正比的权重从多项式分布中进行子采样。
Translation Language Modeling (TLM)

TLM 训练时将随机掩盖源语言和目标语言的 token,除了可以使用一种语言的上下文来预测该 Token 之外(同 BERT),XLM 还可以使用另一种语言的上下文以及 Token 对应的翻译来预测。这样不仅可以提升语言模型的效果还可以学习到 source 和 target 的对齐表示。
GPT2 – 2019.02
效果惊人的GPT 2.0模型:它告诉了我们什么 – 张俊林的文章 – 知乎
改进:
- 更大的模型,更多的参数,更多数据
- 对数据有筛选,质量高
- 还是单向、无监督 finetune
XLNet – 2019.6
TransformerXL
Transformer-XL解读(论文 + PyTorch源码)
Transformer 的训练方式其实是 CNN 的窗口滑行,上一步的计算和下一步没有关联,虽然并行了,但是下一次还需要重新计算隐状态。
文本太长,transformer 就引入了 context fragmentation。为了解决 context fragmentation,就要在当前步中加入上文隐状态,更通俗地说需要复用上一步的隐状态,形成循环递归。
Transformer XL 要做的就是将上一步计算的隐状态引入到当前步中来,不仅解决了 context fragmentation,还复用上一步隐状态(图中的绿色细线),大大加快速度。Transformer XL的结构图如下:

在 Transformer 中,一个重要的地方在于其考虑了序列的位置信息。在分段的情况下,如果仅仅对于每个段仍直接使用 Transformer 中的位置编码,即每个不同段在同一个位置上的表示使用相同的位置编码,就会出现问题。比如,第 i − 2 段和第 i − 1 段的第一个位置将具有相同的位置编码,但它们对于第 i 段的建模重要性显然并不相同(例如第 i − 2段中的第一个位置重要性可能要低一些)。因此,需要对这种位置进行区分。
论文对于这个问题,提出了一种新的位置编码的方式,即会根据词之间的相对距离而非像 Transformer中的绝对位置进行编码。具体见此
XLNet:运行机制及和Bert的异同比较 – 张俊林的文章 – 知乎
自回归语言模型 & 自编码语言模型
自回归(autoregressive AR)是 👉 或者 👈 或者二者拼接,不能同时使用上下文信息。它的优点,跟下游 NLP 任务有关,比如生成类 NLP 任务,比如文本摘要,机器翻译等,在实际生成内容的时候,就是从左向右的,自回归语言模型天然匹配这个过程。而 Bert 这种 DAE 模式,在生成类 NLP 任务中,就面临训练过程和应用过程不一致的问题,导致生成类的 NLP 任务到目前为止都做不太好。
自编码(AE)如 BERT,其实就是一个降噪自编码器。那些被 Mask 掉的单词就是在输入侧加入的所谓噪音。这种 DAE LM 的优缺点正好和 AR LM 反过来,它能比较自然地融入双向语言模型,同时看到被预测单词的上文和下文,这是好处。缺点是啥呢?主要在输入侧引入 [Mask] 标记,导致预训练阶段和 Fine-tuning 阶段不一致的问题,因为 Fine-tuning 阶段是看不到 [Mask] 标记的。DAE 嘛,就要引入噪音,[Mask] 标记就是引入噪音的手段,这个正常。
XLNet 的出发点就是:能否融合自回归 LM 和 DAE LM 两者的优点。就是说如果站在自回归 LM 的角度,如何引入和双向语言模型等价的效果;如果站在 DAE LM 的角度看,它本身是融入双向语言模型的,如何抛掉表面的那个 [Mask] 标记,让预训练和 Fine-tuning 保持一致。
Permutation Language Model
XLNet 仍然遵循两阶段的过程,第一个阶段是语言模型预训练阶段;第二阶段是任务数据 Fine-tuning 阶段。它主要希望改动第一个阶段,就是说不像 Bert 那种带 Mask 符号的 Denoising-autoencoder 的模式,而是采用自回归 LM 的模式。就是说,看上去输入句子仍然是自左向右的输入,看到单词的上文来预测这个单词。但是又希望在上文里,不仅仅看到上文单词,也能看到单词后面的下文单词,这样的话,Bert 里面预训练阶段引入的 Mask 符号就不需要了,于是在预训练阶段,看上去是个标准的从左向右过程,Fine-tuning 当然也是这个过程,于是两个环节就统一起来。

如图所示,引入全排列,这样看上去仍然是个自回归的从左到右的语言模型,但是其实通过对句子中单词排列组合,把一部分Ti下文的单词排到Ti的上文位置中,于是,就看到了上文和下文,但是形式上看上去仍然是从左到右在预测后一个单词。
具体做法是在 Transformer 内部,通过 Attention 掩码,从 X 的输入单词里面,也就是 Ti 的上文和下文单词中,随机选择 i-1 个,放到 Ti 的上文位置中,把其它单词的输入通过 Attention 掩码隐藏掉,于是就能够达成我们期望的目标(当然这个所谓放到 Ti 的上文位置,只是一种形象的说法,其实在内部,就是通过 Attention Mask,把其它没有被选到的单词 Mask 掉,不让它们在预测单词 Ti 的时候发生作用,如此而已。看着就类似于把这些被选中的单词放到了上文 Context_before 的位置了)。
XLNet 起作用主要就是三个因素:
- 引入 Permutation Language Model:在自回归LM模式下,融入双向语言模型
- 引入 Transformer-XL 的主要思路:相对位置编码以及分段RNN机制。实践已经证明这两点对于长文档任务是很有帮助的
- 加大增加了预训练阶段使用的数据规模
RoBERTa – 2019.7
RoBERTa 主要在三方面对之前提出的 BERT 做了该进,其一是模型的具体细节层面,改进了优化函数;其二是训练策略层面,改用了动态掩码的方式训练模型,证明了 NSP(Next Sentence Prediction)训练策略的不足,采用了更大的 batch size;其三是数据层面,一方面使用了更大的数据集,另一方面是使用 BPE(Byte-Pair Encoding)来处理文本数据。
动态 mask
- 原始静态 mask:
BERT中是准备训练数据时,每个样本只会进行一次随机 mask(因此每个 epoch 都是重复),后续的每个训练步都采用相同的 mask,这是原始静态 mask,即单个静态 mask,这是原始 BERT 的做法。
- 修改版静态 mask:
在预处理的时候将数据集拷贝 10 次,每次拷贝采用不同的 mask(总共 40 epochs,所以每一个 mask 对应的数据被训练 4 个 epoch)。这等价于原始的数据集采用 10 种静态 mask 来训练 40 个 epoch。
- 动态 mask:
并没有在预处理的时候执行 mask,而是在每次向模型提供输入时动态生成 mask,所以是时刻变化的。
– NSP
为了探索NSP训练策略对模型结果的影响,将一下4种训练方式及进行对比:
- SEGMENT-PAIR + NSP:
这是原始 BERT 的做法。输入包含两部分,每个部分是来自同一文档或者不同文档的 segment (segment 是连续的多个句子),这两个segment 的token总数少于 512 。预训练包含 MLM 任务和 NSP 任务。
- SENTENCE-PAIR + NSP:
输入也是包含两部分,每个部分是来自同一个文档或者不同文档的单个句子,这两个句子的token 总数少于 512。由于这些输入明显少于512 个tokens,因此增加batch size的大小,以使 tokens 总数保持与SEGMENT-PAIR + NSP 相似。预训练包含 MLM 任务和 NSP 任务。
- FULL-SENTENCES:
输入只有一部分(而不是两部分),来自同一个文档或者不同文档的连续多个句子,token 总数不超过 512 。输入可能跨越文档边界,如果跨文档,则在上一个文档末尾添加文档边界token 。预训练不包含 NSP 任务。
- DOC-SENTENCES:
输入只有一部分(而不是两部分),输入的构造类似于FULL-SENTENCES,只是不需要跨越文档边界,其输入来自同一个文档的连续句子,token 总数不超过 512 。在文档末尾附近采样的输入可以短于 512个tokens, 因此在这些情况下动态增加batch size大小以达到与 FULL-SENTENCES 相同的tokens总数。预训练不包含 NSP 任务。
训练优化
- batch size 更大:8K!!!!!
- 更大数据集
- 字节对编码(BPE):基于字节对而不是 unicode 编码
StructBERT – 2019.8
- https://arxiv.org/pdf/1908.04577.pdf
- ICLR2020 | StructBERT : 融合语言结构的BERT模型
算法
新增了两个预训练目标:Word Structural Objective 和 Sentence Structural Objective。
Word Structural Objective
BERT 无法直接显式的对单词顺序和高阶依赖性建模。而将一句话中的单词打乱,一个好的语言模型应该能够通过重组单词顺序恢复句子的正确排列。为了能在 StructBERT 中实现,用 Word Structural Objective 使得打乱的句子重构成正确的句子顺序。做法是从一句话中未被 mask 的单词中选取一定长度的子序列,将子序列中的单词打乱,然后让模型恢复正确顺序。在具体的实验中,作者从重新排列的子序列中选择 5%,进行词序的打乱。
Sentence Structural Objective
结合 BERT 的 NSP 和 ALBERT 的 SOP:1/3 是顺序上下句,1/3 是同文逆序上下句,1/3 是异文逆序上下句。
实验
- 从预训练任务中删除任何一个结构任务都会导致下游任务的性能下降。持续进行结构预训练的StructBERT模型优于原始的BERT模型,该模型显示了所提出的结构目标的有效性。
- 对于 MNLI,SNLI,QQP 和 SQuAD 等句子对任务,结合 Sentence Structural Objective 可以显著提高性能
- 对于单句任务(例如 CoLA 和 SST-2),Word Structural Objective 发挥了很重要的作用。特别是在与语法纠错有关的 CoLA 任务中,改进超过 5%。
ALBERT – 2019.9
为了解决目前预训练模型参数量过大的问题,本文提出了两种能够大幅减少预训练模型参数量的方法,此外还提出用 Sentence-order prediction(SOP)任务代替 BERT 中的 Next-sentence prediction(NSP)任务,基于这些本文提出了 ALBERT(A Lite BERT)模型,在多个自然语言理解任务中取得了 state-of-the-art 的结果。
算法
- Factorized embedding parameterization
将 embedding matrix 分解为两个矩阵,也就是说先将单词投影到一个低维的 embedding 空间,再将其投影到高维的隐藏空间。这使得 embedding matrix 的维度大大减小。
- Cross-layer parameter sharing
多个层使用相同的参数。参数共享有三种方式:只共享 feed-forward network 的参数、只共享 attention 的参数、共享全部参数。ALBERT 默认共享全部参数。参数共享能够使模型参数更加稳定。
- Inter-sentence coherence loss
在 BERT 中,NSP 任务的正例是文章中连续的两个句子,负例是从两篇文档中各选一个句子构造而成。NSP 并不是一个合适的预训练任务。本文推测其原因是模型在判断两个句子的关系时不仅考虑了两个句子之间的连贯性(coherence),还会考虑到两个句子的话题(topic)。
因此本文提出了 Sentence-order prediction (SOP) 来取代 NSP。具体来说,其正例与 NSP 相同,但负例是通过选择一篇文档中的两个连续的句子并将它们的顺序交换构造的。这样两个句子就会有相同的话题,模型学习到的就更多是句子间的连贯性。
实验
- ALBERT 的训练速度明显比 BERT 快
- Factorized embedding 和 Parameter Sharing 在一定程度上降低了模型的表现
- 如果使用 NSP 作为预训练任务,模型确实能很好的解决 NSP 问题,但是在 SOP 问题上表现却很差,说明 NSP 任务确实很难学到句子间的连贯性;而如果用 SOP 作为预训练任务,则模型也可以较好的解决 NSP 问题,同时模型在下游任务上表现也更好。说明 SOP 确实是更好的预训练任务。
T5 – 2019.10
T5 模型:NLP Text-to-Text 预训练模型超大规模探索 – Andy Yang的文章 – 知乎
将所有 NLP 任务都转化成 Text-to-Text (文本到文本)任务,就可以用同样的模型,同样的损失函数,同样的训练过程,同样的解码过程来完成所有 NLP 任务。

整篇文章进行多个试验,选出了效果最好的:BERT-style + replace span 15% len=3
BART – 2019.10
- BART:Denoising Seq2Seq Pre-training for Natural Language Generation, Tranlation and Comprehension
- ACL2020论文阅读笔记:BART

- (a) BERT:用掩码替换随机 token,双向编码文档。由于缺失 token 被单独预测,因此 BERT 较难用于生成任务。
- (b) GPT:使用自回归方式预测 token,这意味着 GPT 可用于生成任务。但是,该模型仅基于左侧上下文预测单词,无法学习双向交互。
- (c) BART:编码器输入与解码器输出无需对齐,即允许任意噪声变换。使用掩码符号替换文本段,从而破坏文本。使用双向模型编码被破坏的文本(左),然后使用自回归解码器计算原始文档的似然(右)。至于微调,未被破坏的文档是编码器和解码器的输入,研究者使用来自解码器最终隐藏状态的表征。
BART 与 BERT 还有 2 点不同
- decoder 中的每一层都与 encoder 最后隐藏层执行交叉关注(cross-attention,就像在 transformer 序列到序列模型中一样)。
- BERT 在预测 token 之前接一个前馈网络,而 BART 没有。总的来说,BART 比同等大小的 BERT 模型多了大约 10% 的参数。
引入噪声

BART 的一个关键优势是噪声的随意性,可以动用任何方式(包括改变长度)对原始文本进行破坏。这种方式让模型学习更多地考虑句子的整体长度,并对输入进行更大范围的转换,从而将 BERT 中 MLM 和 NSP 目标统一起来。
主要有:
- Token Masking:与 BERT 一样,BART 随机采样 token,并用 [MASK] 这一预定义的特殊token进行替换。
- Token Deletion:从输入中随机删除 token。与 Token Masking 不同,模型必须同时确定输入中缺失的位置。
- Text Infilling:采样多个文本片段,每个文本片段长度服从 λ = 3 的泊松分布。每个文本片段用单个 [MASK] token 替换。从泊松分布中采样出长度为 0 的文本片段对应插入 [MASK] token。这种文本填充方法的思想源于 SpanBERT,但 SpanBERT 采样的文本片段长度服从的是几何分布,且用等长的 [MASK] token 序列替换掉文本片段。因此,BART 能够迫使模型学习到一个片段中所缺失的 token 数量。
- Sentence Permutation:这里的句子排列变换是指按句号将文档分割成多个句子,然后随机打乱这些句子。
- Document Rotation:随机均匀地选择一个 token,再旋转文档使文档以该 token 作为起始。该任务的目的是训练模型识别文档开头。
微调
BART 做机器翻译的时候,将 BART 堆叠在一些额外的 Transformer 层之上,这些附加的 Transformer 层实质上是把其他语种翻译成带噪的英语,再通过 BART 模型,从而将 BART 作为一个预训练好的目标端语言模型。这种方法在 WMT Romanian-English 数据集上高出回译系统 1.1 个 BLEU。

其它的 fintune 任务,包括 Sequence Classification、Token Classification、Sequence Generation 都和 bert 差不多。
SpanBERT – 2019.7
- 论文:SpanBERT: Improving Pre-training by Representing and Predicting Spans
- GitHub:https://github.com/facebookresearch/SpanBERT
- SpanBert:对 Bert 预训练的一次深度探索 – Andy Yang的文章 – 知乎
- 提出了更好的 Span Mask 方案,也再次展示了随机遮盖连续一段字要比随机遮盖掉分散字好;
- 通过加入 Span Boundary Objective (SBO) 训练目标,增强了 BERT 的性能,特别在一些与 Span 相关的任务,如抽取式问答;
- 用实验获得了和 XLNet 类似的结果,发现不加入 Next Sentence Prediction (NSP) 任务,直接用连续一长句训练效果更好。

Span Masking
BERT 随机选取整句中的最小输入单元 token 来进行遮盖(比如 Superman 可能只 mask super)。这样会让本来应该有强相关的一些连在一起的字词,在训练时割裂开来。Google 的 BERT WWM 模型是要遮盖整个词。百度在 ERNIE 模型中,就引入命名实体(Named Entity)外部知识,遮盖掉实体单元,进行训练。
SpanBERT 根据几何分布,先随机选择一段(span)的长度,之后再根据均匀分布随机选择这一段的起始位置,最后按照长度遮盖。文中使用几何分布取 p=0.2,最大长度只能是 10,利用此方案获得平均采样长度分布。
Span Boundary Objective
在训练时取 Span 前后边界的两个词,值得指出,这两个词不在 Span 内,然后用这两个词向量加上 Span 中被遮盖掉词的位置向量,来预测原词。增强了 BERT 的性能,为了让模型让模型在一些需要 Span 的下游任务取得更好表现,特别在一些与 Span 相关的任务,如抽取式问答。
详细做法是将词向量和位置向量拼接起来,过两层全连接层。最后预测 Span 中原词时获得一个新损失,就是 SBO 目标的损失,之后将这个损失和 BERT 的 Mased Language Model (MLM)的损失加起来,一起用于训练模型。
实验结果
- 只用 SM:除了 Coreference Resolution 任务,random sm 方法普遍更优
- 加上 SBO 后效果普遍提高,特别是之前的指代消解任务,提升很大
- BERT 的 NSP 没啥用:
- 相比起两句拼接,一句长句,模型可以获得更长上下文(类似 XLNet 的一部分效果);
- 在 NSP 的负例情况下,基于另一个文档的句子来预测词,会给 MLM 任务带来很大噪音。
- 于是 SpanBERT 就没采用 NSP 任务,直接一句长句,然后 MLM 加上 SBO 任务来进行预训练。
ELECTRA – 2020.3
Methods

- ELECTRA 最主要的贡献是提出了新的预训练任务和框架,把生成式的 Masked language model(MLM) 预训练任务改成了判别式的 Replaced token detection(RTD) 任务,判断当前 token 是否被语言模型替换过。
- 随机替换一些输入中的字词,再让 BERT 去预测是否替换过可以吗?答案:不可以,因为随机替换过于简单,效果不好。
- 为了让替换更加真实,作者提出了利用一个基于 MLM 的 Generator 来替换 example 中的某些个 token,然后丢给 Discriminator 来判别。
- 将 GAN 的思想用在了 NLP 的应用中。
- BERT 虽然对上下文有很强的编码能力,却缺乏细粒度语义的表示(sky 和 sea 明明是天与海的区别,却因为上下文一样而得到了极为相似的编码),ELECTRA 对此进行了优化。
ELECTRA 对抗训练结构和 GAN 的区别

优点
- 任务难度的提升:原始的 MLM 任务是随机进行 mask,样本预测难度是不一样的,比如“夕小瑶的卖[MASK]屋”和“夕[MASK]瑶的卖萌屋”中,卖萌是比较常见的词语,而夕小瑶则是命名实体,没见过的话更难预测出来。生成器相当于对输入进行了筛选,使判别器的任务更难,从而学习到更好的表示
- 效率的提升:运算上,判别器进行2分类而不是 V 分类,复杂度降低。参数利用上,判别器不需要对完整的数据分布进行建模,作者在实验中也发现越小的模型提升越明显,可见参数被更完整地训练了
- Token 自身信息的利用:做 MLM 的任务时,都是 mask 掉 token 自身,利用上下文对自己进行预测。而 ELECTRA 是同时利用自身和上下文预测,和 NLU 任务的 Finetune 阶段也比较一致
- 由于 ELECTRA 是判别式任务,不用对整个数据分布建模,所以更 parameter-efficient。
缺点
- 显存占用增多:之前都是训一个 BERT,现在相当于两个,即使共享参数去训练,由于 Adam 等优化器的关系,需要保存的中间结果数量也是翻倍的。
- 多任务学习超参数调整:ELECTRA 的 loss 由生成器和判别器分别构成,原文中给判别器 loss 的权重是 50,因为二分类的 loss 会比 V 分类低很多。但这个数值太过绝对,最好是变成可学习的参数动态调整。