GPT系列论文笔记

GPT

论文首先指出一个问题:NLP领域中,有标号的数据量太少,难以训练出有效的模型。

然后给出解决思路:先在没有标号的数据上训练一个预训练模型,再在子任务上用有标号的数据微调。

难点:

  • 目标函数如何选取:自监督

  • 如何找到一种能有效应用于不同子任务的表示

预训练

用窗口内的k个词元去预测下一个词元,要使模型输出与原文章相同的概率最大,即最大化以下似然函数: 其中θ是基于transformer解码器的模型:

GPT模型图

与bert不同之处在于,GPT的注意力层带有掩码,训练时是用前k个词元预测下一个词元,而BERT模型的注意力层没有掩码,预测一个词元时能看到上下文信息。

微调

给定序列x_1, x2, ... , x_m,对应标签为y,也就是我们要根据序列x去预测y的概率。我们把序列放入GPT模型中,拿到x_m对应的输出(x_m一般是构造序列时添加的Extract词元),乘以一个输出层并做softmax即得到y的概率,即: h的下标l表示是第l层,即最后一层的输出,上标m表示是x_m对应的输出。

目标函数: 微调时,同时使用了两个目标函数:

  • 在序列中预测下一个词
  • 用完整的序列预测标号

论文中给出了四类常见应用场景的微调。

GPT微调任务

Classification

在文本前添加Start词元,在文本后添加Extract词元,用Extract词元对应的输出向量过一个全连接层,例如共有10种分类,则全连接层输出大小为10。

Entailment

给出两段文本,做一个三分类问题(支持/反对/既不支持也不分对)

将两段文本串成一个序列输入模型。

Similarity

判断两段文本是否相似,因为GPT具有先后顺序,而相似是相互的,因此需要构造两个序列。两个序列的输出相加进入全连接层。

Multiple Choice

做多选题,需要将每个选项分别与题干构造序列,Linear层的输出大小为1,表示该答案正确的置信度,选择置信度最大的序列。

实现细节

  • 使用BPE的词元化方式,字典大小为4000
  • n_model = 768,layer = 12, n_heads = 12
  • 采用可学习的位置编码,位置编码长度为3072
  • 激活函数为GLUE

与bert的差异:

  • GPT预训练直接使用自然文本,没有使用[CLS]、[SEP]等词元
  • bert能捕捉上下文信息,而GPT只能单向捕捉信息
  • GPT采用BPE,bert采用WordPiece
  • bert增加了段编码,而GPT只有位置编码

总结而言,GPT的思路是用大量自然文本做预训练,再用带标号的文本针对下游任务做微调,解决的是分类任务。这篇文章诞生于bert之前,二者的区别在于GPT训练时无法看到后面的数据,而bert可以看到上下文。

GPT2

GPT2训练文本达到百万级,参数量达到15亿

文章提到,NLP传统训练方式是用一个数据集训练一个任务,进而引出多任务学习(Multitask Learning),即只用一个数据集,但构造多个损失函数来达到能在多个任务使用的效果。这种方式虽然很早就提出了,但当时却不是很流行。当时主流的预训练+微调的模式仍需要针对下游任务用有标号的数据进行微调。

GPT2强调了zero-shot的设定,即只需要训练一个模型,不做微调就可以直接应用于各个下游任务。

模型直接由自然文本训练,由于没有微调环节,因此下游任务的输入必须与预训练的文本一样,而不能添加没有见过的符号(如Start、Extract)。

论文使用了prompt的方法(但作者并没有直接提出这个概念),例如要让模型做机器翻译任务,可以构造输入:

  • translate to french, english text, french text

GPT2的训练采用的是来自Reddit的有一定质量的文本数据(只爬取至少有三个karma的),一共40GB文本。

实现细节

  • GPT2采用pre-norm,即将layer normalization放到每个sub-block之前,并在最后一个self-attention后再增加一个layer normalization。

总结而言,GPT2相较于GPT除了规模的提升,更重要的是GPT2能直接运用于下游任务。虽然GPT2在很多任务上和SOTA仍有差距,但其具有强大的通用性,并且论证了模型性能还将随着规模提升。

GPT3

GPT2思路极具新意,但在实际任务中的表现却很一般。在zero-shot表现不佳的情况下,GPT3采用了few-shot,即将模型应用于不同任务时,给出几个样例供模型参考。

GPT3模型有175B的参数。

论文分别用few-shot、one-shot、zero-shot对不同规模的模型进行评估,结果显示当模型规模达到百亿以上时,效果有了显著的提升。

fine-tuning、zero-shot、one-shot、few-shot的区别:

  • fine-tuning:用具有一定规模的样本微调模型,会改变模型参数
  • zero-shot:只给出任务描述,要求模型能预测出答案。例如:“Translate English to Chinese: cheese => ”要求模型能回答出cheese对应的中文。
  • one-shot:除了任务描述外,还给出一个样例供模型参考,例如:“Translate English to Chinese: cheese => 奶酪, biscuit => ”要求模型能回答出biscuit对应的中文。
  • few-shot:与one-shot类似,给出多个样例。

作者提出了“In-context learning”的概念,即样本不用来训练模型的参数,而是作为样例和问题一起提供给模型,比如few-shot。

GPT2为了提高数据质量,采用了来自reddit的数据,但是GPT3需要更大量级的数据,因此只能继续采用Common Crawl数据集。Common Crawl数据较脏,因此作者对其进行了过滤:

  • 将Common Crawl的数据作为低质量的样本(认为该数据集中大部分样本质量都较低),reddit上karma大于3的帖子作为高质量样本,训练一个二分类器,然后对Common Crawl的数据进行分类,过滤掉低质量的数据。
  • 去除掉数据集中的重复文章。(使用LSH算法检索相似文章)
  • 加入一些其他的高质量数据集。

实现细节

  • GPT3使用了稀疏的自注意力(locally banded sparse attention)。sparse attention计算注意力时,只关注距离不超过K以及距离为K, 2K, 3K, ...的token,其余token注意力都设为0。