财大气粗,Google T5

Google 使用一篇 53 页的综述分析了 NLP 预训练中的各种结构与训练策略。文章同时提出了一个统一的 text-to-text 框架,整理并开源了一份巨大的数据集:Colossal Clean Crawled Corpus (C4),训练得到的新模型实现了 SOTA 结果。全文大部分都在分析各个策略的有效性,做了大量的对比实验,可谓是财大气粗。
论文:Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer

Setup

Model

本文的模型基于 Transformer,而 self-attention 本身并不包含位置信息,所以需要在输入中加入序列位置信息。传统的 Transformer 使用三角函数作为位置嵌入,BERT 则使用可学习的绝对位置嵌入。本文使用相对位置嵌入(relative position embeddings),它是根据两个位置之间的偏移量对应的可学习的嵌入向量。简单起见,本文还对其做了简化:

  • 每个偏移量对应一个标量位置嵌入而不是一个向量,计算过程中,直接将该数值加在 attention softmax 之前的 logits 上。
  • 每个 head 有自己的一套相对位置嵌入,所有层之间共享一套嵌入。
  • 某一个范围的 offset 对应着同一个标量。作者共使用了 32 个嵌入,且对于大于 128 的 offset 统一使用同一个编码。(某一层对于大于 128 的位置不敏感,但后续层可通过组合来自先前层的局部信息来构建更大 offset 的敏感性)

The Colossal Clean Crawled Corpus (C4)

通过 Common Crawl 抓取网页 HTML 内容,并通过以下方式进行过滤:

  • 只保留结尾有标点的句子。
  • 移除包含脏话的页面。
  • 删除包含 Javascript 单词的句子。
  • 去掉包含 “lorem ipsum”(排版测试) 的网页。
  • 去掉包含花括号的页面。
  • 以三句为一个整体去重。
  • 过滤非英文的页面。

爬取了 2019 年 4 月以来的网页,经过上述处理,产生了 750GB 的 Colossal Clean Crawled Corpus (C4) 数据集。

Downstream tasks

文章所使用的下游任务有:

  • benchmark:GLUE & SuperGLUE
    • 句子可接受性判断:CoLA
    • 情感分析:SST-2
    • 复述/句子相似性:MRPC / STS-B / QQP
    • 自然语言推断:MNLI / QNLI / RTE /CB
    • 指代消解:WNLI / WSC
    • 句子补全:COPA
    • 词义消歧:WIC
    • 问答:MultiRC / ReCoRD / BoolQ
  • 文本摘要:CNN/Daily Mail
  • 问答:SQuAD
  • 机器翻译:WMT English to German, French, and Romanian

对于 GLUE 和 SuperGLUE,将其中所有的数据集连接起来,将所有任务视为一个任务进行微调。将 Definite Pronoun Resolution (DPR) 数据集加入 SuperGLUE 中。对于 SQuAD 数据集,将问题和上下文喂入模型,使得模型逐字生成答案。对于机器翻译任务,作者仅仅预训练了英文数据集。

Input and output format


为了保证使用一个统一的 text-to-text 框架,模型在训练时对于所有任务皆使用极大似然目标,并使用 teacher forcing。为了区别各个任务,在输入时给不同的任务加上了任务前缀并一起喂入模型。

针对某些数据集,为了使其适应该 text-to-text 框架,需要作出某些改动:

  • 文本分类:模型输出 label 的文本,当输出不匹配的文本时均视为分类错误。
  • 回归:对于 STS-B 任务,将连续的数值分桶到 21 个离散的类别,模型目标为该数值的 string 格式。对于模型的输出,如果其在有效范围内,将其划分到最近的桶内,否则视为预测错误。
  • 指代消解:将原文中的歧义代词用 * 包裹起来(告诉模型歧义代词是哪一个)喂入模型,要求模型输出该代词指示的文本内容。对于 WSC 数据集,由于其包含了文本内容、歧义代词、候选名词、True/False 标签,我们仅仅训练 True 标签的那部分数据,因为不知道 False 那些数据指示的名词具体是哪一个,在估计时,如果模型输出是候选名词中的一部分,就分配 True 标签。
  • 由于 WNLI 训练集和验证集与 WSC 数据重合度较高,因此不训练 WNLI 数据集。

