在之前我们介绍了Word2Vec, GloVe等上下文无关的词嵌入算法。这类算法存在一个缺点,就是无论单词所在的语境如何,词嵌入向量都是固定的。例如,在Word2Vec算法中,词嵌入向量是在训练语料库中以该词为中心词并由它的上下文词表示的一个期望。这种静态表示会大大影响多义词在不同语境下的含义表示。因此,我们希望开发出“上下文敏感”的词向量,即某个词的向量由它的上下文动态表征。幸运的是,在本系列文章的第一篇和第二篇,我们已经研究了能够根据上下文提取特征的深度模型:RNN和Attention model. 受到这些深度模型的启发,我们可以摒弃Word2Vec, GloVe算法学习到的静态向量嵌入层,而是将训练好的深度模型作为一个动态的向量嵌入层。
受”预训练-微调“模式的影响,我们希望可以设计一个通用的任务无关的预训练模型(LLM)。最经典的两个LLM分别是GPT和BERT。 GPT取自Tranformer的解码器,采用生成式预训练, 具有自回归特性。 BERT取自Transformer的编码器,采用掩码语言模型和下一句预测等任务进行预训练,不具有自回归特性。其中GPT更适合于自然语言生成式任务和自然语言理解式任务,BERT更适合于自然语言理解式任务。除此之外还存在编码器-解码器类型的大模型,例如T5和BART。
本文我们我们将重点介绍BERT, GPT, T5, BART等模型。
2. LLM预训练范式的总结
2.1. 经典的预训练架构
上下文无关嵌入层: 通过一个提前预设好的上下文无关的嵌入层将离散的词元映射到连续的词嵌入向量。在学习过程中,这层网络通常是不会更新的。它输出的向量之间没有经过任何注意力汇聚操作,因此也没有任何的上下文信息.
上下文有关嵌入层: 通过编码器输出的向量,因为编码器有上下文注意力汇聚操作,因此这些向量存储了上下文信息。这些上下文有关的向量是模型压缩的最终向量。它们可以通过预训练任务产生损失,来使模型学习到语法规则和常识知识。
2.2. 三种不同基础模型
- 卷积模型: 通过卷积操作来聚合局部信息
- 循环模型: 通过短时记忆记忆单词周围的信息,容易遭受长程依赖问题
- 全连接-自注意力模型: 每个单词都由动态权重的全连接层联系,动态权重由自注意力机制计算
现如今,全连接-自注意力模型的代表Transformer成为构成预训练模型架构的主流。
2.3. 常见的预训练任务
以上表格中的预训练任务主要分为两种:自回归和自编码。
计算损失的做法分为两种:
1.全文本重建(FTR): 将污染的文本序列送入模型,得出在每个词元预测概率与真实词元的交叉熵后相加得出总损失。
2.污染文本重建(CTR): 将污染的文本序列送入模型,得出在每个被污染的词元预测概率与真实词元的交叉熵后相加得出总损失。
2.4. 常见的LLM架构
通过注意力掩码和编码器/解码器的选择可以组合成以下的常见架构:
预训练架构 | 模型 |
---|---|
L2R LM | GPT-1,GPT-2,GPT-3 |
Masked LM | BERT,RoBERTa |
enc-dec | T5, BART |
2.5. 下流任务的总结
以上为NLP中下流任务的分类,不同行为输出不同,不同列为输入不同。我们于每一块取出一个任务举例:
task | example |
---|---|
Sentiment Classification(1,1) | input: today’s great! / label: |positive| |
NLI(1,2) | input: ‘today’s sunny’,’it’s raining’ / label: |contraction| |
POS tagging(2,1) | input: John saw the saw / label: |Noun| |Verb| |Article| |Noun| |
Extractive QA(3,2) | input: ‘… Chongqing is hot and wet …’, ‘how’s Chongqing?’ / label: Chongqing is hot and wet |
Translation(4,1) | input: I love China / label: ‘Ich liebe China’ |
chatbot(4,2) | input: ‘hi,robot’,’today’s weather’ / label: ‘hi’, ‘sunny’ |
注意:
1. 上表中加| |的文字不是字符串,而是一个标签.
2. 上表中加双引号的目的是为了区分多个字符串。
3. masked LM预训练模型无法胜任下游的文本生成任务,例如上图的第三行和第四行中的任务。
4. 除了这些任务,Knowledge Probing(Fact Probing/ Linguistic Probing)任务在零样本学习场景中应用比较广泛,它旨在没有上下文的情况下让模型回答出预训练中学到的知识。
3. BERT
Bidirectional Encoder Representations from TransformersBERT 是开启“预训练-微调”时代的一座里程碑,它采用了Transformer的编码器,并具有上下文敏感、人物无关、双向架构编码等特点。在微调时,BERT一般不冻结编码器只微调任务头,而是执行全参数微调。
3.1. BERT的架构
BERT本质上是对一个Tranformer编码器的魔改。BERT的预训练任务是掩码语言模型和下个句子预测,他将两个句子(遮蔽随机词元后)拼接作为输入,并在文本序列前边附上一个分类词元(用来辨别两个句子是否相邻)。最后在输出序列上做MLM和NSP的损失。
3.2. BERT的预训练任务
3.2.1. 掩蔽语言模型(MLM)
为了双向编码上下文以表示每个词元,BERT随机掩蔽词元并使用来自双向上下文的词元以自监督的方式预测掩蔽词元,BERT最初的做法是将随机遮蔽的词元用<MASK>表示。
但是由于微调任务往往需要的不是预测<MASK>这个特殊词元,而是想要压缩整个句子的所有词元向量,所以导致了预训练和微调的不匹配。换句话说,不匹配的原因是这种遮蔽方式存在缺陷,这种遮蔽方式并不能确定地将句子中非<MASK>的词元压缩。所以BERT的任务无关性受到了考验。
为了解决这个问题,BERT采用了以下的遮蔽方式:
在这个预训练任务中,将随机选择15%的词元作为预测的掩蔽词元,对于这些遮蔽词元,:
- 80%时间为特殊的<MASK>词元;
意义:在不泄露label的情况下,通过被mask的单词的上下文,预测该单词,训练模型和词向量。 - 10%时间为随机词元;
意义:让模型知道,当单词不是<MASK>标记时, 也要学习基于上下文的表示。 - 10%时间内为不变的标签词元;
意义:让模型知道,当词元不是<MASK>(第一种情况),也不是明显的随机词元(第二种情况)也要学习基于上下文的表示。
3.2.2. 下一句预测(NSP)
尽管MLM能够编码双向上下文来表示单词,但它不能显式地建模文本对之间的逻辑关系。为了帮助理解两个文本序列之间的关系,BERT在预训练中考虑了一个二元分类任务——下一句预测。在为预训练生成句子对时,有一半的时间它们确实是标签为“真”的连续句子;在另一半的时间里,第二个句子是从语料库中随机抽取的,标记为“假”。
3.3. BERT的输入和输出
BERT的预训练任务是MLM和NSP,所以理应接收两个句子+一个特殊的分类词元作为输入。但是为了适配下游任务,BERT接受一个文本序列(可能包含两个句子)+一个分类词元作为输入(我们把这个输入序列叫做BERT输入序列)。为了区分文本对,分别将根据输入序列学到的片段嵌入��和��添加到第一序列和第二序列的词元嵌入中。对于单文本输入,仅使用��。
而对于BERT的输出,我们
(1)在预先知道的遮蔽词元位置做MLM任务的损失:在网络输出后接一个输入维度为嵌入向量维度,输出维度为词典大小的全连接层,根据softmax后的概率值做交叉熵。
(2)以及在[cls]词元处做NSP任务的损失:在网络输出后接一个输入维度为嵌入向量维度,输出维度为2的全连接层,根据softmax后的概率值做交叉熵。
3.4. BERT的应用
单文本分类
文本对分类
文本标注
从文章中摘取问答
可以看出微调也需要添加不同的架构,目前prompt learning技术使得微调的架构也统一了。
3.5. BERT的局限性
从上面的应用可以看出BERT的局限性:
1.由于BERT并不是生成式的,所以输出和输入的长度被限制成相同的。这就导致了不能完成机器翻译、机器人对话等高阶的自然语言生成任务。近期,T5模型提出一切下游任务都可以被统一成text-to-text的任务,在这点BERT没有以GPT为首的生成式预训练模型灵活。
2.BERT在输出上有一个的词元,用于表示整个文本序列的语义信息。根据奥卡姆剃刀原理,这种操作是不必要的。
3.BERT在预训练阶段采用了两个任务:针对单句上下文语义提取的MLM和针对文本对逻辑建模的NSP,这个是明显考虑到下游任务后才设计的两个预训练任务。这违背了任务无关的预训练模型建模原则。
4. GPTs: generative pre-trained transformer
GPT采用的是以Transformer解码器为基础的生成式预训练模型。从GPT-1到GPT-3,随着模型参数(0.12B → 1.5B → 175B)和训练数据的增多,研究者发现了自监督预训练的GPT逐渐具有了处理需要有监督微调的下流任务的能力。研究者尝试了以下方法来挖掘GPT的这种涌现能力:在下游任务中嵌入固定提示的零样本微调; 嵌入提示+演示(称作上下文学习)的少样本微调。
4.1. GPT-1
Improve Language Understanding by Generative Pre-training这篇论文是2018年发表的。在这之前,研究者大多还是采用有监督学习来预训练模型。有监督学习的缺点很多:标签太过昂贵;针对一个特定的任务,预训练模型的泛化性不好。因此GPT-1可以算是开创了用自监督学习预训练的一个里程碑,在它之后,大模型基本上都是以自监督来做预训练。
不同于BERT的双向编码,GPT-1是采用单向的自回归编码。这种生成式的预训练范式使他能够适应更多的下游任务,比如自然语言生成、机器翻译等。
4.1.1. 预训练
具体做法和Transformer差不多。除了以下几点:
1.GPT-1不存在编码器,也不存在编码器隐状态和解码器隐状态的注意力汇聚操作。
2.GPT-1限制了上下文范围(�)。在计算某个位置的注意力汇聚时,不同在Transformer中,注意力掩码(也就是前几篇文章中的masked softmax)保留该位置之前的所有词元;在GPT-1中注意力掩码只保留前K个位置的连续词元。
4.1.2. 微调
GPT-1的微调和BERT基本上差不多:都是在一些自然语言理解的任务做全参数微调。只不过BERT是把[cls]放在序列的第一个位置,GPT-1把它放在了最后一个位置(extract)。因为很显然,只有最后一个位置才能得到所有输入的注意力汇聚。
4.1.3. 总结
GPT-1在未经微调的领域表现并不好,说明它只是一个简单的领域专家,而不是一个通用的语言学家。
4.2. GPT-2
Language Models are Unsupervised Multitask Learners随着参数量的增多,研究者发现GPT-2在自监督预训练中会学到有监督的信息。换句话说,模型不仅学会了顺着句子语义说下去的能力:
为了解释上述现象,作者认为,当一个语言模型的容量足够大时,它就足以覆盖所有的有监督任务,也就是说所有的有监督学习都是无监督语言模型的一个子集。
例如当模型训练完”Micheal Jordan is the best basketball player in the history”语料的语言模型之后,使也字会了(question: “who is the best basketball player in the history?”, answer:”Micheal Jordan”)的QA任务。
作者是如何发现这种能力的呢?答案是在下游任务中加一些固定提示。例如对于机器翻译中的一个测试样本是(‘你好’,’hello’),研究者不同于常规地将’你好‘作为输入,而是将 ‘将下列中文翻译成英文: 你好‘ 作为输入。注意,对于每个位置,注意力掩码都不会遮掩这个提示前缀,这种学习范式在前文也介绍过,叫做prefix LM。 这样就构建了output+task的条件,模型可以根据学到的
4.2.1. 总结
GPT-2变成了一个不那么通用的语言学家:在某些未微调任务上表现很好,但是在某些未微调任务上表现很不好,甚至不如随机预测。那么如何更好地挖掘GPT的涌现能力变成了当务之急。
4.3. GPT-3
Language Models are Few Shot Learners研究者开始尝试将任务相关的固定提示魔改成”固定提示+少样本示范”的形式。这也使GPT-3不同于前代在下游任务上的零样本微调,变成了少样本微调。换句话说,研究者发现用提示学习的形式,对GPT进行少样本微调要比零样本微调更可以发掘模型的涌现能力。
这种”固定提示+少样本示范”被称为上下文学习(in-context learning),在提示学习的领域被称为提示增强(prompt augmentation). 提出上下文学习的初衷是作者猜想: 提供和预训练语料一致的文本,或许可以唤醒模型”预训练时的记忆“。更进一步地说,上下文学习(包括整个提示学习)实际上是在挖掘模型的归纳偏置。
5. T5: Text-to-Text Transfer Transformer
在微调时,需要根据不同下游任务在预训练模型上加不同的网络架构以实现微调目的。T5给所有的下游任务提供了一个统一的接口:T5认为,所有下游任务都可以转化为Text-to-Text(seq2seq)的形式。所以T5是以解决seq2seq问题的编码器-解码器架构为基础的预训练模型。
如何实现Text-to-Text形式呢?答案是仿照GPT-2中的提示学习,在编码器输入前加入一个提示前缀后,模型会输出这个任务的答案。不同的是,因为该提示前缀是从双向的编码器输入的,所以这种学习方式还是叫做enc-dec而不是prefix-LM.
5.1. 预训练
T5的自监督任务是BERT MLM任务的升级版,它使得T5可以将[MASK]恢复成不定长的连续词元序列。这种任务被称为片段-掩码去噪任务(span-mask denoising objective)。具体训练步骤如下:
1.首先选择多个随机片段,每个随机片段用哨兵词元(sentinel tokens)遮蔽。
2.将加了噪声后的句子输入编码器。
3.将原片段根据噪声取反得到标签序列:第i个哨兵词元与第i−1个哨兵词元之间的片段用第i个哨兵词元代替。
4.将标签序列以教师强制的方式输入解码器,并与生成的输出序列做交叉熵。
解释:
1.因为输入是全文可见的,所以模型很快就可以学到:要将输入序列中不是哨兵词元的片段输出为对应的哨兵词元。所以模型的主要学习对象是如何预测输入序列中的哨兵词元所对应的片段。因此模型便可利用输入中已知的信息做自回归,来预测哨兵词源的变长片段。
2.教师强制这个方法其实在本系列的第一篇文章中提过,就是模型在训练和预测时解码器的输入不一样。1.在预测时,将解码器预测的词元拼接到当前序列中再次输入到解码器中,重复多次循环(这种方式叫做k步预测);2.在训练时,采用教师强制,即将标签词元而不是预测词元拼接到当前序列中再次输入到解码器中,重复多次循环。在训练时这种方式是可以并行的,因此采用一个对角注意力掩码就可以并行计算多次循环。一般来说,在编码器-解码器架构中都会使用教师强制这个方法来做预训练。
5.2. 微调
将任务相关的提示作为前缀与输入序列相拼接,生成的输出序列与标签序列做交叉熵。
5.3. 预测
在预测时,除了可以执行统一所有下游任务的Text-to-Text任务。T5还可以执行“片段完形填空”,这一特性被应用到了提示学习中自动生成硬提示。(Making Pre-trained Language Models Better Few-shot Learners)
6. BART:
Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension
BART和T5比较相似,不同点是预训练任务有稍许不同、微调阶段BART没有采用Text-to-text的接口。
6.1. 预训练
不同于T5的片段-掩码去噪任务,BART采用了多种给文本加噪声的方式:
6.2. 微调
BART没有采用T5一样的Text-to-text接口,而是遵循老套路:向原预训练模型中加入一些网络结构来适应下游任务微调。
1.序列分类任务:在输入末端加一个[cls]词元,在输出序列中该位置接上全连接层做交叉熵,和GPT-1类似。
2.词元分类任务:每个词元位置都外接一个全连接层(共享参数)做交叉熵。
3.序列生成任务:给输入序列加上噪声,然后输出序列和标签序列做交叉熵损失。
4.机器翻译:将编码器的嵌入层替换为一个”噪声编码器”:它的目的是将源语言序列转化为带噪声的目标语言序列。然后由解码器来恢复这个目标语言序列。