GLM(一) -- 论文翻译:《GLM: General Language Model Pretraining with Autoregressive Blank Infilling》

摘要

  目前已存在各种预训练结构,包括自编码模型(例如BERT)、自回归模型(例如GPT)和编码器-解码器模型(例如T5)。然而,对于涵盖自然语言理解(NLU)、无条件生成和有条件生成等三个主要任务类别的所有任务,目前没有一种预训练框架能够表现最佳。为解决这个问题,我们提出了一种基于自回归空白填充的通用语言模型(GLM)。GLM通过增加二维位置编码和允许任意顺序预测跨度来改进空白填充预训练,从而在NLU任务上表现出超越BERT和T5的性能。

1 引言

  在未标注文本上预训练的语言模型在各种自然语言处理任务中都取得了显著的进展,包括自然语言理解(NLU)和文本生成(Radford et al., 2018a; Devlin et al., 2019; Yang et al., 2019; Radford et al., 2018b; Raffel et al., 2020; Lewis et al., 2019; Brown et al., 2020)。在过去几年中,下游任务的表现以及参数规模也不断增加。

图1

图1:GLM图解。我们扣除了一段文本(绿色部分),并使用自回归的方法生成它们。(图中省略了一些注意的边;参见图2。)

  一般来说,现有的预训练框架可以分为三个类别:自回归模型、自编码模型和编码-解码模型。自回归模型,例如GPT (Radford et al., 2018a),学习从左到右的语言模型。尽管当规模扩大到数十亿个参数时,它们在长文本生成和少样本学习能力方面取得了成功(Radford et al., 2018b; Brown et al., 2020),但其固有的缺点是单向注意机制无法充分捕捉NLU任务中上下文单词之间的依赖关系。

  自编码模型,例如BERT (Devlin et al., 2019),通过去噪目标,如遮蔽语言模型(MLM),学习双向上下文编码器。编码器生成适用于自然语言理解任务的上下文化表示,但不能直接应用于文本生成。编码-解码模型采用了编码器的双向注意力、解码器的单向注意力以及它们之间的交叉注意力(Song et al., 2019; Bi et al., 2020; Lewis et al., 2019)。它们通常用于条件生成任务,如文本摘要和回复生成。T5 (Raffel et al., 2020)通过编码-解码模型统一了NLU和条件生成,但需要更多的参数来达到BRET-based模型(RoBERTa (Liu et al., 2019)和DeBERTa (He et al., 2021))的性能。

  这些预训练框架都不足以在所有NLP任务中具有竞争力的灵活性。之前的工作尝试通过多任务学习(Dong et al., 2019; Bao et al., 2020)将它们的目标结合起来,试图统一不同的框架。然而,由于自编码和自回归目标本质上不同,简单的统一不能完全继承两个框架的优点。

  在这篇论文中,我们提出了一种基于自回归空白填充的预训练框架GLM(General Language Model)。我们从输入文本中随机剔除连续跨度的token,按照自编码的思想进行训练,并按照自回归预训练的思想,依次重构范围(参见图1)。虽然在T5(Raffel et al.,2020)中已经使用了空白填充进行文本到文本预训练,但我们提出了两个改进,即span shuffling和二维位置编码。实验证明,GLM在参数量和计算成本相同的情况下,在SuperGLUE基准测试中的表现明显优于BERT,差距为4.6%-5.0%,且在相似规模(158GB)的语料库上进行预训练时,优于RoBERTa和BART。GLM还使用更少的参数和数据,在NLU和生成任务上明显优于T5。

  受Pattern-Exploiting Training(PET)(Schick和Schütze,2020a)的启发,我们将NLU任务重新表述为模仿人类语言的手动完形填空问题。与PET使用的基于BERT的模型不同,GLM可以通过自回归空白填充从自然地处理填空问题的角度处理多个token的答案。

  此外,我们还展示了通过变化缺失范围的数量和长度,自回归填空目标可以预训练语言模型进行有条件和无条件生成。通过多任务学习不同的预训练目标,单个GLM可以在NLU和(有条件和无条件)文本生成方面表现出色。实证结果表明,与独立基线相比,具有多任务预训练的GLM通过参数共享在NLU、条件文本生成和语言建模任务中都取得了改善。

2 GLM 预训练框架

  我们提出了一个基于新型自回归空白填充目标的通用预训练框架GLM。GLM将NLU任务构建为包含任务描述的填空问题,可以通过自回归生成回答。

2.1 预训练目标