Experiments

Baseline

使用了标准的 Transformer 框架,使用去噪目标函数进行预训练,并对下游任务进行分别微调。

  • 模型参数:
    • encoder 和 decoder 均为 12 blocks,12 heads
    • $d_{ff}=3072,d_{kv}=64,d_{model}=768$
    • 大约 220 million 参数
  • pre-training 设置:
    • 标准的极大似然,即 teacher forcing 和交叉熵损失;AdaFactor 优化器;greedy decoding
    • $2^{19}$ 步;序列长度 512;batch size 128
    • “inverse square root” 调整学习率:$1/\sqrt{\max(n,k)}$,$n$ 为当前迭代步,$k$ 为 warm-up 步
  • fine-tuning 设置:
    • $2^{18}$ 步;序列长度 512;batch size 128
    • 学习率 $0.001$
    • 每 $5000$ 步做一次验证
  • 目标函数:denoising objective。在输入句子中随机采样 15% 的 token,该 token 的连续 span 也都被一起 mask 掉,每个 mask 的位置采用一个唯一的标识符,预测目标则为该标识符后接目标 tokens,句子最终使用一个结束标识符。下图是一个具体的例子
  • baseline 结果:No pre-training 表示不使用预训练,直接在下游任务训练 $2^{18}$ 步

Architectures

Comparing different model structures

考虑了三种不同的 Transformer 结构:Encoder-Decoder,Language model 和 Prefix LM。分别对应三种不同的注意力掩码模式。Language model 和 Prefix LM 直接将输入和目标拼接起来,Prefix LM 使用了更加合理的 Causal with prefix 掩码模式,使得其对输入部分的注意力完全可见,对于目标部分 causal 可见。

为了公平的比较,需要在某种程度上使得各个参与比较的结构具有等价性。而 $L+L$ 层的 encoder-decoder 模型与 $L$ 层的 language model 计算量是几乎一致的。这是因为 language model 需要把输入和输出拼接起来,这 $L$ 层模型同时处理了输入和输出部分,而 encoder-decoder 模型则是一个处理输入、一个处理输出。文中考虑了 5 个结构:

  • Encoder-decoder: $L+L$ layers, $2P$ parameters, $M$ FLOPs1
  • Encoder-decoder: $L+L$ layers,共享 encoder 和 decoder 部分的参数,$P$ parameters, $M$ FLOPs
  • Encoder-decoder: $L/2+L/2$ layers, $P$ parameters, $M/2$ FLOPs
  • Language model: $L$ layers, $P$ parameters, $M$ FLOPs
  • Prefix LM: $L$ layers, $P$ parameters, $M$ FLOPs
1. We will use $M$ to refer to the number of FLOPs required for an $L+L$-layer encoder-decoder model or $L$-layer decoder-only model to process a given input-target pair.

Objectives

对于上述结构,使用两种目标函数:

  • basic language modeling objective:即自回归目标
    • 对于 encoder-decoder 结构和 prefix-LM 结构,先从未标记数据中采样一段文本,再对这段文本随机切分为两部分:prefix 和 target,在 target 上计算该目标函数
    • 对于标准的 LM 结构,直接从头到尾计算该目标函数
  • denoising objective:
    • 对于 prefix-LM 和 LM 结构,将输入和目标直接拼接起来

结论

  • encoder-decoder + denoising objective 效果最好
  • 参数共享策略在没有大幅损害性能的前提下减少了大约一半的参数量(与 ALBERT 结论一致)
  • denoising objective 效果总是比 language modeling objective 好

Unsupervised objectives

Disparate high-level approaches

考虑三种无监督目标的方式,分别对应表格前三行:

  • Prefix language modeling:随机找一个切分点,执行自回归目标函数
  • BERT-style:Masked language model
  • Deshuffling:乱序输入,要求复原正确的顺序


