基于Transformer的经典模型

在LLM出现之前,有很多基于Transformer的经典模型,主要有三种类型:以BERT为代表的基于Encoder的模型,以BART为代表的基于Encoder-Decoder的模型,还有以GPT系列为代表的基于Decoder的模型。

BERT

BERT模型是基于Encoder Only架构最经典的模型,其它的模型只是预训练任务或者注意力模块等存在细微差别。

原文链接BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

BERT是一个语言表示模型,其目的是学到通用的文本表示,预训练之后的BERT针对不同的任务设置额外的输出层,在微调之后能够达到很好的效果。

Word2Vec已经证明了预训练之后的语言模型(Language Model)能够提升自然语言处理任务的性能,Pre-train+Fine-tuning的范式在GPT1(使用Transformer的Decoder部分)上也得到了应用。BERT的创新在于,设置了一个掩码语言模型masked language model,MLM)的预训练目标,使用Transformer的Encoder部分关注两个方向的上下文(从左到右和从右到左)。

整体流程

整体流程分为两部分,一部分是预训练,另一部分是微调

  • 预训练:在无标注数据上用不同的预训练任务训练模型
  • 微调:用预训练得到的参数初始化BERT模型,随后用下游任务的标注数据微调所有模型参数

预训练任务

有两个训练任务:

  • masked language model
    具体来说,输入文本随机mask一些tokens(15%),然后基于上下文预测出这些被mask掉的tokens。此外,由于fine-tuning阶段并没有[MASK]这个token,为了弥补预训练和微调之间的不匹配,随机mask的token并不总是用[MASK]标记来表示。
    实际训练时,如果某个位置的token要被mask掉,有80%的可能性用[MASK]标记替代,有10%的可能性随机挑选一个token替代,还有10%的可能性保持原始token不变
  • next sentence prediction
    具体来说,给定一个文本对,预测第二个句子是否是第一个句子的下一句。实际训练挑选句子$A$和句子$B$时,有50%的可能性$B$确实是跟在$A$后面的,标记为IsNext;还有50%的可能性$B$是从语料中随机挑选的句子,标记为NotNext

    模型结构

    BERT的模型架构采用了多层的、双向的Transformer encoder,其代码实现可以参考The Annotated Transformer,这是哈佛大学关于Transformer的教程。也可以看这篇Transformer论文精读
    如果用$L$表示Transformer blocks的数目,$H$表示隐藏层的维度,$A$表示多头注意力中head的数目,那么这是模型的参数:
BERT-BASE BERT-Large
L 12 24
H 768 1024
A 12 16
Param 110M 340M

不过由于采用了Next Sentence Prediction这个预训练任务,BERT在处理输入时和Transformer略有不同。

其中[CLS]是每个句子的第一个token,该token对应的最终隐藏状态可以看作序列表示,可以用于分类任务;[SEP]用于分割句子,以区分两个不同的句子。

我们可以看到BERT的输入部分有三种Embedding:

  • Token Embedding
  • Segment Embedding
  • Position Embedding

通过将这三种Embedding相加,可以将三种信息融合,模型在不增加额外参数的情况下将多种信息编码到同一个向量中。这种设计提高了BERT模型的兼容性,它可以组合不同的Embedding来适应不同的输入格式和任务需求。

从语义层面,为什么这三种Embedding可以相加?

相加之后的向量大小和方向就改变了,模型拿到的是三个向量之和,它怎么知道原来的三个向量?

苏剑林:embedding的数学本质就是以one-hot为输入的单层全连接网络,也就是说世界上本没有什么embedding,有的只是one-hot。从这个角度理解,这三个Embedding相加等价于三个原始的one-hot向量拼接再经过一个全连接网络。

训练语料

预训练的语料来源有:

  • BooksCorpus:800M words
  • English Wikipedia:2,500M words

使用WordPiece作为Tokenizer,建立了30,000个token的词汇表。

微调

对于每一个不同的下游任务,需要将不同的输入和输出插入BERT,然后端到端地微调所有参数

对于输入来说,预训练阶段的句子$A$和句子$B$和这些下游任务的输入是一样的:1)question answering中的(问题,段落)对;2)文本分类中的(text - $\varnothing$)对;3)序列标注中的(text - $\varnothing$)对。

对于输出来说,token的表示可以作为输出层的输入,从而应用于token级别的任务,如序列标注或者问答;[CLS]的表示可以输入到输出层,用于分类任务,例如情感分析或文本蕴含。