2.1.1 自回归空白填充

   GLM通过优化自回归空白填充目标进行训练。给定输入文本 x = [ x 1 , ⋅ ⋅ ⋅ , x n ] x = [x_1, · · · , x_n] x=[x1,⋅⋅⋅,xn],我们随机采样多个span s 1 , ⋅ ⋅ ⋅ , s m {s_1, · · · , s_m} s1,⋅⋅⋅,sm,其中每个span s i s_i si对应 x x x中一系列连续的标记 [ s i , 1 , ⋅ ⋅ ⋅ , s i , l i ] [s_{i,1}, · · · , s_{i,l_i}] [si,1,⋅⋅⋅,si,li]。我们用单个[MASK]标记替换每个span,形成破损的文本 x c o r r u p t x_{corrupt} xcorrupt。模型通过自回归方式从破损的文本中预测span中缺失的token,这意味着在预测span中的缺失token时,模型可以访问破损的文本和先前预测的span。为了完全捕捉不同span之间的相互依赖关系,我们随机排列span的顺序,类似于置换语言模型(Yang et al.,2019)。具体而言,令 Z m Z_m Zm为长度为 m m m的索引序列 [ 1 , 2 , ⋅ ⋅ ⋅ , m ] [1, 2, · · · , m] [1,2,⋅⋅⋅,m]的所有可能排列的集合, s z < i s_{z<i} sz<i [ s z 1 , ⋅ ⋅ ⋅ , s z i − 1 ] [s_{z1}, · · · , s_{z_i−1}] [sz1,⋅⋅⋅,szi1],我们定义预训练目标为

max ⁡ θ E z ∼ Z m [ ∑ i = 1 m l o g p θ ( s z i ∣ x c o r r u p t , s z < i ) ] \begin{equation} \max_\theta\mathbb{E}_{z \sim Z_m} \begin{bmatrix} \sum^m_{i=1} logp_{\theta}(s_{z_i} | x_{corrupt},s_{z<i}) \end{bmatrix} \end{equation} θmaxEzZm[i=1mlogpθ(szixcorrupt,sz<i)]

  我们总是按照从左到右的顺序生成每个空白内的标记,即生成span s i s_i si的概率分解为
p θ ( s i ∣ x c o r r u p t , s z < i ) = ∏ i = 1 l i p ( s i , j ∣ x c o r r u p t , s z < i , s i , < j ) \begin{equation} p_{\theta} (s_i | x_{corrupt},s_{z<i} ) =\prod^{l_i}_{i=1}p(s_{i,j}|x_{corrupt},s_{z<i},s_{i,<j}) \end{equation} pθ(sixcorrupt,sz<i)=i=1lip(si,jxcorrupt,sz<i,si,<j)
  我们使用以下技术实现自回归空白填充目标。输入 x x x分为两部分:A部分是破损的文本 x c o r r u p t x_{corrupt} xcorrupt,B部分由被遮蔽的span组成。A部分的token可以相互看到,但不能看到B部分中的任何token。B部分的token可以看到A部分和B部分中的前序token,但不能看到B部分中的后续token。为了实现自回归生成,每个span都用特殊的token [START]和[END]进行填充,用于输入和输出。通过这种方式,我们的模型在一个统一的模型中自动学习了双向编码器(用于A部分)和单向解码器(用于B部分)。GLM的实现示意图如图2所示。
在这里插入图片描述

图 2:GLM 预训练。 (a) 原始文本为[x1,x2,x3,x4,x5,x6]。采样了两个span [x3] 和 [x5, x6]。 (b) 在 Part A 中将采样到的span替换为 [M],在 Part B 中打乱span的顺序。 (c) GLM 自回归生成 Part B。每个span以 [S] 作为输入,以 [E] 作为输出。2D 位置编码表达span内和span间的位置。 (d) 自注意力掩码,灰色区域被遮蔽部分。Part A 的token可以看到自身(蓝色框),但不能看到 B。Part B 的token可以看到 A 及其在 B 中的前驱(黄色和绿色框分别对应两个span)。[M] := [MASK],[S] := [START],[E] := [END]。

  我们通过泊松分布(λ = 3)随机采样长度为m的范围。我们重复采样新的范围,直到至少有15%的原始标记被遮蔽。实证结果表明,15%的比例对下游NLU任务的性能表现至关重要。

2.1.2 多任务预训练

  在前一节中,GLM掩盖了短的span,并适用于NLU任务。然而,我们的兴趣在于预训练一个能够处理NLU和文本生成的单一模型。因此,我们研究了一个多任务预训练设置,在该设置中,生成更长的文本的第二个目标与填空目标联合优化。我们考虑了以下两个目标:

  • 文档级别。我们随机采样一个span,其长度从原始长度的50%到100%之间均匀分布。该目标的目的是生成较长的文本。
  • 句子级别。我们限制被掩盖的跨度必须是完整的句子。多个跨度(句子)被采样以覆盖原始标记的15%。该目标适用于序列到序列任务,其预测通常是完整的句子或段落。