结果发现 BERT-style 效果最好。

Simplifying the BERT objective

基于上述结果,作者考虑了 BERT-style 的三个变种:

  • 去掉随机替换为某个单词的选择,只随机替换为 mask 标识符。(Table 3 第 4 行)
  • 在输入中 mask spans 为唯一标识符,连续输出 mask 掉的 spans 内容,用对应的唯一标识符分割。(即 baseline 中的目标函数,也是 Table 3 第 5 行)
  • 在输入中随机删除某些单词,依次输出删除的这些单词。(Table 3 第 6 行)

实验发现,上述三个变体性能相近。后两个变体不需要预测完整的序列,它们的目标序列更短,训练速度更快。

Varying the corruption rate

作者还探索了不同的掩码率对于效果的影响,发现使用较大的掩码率会导致目标更长,可能会减慢训练速度。根据这些结果以及 BERT 的设定,未来将继续使用 15% 的掩码率。

Corruption spans

预测更短的目标可以加快训练速度。因此考虑替换 spans 而不是独立的 tokens。实验结果发现,它们的区别不是很大,其中长度为 3 的 span 在大多数非翻译问题上略微好于 i.i.d 的结果,长度为 10 的 span 效果比较差。

结论

  • 最大的收益在于 BERT-style 的 denoising objectives
  • denoising objectives 变种之间没有很大的性能区别
  • 可以选择具有更短预测序列的目标函数,可以使得训练速度加快

Pre-training dataset

Unlabeled datasets

比较 C4 数据集与它的几个变体:

  • C4
  • Unfiltered C4
  • RealNews-like:忽略了 C4 中任何非新闻内容
  • WebText-like:提交到内容聚合网站 Reddit 且收到的 “score” 至少为 3 的网页内容
  • Wikipedia
  • Wikipedia + Toronto Books Corpus:TBC 包含从电子书中提取的文本,它代表自然语言的不同领域

通过实验以上数据集发现:

  • 未进行启发式过滤的 C4 数据集在所有任务中效果都很差
  • 在某些情况下包含了某些领域的数据集优于多样化的 C4
  • 对域内未标记的数据进行预训练可以提高下游任务的性能

Pre-training dataset size

对 C4 这样的大型数据集进行预训练可以不需要重复数据,但是尚不清楚重复数据是否对下游任务有益或有害。因此研究了更小的数据集会导致怎样的结果。Baseline 中使用 $2^{35}$ 个 tokens,现在考虑 $2^{29}$,$2^{27}$,$2^{25}$ 和 $2^{23}$ 个 tokens 大小的数据集,分别重复 64,256,1024 和 4096 次。

通过实验发现:

  • 随着数据集变小,模型性能变差。猜测原因为可能模型已经开始记住预训练数据集
  • 一定程度的重复预训练数据可能不会有害
  • 建议尽可能使用大型的预训练数据集(因为后面会看到额外的预训练可能是有益的)

Training strategy

Fine-tuning methods

之前的策略是在一个非监督任务上预训练,然后在下游的监督任务上独立的微调。

相较于在微调阶段调整所有的模型参数,考虑两种不同的微调策略:

  • adapter layers:在之前 Transformer 的基础上,在每个 block 的每个 feed-forward 层之后加上全新的 dense-ReLU-dense 层。我们只需微调这个层和 layer norm。第二个 dense 层维度被设置为匹配后面的输入,二第一个 dense 层的维度我们将考虑赋为不同的值以观察效果。
  • gradual unfreezing:随着时间的流逝,从最后一层到所有的层,越来越多的模型参数会进行微调。在 encoder-decoder 模型中,从尾到头并行的解冻 encoder 和 decoder 中的层。而输出分类矩阵和输入嵌入矩阵共享,所以整个过程它们都参与微调

