Skip to content

Latest commit

 

History

History
283 lines (152 loc) · 23.5 KB

016_gpt.md

File metadata and controls

283 lines (152 loc) · 23.5 KB

GPT-1、GPT-2、GPT-3

image

GPT 和 Transformer 的简单对比:

GPT 的核心技术:将 Transformer 的解码器拿出来,在大量的无标注的文本数据上,训练得到一个语言预训练模型,然后再用它在子任务上进行 finetune,得到每一个任务所需要的分类器。

BERT的核心技术:将 Transformer 的编码器拿出来,然后在一个更大的数据集上做预训练,效果比 GPT 好很多。

BERT 提供了两个大小模型,其中 bert-base 大小和 GPT 相同,bert-large 大于 GPT,bert-base 效果优于 GPT,bert-large 效果远好于 GPT。

GPT-2 仍是使用 Transformer 的解码器,在之前的基础上收集了一个更大的数据集,训练了一个更大的模型(比 bert-large 更大),发现它很适合做 zero-shot 任务,但是在其它任务的效果上没有太惊艳。

GPT-3 相较于 GPT-2 就是数据和模型都大了 100 倍,大力出奇迹,终于使得效果非常惊艳。

GPT 和 Transformer 的影响力:

OpenAI 的 GPT 系列在学术界的影响力不如 Google 的 Transformer 和 BERT,原因并不是因为其缺少创新度和效果,而是 OpenAI 想要解决更大的问题,在技术实现上更难一些,出效果也更难一些,GPT-3 的规模别的团队很难复现,OpenAI 使用这样的技术问题去解决是因为其整个公司想要做强人工智能,解决更大的问题,必须在选择问题上更大一些(从 chatGPT 回来看,真的牛逼!)

对比来看,Transformer 和 BERT 一开始想解决的问题就比较小,比如 Transformer 开始就是想解决机器翻译问题,BERT 就是想把计算机视觉成熟的套路(先预训练,再微调)搬到 NLP 领域,在同等规模的数据和模型上效果优于 GPT,一般的公司努力一下还是可以找到足够的机器把模型跑起来,效果也不错,而 GPT 可能连实验都跑不出来。

GPT: Improving Language Understanding by Generative Pre-Training

paper | code

GPT 名字取自标题中 Generative Pre-Training 的三个首字母。

Alec Radford 也是 DCGAN、PPO 等一系列工作的作者,Ilya Sutskever 是 AlexNet 的二作,为 OpenAI 的 CTO。

摘要

在 NLP 领域,有大量的无标注文本数据,有标注数据相对比较少,若要在少量有标注数据上训练得到好的判别模型是比较困难的。针对此问题,本文提出的方式是:现在无标注数据上训练得到一个预训练模型(生成式任务),然后再在有标注数据的子任务上进行微调得到最终的模型(判别式模型)。

先预训练,再微调是 CV 领域很早之前就比较成熟的模式,但在 NLP 领域一直没有流行起来。原因是缺少一个像 CV 领域中 ImageNet 那样的大规模、有标注的预训练数据集(100w 张图片),虽然机器翻译任务上或许可以做到 100w 的量级,但是一个句子和一张图片不在一个尺度上面,一张图片含有的像素的信息比一个句子里面抽取到的信息多很多(一张图或许可以换10个句子),意味着当有一个1000w级别、有标注的文本数据集时,才有可能训好一个语言模型,这导致了深度学习在 NLP 领域的发展并不是很顺利,知道 GPT 和 BERT 的出现才打开了局面。

虽然 NLP 领域也采用了先预训练,再微调的范式,但不一样的是,NLP 中的预训练使用的都是无标注的数据

GPT 和之前工作的主要区别:之前的工作都是在微调时,根据任务的不同构造跟任务相关的输入,从而使得很少的改变模型架构就可以。文本和图片不同,它的任务更加多样一些,比如对词进行判断、对句子进行判断、处理一对句子或三个句子、生成一个句子等,导致每个任务都需要有自己的模型。而 GPT 只需要改变输入的形式就可以,不需要改变模型,。