这两个新目标的定义方式与原始目标相同,即公式(1)。唯一的区别在于跨度的数量和跨度的长度。

2.2 模型架构

  GLM 使用单个 Transformer,并对架构进行了多项修改:(1)我们重新排列了层归一化和残差连接的顺序,这已被证明对于大规模语言模型避免数值错误至关重要(Shoeybi 等人 2019); (2)我们使用单个线性层进行输出标记预测; (3) 我们用 GeLU 替换 ReLU 激活函数(Hendrycks 和 Gimpel,2016)。

2.2.1 二维位置编码

  自回归的填空任务面临的一个挑战是如何编码位置信息。Transformer依赖于位置编码来注入token的绝对和相对位置。我们提出了二维位置编码来解决这个挑战。具体来说,每个token都用两个位置ID进行编码。第一个位置ID表示损坏文本 x c o r r u p t x_{corrupt} xcorrupt中的位置。对于被掩盖的span,它是相应的[MASK] token 的位置。第二个位置ID表示跨度内的位置。对于第A部分中的标记,它们的第二个位置ID为0。对于第B部分中的标记,它们的第二个位置ID范围从1到跨度的长度。这两个位置ID通过可学习的embedding tables投影为两个向量,然后将它们添加到输入token 的 embedding 中。
在这里插入图片描述


图 3:将情感分类任务表述为用 GLM 填充空白。

  我们的编码方法确保了在重构被掩盖的span时,模型不知道span的长度。这与其他模型有重要区别。例如,XLNet(Yang等,2019)编码了原始位置,以便感知缺失标记的数量,而SpanBERT(Joshi等,2020)用多个[MASK]标记替换了span并保持长度不变。我们的设计适合下游任务,因为通常生成的文本的长度事先未知。

2.3 微调GLM

  通常情况下,对于下游NLU任务,一个线性分类器将预训练模型生成的序列或token的表示作为输入,并预测正确的标签。这些做法与生成式预训练任务不同,导致预训练和微调之间的不一致性。因此,我们按照PET(Schick和Schütze,2020a)的方法,将NLU分类任务重新制定为填空生成任务。具体来说,给定一个标记示例 ( x , y ) (x, y) (x,y),我们通过包含单个掩码token的模式将输入文本 x x x 转换为完形填空问题 c ( x ) c(x) c(x)。该模式用自然语言编写,表示任务的语义。例如,情感分类任务可以表示为“{SENTENCE}。它真的很[MASK]”。候选标签 y ∈ Y y\in \mathcal Y yY也被映射为填空的答案,称为verbaler v ( y ) v(y) v(y)。在情感分类中,标签“positive”和“negative”被映射为单词“good”和“bad”。根据给定 x x x预测 y y y的条件概率为
p ( y ∣ x ) = p ( v ( y ) ∣ c ( x ) ) Σ y ′ ∈ Y p ( v ( y ′ ) ∣ c ( x ) ) p(y|x) = \frac{p(v(y)|c(x))} {\Sigma_{y^′ \in \mathcal Y} p(v(y^′)|c(x))} p(yx)=ΣyYp(v(y)c(x))p(v(y)c(x)),其中 Y \mathcal Y Y是标签集。因此,句子为正或负的概率与在空白处预测“good”或“bad”成正比。然后,我们使用交叉熵损失微调GLM(见图3)。

  对于文本生成任务,给定上下文构成输入的A部分,在末尾附加一个MASK标记。模型自回归地生成B部分的文本。我们可以直接应用预训练的GLM进行无条件生成,或者在下游有条件生成任务上对其进行微调。