通过实验发现:

  • 只要将维度适当地缩放到任务大小,adapter layers 可能是一种在较少参数量上有前途的微调方案
  • 尽管在微调过程中有一定加速作用,但 gradual unfreezing 在所有任务中造成了轻微的性能下降。

Multi-task learning

multi-task learning 是在预训练阶段对于该模型同时训练多个任务,也即该模型参数在这些任务间共享。在统一的 text-to-text 框架下,multi-task 对应着 mixing datasets。而其他 NLP 常见的做法是为多任务对应不同的分类层或者使用不同的损失函数。

我们的目标是不对模型进行 under or over-train,也就是说,希望模型从给定任务中看到足够的数据以使其能够很好地执行任务,但又不想看到太多数据以致于记住训练集。另一个问题是 task interference 和 negative transfer(ERNIE 2.0 中类似的动机)。因此下面探索各个任务不同数据比例带来的影响。

直接按照数据集比例进行采样是不可行的,因为非监督降噪任务的数据集太庞大了,以致于在数据集比较小的监督任务上 undertrain。因此采用一个人工限制来干扰这个比例:

其中,$e$ 为本身数据集的大小,$K$ 为人工数据集大小限制。

此外,还可以对 $r_m$ 进行 temperature-scaled mixing。即对每个 $r_m$ 都执行 $1/T$ 次幂,再把它们重新归一化为和为 1 的采样概率。该方法起初被用于多语言版的 BERT 来在低资源语言上得到充分训练。

对于 multi-task,直接将它训练 $2^{19}+2^{18}$ 步。通过实验发现:

  • 在大多数任务上,multi-task training 不如 pre-train then fine-tune
  • 相等概率的混合数据集会严重地损害性能

Combining multi-task learning with fine-tuning

下面考虑模型在所有的任务上预训练一次,但在监督的任务上独立的进行微调。因此,我们考虑三个变体:

  • 使用 $K=2^{19}$ 的数据混合进行多任务预训练,再在各个下游任务上独立地微调。(注:此方法与前述的 multi-task 不同,前述方法没有微调过程)这帮助我们度量在预训练阶段是否将监督任务与非监督目标一起训练可以使模型对下游任务有一些有益的早期暴露。
  • 与上一个一样使用相同的数据进行预训练,但除去将要微调的那个数据集,再在该数据集上进行微调。被称为 leave-one-out。
  • 直接对所有的下游监督任务进行 $K=2^{19}$ 的数据混合预训练然和微调。

训练和微调步长均保持与 baseline 一致为 $2^{19}$ 与 $2^{18}$。得到以下结论:

  • 多任务预训练 + 微调性能和无监督预训练 + 微调差不多
  • leave-one-out 性能仅仅轻微的变差。这说明在各种各样的任务上进行预训练仍然能够适应新任务。
  • 翻译任务从(英语的)无监督预训练中受益较少,而无监督预训练则是其他任务中的重要因素。

Scaling

The “bitter lesson” of machine learning research argues that general methods that can leverage additional computation ultimately win out against methods that rely on human expertise.

该部分解决一个问题:如果拥有了 4 倍的计算量,应该如何去使用它?

作者提出三种思路,每种思路又有不同的实现方式:

  • 训练 4 倍的原始步长。
  • batch size 变为原来的 4 倍。
  • 训练 2 倍的原始步长,并把模型变为原来的 2 倍。
  • 把模型变为原来的 4 倍。
  • $4\times$ ensemble。将 ensemble 之间的 logits 作平均输入 softmax 层以获得一个平均预测。
  • 训练一个模型,但执行 4 次单独的微调。

通过实验,增加训练时间或者模型尺寸都可以提升效果,具体的:

  • 增加模型训练时间和增加模型大小都可以提升性能
  • ensemble 提供了一种 orthogonal2 的手段来提升模型性能
  • 预训练一个模型,但在 fine-tuning 阶段进行 ensemble 也能提升性能,而且代价更小。
  • 在选择 scaling 方法时要考虑模型的最终用途。因为较大模型较短步长、较小模型较大步长、集成模型等对于下游的微调和推断来说代价是不同的。