GPT 在 12 个任务之上,有 9 个都好于之前的结果。而之后提出的 BERT 在所有任务上都更好,这也是 BERT 更吸引人的地方。但是从创新度来讲,GPT 获取比 BERT 更好,毕竟是更早的工作,BERT 的很多思路都是和 GPT 相同。

引言

在 GPT 之前,使用无标注文本数据比较好的工作还是 word embedding。

使用无标注数据主要面临两个难点:1.不知道用什么样的目标函数;2.如果将在无标注文本上学到的文本表示传递到子任务上(预训练和 finetune 之间的 gap 问题),主要还是 NLP 中的子任务之间差异比较大,没有有效的统一方式。

GPT 提出了一个半监督(当时还叫半监督,因为预训练无标注,微调有标注,现在此类方法都是叫自监督)方法,在无标注数据上训练得到一个比较大的语言模型,然后在子任务上进行微调。

GPT 中两个技术要点:

  1. GPT 采用 Transformer 架构,和 RNN 相比,Transformer 在迁移学习时学到的 feature 更稳健,作者认为原因可能是 Transformer 中有更加结构化的记忆,使得能够处理更长的文本信息,从而能够抽取到更好的句子层面、段落层面的语义信息。
  2. GPT 在做迁移时,用的是任务相关的输入表示。

方法

预训练

给定一段文本,其中包含 n 个词,那么该文本可用 U = {u1, . . . , un} 表示。

GPT 使用一个标准的语言模型目标函数来最大化下面的似然函数:

image

简单来说,该语言模型是给定 ui 前面的 k 个词 (u_i-k, ..., u_i-1) 以及预测模型 Θ,来预测第 i 个词是什么,把每一个位置 i(从 0 到最后)的预测概率取 log 之后全部加起来就是目标函数。通俗的理解,就是训练一个模型,使得它能够最大概率的输出和输入长得一样的文本。式中,Θ 为模型参数,k 为输入序列的长度,k 越大模型看的越长,越倾向于在一个比较长的文本中寻找关系,k 越小模型越简单,只需要看比较少的信息。如果想让模型更强,就需要 k 比较大。

GPT 使用 multi-layer Transformer decoder 作为语言模型结构:

Transformer encoder 与 decoder 最大的区别:一个序列送给encoder,对第 i 个元素抽特征时,它能够看到整个序列里面所有的元素;而 decoder 中因为有掩码的存在,所以在对第 i 个元素抽特征时,它只会看到当前元素和之前的元素,后面的元素通过掩码使得在计算注意力机制时变为 0,即看不到后面的东西。

标准的语言模型只对前预测,预测第 i 个词的时候不会看到该词后面的词是什么,所以 GPT 只能使用 Transformer 的 decoder,而不能使用 encoder。

GPT 与 BERT 的区别:

BERT 不是一个标准的语言模型,而是一个带掩码的语言模型(完形填空),即给定一个句子,将中间的一个词 mask 掉,然后再预测这个词,所以在预测时,既能看到它前面的词,也能看到它后面的词,对应的是 Transformer 的 encoder。

使用 encoder 或 decoder 并不是两者的主要区别,主要区别是两者的目标函数的选取,GPT 相对更难,给定前面的词预测下一个词,预测未来比完形填空更难,预测一个开放式的结局比预测一个中间状态更难。这也是导致 GPT 在训练和效果上比 BERT 差一些的原因。

换句话说,如果一个模型可以预测未来,是比 BERT 这种通过完形填空训练模型强大很多的,这也是 GPT 系列一直把模型做大、选择更难的技术路线的原因。

finetune

finetune 时使用的是有标注的数据,给定一个长度为 m 的词序列以及其标注 y,然后预测为 y 的概率:

image

上述公式,每次给定 x_1 ~ x_m 个词,送入训好的 GPT 模型中,然后拿到 transformer 块的最后一层的输出 hl_m,然后再乘一个输出层 W_y,做一个 softmax 之后得到预测为 y 的概率。

该部分的损失函数是一个标准的分类损失:

image

微调时发现将之前的语言模型的目标函数放进来效果会更好,即微调时,一个任务是给定一个序列,预测该序列的下一个词;另外一个任务是给定一个序列,预测该序列的下一个词是标签 y 的概率。

image