2.4 讨论和分析

  在本节中,我们讨论了GLM与其他预训练模型之间的区别。我们主要关注它们如何适应下游填空生成任务。

  与BERT (Devlin et al., 2019) 的比较。 正如(Yang et al., 2019)所指出的,由于MLM的独立假设,BERT无法捕捉到掩码标记之间的相互依赖关系。BERT的另一个缺点是不能正确地填充多个标记的空白。为了推断长度为l的答案的概率,BERT需要执行l个连续预测。如果长度l未知,我们可能需要列举所有可能的长度,因为BERT需要根据长度改变[MASK]标记的数量。

  与XLNet (Yang et al., 2019) 的比较。 GLM和XLNet都是使用自回归目标进行预训练,但它们之间存在两个差异。首先,XLNet在破坏之前使用原始的位置编码。在推理过程中,我们需要知道或列举答案的长度,与BERT面临相同的问题。其次,XLNet使用双流自注意机制,而不是右移操作,以避免Transformer内的信息泄漏。这使得预训练的时间成本翻倍。

  与T5 (Raffel et al., 2020) 的比较。 T5提出了类似的填空目标来预训练编码器-解码器Transformer。T5对编码器和解码器使用独立的位置编码,并依赖于多个占位符token来区分隐藏的区域。在下游任务中,只使用其中一个占位符标记,导致模型容量的浪费和预训练与微调之间的不一致性。此外,T5总是按照固定的从左到右的顺序预测区域。因此,GLM在更少的参数和数据情况下,在NLU和seq2seq任务上与T5相比表现出更好的性能,如第3.2节和第3.3节所述。

  与UniLM (Dong et al., 2019) 的比较。 UniLM通过在双向、单向和交叉注意力之间改变注意力掩码,将不同的预训练目标结合到自编码框架中。然而,UniLM总是用[MASK] token替换掉隐藏的区域,限制了其对隐藏区域及其上下文之间依赖关系的建模能力。GLM引入了前一个token并自回归生成下一个标记。将UniLM微调用于下游生成任务还依赖于掩码语言模型,这种方式不够高效。UniLMv2 (Bao et al., 2020) 采用部分自回归模型来进行生成任务,并使用自动编码目标进行NLU任务。相比之下,GLM通过自回归预训练统一了NLU和生成任务。

3 实验

我们现在描述我们的预训练设置和下游任务的评估。

3.1 预训练设置

  为了与 BERT (Devlin et al., 2019) 进行公平比较,我们使用 BooksCorpus (Zhu et al., 2015) 和英语维基百科作为我们的预训练数据。 我们使用 BERT 的 uncased wordpiece tokenizer,拥有 30k 词汇量。 我们使用与 BERTBase 和 BETLarge 相同的架构来训练 GLMBase 和 GLMLarge,分别包含 110M 和 340M 参数。

  对于多任务预训练,我们训练了两个大型模型,其中混合了空白填充目标和文档级或句子级目标,表示为 GLMDoc 和 GLMSent。 此外,我们还通过文档级多任务预训练训练了两个较大的 GLM 模型,其参数为 410M(30 层,隐藏层大小为 1024 、16 个注意力头)和 515M(30 层,隐藏层大小为 1152 、18 个注意力头)参数, 表示为GLM410M和GLM515M。

  为了与 SOTA 模型进行比较,我们还训练了一个具有与 RoBERTa 相同的数据、标记化和超参数的大型模型(Liu et al., 2019),表示为 GLMRoBERTa。 由于资源限制,我们只预训练了 250,000 步的模型,这是 RoBERTa 和 BART 训练步数的一半,并且在训练的 token 数量上接近 T5。 更多实验细节可以在附录 A 中找到。

3.2 SuperGLUE

  为了评估我们预训练的 GLM 模型,我们在 SuperGLUE 基准(Wang 等人,2019)上进行实验并给出了标准指标。 SuperGLUE 包含 8 个具有挑战性的 NLU 任务。 我们遵循 PET,将分类任务重新表述为用人工设计的完形填空问题填充空白(Schick 和 Schütze,2020b)。 然后我们对每个任务的预训练 GLM 模型进行微调,如第 2.3 节所述。 完形填空题和其他详细信息可以在附录 B.1 中找到。

  为了与 GLMBase 和 GLMLarge 进行公平比较,我们选择 BERTBase 和 BETLarge 作为基线,它们在相同的语料库上进行了相似的预训练。 我们给出了标准微调的性能(即 [CLS] token表示的分类)。 3.4 节给出了 BERT 在完形填空问题上的表现。 为了与 GLMRoBERTa 进行比较,我们选择 T5、BARTLarge 和 RoBERTaLarge 作为基线。 T5 在参数数量上与 BERTLarge 没有直接匹配,因此我们展示了 T5Base(220M 参数)和 T5Large(770M 参数)的结果。 所有其他基线的大小与 BERTLarge 相似。

  结果如表1所示。 在相同数量的训练数据下,无论是基础架构还是大型架构,GLM 在大多数任务上始终优于 BERT。 唯一的例外是 WiC(词义消歧)。 平均而言,GLMBase 的得分比 BERTBase 高 4.6%,GLMLarge 的得分比 BERTLarge 高 5.0%。 它清楚地展示了我们的方法在 NLU 任务中的优势。 在 RoBERTaLarge 的设置中,GLMRoBERTa 仍然可以实现相对于基线的改进,但幅度较小。 具体来说,GLMRoBERTa 的性能优于 T5Large,但大小仅为 T5Large 的一半。 我们还发现 BART 在具有挑战性的 SuperGLUE 基准测试中表现不佳。 我们推测这可以归因于编码器-解码器架构和去噪序列到序列目标的低参数效率。