相比于预训练,微调花费的资源要小很多。

BART

BART全称BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension

2019年10月,Facebook提出了BART,这篇文章在抽象总结和对话等生成任务上都取得了更好的下游性能,相比于BERT做出了如下改变:

  • 在双向编码器架构中添加了因果解码器
  • 用更复杂的预训练任务代替BERT的完形填空任务

预训练任务

BART会使用任意噪声函数破坏文本,然后预训练的任务就是让模型重建原始文本

具体来说,BART会随机打乱原始句子的顺序,然后使用单个[MASK]来替换文本片段,这个文本片段可以是多个Token。通过这种方式,迫使模型对句子的整体长度进行更多的推理,并且对输入进行更长范围的转换,概括了BERT中的两个预训练任务。

重建原始文本的重建损失就是解码器输出和原始输入之间的交叉熵。

下游任务

BART常用语Seq2Seq任务,如机器翻译,摘要生成等自然语言处理任务。

GPT

GPT系列文章是由OpenAI提出的,是基于Decoder Only架构的生成式语言模型的代表作。

GPT-1

GPT-1原文是Improving Language Understanding by Generative Pre-Training
GPT-1验证了生成式预训练+判别式微调这种范式的可行性。
GPT-1采用了BPE(bytepair encoding)作为Tokenizer。

预训练

预训练的最终目标就是学到好的文本表示。什么是好的文本表示很难定义,不过我们希望这个文本表示不仅需要包含词级别的信息,还需要包含上下文级别的信息。

对此,GPT-1采用标准的语言建模(Language Modeling)任务,以期望学到通用、带有高级语义信息的文本表示。

给定无标注的语料$C=\{u_1,…,u_n\}$,标准语言建模的目标是最大化以下的似然函数:

其中$k$是上下文窗口的大小,$\Theta$是神经网络的参数,用于表示条件概率$P$。具体来说,GPT-1采用多层Transformer decoder blocks来作为这个神经网络。

假设上下文对应的向量是$U=(u_{-k},…,u_{-1})$,$n$是Transformer decoder blocks的数目,$W_e$是token embedding matrix,$W_{p}$是position embedding matrix,那么通过以下方式计算给定上下文如何得到目标token的输出分布

微调

在微调阶段,不管是什么任务,都需要将其输入转换为token序列。假设输入序列是$(x^1, …, x^m)$,对应的标签是$y$。

输入序列+预训练模型——>最后一层transformer block的激活$h_l^m$,随后该向量作为一个额外线性输出层的输入:

此时的训练目标是:

不过,在实验阶段论文作者发现将language modeling作为辅助任务有助于提升监督模型的泛化性,还可以加速收敛。

所以最终微调阶段的优化目标是这样的:

其中$D$是微调阶段的标注数据集。

GPT-2

GPT-2原文是Language Models are Unsupervised Multitask Learners

GPT-2用更多的数据预训练,验证了预训练模型强大的Zero-Shot能力,一定程度上验证了通用模型的可行性。

GPT-2采用BPE作为Tokenizer,不过实现的时候加了一些规则阻止部分token合并。

预训练

通用的系统可以执行多种不同任务,即使输入相同,它需要根据不同的任务,输出不同的内容。因此,在构建模型时,需要建模$p(output|input, task)$。

模型结构在Transformer decoder block的基础上做了一些小改动,Layer Normalization移到每一个sub-block的输入,类似pre-activation,在最终的self-attention block之后添加了额外的Layer Normalization模块。

上下文长度也从512增加到1024。

下游任务

GPT-2采用了Zero-Shot的方式进行预测,由输入格式决定要完成什么任务。此前这些格式的数据已经在预训练阶段见过。

GPT-3

GPT-3的原文是Language Models are Few-Shot Learners

GPT-3用更多的数据、更大的模型(175B)进行预训练,验证了预训练模型强大的Few-Shot能力和in-context learning能力,更进一步验证了通用模型的可行性。

此外,GPT-3还揭示了随着模型参数规模增大,in-context learning的能力会进一步增强。

预训练

和GPT-2的预训练过程类似,只不过增大了数据规模、模型参数和训练长度等。

应用

GPT-3并没有采用微调的方式处理下游应用,而是利用模型in context learning的能力,给模型传达指令。这种方式不会改变模型的权重,只是改变了输入格式。

  • Few Shot
  • One Shot
  • Zero Shot