子任务输入形式转换

如何把 NLP 里不同的子任务表示成 一个输入序列 x1~xm + 一个标签 y 的形式。

image

上图给出了常见的 4 个 NLP 任务在 GPT 中的输入处理方式:

  1. Classification 分类:给定一段文本,判断它的类别,比如对一个产品的评价是正面的还是负面的。具体处理是,在这段文本之前放一个 Start 词元(token),在后面加一个 Extract 词元,然后将这个新的序列送入 Transformer decoder,得到特征之后通过一个线性层 Linear 得到最后的类别。微调时,Linear 是新加入的。
  2. Entailment 蕴含:给定一段文本和一个假设,判断这段文本是否蕴含了假设提出的内容。比如文本是 a 送给 b 一束玫瑰,假设是 a 喜欢 b,预测结果应该是给定的文本是支持给出的假设的。其实是一个三分类问题:支持、不支持、不确定。具体做法是,用 开始符 Start、分隔符 Delim 和抽取符 Extract 将两段文本连接成一段文本,然后送入Transformer decoder,通过线性层得到预测结果。
  3. Similarity 相似:判断两段文本是否相似,常用于检索和去重。相似是一个对称关系,a 和 b 相似意味着 b 和 a 也相似,但是在语言模型中是有先后顺序的,GPT 中的处理是做了两个序列,分别是 Text1 在前 Text2 在后和 Text2 在前 Text1 在后,两段序列分别送入 Transformer 后提取特征,融合之后送入 Linear 得到是否相似的二分类结果。
  4. Multiple Choice 多选:给定一个问题和多个答案,然后选出正确的一个。如果有 n 个答案就构造 n 个序列,其中前面的 Context 是问题,后面 Answer 是答案,将序列分别送入 Transformer 提取特征,在通过 Linear 得到该答案属于该问题的置信度,最后通过一个 softmax 计算得到每个答案属于正确答案的概率。

以上,每个任务虽然都不太一样,但是都是通过构造成序列送给 Transformer,其中预训练好的 Transformer 是不需要做任何结构上的改动的,这也是 GPT 和之前工作最大的区别。

实验

预训练是在 BooksCorpus 数据集上完成的,包含了 7000 篇没有发表的书;模型是用了 12 层的 transformer decoder,每一层的维度为 768。

image

从实验结果看,GPT 大部分都是优于之前的方法。

GPT 和 BERT 的对比:

BERT-base 是对标 GPT 的,模型是 12 层的 transformer encoder,每一层的维度也是 768,encoder 因为少了一个掩码,相比于 decoder 是要简单一些的。而 BERT-large 层数翻了 1 倍,宽度为 1.3 倍,复杂度为 base 的 3 倍。复杂度可以翻 3 倍得益于其预训练数据集为 BookCorpus(8 亿个词)+ Wikipedia(20 亿词),数据集大概是 GPT 中用的 4倍,然后训了一个3 倍于 GPT 的模型。

image

从结果来看,BERT-base 在同复杂度下也是要优于 GPT 的,BERT-large 一个更大的模型用更大的数据集效果提升很明显,这也引出了 GPT-2 的工作。

GPT-2: Language Models are Unsupervised Multitask Learners

paper | code

语言模型是一个无监督的多任务学习器。

摘要

GPT-2 使用了一个新的数据集 WebText(含百万级别的文本),训练了一个更大的模型(15 亿参数),当数据规模和模型大小都增大了很多时,可效果相比于 BERT 并没有明显的提升,作者就从 zoro-shot 的角度来说明 GPT-2 的优势。

引言

目前对于一个任务,现在主流的方法是先收集一个数据集,然后在上面训练得到一个模型做预测,因为现在的模型泛化能力并不是很好。

多任务学习是在训练一个模型时,同时看多个数据集,通过多个损失函数来实现用一个模型在多个任务上都能使用。但是在 NLP 领域,主流的方法还是和 GPT 与 BERT 类似,即先用大的数据集预训练,再在下游任务上使用小的数据集 finetune。这就存在两个问题:1.对于每一个任务还是需要重新训练模型;2.还是需要收集有标注的数据。