表 1:SuperGLUE 开发集的结果。

在这里插入图片描述

表 2:CNN/DailyMail 和 XSum 测试集上的摘要生成结果。

在这里插入图片描述

3.3 多任务预训练

  然后我们在多任务设置下评估GLM的性能(见第2.1节)。在一个训练批次内,我们以相等的概率选择短跨度和长跨度(文档级或句子级)。我们评估多任务模型在NLU、seq2seq、填空问题和零样本语言建模中的性能。

  SuperGLUE。 对于NLU任务,我们在SuperGLUE基准测试上评估模型。表1中也显示了这些结果。我们观察到,在多任务预训练的情况下,GLMDoc和GLMSent的性能略低于GLMLarge,但仍然优于BERTLarge和UniLMLarge。在多任务模型中,GLMSent的性能平均上优于GLMDoc 1.1%。将GLMDoc的参数增加到410M(BERTLarge的1.25倍)可以实现比GLMLarge更好的性能。GLM在515M参数(BERTLarge的1.5倍)的情况下,性能进一步提升。

  序列到序列。 考虑到现有的基线结果,我们使用Gigaword数据集进行抽象摘要(Rush et al。,2015),使用SQuAD 1.1数据集(Rajpurkar et al。,2016)进行问题生成(Du et al。,2017)作为模型在BookCorpus和Wikipedia上预训练的基准。另外,我们使用CNN/DailyMail(See et al。,2017)和XSum(Narayan et al。,2018)数据集作为在更大的语料库上预训练模型的基准,用于抽象摘要。

  在BookCorpus和Wikipedia上训练的模型结果如表格3和4所示。我们观察到,GLMLarge在两个生成任务上能够达到与其他预训练模型相媲美的性能。GLMSent的表现比GLMLarge更好,而GLMDoc的表现略差于GLMLarge。这表明,文档级目标教导模型扩展给定上下文的能力对于条件生成并不太有帮助,而条件生成的目标是从上下文中提取有用的信息。将GLMDoc的参数增加到410M可以在两个任务上获得最佳性能。在更大的语料库上训练的模型结果如表2所示。GLMRoBERTa可以达到与seq2seq BART模型相当的性能,并且胜过T5和UniLMv2。

  文本填充。 文本填充是预测与上下文一致的缺失文本部分的任务(Zhu等,2019;Donahue等,2020;Shen等,2020)。GLM通过自回归的空白填充目标进行训练,因此可以直接解决这个任务。我们在Yahoo Answers数据集(Yang等,2017)上评估了GLM,并将其与专门设计用于文本填充的Blank Language Model(BLM)(Shen等,2020)进行比较。从表5的结果可以看出,GLM在这个数据集上以较大的差距(1.3到3.9 BLEU)胜过以前的方法,并实现了最先进的结果。我们注意到GLMDoc的性能略低于GLMLarge,这与我们在seq2seq实验中的观察结果一致。

表 3:Gigaword 摘要结果。

在这里插入图片描述

表 4:SQuAD 问题生成的结果。

在这里插入图片描述

表 5:雅虎文本填充的 BLEU 分数。

在这里插入图片描述
  语言建模。 大多数语言建模的数据集,如WikiText103,是从维基百科文档中构建的,而这些文档已经包含在我们的预训练数据集中。因此,我们在预训练数据集中的一个保留测试集(包含约20M个token)上评估语言建模困惑度,该测试集称为BookWiki。我们还在LAMBADA数据集(Paperno等,2016)上评估了GLM,该数据集测试系统对文本中的长距离依赖关系的建模能力。任务是预测段落的最后一个词。作为基线,我们使用与GLMLarge相同的数据和分词方式训练了一个GPTLarge模型(Radford等,2018b;Brown等,2020)。

在这里插入图片描述

图 4:零样本语言建模结果。

  结果如图4所示。所有模型都是在零样本设置下评估的。由于GLM学习了双向注意力,我们还在上下文使用双向注意力编码的设置下评估了GLM。在预训练期间没有生成目标的情况下,GLMLarge无法完成语言建模任务,困惑度超过100。在相同数量参数的情况下,GLMDoc的表现比GPTLarge差。这是预期的,因为GLMDoc还优化了空白填充目标。将模型的参数增加到410M(GPTLarge的1.25倍)可以获得与GPTLarge接近的性能。GLM515M(GPTLarge的1.5倍)进一步超越GPTLarge。在相同数量参数的情况下,使用双向注意力编码上下文可以提高语言建模的性能。在这个设置下,GLM410M胜过GPTLarge。这是GLM相对于单向GPT的优势。我们还研究了二维位置编码在长文本生成中的贡献。我们发现,删除二维位置编码的第二维会降低语言建模的准确性及增大困惑度。