2. 这里可以理解为这些 ensemble 的模型是独立的。优点就是任何时候训练的模型都可以,不论尺寸不论步长等。

Putting it all together

做了以上的大量研究,现在将成果汇总到一起得出 T5 的预训练模型。基于 baseline 做出以下改进:

  • Objective。使用平均 span 长度为 3 ,掩码率为 15% 的 span corruption 目标。
  • Longer training。使用 C4 数据集预训练 1 million 步,$2^{11}$ batch size,句子长度为 512,总共大约 1 trillion tokens。
  • Model sizes。
$d_{model}$ $d_{ff}$ $d_{kv}$ heads layers params
Small 512 2048 64 8 6 60 million
Base 768 3072 64 12 12 220 million
Large 1024 4096 64 16 12 770 million
3B 1024 16384 128 32 24 2.8 billion
11B 1024 65536 128 128 24 11 billion
  • Multi-task pre-training。对每个大小的模型使用不同大小的数据集,再使用 example-proportional mixing 得到多任务的数据集,并对于翻译任务的数据集大小做了适当限制。
  • Fine-tuning on individual GLUE and SuperGLUE tasks。对 benchmark 的各个任务单独 fine-tune 可以小幅提升模型性能。为了不在某些 low-resource 任务上过拟合,在 fine-tuning 阶段选择更小的 batch size 为 8,每 1000 步做一次验证。也执行了统一的一次性微调。最终对于每个人物选择统一微调和单独微调中验证效果最好的结果。
  • Beam search。对于长输出的句子,使用 beam search 可以提升效果。
  • Test set。使用标准的 test set 报道结果(除 SQuAD 之外)。

最终,T5 在 24 个任务中的 17 个上达到了 SOTA。

Reflection

Takeaways

把前面实验的各个部分得到的最重要的结论总结如下:

  1. Text-to-text。可以使用相同的损失函数和解码程序在各种文本任务上训练一个模型。
  2. Architectures。原始的 encoder-decoder 在 text-to-text 框架下表现最好。共享参数策略并没有使得模型性能大幅下降。
  3. Unsupervised objectives。大多数 denoising 目标在 text-to-text 框架下效果相似,因此建议使用产生较短目标序列的目标函数,可以使得训练更快。
  4. Datasets。对域内未标记数据的训练可以提高一些下游任务的性能,但是当一个小数据集重复多次时效果会下降。使用较大型的丰富数据集(如 C4)来做通用的语言理解任务比较好。
  5. Training strategies。在 fine-tuning 阶段更新所有参数比更新部分参数效果好。没有一种混合样本比例策略的多任务训练与先非监督预训练后微调有可比性,但是在多任务预训练之后进行微调与非监督预训练行性能相近。
  6. Scaling。数据、模型大小、是否集成都可以带来模型的效果增长。其中,在更多的数据上训练一个小模型比在小数据上训练一个大模型好。

Outlook

未来工作中一些可能有效的方向:

  1. The inconvenience of large models。更大的模型一般会得到更好的结果,但是由于资源和场景限制,使用较小的开销实现强大的性能也是重要的研究方向,如 distillation、parameter sharing 和 conditional computation。
  2. More efficient knowledge extraction。denoising objective 不一定是一个非常有效的教模型学习自然语言知识的方法,如果有一种方法能够不需要线训练模型很多很多步就能够实现很好的微调效果,那么将很有用。
  3. Formalizing the similarity between tasks。之前看到,对未标记的域内数据进行预训练可以提高下游任务的性能。定义一个更严格的预训练和下游任务之间的相似度是非常有用的,可以帮助我们选择更有效的数据源。
  4. Language-agnostic models。无论文本的语言是什么,模型能够实现很好的性能。

参考

Google AI Blog:Exploring Transfer Learning with T5: the Text-To-Text Transfer Transformer
官方代码:https://github.com/google-research/text-to-text-transfer-transformer
https://zhuanlan.zhihu.com/p/89719631