GPT-2 在做下游任务时,会使用一个 zero-shot 的设定,不需要下游任务的任何标注信息,也不需要再训练模型。

方法

GPT 在预训练时是在自然的文本上训练的,但是在做下游任务时,对输入进行了构造,加入了开始符、分隔符以及结束符,这些符号在之前预训练时是没有看过的,但是因为有微调的环节,模型会在微调时去认识这些符号。而在 GPT-2 中要做 zero-shot,问题是在做下游任务时模型不能再做调整了,如果还引入之前模型没见过的符号时,模型就会很困惑。所以在这个前提下,做下游任务时就不能引入那些没见过的符号,需要让下游任务的输入和预训练时的输入相同,也是自然语言。举个例子:

做机器翻译时,假如把英语翻译成法语,文本序列可以表示成:translate to french, english text, french text,前面的三个词可以认为是做了一个特殊的分隔符的意思,在之后的工作中把这个叫做 prompt(提示)。另一个例子,如果做阅读理解,可以设置下面的提示:answer the question, document, question, answer,其中的answer the question就是prompt,让模型知道要做的任务。

Prompt 为什么可以 work?

作者认为,如果模型足够强大,它能理解提示符要做的事情肯定是更好的;另外这样的设置在自然文本中也比较常见,详细可看下面数据的介绍。

训练数据

GPT-2 中使用了 Common Crawl,它是一个抓取公开网页的项目,不断的在网上抓取网页并放到 aws s3 存储,然后供人免费下载,目前应该有 TB 级的大小,但是这个数据集的信噪比比较低,因为很多网页的信息是没有意义的,为了过滤出比较好的网页信息,文章中使用了 reddit (美国排名靠前的新闻聚合页,可理解为美国贴吧。。),选出 reddit 的评论超过三个的帖子,最后得到了 4500 万个链接,然后将文字信息抽取出来的到一个数据集,该数据集包含了 800W 个文本,共 40 GB 的文字。

模型

当拥有更大的数据集时,就可以把模型设置的更大了,GPT-2 中一个设置了 4 个大小的模型

image

第一个模型大小与 GPT 和 BERT-base 相同;第二个与 BERT-large 相同;最大的有 15 亿参数。

实验

image

上表主要是和其它的专门做 zero-shot 的方法作了对比,可见 GPT-2 比 SOTA 都好,毕竟数据量和模型大小甩了别人一条街。

image

上标展示了 GPT-2 在几个任务上虽然效果相比于最好的方法还差点意思,但是从曲线可以看到,随着模型变大,性能还是上升的,也就是说如果模型更大,还是有希望使得效果更好的。这也是 GPT-3 要做的事情。

GPT-3: Language Models are Few-Shot Learners

paper

GPT-2 虽然新颖度不错(zero-shot),但是有效性比较低(效果没有太惊艳),而 GPT-3 就是要解决有效性的问题。

Few-shot 的意思是在做下游任务时,还是会给一些样本,但不用太多,只需要你的样本在可控的范围内,成本相对还是比较低的。

摘要

本文训练了一个 GPT-3 模型,它也是一个自回归模型,有 1750 亿个可学习参数,比之前所有的非稀疏(权重是稀疏的,里面可能有大量的 0)的模型要大 10 倍,因为模型太大,如果在子任务上还要再训练的话,成本是很大的。 GPT-3 在做子任务时,是不做任何的梯度更新或者微调的,即便是 few-shot 给定一些样本,GPT-3 也不用微调。

GPT-3 在 NLP 多个任务上都取得了很好的成绩,另外 GPT-3 还能生成一些新闻文章,人类读起来也很难区分。

关键词:大、不需要计算梯度(微调)、效果很好

引言

目前,对于 NLP 任务一般都是使用预训练好的模型,然后再做微调,在子任务上还是需要一个任务相关的数据集。这样带来的问题是:

1.数据集需要标注;2.当一个样本没有出现在数据分布里时,泛化性不见得比小模型好,就算在子任务上微调拟合的比较好也不能说明预训练的泛化性好;3.对人类来说,对于一个子任务,并不需要大量的数据集去学习。

Meta-learning:训了一个很大的模型,其泛化能力还不错;

In-Context learning:预训练完成之后,即使再给定一些样本,也不用来更新权重。