表 6:SuperGLUE 开发集的消融研究。 (T5 ≈ GLM – shuffle spans + sentinel tokens.)

在这里插入图片描述

总结。 总之,我们得出结论,GLM能够有效地在自然语言理解和生成任务中共享模型参数,并且比独立的BERT、编码-解码器或GPT模型获得更好的性能。

3.4消融研究。

  表6显示了我们对GLM进行的消融分析。首先,为了与BERT进行对照比较,我们使用我们的实现、数据和超参数训练了一个BERTLarge模型(第2行)。性能略低于官方的BERTLarge,且明显低于GLMLarge。这证实了GLM相对于NLU任务上的Masked LM预训练的优越性。其次,我们展示了GLM在作为序列分类器进行微调的SuperGLUE性能(第5行)以及使用填空样式进行微调的BERT(第3行)。与使用填空样式进行微调的BERT相比,GLM受益于自回归预训练。特别是在ReCoRD和WSC上,其中verbalizer由多个标记组成,GLM始终优于BERT。这证明了GLM在处理长度可变的空白时的优势。另一个观察结果是,对于GLM在NLU任务上的表现,填空形式对其性能至关重要。对于大模型,填空样式微调可以提高性能7个点。最后,我们比较了具有不同预训练设计的GLM变体以了解它们的重要性。第6行显示删除跨度调整(总是从左到右预测被遮盖的跨度)导致SuperGLUE上性能严重下降。第7行使用不同的标志性标记代替单个[MASK]标记来表示不同的被遮盖跨度。该模型的表现比标准GLM更差。我们推测这是因为它浪费了一些建模能力来学习不在下游任务中使用的不同标志性标记。在图4中,我们展示了删除二维位置编码的第二维会影响长文本生成的性能。

  我们注意到T5是使用类似的空白填充目标进行预训练的。GLM在三个方面与之不同:(1) GLM只有一个编码器,(2) GLM对被遮蔽的跨度进行重排,(3) GLM使用单个[MASK]而不是多个标志符。虽然由于训练数据和参数数量的不同,我们无法直接将GLM与T5进行比较,但表1和表6的结果已经证明了GLM的优势。

4 相关工作

  预训练语言模型。大规模预训练语言模型显著提高了下游任务的性能。预训练模型可分为三类。第一类是自编码模型,通过去噪目标学习自然语言理解的双向上下文编码器 (Devlin et al., 2019; Joshi et al., 2020; Yang et al., 2019; Liu et al., 2019; Lan et al., 2020; Clark et al., 2020)。第二类是自回归模型,采用从左到右的语言建模目标进行训练 (Radford et al., 2018a,b; Brown et al., 2020)。第三类是编码器-解码器模型,针对序列到序列任务进行预训练 (Song et al., 2019; Lewis et al., 2019; Bi et al., 2020; Zhang et al., 2020)。

  在编码器-解码器模型中,BART (Lewis et al., 2019) 通过将相同的输入送入编码器和解码器,并提取解码器的最终隐藏状态来进行NLU任务。相反,T5 (Raffel et al., 2020) 将大部分语言任务都纳入了文本到文本的框架中。然而,这两个模型需要更多的参数才能超越 RoBERTa (Liu et al., 2019)等自编码模型。UniLM (Dong et al., 2019; Bao et al., 2020) 则统一了三种预训练模型,使用不同的注意力遮罩进行了掩码语言建模目标的训练。

  NLU作为生成任务。之前的预训练语言模型通过线性分类器在学习到的表示上完成NLU的分类任务。GPT-2 (Radford et al., 2018b) 和 GPT-3 (Brown et al., 2020) 的研究表明,生成型语言模型可以直接预测正确答案来完成诸如问答之类的NLU任务,而无需微调或者给出任务指令或一些标注样例。然而,生成型模型由于单向注意力的限制,需要更多的参数才能正常工作。最近,PET (Schick and Schütze, 2020a,b) 提出在少样本场景下,将输入样例重新表示成与预训练语料相似的填空问题,并与基于梯度微调相结合,取得了优于GPT-3的性能,同时只需其0.1%的参数量。类似地,Athiwaratkun et al. (2020) 和 Paolini et al. (2020) 将结构化的预测任务,如序列标注和关系抽取,转化为序列生成任务。Blank 语言建模。Donahue et al. (2020) 和 Shen et al. (2020) 也研究了填充填充模型。与他们的工作不同的是,我们使用填充填充目标预训练语言模型,并评估其在下游NLU和生成任务中的性能。

5 结论

  GLM是一个通用的自然语言理解和生成的预训练框架。我们证明了NLU任务可以被转化为条件生成任务,因此可以通过自回归模型来解决。GLM将不同任务的预训练目标统一为自回归填充填充,并使用混合注意力遮罩和新颖的2D位置编码。实证结果表明,GLM在NLU任务上优于先前方法,并且可以有效地共享参数用于不同任务。

致谢 …

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
***请支持开源*** 汇编大师Richard Blum的经典AT&T汇编教程英文原版(没有中文版) 下面是书中的介绍 Introduction Assembly language is one of the most misunderstood programming languages in use. When the term assembly language is used, it often invokes the idea of low-level bit shuffling and poring over thousand- page instruction manuals looking for the proper instruction format. With the proliferation of fancy high- level language development tools, it is not uncommon to see the phrase “assembly language programming is dead” pop up among various programming newsgroups. However, assembly language programming is far from dead. Every high-level language program must be compiled into assembly language before it can be linked into an executable program. For the high- level language programmer, understanding how the compiler generates the assembly language code can be a great benefit, both for directly writing routines in assembly language and for understanding how the high-level language routines are converted to assembly language by the compiler. Who This Book Is For The primary purpose of this book is to teach high-level language programmers how their programs are converted to assembly language, and how the generated assembly language code can be tweaked. That said, the main audience for this book is programmers already familiar with a high-level language, such as C, C++, or even Java. This book does not spend much time teaching basic programming principles. It assumes that you are already familiar with the basics of computer programming, and are interested in learning assembly language to understand what is happening underneath the hood. However, if you are new to programming and are looking at assembly language programming as a place to start, this book does not totally ignore you. It is possible to follow along in the chapters from the start to the finish and obtain a basic knowledge of how assembly language programming (and programming in general) works. Each of the topics presented includes example code that demonstrates how the assem- bly language instructions work. If you are completely new to programming, I recommend that you also obtain a good introductory text to programming to round out your education on the topic. What This Book Covers The main purpose of this book is to familiarize C and C++ programmers with assembly language, show how compilers create assembly language routines from C and C++ programs, and show how the gener- ated assembly language routines can be spruced up to increase the performance of an application. All high-level language programs (such as C and C++) are converted to assembly language by the com- piler before being linked into an executable program. The compiler uses specific rules defined by the cre- ator of the compiler to determine exactly how the high-level language statements are converted. Many programmers just write their high-level language programs and assume the compiler is creating the proper executable code to implement the program. Introduction However, this is not always the case. When the compiler converts the high-level language code state- ments into assembly language code, quirks and oddities often pop up. In addition, the compiler is often written to follow the conversion rules so specifically that it does not recognize time-saving shortcuts that can be made in the final assembly language code, or it is unable to compensate for poorly written high- level routines. This is where knowledge of assembly language code can come in handy. This book shows that by examining the assembly language code generated by the compiler before link- ing it into an executable program, you can often find places where the code can be modified to increase performance or provide additional functionality. The book also helps you understand how your high- level language routines are affected by the compiler’s conversion process. How This Book Is Structured The book is divided into three sections. The first section covers the basics of the assembly language programming environment. Because assembly language programming differs among processors and assemblers, a common platform had to be chosen. This book uses the popular Linux operating system, running on the Intel family of processors. The Linux environment provides a wealth of program devel- oper tools, such as an optimizing compiler, an assembler, a linker, and a debugger, all at little or no charge. This wealth of development tools in the Linux environment makes it the perfect setting for dissecting C programs into assembly language code. The chapters in the first section are as follows: Chapter 1, “What Is Assembly Language?” starts the section off by ensuring that you understand exactly what assembly language is and how it fits into the programming model. It debunks some of the myths of assembly language, and provides a basis for understanding how to use assembly language with high- level languages. Chapter 2, “The IA-32 Platform,” provides a brief introduction to the Intel Pentium family of processors. When working with assembly language, it is important that you understand the underlying processor and how it handles programs. While this chapter is not intended to be an in-depth analysis of the opera- tion of the IA-32 platform, it does present the hardware and operations involved with programming for that platform. Chapter 3, “The Tools of the Trade,” presents the Linux open-source development tools that are used throughout the book. The GNU compiler, assembler, linker, and debugger are used in the book for com- piling, assembling, linking, and debugging the programs. Chapter 4, “A Sample Assembly Language Program,” demonstrates how to use the GNU tools on a Linux system to create, assemble, link, and debug a simple assembly language program. It also shows how to use C library functions within assembly language programs on Linux systems to add extra fea- tures to your assembly language applications. The second section of the book dives into the basics of assembly language programming. Before you can start to analyze the assembly language code generated by the compiler, you must understand the assem- bly language instructions. The chapters in this section are as follows: xxiv Introduction Chapter 5, “Moving Data,” shows how data elements are moved in assembly language programs. The concepts of registers, memory locations, and the stack are presented, and examples are shown for mov- ing data between them. Chapter 6, “Controlling Execution Flow,” describes the branching instructions used in assembly lan- guage programs. Possibly one of the most important features of programs, the ability to recognize branches and optimize branches is crucial to increasing the performance of an application. Chapter 7, “Using Numbers,” discusses how different number data types are used in assembly lan- guage. Being able to properly handle integers and floating-point values is important within the assembly language program. Chapter 8, “Basic Math Functions,” shows how assembly language instructions are used to perform the basic math functions such as addition, subtraction, multiplication, and division. While these are gener- ally straightforward functions, subtle tricks can often be used to increase performance in this area. Chapter 9, “Advanced Math Functions,” discusses the IA-32 Floating Point Unit (FPU), and how it is used to handle complex floating-point arithmetic. Floating-point arithmetic is often a crucial element to data processing programs, and knowing how it works greatly benefits high-level language programmers. Chapter 10, “Working with Strings,” presents the various assembly language string-handling instruc- tions. Character data is another important facet of high-level language programming. Understanding how the assembly language level handles strings can provide insights when working with strings in high-level languages. Chapter 11, “Using Functions,” begins the journey into the depths of assembly language programming. Creating assembly language functions to perform routines is at the core of assembly language optimiza- tion. It is good to know the basics of assembly language functions, as they are often used by the compiler when generating the assembly language code from high-level language code. Chapter 12, “Using Linux System Calls,” completes this section by showing how many high-level func- tions can be performed in assembly language using already created functions. The Linux system pro- vides many high-level functions, such as writing to the display. Often, you can utilize these functions within your assembly language program. The last section of the book presents more advanced assembly language topics. Because the main topic of this book is how to incorporate assembly language routines in your C or C++ code, the first few chapters show just how this is done. The remaining chapters present some more advanced topics to round out your education on assembly language programming. The chapters in this section include the following: Chapter 13, “Using Inline Assembly,” shows how to incorporate assembly language routines directly in your C or C++ language programs. Inline assembly language is often used for “hard-coding” quick rou- tines in the C program to ensure that the compiler generates the appropriate assembly language code for the routine. Chapter 14, “Calling Assembly Libraries,” demonstrates how assembly language functions can be com- bined into libraries that can be used in multiple applications (both assembly language and high-level language). It is a great time-saving feature to be able to combine frequently used functions into a single library that can be called by C or C++ programs. xxv Introduction Chapter 15, “Optimizing Routines,” discusses the heart of this book: modifying compiler-generated assembly language code to your taste. This chapter shows exactly how different types of C routines (such as if-then statements and for-next loops) are produced in assembly language code. Once you understand what the assembly language code is doing, you can add your own touches to it to customize the code for your specific environment. Chapter 16, “Using Files,” covers one of the most overlooked functions of assembly language program- ming. Almost every application requires some type of file access on the system. Assembly language pro- grams are no different. This chapter shows how to use the Linux file-handling system calls to read, write, and modify data in files on the system. Chapter 17, “Using Advanced IA-32 Features,” completes the book with a look at the advanced Intel Single Instruction Multiple Data (SIMD) technology. This technology provides a platform for program- mers to perform multiple arithmetic operations in a single instruction. This technology has become cru- cial in the world of audio and video data processing. What You Need to Use This Book All of the examples in this book are coded to be assembled and run on the Linux operating system, run- ning on an Intel processor platform. The Open Source GNU compiler (gcc), assembler (gas), linker (ld), and debugger (gdb) are used extensively throughout the book to demonstrate the assembly language features. Chapter 4, “A Sample Assembly Language Program,” discusses specifically how to use these tools on a Linux platform to create, assemble, link, and debug an assembly language program. If you do not have an installed Linux platform available, Chapter 4 demonstrates how to use a Linux distribution that can be booted directly from CD, without modifying the workstation hard drive. All of the GNU development tools used in this book are available without installing Linux on the workstation.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值