GPT-3 的评估采用了三种方式:

  1. Few-shot: 对每一个子任务,给定 10-100 较少的样本用于训练;
  2. One-shot: 每个任务,只给定一个样本;
  3. zero-shot: 一个样本也不提供;

image

上图展示了随着模型大小的变化,三种方式的性能。

方法

image

  1. Finetune: 训练好预训练模型之后,在每一个子任务上,提供一些训练样本,去更新权重。微调对训练数据的要求通常少于从 0 开始训练,而且在学习率上通常可以小一点。GPT-3 中追求的是不对梯度进行更新,一方面是考虑到新颖度,另一方面如果模型那么大还需要再计算梯度更新权重,成本就太大了;
  2. Zero-shot:以英语翻译法语为例,首先是给定任务的描述 Translate English to French:,然后给定待翻译的英文文本cheese,再给定 prompt =>,告诉模型接下来就是要做预测了;
  3. One-shot:在给定任务描述之后和模型做翻译之前,插入一个样本进来,希望模型在看到样本之后能够从中提取出来有用的信息来帮助后面的翻译,需要注意的是,虽然这个样本放进去了,但是只做预测不做训练;所以它希望的是在模型做前向推理时,能够通过注意力机制,去处理比较长的序列信息,去帮助接下来的预测,这也是为什么叫做上下文的学习;
  4. Few-shot:相当于 one-shot 的扩展,给定多个样本,序列更长,但是模型不一定有能力把所有的信息都能提取出来;

GPT-3 的 xxx-shot 设置的确不需要训练样本,但是也带来了一些问题:比如,假设真的有很多训练样本怎么利用?

这时如果想把所有的训练样本当成 few-shot 的形式放进去是不可行的,因为模型处理的序列长度有一定限制;另一个问题是,假设有一些不错的训练样本,模型在不给训练样本时表现不行,这就需要每次预测时都需要给定训练样本,以为模型不能把上一次从训练样本中提取的信息存到模型中,每次都需要重新提;

模型结构

image

这里就不一一说明了,只能说:真大。

数据集

使用 Common Crawl 爬取数据,为了清洗数据做了以下三个步骤:

  1. 首先假设 Common Crawl 数据为负类(比较脏),假设 GPT-2 中使用的 reddit 上的数据为正类,以此训练一个二分类,然后对 Common Crawl 数据进行分类,得分高的数据拿出来,得分低的过滤掉;
  2. 去重:如果两篇文章比较相似,过滤掉其中一篇,具体使用的是 lsh 技术(这里不具体看了);
  3. 加入一些已知的高质量样本,比如之前 BERT、GPT-2 使用的数据集;

各个数据集的规模:

image

虽然 Common Crawl 比 WebText2 大了20倍,但是考虑到其中噪声比较大,所以在训练时对数据集采样还加了一个权重,实际使用中也就是 3 倍左右。

评估方式

预训练完成之后就直接做评估,不用在子任务上做微调。

对 Few-shot 来说,每次预测从训练集中采样 K 个样本作为条件,prompt 使用的是 answer:A:

实验

image

上图为不同大小的模型在训练时,和计算量的关系,x 轴为计算量,y 轴为验证损失。

image

上图为不同模型大小在不同评估方式下的精度变化。

其他的一些类似结果的展示就不一一列举了。

局限性

  1. 文本生成上还是比较弱;
  2. 结构和算法上的局限性:GPT-3 使用的语言模型是 transformer decoder,每次都是均匀的预测下一个词,没有考虑每个词的重要性;
  3. 使用的只是文本,没有其他的模态;
  4. 样本有效性不够;
  5. 训练特别贵;
  6. 可解释性和其他的模型一样都比较差;

GPT、GPT-2、GPT-3 总结

GPT 先把 transformer decoder 拿来做预训练,然后验证效果很好,但是没想到另一条路更容易一些(BERT 用的 encoder);

GPT-2 决定一条路走到黑,继续使用 decoder,把模型做的更大,尝试一个更难的问题,不做 finetune;

GPT-3 为了解决 GPT-2 效果并不是很惊艳,就搞的再大一些,大力出奇迹。