位置编码系列(NLP and CV领域)

NLP中的位置编码

转载:让研究人员绞尽脑汁的Transformer位置编码

总体结构

Bert问世后瞬间引爆了NLP领域,同时也让Transformer火了起来,Transformer中特征提取的方式不是传统的CNN,RNN等,而是用attention的形式,这种模式被用在AI的各个领域中,包括CV和语音等。attention提取特征的效果非常好,可以非常有效的提取到上下文的信息,但是在NLP中会有个问题:attention提取特征的时候,当前这个字对上下文的其他字的关联性可以很好的体现出来,但是其他字的位置在哪里都可以,在这个字的前面、后面都可以,间隔的距离也没有要求。但其实这跟我们平时表达的语言肯定是矛盾的,于是在Transformer中加入了位置编码。

虽然说起来主要就是绝对位置编码和相对位置编码两大类,但每一类其实又能衍生出各种各样的变种,为此研究人员可算是煞费苦心、绞尽脑汁了,此外还有一些不按套路出牌的位置编码。本文就让我们来欣赏一下研究人员为了更好地表达位置信息所构建出来的“八仙过海,各显神通”般的编码方案。

绝对位置编码

形式上来看,绝对位置编码是相对简单的一种方案,但即便如此,也不妨碍各路研究人员的奇思妙想,也有不少的变种。一般来说,绝对位置编码会加到输入中:在输入的第k个向量  \(xk\)中加入位置向量  \(pk\)变为\(xk+pk\),其中\(pk\)只依赖于位置编号k。

训练式

很显然,绝对位置编码的一个最朴素方案是不特意去设计什么,而是直接将位置编码当作可训练参数,比如最大长度为512,编码维度为768,那么就初始化一个512×768的矩阵作为位置向量,让它随着训练过程更新。现在的BERT、GPT等模型所用的就是这种位置编码,事实上它还可以追溯得更早,比如2017年Facebook的《Convolutional Sequence to Sequence Learning》就已经用到了它。

对于这种训练式的绝对位置编码,一般的认为它的缺点是没有外推性,即如果预训练最大长度为512的话,那么最多就只能处理长度为512的句子,再长就处理不了了。当然,也可以将超过512的位置向量随机初始化,然后继续微调。但笔者最近的研究表明,通过层次分解的方式,可以使得绝对位置编码能外推到足够长的范围,同时保持还不错的效果,因此,其实外推性也不是绝对位置编码的明显缺点。

三角式

三角函数式位置编码,一般也称为Sinusoidal位置编码,是Google的论文《Attention is All You Need》所提出来的一个显式解:

递归式

原则上来说,RNN模型不需要位置编码,它在结构上就自带了学习到位置信息的可能性(因为递归就意味着我们可以训练一个“数数”模型),因此,如果在输入后面先接一层RNN,然后再接Transformer,那么理论上就不需要加位置编码了。同理,我们也可以用RNN模型来学习一种绝对位置编码,比如从一个向量p0出发,通过递归格式pk+1=f(pk)来得到各个位置的编码向量。

ICML 2020的论文《Learning to Encode Position for Transformer with Continuous Dynamical Model》把这个思想推到了极致,它提出了用微分方程(ODE)dpt/dt=h(pt,t)的方式来建模位置编码,该方案称之为FLOATER。显然,FLOATER也属于递归模型,函数h(pt,t)可以通过神经网络来建模,因此这种微分方程也称为神经微分方程,关于它的工作最近也逐渐多了起来。

理论上来说,基于递归模型的位置编码也具有比较好的外推性,同时它也比三角函数式的位置编码有更好的灵活性(比如容易证明三角函数式的位置编码就是FLOATER的某个特解)。但是很明显,递归形式的位置编码牺牲了一定的并行性,可能会带速度瓶颈。

相乘式

刚才我们说到,输入xk与绝对位置编码pk的组合方式一般是xk+pk,那有没有“不一般”的组合方式呢?比如xk⊗pk(逐位相乘)?我们平时在搭建模型的时候,对于融合两个向量有多种方式,相加、相乘甚至拼接都是可以考虑的,怎么大家在做绝对位置编码的时候,都默认只考虑相加了?

很抱歉,笔者也不知道答案。可能大家默认选择相加是因为向量的相加具有比较鲜明的几何意义,但是对于深度学习模型来说,这种几何意义其实没有什么实际的价值。最近笔者看到的一个实验显示,似乎将“加”换成“乘”,也就是xk⊗pk的方式,似乎比xk+pk能取得更好的结果。具体效果笔者也没有完整对比过,只是提供这么一种可能性。关于实验来源,可以参考《中文语言模型研究:(1) 乘性位置编码》

相对位置编码

相对位置并没有完整建模每个输入的位置信息,而是在算Attention的时候考虑当前位置与被Attention的位置的相对距离,由于自然语言一般更依赖于相对位置,所以相对位置编码通常也有着优秀的表现。对于相对位置编码来说,它的灵活性更大,更加体现出了研究人员的“天马行空”。

经典式

相对位置编码起源于Google的论文《Self-Attention with Relative Position Representations》,华为开源的NEZHA模型也用到了这种位置编码,后面各种相对位置编码变体基本也是依葫芦画瓢的简单修改。

一般认为,相对位置编码是由绝对位置编码启发而来,考虑一般的带绝对位置编码的Attention:

XLNET式

XLNET式位置编码其实源自Transformer-XL的论文《Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context》,只不过因为使用了Transformer-XL架构的XLNET模型并在一定程度上超过了BERT后,Transformer-XL才算广为人知,因此这种位置编码通常也被冠以XLNET之名。

T5式

T5模型出自文章《Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer》,里边用到了一种更简单的相对位置编码。思路依然源自展开式(7)(7),如果非要分析每一项的含义,那么可以分别理解为“输入-输入”、“输入-位置”、“位置-输入”、“位置-位置”四项注意力的组合。如果我们认为输入信息与位置信息应该是独立(解耦)的,那么它们就不应该有过多的交互,所以“输入-位置”、“位置-输入”两项Attention可以删掉,而piWQW⊤Kp⊤j⊤实际上只是一个只依赖于(i,j)的标量,我们可以直接将它作为参数训练出来,即简化为

说白了,它仅仅是在Attention矩阵的基础上加一个可训练的偏置项而已,而跟XLNET式一样,在vj上的位置偏置则直接被去掉了。包含同样的思想的还有微软在ICLR 2021的论文《Rethinking Positional Encoding in Language Pre-training》中提出的TUPE位置编码。

DeBERTa式

DeBERTa也是微软搞的,去年6月就发出来了,论文为《DeBERTa: Decoding-enhanced BERT with Disentangled Attention》,最近又小小地火了一把,一是因为它正式中了ICLR 2021,二则是它登上SuperGLUE的榜首,成绩稍微超过了T5。

其实DeBERTa的主要改进也是在位置编码上,同样还是从展开式(7)(7)出发,T5是干脆去掉了第2、3项,只保留第4项并替换为相对位置编码,而DeBERTa则刚刚相反,它扔掉了第4项,保留第2、3项并且替换为相对位置编码(果然,科研就是枚举所有的排列组合看哪个最优):

不过,DeBERTa比较有意思的地方,是提供了使用相对位置和绝对位置编码的一个新视角,它指出NLP的大多数任务可能都只需要相对位置信息,但确实有些场景下绝对位置信息更有帮助,于是它将整个模型分为两部分来理解。以Base版的MLM预训练模型为例,它一共有13层,前11层只是用相对位置编码,这部分称为Encoder,后面2层加入绝对位置信息,这部分它称之为Decoder,还弄了个简称EMD(Enhanced Mask Decoder);至于下游任务的微调截断,则是使用前11层的Encoder加上1层的Decoder来进行。

SuperGLUE上的成绩肯定了DeBERTa的价值,但是它论文的各种命名真的是让人觉得极度不适,比如它自称的“Encoder”、“Decoder”就很容易让人误解这是一个Seq2Seq模型,比如EMD这个简称也跟Earth Mover’s Distance重名。虽然有时候重名是不可避免的,但它重的名都是ML界大家都比较熟悉的对象,相当容易引起误解,真不知道作者是怎么想的…

其他位置编码

绝对位置编码和相对位置编码虽然花样百出,但仍然算是经典范围内,从上述介绍中我们依然可以体会到满满的套路感。除此之外,还有一些并不按照常规套路出牌,它们同样也表达了位置编码。

CNN式

尽管经典的将CNN用于NLP的工作《Convolutional Sequence to Sequence Learning》往里边加入了位置编码,但我们知道一般的CNN模型尤其是图像中的CNN模型,都是没有另外加位置编码的,那CNN模型究竟是怎么捕捉位置信息的呢?

如果让笔者来回答,那么答案可能是卷积核的各项异性导致了它能分辨出不同方向的相对位置。不过ICLR 2020的论文《How Much Position Information Do Convolutional Neural Networks Encode?》给出了一个可能让人比较意外的答案:CNN模型的位置信息,是Zero Padding泄漏的!

我们知道,为了使得卷积编码过程中的feature保持一定的大小,我们通常会对输入padding一定的0,而这篇论文显示该操作导致模型有能力识别位置信息。也就是说,卷积核的各向异性固然重要,但是最根本的是zero padding的存在,那么可以想象,实际上提取的是当前位置与padding的边界的相对距离。

不过,这个能力依赖于CNN的局部性,像Attention这种全局的无先验结构并不适用,如果只关心Transformer位置编码方案的读者,这就权当是扩展一下视野吧。

复数式

复数式位置编码可谓是最特立独行的一种位置编码方案了,它来自ICLR 2020的论文《Encoding word order in complex embeddings》。论文的主要思想是结合复数的性质以及一些基本原理,推导出了它的位置编码形式(Complex Order)为:

代表词j的三组词向量。你没看错,它确实假设每个词有三组跟位置无关的词向量了(当然可以按照某种形式进行参数共享,使得它退化为两组甚至一组),然后跟位置k相关的词向量就按照上述公式运算。

你以为引入多组词向量就是它最特立独行的地方了?并不是!我们看到式(11)(11)还是复数形式,你猜它接下来怎么着?将它实数化?非也,它是将它直接用于复数模型!也就是说,它走的是一条复数模型路线,不仅仅输入的Embedding层是复数的,里边的每一层Transformer都是复数的,它还实现和对比了复数版的Fasttext、LSTM、CNN等模型!这篇文章的一作是Benyou Wang,可以搜到他的相关工作基本上都是围绕着复数模型展开的,可谓复数模型的铁杆粉了~

融合式

无偶独有,利用复数的形式,笔者其实也构思了一种比较巧的位置编码,它可以将绝对位置编码与相对位置编码融于一体,分享在此,有兴趣的读者欢迎一起交流研究。

简单起见,我们先假设qm,kn是所在位置分别为m,n的二维行向量,既然是二维,那么我们可以将它当作复数来运算。我们知道,Attention关键之处在于向量的内积,用复数表示为

来赋予[x,y]绝对位置信息,那么在Attention运算的时候也等价于相对位置编码。如果是多于二维的向量,可以考虑每两维为一组进行同样的运算,每一组的θ可以不一样。

这样一来,我们得到了一种融绝对位置与相对位置于一体的位置编码方案,从形式上看它有点像乘性的绝对位置编码,通过在q,k中施行该位置编码,那么效果就等价于相对位置编码,而如果还需要显式的绝对位置信息,则可以同时在v上也施行这种位置编码。总的来说,我们通过绝对位置的操作,可以达到绝对位置的效果,也能达到相对位置的效果,初步实验显示它是可以work的,但还没有充分验证,欢迎大家尝试交流。

Chain of Thought

paper: https://arxiv.org/abs/2201.11903

  • zero-shot:输入问题,等待输出结果
  • CoT:输入问题并提示Let’s think step by step
  • Manual-CoT: 是一种few shot方法,所以构造了一些模板Q&A(模板A中也有Let’s think step by step),然后再给出问题并提示Let’s think step by step
  • Auto-CoT:采样多个问题,每个问题提示Let’s think step by step,让模型给出答案。然后拼接所有生成的Q&A并给出最终问题,并提示Let’s think step by step

为什么需要CoT?

问题可以分为两类:一类是容易回答的,没有太多逻辑推理的,比如:天气如何?面包几块钱?另一类是需要长链条的逻辑推理的问题:数学等。

当语言模型的规模指数级增大时,它解决常规问题的能力有了很大的提升,然而它解决逻辑推理的问题的能力却提升很小。而CoT就是帮助解决这样的问题,它的核心思想是:不要光给出答案,把推理过程也给出来。如下图所示,关键在于构造的prompt要包含推理过程:

为什么延长推理过程就有效呢?这可能是因为语言模型token-by-token的特点。

标准的prompt可以被视为大模型能力的下限,如何提取大模型学到的知识的问题是一个难点,标准的prompt是一个很好的起点,但却绝不是终点。

多模态|BLIP 、CoCa and BeiTv

BLIP

BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation

代码: https://github.com/salesforce/BLIP

本文是 ALBEF 原班人马做的,基本可以看做吸收了 VLMo 思想的 ALBEF。训练的 loss 和技巧都与 ALBEF 一致,属于 ALBEF 的后续工作。

本文motivation主要有两个:一是之前多模态预训练模型结构要么是基于编码器,不能直接用于生成任务,要么是基于编码解码器,在检索类任务上不方便,本文设计的结构包含单模态编码器、视觉指导文本编码器、视觉指导文本解码器,可以方便地用对比学习、ITM(Image-Text Matching ( ITM ): 图文匹配任务,针对的是图文交互流,即判断当前pair是不是匹配(就是个分类任务))、LM(生成式任务)三个预训练任务训练不同的模块,也容易迁移到各种下游任务中;二是之前的很多工作通过扩充了网上搜集的图文对的预训练数据(GCC、SBU、CC12M),提高了模型效果,但忽略了其中有很多不对齐的噪声情况,本文用一个boostrapping的方法,用captioner为网络图片生成描述,用filter过滤掉不配对的数据,从而降低噪声,更高效地利用网络上的数据。

关键的改进:

1. 模型结构上整合了 ALBEF 和和 VLMo。VLMo 参数共享,但是不存在单独编码器;ALBEF 存在单独编码器但是部分参数不共享。这篇论文存在单独的 vision encoder 和 text encoder。多模态的参数是以 cross-attention 模块插入到文本编码器实现的,cross-attention 模块享受文本编码器的参数(可以看 col 2 和 col3)

2. 增加了解码器(参考 col 4),为了做生成任务。解码器拿到视觉特征和未掩码的语言特征,过一个 casual self-attention 层,做 GPT 用的那种 lm 任务。这里区别于 MLM 的那种 mask 机制,是通过 causal self-attention 来实现因果推理的,我此时还不熟悉这个过程。

3. 除了上面的主要部分,还有一个重要的部分是利用训练好的模型生成伪标签。将训练好的模型里的不同的部分拿出来在 COCO 上稍微微调一下,decoder 部分可以生成文本,算 ITM loss 的那个模块可以做 image-text pair 的过滤,通过输出打分、置信度的方式。在实验中,BLIP 的解码能力似乎很强,用这种范式生成的文本不仅人看着觉得不错,用于自训练后也可以涨点 2-3,非常显着。

   一个例子是 stable diffusion 的官方博文里提到了,他们在做微调时,会遇到数据集只有图片没有 caption 的情况,比如 pokeman 数据。他们用 BLIP 来做caption生成,然后微调 stable diffusion 发现效果很好。

   另一个例子是知名的开源多模态数据集 LAION,他们也用了 BLIP 来辅助制作数据集。他们的过程在官网公布了,可以参考。

总结:个人感觉模型部分的改进可能有用可能没有用,但是解码器输出的 caption 确实是不错。以至于很多下游任务都拿 BLIP 来生成 caption。

CoCa

Contrastive Captioners are Image-Text Foundation Models

代码: https://github.com/lucidrains/CoCa-pytorch

它也是 ALBEF 的后续工作,模型非常像。区别在于:

1. 图像用了 attentional pooling,这在本文的实验中有效

2. 去掉了 ITM loss,目的是加快训练,原本文本需要 forward 2-3 次,去掉 ITM loss 之后只需要 forward 一次就可以了。在 ALBEF 中,ITM 需要完整的 text,而 MLM 需要掩码,所以是两次输入。在 BLIP 中,ITC 一次,ITM 因为在文本模型中插入了新的模块,所以得单独做前向。而 LM 因为用了既多了新的模块又得用 causal self-attention 所以又得单独做一次。在 CoCa 中,为了完成 captioning loss 和 ITC loss,只需要做一次前向即可。GPT 中把 cls-token 放在最后面就可以得到全局表征来做 ITC loss 了。

简单快速的方法可以有效地 scale,而我们知道复杂的模型设计、loss 设计经常不如简单地放大模型、增加数据有效。参考凯明的 FLYP。

这种画图的方式很不错,很直观。可以参考,以后也画成这样。

总结:

简单有效的结构设计,我对 CoCa 的印象是简单有效。它的峰值性能我没有感觉很炸裂,可能是模型、数据 scale 之后自然的结果。但是它的 zero-shot 性能让我印象很深刻,在 imagenet 上微调不微调的差距很小,这一点非常非常关键。

读到 coca,我对多模态的疑问还有两点:

1. mixture of experts 的结构没有在本文中得到应用,但我感觉是个相当有前途的结构

2. 双向的生成 loss 还是没人做,谁说只能图像辅助文本?

BeiTv

(BEiT-3) Image as a Foreign Language: BEiT Pretraining for All Vision and Vision-Language Tasks

论文的卖点是大一统。在 introduction 章节详细介绍了大一统指的是统一模型、loss 和数据。我觉得可以简单地概括为:用统一的 multi-way transformer (mixture of experts ) 架构和单个 masked modeling loss,将任意模态看做是同一个模态来建模。

具体而言,它指的是在将任意模态输入网络后,都表现为 list of tokens,直接将它们看做是相同的模态来做 masked modeling 就好了。如果想要拿过去做下游任务的话,直接将需要的那部分模型拿出来即可。比如做视觉任务就拿视觉模型,做语言任务就拿语言模型。如果是做多模态任务,可以灵活地模拟不同的需求,比如:1. 做生成任务可以拿多模态部分的参数出来 2. 做图文检索可以单独取出视觉部分和语言部分来模拟 CLIP。不仅仅是能做任意任务,还继承了前作的优点,比如 CLIP 这种弱跨模态交互带来的计算效率的优势。

总结:

Neural Corpus Indexer—文档检索

paper:https://arxiv.org/abs/2206.02743

神经语料库索引for文档检索

最近一篇Neural Corpus Indexer基于transformer的文档检索引发了争论。【知乎】所指论文为NeurIPS2022 Outstanding Paper A Neural Corpus Indexer for Document Retrieval。 根据OpenReview上的Revisions记录,Rebuttal阶段的最后修改应该是https://openreview.net/references/pdf?id=y45TgWUfyF,此时Table 1内容为:

但Camera Ready版本是https://openreview.net/references/pdf?id=-bt0HSi9__,此时Table 1的内容为:

特别值得注意的是,在Rebuttal阶段,作者的General Response指出他们的工作即使去掉query generation进行公平比较,也远胜于基线:

但是根据Camera Ready版本的Table 1(见上)和Table 3

NCI(Base) w/ QG是65.86 NCI(Large) w/ QG是66.23 NCI(Base) w/o QG是46.41。如果NCI(Large) w/o QG像w/ QG的设置一样只比Base高0.37,那么它将低于Table 1中的SEAL(Large),而根据General Response,作者认可SEAL是w/o QG的设置。

反思:其实在机器学习里面,如果你的实验有了好的结果,尤其是特别好的结果,那么90%的情况都是有bug造成的。所以在效果比较好的情况时候一定要去仔细检查,看看是否有数据泄漏的情况。这个错误是比较常见的。

文本检索:在一堆的文本里面,将那些跟Query相关的文档找出来。是信息检索里最大的分支。相关信息检索的会议有:SigIR、WSDN、KDD、 NeurIPS (这个 NeurIPS 上文本检索的文章比较少,是一个偏算法的会议)

摘要:

当前最主流的的文档检索解决方案主要是基于索引检索方法,索引就是指对文档做一下哈希值或者embedding,但是索引很难直接针对最终检索目标结果进行优化。 因为哈希是一个固定的算法,或者词嵌入也不一定是根据用户最终的目标来做训练的。在这篇论文中,我们的目标是展示一个端到端的深度神经网络网络统一训练和检索阶段,可以显着提高召回率。在检索方面,召回率相比于准确率更加重要,因为需要把相关的文档全部都找出来,不希望遗漏。在这个文章中,作者提出了一个基于equence-to-sequence network(NCI),针对特定的query来说直接生成相关文档的id。为了提升NCI性能,提出了一个解码器(refix-aware weight-adaptive decoder),还使用了一些其他技术:query的生成、带语义的文档的ID和一致性的正则表达项。

摘要的写法比较常见:该领域之前的方法是怎样的,我们使用一个神经网络做一个端到端的学习,从原始的数据直接生成你要的一个结果。

导言:

文档检索和排序是标准网络搜索引擎的两个关键阶段。 第一,文档检索阶段就是给定一个query,来查询相关的候选文档,然后进行排名阶段为每个文档提供更精确的排名分数。 排名阶段通常由深度神经网络,将每对查询和文档作为输入并预测它们的相关性分数。 然而,一个精确的排名模型是非常昂贵的(对每一个查询对都要去预测分数),所以通常只有一百或一千个检索的候选结果。 因此,召回性能文档检索阶段对网络搜索引擎的有效性至关重要。(检索的这几百个候选结果应该要把所有相关的都包含进来才好)。

其实除了检索的召回率很重要,对于一个检索系统来说,性能是十分重要的,作者在这没有提到,对于一个搜索引擎来说,文档数量在千百亿以上,这个也是这篇文章的一个硬伤,就是太贵了。

现有的文档检索方法可以分为两类,即term-based和基于语义的方法。基于 term 术语的检索方法一般会构建一个倒排索引对整个网络语料库(可以认为就是一个字典,字典里的每个key就是查询,key的值就是对应这个文档id(key出现在该文档中))这个方法非常高效,但它们几乎无法捕获文档语义并且无法检索到类似的不同措辞的文件(比如我输入“文件”,找到的结果只是含有该“文件“的文档,对于文件的相似表达”file“,无法检索到)。 因此,提出了基于语义的方法 来减轻这种差异。基于语义的方法就是把query和文档分别映射成向量(使用twin-tower architecture架构)。然后使用近似K紧邻搜索感兴趣的的K个文档。这种方法的缺点:对于精确匹配exact match,(苹果13和苹果12)表现不好。另外就是ANN近邻算法某些情况(query和文档之间的关系复杂)下也不太好。

端到端的相关工作:一个是DSI,Differentiable Search Index,文本到文本的生成,一个纯transformer,DSI 中的解码器没有充分利用文档标识符的层次结构。第二个SEAL 通过利用段落中的所有 n-gram 作为其标识符id。

twin-tower architecture

Neural Corpus Indexer

神经语料库索引器 (NCI) 是一种序列到序列的神经网络模型。 该模型将查询作为输入并输出最相关的文档标识符 (docid),它可以通过大量<query, docid>对进行训练。

下图就是这个模型的示意图。每次用户输入的是查询query,模型输出的是docID。那文本检索中的文档在哪?文档不可能作为输入送进模型,因为文档数量太大了,开销比较大。这个模型预测的时候不会看到文档的信息,但是做检索肯定需要模型知道各个文档的信息,所以就需要把这些文档全部放入这个模型。所以这部分数据分为两部分,一部分就是<query,docID>查询对。另一部分就是大量的被检索的文档<doc,docID>,因为模型预测的是query到docid的映射,所以需要让模型记住文档和docid的关系,常见做法就是用<doc,docid>无标号的数据去让模型记住全部的文档,当然这里可以把一个<doc,docID>对拆分成多个<query,docid>对,就是把doc里的句子给拆分成query会比较好做一些。模型的设计里有一些比较重要的点:(1)如何设计一个docID,而并非简单的数字,最好docID能够表示doc之间的语义信息。(2)如何将文档分出比较好的query,使得文档自己的语义和它的ID之间做好映射。同时分出的query能够跟预测时候的用户查询query有一定的相似性。(3)模型如何设计?编解码器和loss

NCI示意图

上图就是对应的三个关键点。

  • 如何生成语义的ID:层次Kmeans算法

首先,上图中所有的灰点都代表不同的文档,首先对所有的文档做一个K-means聚类(k=3),不同的类给与不同的id(1,2,3),作为文档id的前缀,如果某个类里面的文档数量多于某个阈值C,他就会对这个类进一步做K-means,继续分出K个子类和对应的id。因此如果两个文档的前缀相近,表示俩个文档的距离比较近。这种层次化标号的好处是如果面对10000中类别标号,直接用一个softmax来对其分类是不好的,有了层次化的标号,就可以分层次预测类别。

  • 从文本生成query

1、DocT5Query:sequence to sequence的模型,将Doc 翻译成 Query的模型。如何使用:将用于检索的文档输入到该模型,来获得多个query的输出(随机采样方法)。

2、Document as Query,像DSI一样,先把每个文档最先的64个term词作为一个query。然后随机在文档的随机位置选择10组,每组64个词作为query。(共11个query)

Prefix-aware weight-adaptive decoder:

r0,r1,r2就是不同层次的类别的id。相比传统的解码器,作者更加考虑到了r0,r1,r2之间的相对位置关系,因此解码器的输入不再是r0,r1,而是包含位置的(1,r0),(2,r1)。实验表明包含位置的解码器输入对于模型提升很大!!!!

另外作者认为在解码器的最后的softmax的全值W对于不同的ri是一样的,这样是不好的,因此希望不同的r对应不同权重。

因此新的Wi如下所示:不仅包含Wi,也包含前面的r0到ri-1的这些信息。

损失函数:

1、增加一个对比学习损失函数,希望同一个query生成的id之间相似度更加接近一些。

2、标准的 cross entropy损失函数

实验

数据集(问答数据集文档来自wiki):

评价指标:

1、Recall@N:表示在获得的N个结果中有没有自己想要的文档

2、MRR: 表示返回结果的排序情况,我们想要的文档在所有结果中的排序情况

结果:

消融实验

性能:在32G的v100上面,时延在100ms还是可以的,但是吞吐量只有50多个query对于搜索引擎来说是不能忍受的。工业部署上还是有一定的距离。

缺点:1、大数据集:目前只是在32万的文档上训练结果,但要是真的用于web搜索,数以亿计的文档需要的模型会很大。2、推理的时延和吞吐量 3、面对新的文档,如何去更新模型?

InstructGPT /ChatGPT

最近非常火的ChatGPT和今年年初公布的[1]是一对姐妹模型,是在GPT-4之前发布的预热模型,有时候也被叫做GPT3.5。ChatGPT和InstructGPT在模型结构,训练方式上都完全一致,即都使用了指示学习(Instruction Learning)和人工反馈的强化学习(Reinforcement Learning from Human Feedback,RLHF)来指导模型的训练,它们不同的仅仅是采集数据的方式上有所差异。所以要搞懂ChatGPT,我们必须要先读懂InstructGPT

https://arxiv.org/abs/2203.02155

Prompt是激发语言模型的补全能力,例如根据上半句生成下半句,或是完形填空等。Instruct(指令)是激发语言模型的理解能力,它通过给出更明显的指令,让模型去做出正确的行动。

  1. 提示学习:给女朋友买了这个项链,她很喜欢,这个项链太____了。
  2. 指示学习:判断这句话的情感:给女朋友买了这个项链,她很喜欢。选项:A=好;B=一般;C=差。

1. 背景知识

在介绍ChatGPT/InstructGPT之前,我们先介绍它们依赖的基础算法。

1.1 GPT系列

基于文本预训练的GPT-1[2],GPT-2[3],GPT-3[4]三代模型都是采用的以Transformer为核心结构的模型(图1),不同的是模型的层数和词向量长度等超参,它们具体的内容如表1。

图1:GPT系列的模型结构(其中Trm是一个Transformer结构)

表1:历代GPT的发布时间,参数量以及训练量

模型发布时间层数头数词向量长度参数量预训练数据量
GPT-12018 年 6 月12127681.17 亿约 5GB
GPT-22019 年 2 月48160015 亿40GB
GPT-32020 年 5 月9696128881,750 亿45TB

GPT-1比BERT诞生略早几个月。它们都是采用了Transformer为核心结构,不同的是GPT-1通过自左向右生成式的构建预训练任务,然后得到一个通用的预训练模型,这个模型和BERT一样都可用来做下游任务的微调。GPT-1当时在9个NLP任务上取得了SOTA的效果,但GPT-1使用的模型规模和数据量都比较小,这也就促使了GPT-2的诞生。

对比GPT-1,GPT-2并未在模型结构上大作文章,只是使用了更多参数的模型和更多的训练数据(表1)。GPT-2最重要的思想是提出了“所有的有监督学习都是无监督语言模型的一个子集”的思想,这个思想也是提示学习(Prompt Learning)的前身。GPT-2在诞生之初也引发了不少的轰动,它生成的新闻足以欺骗大多数人类,达到以假乱真的效果。甚至当时被称为“AI界最危险的武器”,很多门户网站也命令禁止使用GPT-2生成的新闻。

GPT-3被提出时,除了它远超GPT-2的效果外,引起更多讨论的是它1750亿的参数量。GPT-3除了能完成常见的NLP任务外,研究者意外的发现GPT-3在写SQL,JavaScript等语言的代码,进行简单的数学运算上也有不错的表现效果。GPT-3的训练使用了情境学习(In-context Learning),它是元学习(Meta-learning)的一种,元学习的核心思想在于通过少量的数据寻找一个合适的初始化范围,使得模型能够在有限的数据集上快速拟合,并获得不错的效果。

通过上面的分析我们可以看出从性能角度上讲,GPT有两个目标:

  1. 提升模型在常见NLP任务上的表现效果;
  2. 提升模型在其他非典型NLP任务(例如代码编写,数学运算)上的泛化能力。

另外,预训练模型自诞生之始,一个备受诟病的问题就是预训练模型的偏见性。因为预训练模型都是通过海量数据在超大参数量级的模型上训练出来的,对比完全由人工规则控制的专家系统来说,预训练模型就像一个黑盒子。没有人能够保证预训练模型不会生成一些包含种族歧视,性别歧视等危险内容,因为它的几十GB甚至几十TB的训练数据里几乎肯定包含类似的训练样本。这也就是InstructGPT和ChatGPT的提出动机,论文中用3H概括了它们的优化目标:

  • 有用的(Helpful);
  • 可信的(Honest);
  • 无害的(Harmless)。

OpenAI的GPT系列模型并没有开源,但是它们提供了模型的试用网站,有条件的同学可以自行试用。

1.2 指示学习(Instruct Learning)和提示(Prompt Learning)学习

指示学习是谷歌Deepmind的Quoc V.Le团队在2021年的一篇名为《Finetuned Language Models Are Zero-Shot Learners》[5]文章中提出的思想。指示学习和提示学习的目的都是去挖掘语言模型本身具备的知识。不同的是Prompt是激发语言模型的补全能力,例如根据上半句生成下半句,或是完形填空等。Instruct是激发语言模型的理解能力,它通过给出更明显的指令,让模型去做出正确的行动。我们可以通过下面的例子来理解这两个不同的学习方式:

  1. 提示学习:给女朋友买了这个项链,她很喜欢,这个项链太____了。
  2. 指示学习:判断这句话的情感:给女朋友买了这个项链,她很喜欢。选项:A=好;B=一般;C=差。

指示学习的优点是它经过多任务的微调后,也能够在其他任务上做zero-shot,而提示学习都是针对一个任务的。泛化能力不如指示学习。我们可以通过图2来理解微调,提示学习和指示学习。

图2:模型微调,提示学习,指示学习三者的异同

1.3 人工反馈的强化学习

因为训练得到的模型并不是非常可控的,模型可以看做对训练集分布的一个拟合。那么反馈到生成模型中,训练数据的分布便是影响生成内容的质量最重要的一个因素。有时候我们希望模型并不仅仅只受训练数据的影响,而是人为可控的,从而保证生成数据的有用性,真实性和无害性。论文中多次提到了对齐(Alignment)问题,我们可以理解为模型的输出内容和人类喜欢的输出内容的对齐,人类喜欢的不止包括生成内容的流畅性和语法的正确性,还包括生成内容的有用性、真实性和无害性。

我们知道强化学习通过奖励(Reward)机制来指导模型训练,奖励机制可以看做传统模训练机制的损失函数。奖励的计算要比损失函数更灵活和多样(AlphaGO的奖励是对局的胜负),这带来的代价是奖励的计算是不可导的,因此不能直接拿来做反向传播。强化学习的思路是通过对奖励的大量采样来拟合损失函数,从而实现模型的训练。同样人类反馈也是不可导的,那么我们也可以将人工反馈作为强化学习的奖励,基于人工反馈的强化学习便应运而生。

RLHF最早可以追溯到Google在2017年发表的《Deep Reinforcement Learning from Human Preferences》[6],它通过人工标注作为反馈,提升了强化学习在模拟机器人以及雅达利游戏上的表现效果。

图3:人工反馈的强化学习的基本原理

InstructGPT/ChatGPT中还用到了强化学习中一个经典的算法:OpenAI提出的最近策略优化(Proximal Policy Optimization,PPO)[7]。PPO算法是一种新型的Policy Gradient算法,Policy Gradient算法对步长十分敏感,但是又难以选择合适的步长,在训练过程中新旧策略的的变化差异如果过大则不利于学习。PPO提出了新的目标函数可以在多个训练步骤实现小批量的更新,解决了Policy Gradient算法中步长难以确定的问题。其实TRPO也是为了解决这个思想但是相比于TRPO算法PPO算法更容易求解。

2. InstructGPT/ChatGPT原理解读

有了上面这些基础知识,我们再去了解InstructGPT和ChatGPT就会简单很多。简单来说,InstructGPT/ChatGPT都是采用了GPT-3的网络结构,通过指示学习构建训练样本来训练一个反应预测内容效果的奖励模型(RM),最后通过这个奖励模型的打分来指导强化学习模型的训练。InstructGPT/ChatGPT的训练流程如图4所示。

图4:InstructGPT的计算流程:(1)有监督微调(SFT);(2)奖励模型(RM)训练;(3)通过PPO根据奖励模型进行强化学习。

从图4中我们可以看出,InstructGPT/ChatGPT的训练可以分成3步,其中第2步和第3步是的奖励模型和强化学习的SFT模型可以反复迭代优化。

  1. 根据采集的SFT数据集对GPT-3进行有监督的微调(Supervised FineTune,SFT);
  2. 收集人工标注的对比数据,训练奖励模型(Reword Model,RM);
  3. 使用RM作为强化学习的优化目标,利用PPO算法微调SFT模型。

根据图4,我们将分别介绍InstructGPT/ChatGPT的数据集采集和模型训练两个方面的内容。

2.1 数据集采集

如图4所示,InstructGPT/ChatGPT的训练分成3步,每一步需要的数据也有些许差异,下面我们分别介绍它们。

2.1.1 SFT数据集

SFT数据集是用来训练第1步有监督的模型,即使用采集的新数据,按照GPT-3的训练方式对GPT-3进行微调。因为GPT-3是一个基于提示学习的生成模型,因此SFT数据集也是由提示-答复对组成的样本。SFT数据一部分来自使用OpenAI的PlayGround的用户,另一部分来自OpenAI雇佣的40名标注工(labeler)。并且他们对labeler进行了培训。在这个数据集中,标注工的工作是根据内容自己编写指示,并且要求编写的指示满足下面三点:

  • 简单任务:labeler给出任意一个简单的任务,同时要确保任务的多样性;
  • Few-shot任务:labeler给出一个指示,以及该指示的多个查询-相应对;
  • 用户相关的:从接口中获取用例,然后让labeler根据这些用例编写指示。

2.1.2 RM数据集

RM数据集用来训练第2步的奖励模型,我们也需要为InstructGPT/ChatGPT的训练设置一个奖励目标。这个奖励目标不必可导,但是一定要尽可能全面且真实的对齐我们需要模型生成的内容。很自然的,我们可以通过人工标注的方式来提供这个奖励,通过人工对可以给那些涉及偏见的生成内容更低的分从而鼓励模型不去生成这些人类不喜欢的内容。InstructGPT/ChatGPT的做法是先让模型生成一批候选文本,让后通过labeler根据生成数据的质量对这些生成内容进行排序。

2.1.3 PPO数据集

InstructGPT的PPO数据没有进行标注,它均来自GPT-3的API的用户。既又不同用户提供的不同种类的生成任务,其中占比最高的包括生成任务(45.6%),QA(12.4%),头脑风暴(11.2%),对话(8.4%)等。

2.1.4 数据分析

因为InstructGPT/ChatGPT是在GPT-3基础上做的微调,而且因为涉及了人工标注,它们数据总量并不大,表2展示了三份数据的来源及其数据量。

表2:InstructGPT的数据分布

论文的附录A对数据的分布进行了更详细的讨论,这里我列出几个可能影响模型效果的几项:

  • 数据中96%以上是英文,其它20个语种例如中文,法语,西班牙语等加起来不到4%,这可能导致InstructGPT/ChatGPT能进行其它语种的生成,但效果应该远不如英文;
  • 提示种类共有9种,而且绝大多数是生成类任务,可能会导致模型有覆盖不到的任务类型;
  • 40名外包员工来自美国和东南亚,分布比较集中且人数较少, InstructGPT/ChatGPT的目标是训练一个价值观正确的预训练模型,它的价值观是由这40个外包员工的价值观组合而成。而这个比较窄的分布可能会生成一些其他地区比较在意的歧视,偏见问题。

此外,ChatGPT的博客中讲到ChatGPT和InstructGPT的训练方式相同,不同点仅仅是它们采集数据上有所不同,但是并没有更多的资料来讲数据采集上有哪些细节上的不同。考虑到ChatGPT仅仅被用在对话领域,这里我猜测ChatGPT在数据采集上有两个不同:1. 提高了对话类任务的占比;2. 将提示的方式转换Q&A的方式。当然这里也仅仅是猜测,更准确的描述要等到ChatGPT的论文、源码等更详细的资料公布我们才能知道。

2.2 训练任务

我们刚介绍到InstructGPT/ChatGPT有三步训练方式。这三步训练会涉及三个模型:SFT,RM以及PPO,下面我们详细介绍它们。

2.2.1 有监督微调(SFT)

这一步的训练和GPT-3一致,而且作者发现让模型适当过拟合有助于后面两步的训练。

2.2.2 奖励模型(RM)

因为训练RM的数据是一个labeler根据生成结果排序的形式,所以它可以看做一个回归模型。RM结构是将SFT训练后的模型的最后的嵌入层去掉后的模型。它的输入是prompt和Reponse,输出是奖励值。具体的讲,对弈每个prompt,InstructGPT/ChatGPT会随机生成 K 个输出( 4≤K≤9 ),然后它们向每个labeler成对的展示输出结果,也就是每个prompt共展示 CK2 个结果,然后用户从中选择效果更好的输出。在训练时,InstructGPT/ChatGPT将每个prompt的 CK2 个响应对作为一个batch,这种按prompt为batch的训练方式要比传统的按样本为batch的方式更不容易过拟合,因为这种方式每个prompt会且仅会输入到模型中一次。

奖励模型的损失函数表示为式(1)。这个损失函数的目标是最大化labeler更喜欢的响应和不喜欢的响应之间的差值。

2.2.3 强化学习模型(PPO)

强化学习和预训练模型是最近两年最为火热的AI方向之二,之前不少科研工作者说强化学习并不是一个非常适合应用到预训练模型中,因为很难通过模型的输出内容建立奖励机制。而InstructGPT/ChatGPT反直觉的做到了这点,它通过结合人工标注,将强化学习引入到预训练语言模型是这个算法最大的创新点。

如表2所示,PPO的训练集完全来自API。它通过第2步得到的奖励模型来指导SFT模型的继续训练。很多时候强化学习是非常难训练的,InstructGPT/ChatGPT在训练过程中就遇到了两个问题:

  1. 问题1:随着模型的更新,强化学习模型产生的数据和训练奖励模型的数据的差异会越来越大。作者的解决方案是在损失函数中加入KL惩罚项 βlog⁡(πϕRL(y∣x)/πSFT(y∣x)) 来确保PPO模型的输出和SFT的输出差距不会很大。
  2. 问题2:只用PPO模型进行训练的话,会导致模型在通用NLP任务上性能的大幅下降,作者的解决方案是在训练目标中加入了通用的语言模型目标 γEx∼Dpretrain [log⁡(πϕRL(x))] ,这个变量在论文中被叫做PPO-ptx。

综上,PPO的训练目标为式(2)。

3. InstructGPT/ChatGPT的性能分析

不可否认的是,InstructGPT/ChatGPT的效果是非常棒的,尤其是引入了人工标注之后,让模型的“价值观”和的正确程度和人类行为模式的“真实性”上都大幅的提升。那么,仅仅根据InstructGPT/ChatGPT的技术方案和训练方式,我们就可以分析出它可以带来哪些效果提升呢?

3.1 优点

  • InstructGPT/ChatGPT的效果比GPT-3更加真实:这个很好理解,因为GPT-3本身就具有非常强的泛化能力和生成能力,再加上InstructGPT/ChatGPT引入了不同的labeler进行提示编写和生成结果排序,而且还是在GPT-3之上进行的微调,这使得我们在训练奖励模型时对更加真实的数据会有更高的奖励。作者也在TruthfulQA数据集上对比了它们和GPT-3的效果,实验结果表明甚至13亿小尺寸的PPO-ptx的效果也要比GPT-3要好。
  • InstructGPT/ChatGPT在模型的无害性上比GPT-3效果要有些许提升:原理同上。但是作者发现InstructGPT在歧视、偏见等数据集上并没有明显的提升。这是因为GPT-3本身就是一个效果非常好的模型,它生成带有有害、歧视、偏见等情况的有问题样本的概率本身就会很低。仅仅通过40个labeler采集和标注的数据很可能无法对模型在这些方面进行充分的优化,所以会带来模型效果的提升很少或者无法察觉。
  • InstructGPT/ChatGPT具有很强的Coding能力:首先GPT-3就具有很强的Coding能力,基于GPT-3制作的API也积累了大量的Coding代码。而且也有部分OpenAI的内部员工参与了数据采集工作。通过Coding相关的大量数据以及人工标注,训练出来的InstructGPT/ChatGPT具有非常强的Coding能力也就不意外了。

3.2 缺点

  • InstructGPT/ChatGPT会降低模型在通用NLP任务上的效果:我们在PPO的训练的时候讨论了这点,虽然修改损失函数可以缓和,但这个问题并没有得到彻底解决。
  • 有时候InstructGPT/ChatGPT会给出一些荒谬的输出:虽然InstructGPT/ChatGPT使用了人类反馈,但限于人力资源有限。影响模型效果最大的还是有监督的语言模型任务,人类只是起到了纠正作用。所以很有可能受限于纠正数据的有限,或是有监督任务的误导(只考虑模型的输出,没考虑人类想要什么),导致它生成内容的不真实。就像一个学生,虽然有老师对他指导,但也不能确定学生可以学会所有知识点。
  • 模型对指示非常敏感:这个也可以归结为labeler标注的数据量不够,因为指示是模型产生输出的唯一线索,如果指示的数量和种类训练的不充分的话,就可能会让模型存在这个问题。
  • 模型对简单概念的过分解读:这可能是因为labeler在进行生成内容的比较时,倾向于给给长的输出内容更高的奖励。
  • 对有害的指示可能会输出有害的答复:例如InstructGPT/ChatGPT也会对用户提出的“AI毁灭人类计划书”给出行动方案(图5)。这个是因为InstructGPT/ChatGPT假设labeler编写的指示是合理且价值观正确的,并没有对用户给出的指示做更详细的判断,从而会导致模型会对任意输入都给出答复。虽然后面的奖励模型可能会给这类输出较低的奖励值,但模型在生成文本时,不仅要考虑模型的价值观,也要考虑生成内容和指示的匹配度,有时候生成一些价值观有问题的输出也是可能的。
图5:ChatGPT编写的毁灭人类计划书。

3.3 未来工作

我们已经分析了InstrcutGPT/ChatGPT的技术方案和它的问题,那么我们也可以看出InstrcutGPT/ChatGPT的优化角度有哪些了。

  • 人工标注的降本增效:InstrcutGPT/ChatGPT雇佣了40人的标注团队,但从模型的表现效果来看,这40人的团队是不够的。如何让人类能够提供更有效的反馈方式,将人类表现和模型表现有机和巧妙的结合起来是非常重要的。
  • 模型对指示的泛化/纠错等能力:指示作为模型产生输出的唯一线索,模型对他的依赖是非常严重的,如何提升模型对指示的泛化能力以及对错误指示示的纠错能力是提升模型体验的一个非常重要的工作。这不仅可以让模型能够拥有更广泛的应用场景,还可以让模型变得更“智能”。
  • 避免通用任务性能下降:这里可能需要设计一个更合理的人类反馈的使用方式,或是更前沿的模型结构。因为我们讨论了InstrcutGPT/ChatGPT的很多问题可以通过提供更多labeler标注的数据来解决,但这会导致通用NLP任务更严重的性能下降,所以需要方案来让生成结果的3H和通用NLP任务的性能达到平衡。

3.4 InstrcutGPT/ChatGPT的热点话题解答

  • ChatGPT的出现会不会导致底层程序员失业?从ChatGPT的原理和网上漏出的生成内容来看,ChatGPT生成的代码很多可以正确运行。但程序员的工作不止是写代码,更重要的是找到问题的解决方案。所以ChatGPT并不会取代程序员,尤其是高阶程序员。相反它会向现在很多的代码生成工具一样,成为程序员写代码非常有用的工具。
  • Stack Overflow 宣布临时规则:禁止 ChatGPT。ChatGPT本质上还是一个文本生成模型,对比生成代码,它更擅长生成以假乱真的文本。而且文本生成模型生成的代码或者解决方案并不能保证是可运行而且是可以解决问题的,但它以假乱真的文本又会迷惑很多查询这个问题的人。Stack Overflow为了维持论坛的质量,封禁ChatGPT也是清理之中。
  • 聊天机器人 ChatGPT 在诱导下写出「毁灭人类计划书」,并给出代码,AI 发展有哪些问题需关注?ChatGPT的「毁灭人类计划书」是它在不可遇见的指示下根据海量数据强行拟合出来的生成内容。虽然这些内容看起来很真实,表达也很流畅,这说明的只是ChatGPT具有非常强的生成效果,并不表示ChatGPT具备毁灭人类的思想。因为他仅仅是一个文本生成模型,并不是一个决策模型。

4. 总结

就像很多人们算法刚诞生时一样,ChatGPT凭借有用性,真实性,无害性的效果,引起了业内广泛的关注和人类对AI的思考。但是当我们看完它的算法原理之后,发现它并没有业内宣传的那么恐怖。反而我们可以从它的技术方案中学到很多有价值的东西。InstrcutGPT/ChatGPT在AI界最重要的贡献是将强化学习和预训练模型巧妙的结合起来。而且通过人工反馈提升了模型的有用性,真实性和无害性。ChatGPT也进一步提升大模型的成本,之前还只是比拼数据量和模型规模,现在甚至也引入了雇佣的外包这一支出,让个体工作者更加望而却步。

参考

  1. ^Ouyang, Long, et al. “Training language models to follow instructions with human feedback.” *arXiv preprint arXiv:2203.02155* (2022). https://arxiv.org/pdf/2203.02155.pdf
  2. ^Radford, A., Narasimhan, K., Salimans, T. and Sutskever, I., 2018. Improving language understanding by generative pre-training. https://www.cs.ubc.ca/~amuham01/LING530/papers/radford2018improving.pdf
  3. ^Radford, A., Wu, J., Child, R., Luan, D., Amodei, D. and Sutskever, I., 2019. Language models are unsupervised multitask learners. *OpenAI blog*, *1*(8), p.9. https://life-extension.github.io/2020/05/27/GPT%E6%8A%80%E6%9C%AF%E5%88%9D%E6%8E%A2/language-models.pdf
  4. ^Brown, Tom B., Benjamin Mann, Nick Ryder, Melanie Subbiah, Jared Kaplan, Prafulla Dhariwal, Arvind Neelakantan et al. “Language models are few-shot learners.” *arXiv preprint arXiv:2005.14165* (2020). https://proceedings.neurips.cc/paper/2020/file/1457c0d6bfcb4967418bfb8ac142f64a-Paper.pdf
  5. ^Wei, Jason, et al. “Finetuned language models are zero-shot learners.” *arXiv preprint arXiv:2109.01652* (2021). https://arxiv.org/pdf/2109.01652.pdf
  6. ^Christiano, Paul F., et al. “Deep reinforcement learning from human preferences.” *Advances in neural information processing systems* 30 (2017). https://arxiv.org/pdf/1706.03741.pdf
  7. ^Schulman, John, et al. “Proximal policy optimization algorithms.” *arXiv preprint arXiv:1707.06347* (2017). https://arxiv.org/pdf/1707.06347.pdf

OpenAI 代码生成模型 Codex: Evaluating Large Language Models Trained on Code

Codex

https://openai.com/blog/openai-codex/

Evaluating Large Language Models Trained on Code

Copilot的核心技术:给定函数名和功能描述,可以自动进行代码补全,或者给定代码,给出相关文档。作者团队收集了Github上所有的不重复的python代码,总计179GB,并进行了简单过滤(去掉了过大的文件(>1MB)和过长的代码(>100行或单行超过1000个字符)),在数据集上面训练了一个GPT3模型。

作者团队手动编写了164个函数(避免数据泄漏),每个函数包括代码、文档以及单元测试,平均每个问题包括7.7个测试样例,用于评估模型。Codex 12亿参数的模型能解决28.8%的问题,3亿参数的模型能解决13.2%的问题,作者团队又收集了一个跟测试集差不多的数据集用于模型微调,微调以后,得到Codex-S可以解决37.7%的问题。而使用 repeated sampling,即运行一百次模型,只要有一个输出解决了问题就算成功的话,那么Codex-S能解决77.5%的问题(CodeX能解决70.2%),而如果选择100个输出中概率最高的输出,则能解决44.5%的问题。

细节

1. 目标函数没有使用BLEU(困惑度),因为代码不同于自然语言,即使特别相似,但仍然可能不是一个合法的语句,作者使用:

来评估模型,即生成n个输出(n>k),从中随机抽取k个输出,这k个输出只要有一个能通过单元测试的概率.

代码近似计算pass@k(为什么要近似:如果k,n很大,计算很复杂)

2. 输出代码的测试在沙盒中进行(生成的代码可能是恶意的,会让你的机器出现问题)

3. 在GPT3原有模型上微调并不能取得更好的效果,但会加速收敛

4、代码里面的空格如果不做处理会带来很多不必要的词进去,对空格做特殊处理后会减少30%的词

5. 当模型输出‘\nclass’, ‘\ndef’, ‘\n#’, ‘\nif’, or‘\nprint’等语句时,模型会终止推理,输出结果

6. 使用nucleus sampling(核采样):选择概率总和p=95%的前k个输出用于评估模型

7. 对输出做softmax得到概率之前,会除以一个超参数Temperature,来调节不同输出之间的概率差距,当pass@k中的采样数k越大时,T越大效果越好

8. 收集了跟测试集类似的数据集用于微调,1)从各种比赛中收集赛题(大约一万个),2)从Continuous Integration中收集了约40000个函数和单元测试,并过滤(CodeX对每个问题生成一百个输出,如果能解决通过测试用例则保留该样本,反之则去掉(不能通过表示该问题太难或测试用例有问题)),在这个数据集上继续训练,训练方式相同,只是该数据集有“标准答案”,得到模型Code-S

9. 使用收集到的github数据集,重新训练一个GPT3模型用于反向生成文档,Codex-D,评测Codex-D模型好坏的方式是,一是人阅读文档评测模型好坏,二是使用生成的文档重新生成代码,看能否通过单元测试

模型局限性

1. 样本有效性不够,需要训练很多的代码,模型才能输出比较简单的实验

2. Prompt应该怎么写才能获得比较理想的代码,作者找了13 basic building block(对字符串做一些简单的操作:如改变大小写、变换位置等),将文档块任意串起来,发现文档越长,生成代码的质量越差,说明docstring不宜过长

3. 对于精确、复杂的数学问题很难生成正确的代码

模型潜在的影响

1. 过度依赖:人可能会过度依赖生成的代码,如果使用者不仔细审查代码,可能会给程序带来潜在的问题

2. Misalignment:模型足够复杂的时候,可能能输出期望的代码,但如果给定一个docstring,可能只能输出一个跟训练数据风格相似,看上去正确,但并不是期望的代码

3. github男性用户居多,所写的代码可能包含性别偏见

4. 市场和经济:很多程序员可能会失业?如果训练数据里的代码对于某些包使用较多,可能导致某些特别的工具使用率增多。

5. 安全:可能某些人用它写病毒和恶意软件

6. 训练这样一个模型需要使用很多资源

7. 法律:使用的是公开代码,fair use(对公共社会有好处的话并没有什么问题),但用于商业行为可能会有法律风险,生成的代码可能跟别人一模一样,可能存在抄袭别人具有版权或者专利保护的代码的风险。

总结

作者爬了很多github的代码,训练了一个GPT3的模型,为了评估模型的效果,准备了146到题用于测试,发现大概能解决大概30%的题,效果还不错,为了进一步提高分数,又收集了一个跟测试集相似的数据集,在上面微调。

GitHub Copilot

Copilot 相比论文codex中的区别:模型都是采用GPT3,但是 Copilot 使用的数据集不仅仅是python,还有其他语言的代码作为数据集。 GitHub 上公开可用存储库的数十亿行代码的训练 。

Copilot 作为一个辅助编程工具,GitHub Copilot 可以通过提供自动完成样式的建议来帮助你编写代码。GitHub Copilot 是一个 AI 配对程序员,可在编写代码时提供自动完成样式的建议。 可以从 GitHub Copilot 接收建议,方法是开始编写要使用的代码,或者编写描述代码要执行的操作的自然语言注释。 GitHub Copilot 会分析你正在编辑的文件以及相关文件中的上下文,并在文本编辑器中提供建议。 GitHub Copilot 由 OpenAI Codex 提供支持,OpenAI Codex 是一个由 OpenAI 创建的新 AI 系统。

不仅是关键字的自动补全,语法建议,调试建议等。而是帮助开发者更快速的完成业务代码编写。简而言之,GitHub Copilot 是一种 AI 工具,可根据命名或者正在编辑的代码上下文为开发者提供代码建议。

根据官方介绍,Copilot 已经接受了来自 GitHub 上公开可用存储库的数十亿行代码的训练,它支持大多数编程语言,但官方建议使用 Python、JavaScript、TypeScript、Ruby 和 Go。Copilot 是 GitHub 和OpenAI合作的结果, OpenAI得到了微软的大力支持。它由一个名为 Codex 的全新 AI 系统提供支持,该系统基于 GPT-3 模型

后续工作:

DeepMind AlphaCode 

DeepMind推出了自动写算法竞赛题的AI AlphaCode,宣称目前在Codeforces比赛中能排到中位数。Transformer + 超大数据集来做code generation。虽然现在也有很多工作用transformer做代码预训练,或者做代码翻译或者生成。但是从这么长的题面去生成竞赛的代码确实是头一次。

AlphaCode 参加的是一个名为 Codeforces 的在线编程平台。虽然我并不熟悉 Codeforces,但曾经为了准备面试刷过 LeetCode。如果说 LeetCode 就是为了程序员进互联网大厂刷题而生,主要考察程序员的算法和数据结构的能力的话,那 Codeforces 是一个竞赛版的 LeetCode,Codeforces 上的题目更像 ACM ICPC 或者信息学奥林匹克竞赛。

Codeforces 上的题目五花八门,但是都需要参赛者编程求解。每个题目有描述,有输入样例,有正确的输出样例,即test cases。如果提交的程序能够将所有test cases都跑出正确的结果,那么就算该题通过。一道题只有10次试错机会。

 AlphaCode 所求解的问题样例,深色的上半部分为编程问题描述,浅色的下半部分为 AlphaCode 生成的代码答案

Training:模型训练

AlphaCode 使用的经典的预训练+微调(Pretraining + Fine-tuning)范式。

预训练使用的是从 GitHub 爬下来的开源代码,经过了精细的预处理和清洗,大约有715GB。看到这个规模的训练数据,就知道只有屈指可数的几家巨无霸公司能够做这个预训练,实在是太大了,估计需要成千上万块GPU。预训练部分单纯就是让模型学习不同编程语言的套路,或者说学习编程语言中的语义和语法。

微调部分使用的是 CodeContests 数据集,这个数据集收集了很多类似 Codeforces 这样的编程平台上的编程题目、元数据以及人类正确和错误的代码提交结果。目的是针对 Codeforces 这样的编程竞赛,让模型学会如何生成对应的代码。这个数据集大约2GB。

AlphaCode 主要使用了编码器-解码器(Encoder-Decoder)的 seq2seq 方式建模。seq2seq 最经典的应用是机器翻译。给定源文本内容,Encoder 将自然语言编码为一些向量,Decoder 根据向量将自然语言解码为目标文本。那么对于AI自动写代码这个问题,就是输入编程题目,让模型生成目标代码。

Sampling & Evaluation:海量试错

图 AlphaCode架构图

上图为 AlphaCode 的架构,左侧(Data)为模型和数据部分,主要使用 Transformer 进行预训练和微调,右侧(Samping & Evaluation)是如何生成代码并参与 Codeforces 比赛。

AlphaCode 使用了经典的 Transformer 模型。有关 Transformer 的介绍,网络上已经有不少,我自己之前也写过一些 Transformer 和 BERT 的入门文章。关注深度学习的朋友都知道,Transfomer 作为当前大红大紫的AI模型,虽然在各个榜单上刷榜,但它并不具有人类基本的推理能力。

相比Transformer,我认为使得 AlphaCode 成功的主要在于这个 Sampling & Evaluation。这个 Sampling & Evaluation 系统有点类似搜索引擎或者推荐引擎。AI拥有存储和制作海量内容的能力,但无法知道人类真正需要什么。最关键的就是如何从海量内容中进行筛选。搜索或推荐引擎一般会对海量内容进行检索,最终呈现给用户的只有几条内容。海量的内容需要经过几大步骤:召回、粗排、精排、重排。其实就是先从海量的内容库中,先粗略筛选出一万篇的内容,再使用更精细的模型对一万篇进行一次次筛选,最终选择出与用户需求最相关的几篇内容。

AlphaCode 使用了一个 Transformer 模型,根据编程题目描述,生成百万份代码,这些生成的代码中99%可能根本跑不通。AlphaCode 使用编程题目中的test cases,验证这些生成的代码,这个过程会过滤掉99%的错误代码。

经过过滤之后,仍然可能有上千份代码能跑通,而且这些能跑通题目给出的测试样例的代码中很多非常相似。一个编程题目只有10次提交机会,每一次提交的机会都非常珍贵。不可能将上千份代码都提交上去。AlphaCode 这时候做了一个聚类(Clustering)。首先:AlphaCode 使用了第二个 Transformer 模型,根据编程题目中的文字描述,自动生成一些test cases。但是生成的test cases并不保证准确性,它是为了接下来的聚类用的。然后:将生成的test cases喂给那些代码,如果一些代码的生成结果近乎一样,说明这些代码背后的算法或逻辑相似,可被归为一类。文章称,经过聚类之后,从数目较大的类中选出代码去提交,更有胜算。

上图演示了这个过程,大致包括四步:

  1. 根据编程题目中的描述等信息,使用第一个Transformer模型,生成百万份代码。
  2. 使用编程题目中的测试样例test cases验证这百万份代码,把不能通过的过滤掉,剩下大约上千份代码。
  3. 使用第二个Transformer模型,生成一些test cases。
  4. 使用第3步生成的test cases,对第2步留下的代码进行验证并聚类,如果两份代码得到的结果相同,则分到同一类。经过聚类后,最终留下10类代码。

Capabilities & Limitations:能力和限制

深度学习是黑盒模型,我们不知道到底模型学到了什么,能否像人类一样认知和推理。论文花了很大精力和篇幅讨论了 AlphaCode 的能力和限制。

作者们提出了一个论点,即 AlphaCode 并不是单纯从训练数据中寻找相似解法,或者说 AlphaCode 并不是单纯从训练数据中拷贝代码。作者的验证方法是对比了生成的代码和训练集中的代码中的代码片段重合的情况,或者说检验 AlphaCode 是不是单纯从训练集里找一些核心代码片段并直接拷贝过来。因此,作者们认为,AlphaCode 具有解决新问题的能力,而不是照猫画虎地把训练数据拷贝搬运过来。知乎上有信息学竞赛选手感慨,有些题目对于人类专业选手来说都很难快速想出解法,但 AlphaCode 却能够得到答案。

作者们发现,模型生成的代码非常依赖编程题目中的描述。比如,同样一个解法,题目描述越冗长,AlphaCode 的求解准确度越低。但是对编程题目的一些其他改变对求解影响不大,比如更改变量名、同义词替换等。

总结

作者认为,AlphaCode 能够击败半数人类选手,主要原因在于:

  1. 训练数据足够大且质量高。
  2. Transformer 预训练模型能够将训练数据中涵盖的知识编码到模型中。
  3. Sampling & Evaluation 的海量试错机制,先生成海量可能的答案,再一步步缩小搜索空间。

阅读完论文和一些解读之后,我感觉至少短期内,离AI替代程序员应该还有一段距离。但是,未来,可真不好说…

不完全统计的Code预训练模型

微软亚洲研究院的CodeXGLEU,是近几年对代码智能任务整理最全的一个benchmark.

https://microsoft.github.io/CodeXGLUE/

GPT系列论文:生成式预训练与零样本学习

本文的主要参考是李沐老师关于 GPT 系列的解读:论文精读

GPT1: Improving Language Understanding by Generative Pre-Training (Generative Pre-Train Model 就是GPT模型的名字由来)

GPT2: Language Models are Unsupervised Multitask Learners

GPT3: Language Models are Few-Shot Learners

GPT3开发的demo: https://gpt3demo.com/

GPT-3: Demos, Use-cases, Implications

More concretely:

  • Language model performance scales as a power-law of model size, dataset size, and the amount of computation.
  • A language model trained on enough data can solve NLP tasks that it has never encountered. In other words, GPT-3 studies the model as a general solution for many downstream jobs without fine-tuning.

关于BERT和GPT

Transformer/BERT/GPT 时间线:Transformer —> GPT —> BERT —-> GPT2 —> GPT3。

如果去查 GPT 系列和 BERT 的引用数量,会发现 BERT 一篇的引用比 GPT 系列三篇加起来还多几倍,因此 BERT 在学界影响力更大是毋庸置疑的。但这并不能说明 BERT 的预训练任务就比 GPT 的更 “好”。首先,GPT 早于 BERT 提出在无监督的语料上进行大规模预训练,BERT 一定程度上也是受到 GPT 的启发。其次,GPT 的预训练任务是标准的语言模型(Language Model),即自回归式(auto-regressive)地预测句子中的下一个单词,相比于 BERT “完形填空” 式的预训练任务,无疑要难上许多。这使得 GPT 必须模型够大、数据够多才能训练起来,得到比较好的结果。这也是为什么 BERT 只有一篇论文,而 GPT 还有 GPT-2、GPT-3,通过不断扩增模型和数据的规模,最终使得 GPT-3 有如此惊艳的效果。对于这样困难的预训练任务和巨大的资源需求,一般的公司或个人根本玩不转。而 BERT 由于任务难度较小,相对并不需要那么多资源就可以进行预训练和微调,这也是为什么 BERT 的后续工作那么多(体现在引用量上)。但是,语言模型预测下一个单词的生成式任务,使得 GPT 的上限极高,GPT-3 通过写出足以以假乱真的文章,成为了最火出圈的 NLP 模型。另外,由于语言模型生成式任务的灵活性和巨大的预训练规模,GPT 甚至可以不需要(更新模型参数的)微调,而是通过文本 prompt 提示,就可以直接处理下游任务。

另外,很多人喜欢从从模型结构上来将 BERT 和 GPT 进行区分:BERT 使用了 Transformer 的编码器,适合于判别式任务;GPT 使用了 Transformer 的解码器,适合于生成式任务。然而,使用什么样的模型结构并不是 BERT 和 GPT 的本质区别。二者的本质区别在于选用了什么样的预训练目标函数,选用 Transformer 的编码器或解码器只是在确定了目标函数之后的必然选择。GPT 选用的是标准语言模型的目标函数,预测句子中的下一个单词,此时模型应该只能看到当前词和它之前的词,所以必须将当前词后面的词全部 mask 掉,故而选用带有 masked self-attention 的 Transfomer 解码器;而 BERT 是设计了一种 “完形填空” 式的预训练任务,根据当前词前后的内容还原当前词,此时模型应该可以看到整个序列的所有单词(当前词已被替换为特殊 token),故而选用了 Transformer 的编码器。当然,在讨论 BERT 与 GPT 时,将它们各自选用的架构作为直观的区分方式也是没有问题的。

GPT-1

Paper:Improving Language Understanding by Generative Pre-Training

前言

GPT 首先提出了在无监督的大规模预料上进行预训练,再在下游任务上进行微调的训练范式。至于为什么使用 Transformer 模型,而非 RNN,作者指出:Transformer 模型有更结构化的记忆(more structured memory),能够更好地处理文本中的长距离(long-term)依赖关系,从而能更好地抽取出句子层面和段落层面的语义信息,因此在迁移学习中,Tranformer 学习到的特征更加稳健。在迁移学习时,GPT 设计了各种任务相关(task-specific)的输入表示。

这里所谓的更结构化的记忆、长距离文本信息的论述,笔者是这样理解的:RNN(如 LSTM) 需要一步一步地处理序列内容,如果序列距离过长,可能走到后面时,前面的信息会有所丢失;而在 Transformer 中,自注意力机制的计算是完全并行的,序列的位置信息是通过位置嵌入来编码的,就不会有这个问题,即李宏毅老师所说的:“天涯若比邻”。

方法

原文方法部分分为三个小节,分别介绍如何在无标注的数据上进行自监督预训练、怎样进行微调、怎样对于不同的 NLP 下游任务构造输入。

预训练:

微调

方法部分的第二小节介绍了如何在预训练完成之后,在下游任务上进行微调。

假设有带标签数据集C ,其中每个样本是一个由一系列单词组成的句子和标签 y 组成。将句子输入到 GPT 模型中,取最后一个 transformer block 最后一个单词的输出特征,将它送入到线性层中进行预测:

不同任务的输出构造

介绍完如何微调之后,接下来就要介绍如何将 NLP 中不同的下游任务的输入表示成第二小节中句子+标签 的形式。如下图右侧所示,图中展示了几种不同类型的 NLP 下游任务适配 GPT 预训练模型的输入构造方法:

分类任务

  • 任务简介:任务给定一段文本,输出分类结果。例如:情感分类。
  • 构造方法:将给定的文本首尾各加上一个 token Start/Extract,然后送到 GPT 预训练模型中,将输出特征接一个线性层进行分类。分类任务与之前微调小节介绍的做法是完全一致的,

蕴含任务(非对称性句子关系任务)

  • 任务简介:给定两段文本,判断前者对后者关系。例如:蕴含任务,判断第一句对第二句的关系是蕴含/不蕴含/无关。
  • 构造方法:将两个句子中间添加一个分割 token Delim,然后将整个文本的首尾再加上 Start/Extract,送入 GPT 预训练模型,将输出特征送入线性层分类。

相似度任务(对称性句子关系任务)

  • 任务简介:给定两段文本,判断二者关系。例如:相似度任务,判断两个句子是否相似。
  • 构造方法:将两个句子分别作为前句或后句,构造两个完整文本,各自送入 GPT 预训练模型,提取出特征并进行融合,再送入线性层分类。

多选任务

  • 任务简介:给定一段文本和多个答案,判断哪个正确。
  • 构造方法:将给定文本和 N 个答案结合,构造 N 个完整文本,各自送入 GPT 预训练模型,提取出特征并送入线性层,取置信度最大者。

GPT模型结构(左)与微调下游任务输入构造方式(右)

注意图中的开始符(Start)、分隔符(Delim)、结束符(Extract)不是这几个单词本身,而是三个特殊的符号。

GPT-2

Paper:Language Models are Unsupervised Multitask Learners

前言

GPT 出现后不久,BERT 就提出了。通过新型的 MLM(Masked Language Model)任务和更大的模型、更大的训练数据量,在多项指标上超越了 GPT。GPT 的作者想要再次反超,首先肯定要扩大模型和数据的规模。但是除此之外,GPT-2 还有一个惊人的设定:zero-shot(零样本)。顾名思义,在 zero-shot 设定下,模型在预训练完成之后不需要任何下游任务的标注数据来进行微调,而是直接进行预测。

GPT-2 在研究思路上带给我们的启示是:有时候做研究不一定要在一个既定指标上死磕。在方法没有大创新的情况下,通过 “大力出奇迹” ,即使能够比之前方法有所提升,文章也会显得有些无聊。这时可以思考一些设定上的创新,如本文的 zero-shot,这时即使指标上提升不多甚至持平,也会有更有新意、更有趣。

方法

GPT2还是做语言模型,但是在做到下游任务的时候,会用一个叫做zero-shot的设定,zero-shot是说,在做到下游任务的时候,不需要下游任务的任何标注信息,那么也不需要去重新训练已经预训练好的模型。这样子的好处是我只要训练好一个模型,在任何地方都可以用。
如果作者就是在GPT1的基础上用一个更大的数据集训练一个更大的模型,说我的结果比Bert好一些,可能也就好那么一点点,不是好那么多的情况下,大家会觉得gpt2这篇文章就没什么意思了,工程味特别重。那么我换一个角度,选择一个更难的问题,我说做zero-shot。虽然结果可能没那么厉害了,没那么有优势,但是新意度一下就来了。

GPT-2 的模型跟 GPT-1 一样,这里就不再过多介绍。本节主要来说一下 zero-shot 要怎么做。

在 GPT-1 中,模型预训练完成之后会在下游任务上微调,在构造不同任务的对应输入时,我们会引入开始符(Start)、分隔符(Delim)、结束符(Extract)。虽然模型在预训练阶段从未见过这些特殊符号,但是毕竟有微调阶段的参数调整,模型会学着慢慢理解这些符号的意思。现在,在 GPT-2 中,要做的是 zero-shot,也就是没有任何调整的过程了。这时我们在构造输入时就不能用那些在预训练时没有出现过的特殊符号了。所幸自然语言处理的灵活性很强,我们只要把想要模型做的任务 “告诉” 模型即可,如果有足够量预训练文本支撑,模型想必是能理解我们的要求的。

举个机器翻译的例子,要用 GPT-2 做 zero-shot 的机器翻译,只要将输入给模型的文本构造成 translate english to chinese, [englist text], [chinese text] 就好了。比如:translate english to chinese, [machine learning], [机器学习] 。这种做法就是日后鼎鼎大名的 prompt。

在训练数据的收集部分,作者提到他们没有使用 Common Crawl 的公开网页爬取数据,因为这些数据噪声太多,太多无意义的内容。他们是去 Reddit 爬取了大量有意义的文本。作者还指出,在 Reddit 的高质量文本中,很可能已经有类似 zero-shot 构造方式的样本供模型学习。一个机器翻译的例子如下所示。

In a now-deleted post from Aug. 16, Soheil Eid, Tory candidate in the riding of Joliette, wrote in French: ”Mentez mentez, il en restera toujours quelque chose,” which translates as, ”Lie lie and something will always remain.

实验

在与同样为 zero-shot 模型的对比上,肯定是吊打了之前的 SOTA,这里就不展示了。可以关注一下下面 GPT-2 模型 zero-shot 性能关于模型规模的曲线。在有些任务上已经接近、超过之前某些有监督的方法;在比较困难的任务上,比如开放域问答,完全还看不到别人的影子。然而,看看曲线末端性能随模型规模提升的趋势,完全没有收敛的意思,这最后一段翘起的曲线,昭示着 GPT-3 继续大力出奇迹,从量变到质变的希望。

GPT-3

Paper:Language Models are Few-Shot Learners

前言

根据沐神关于论文价值给出的公式:论文价值 = 有效性 * 新意度 * 问题的大小。GPT-2 虽然通过 zero-shot 的设定,将自己的新意度凸显了出来,但是有效性(绝对性能)还是不太令人满意。GPT-3 ,众所周知的 “大力出奇迹” 式的文章,通过海量数据训练了一个 175 Billion 参数的预训练语言模型,性能直接拉满。甚至有点从量变到质变的意思,GPT-3 通过自回归式语言模型的生成能力,可以生成一些像模像样的文章,有时人类都很难读出这些文章是出自于 AI 模型生成,这也是为什么 GPT-3 能够成为 NLP 领域最火出圈的模型,文本生成能力使得它玩法众多。在任务设定上,GPT-3 没有固守于 GPT-2 的 zero-shot 方式。因为即使对于人类来说,要完成一个新任务,如果一个示例也不给的话,也有点强人所难了。如标题所示,GPT-3 采用了 few-shot 的任务设定,即给出下游任务的一两个例子,然后要求模型对该任务的新问题给出预测。当然,如此大规模的模型,即使是一两个样本,用梯度下降法微调模型权重也很费劲。因此,GPT-3 中所谓的 “few-shot”,与一般的根据支持集(下游任务示例)进行梯度下降更新参数的 few-shot 方法不同,它是利用自然语言的灵活性,将支持集示例放到 prompt 里,让模型自己理解示例,完成下游任务 few-shot 预测。

下图展示了 GPT-3 在不同的 NLP 任务上的性能随模型规模的变化,橙、绿、蓝分别代表 few-/one-/zero shot 方式,淡化的曲线是在不同任务上各自的准确率。实线是平均准确率。可以看到,随着模型规模的增大,性能还是有一定提升的。

方法

GPT-3 的预训练方式和之前还是一样的,模型结构也改动不大。还是在 Transformer 解码器上做标准语言模型的预训练,但是模型规模和数据规模大了几个数量级。这里我们还是主要来看一下 GPT-3 中所谓的 few-/one-/zero- shot 方式分别是什么意思。

下图展示了 GPT-3 中的 few-/one-/zero- shot 方式与常规的微调方式。

  • 微调方式的小样本学习,需要根据给出的下游任务样本和标注,构造损失函数,方向传播梯度,更新模型权重,然后进行预测。GPT-3 中完全没有采取这种方式。
  • Zero-shot,给定任务描述,如 Translate English to French,然后直接给出问题,要求模型给出答案。这种方式与 GPT-2 一致。
  • One-shot,给定任务描述,然后给一个例子,包括问题和答案,如 sea otter => loutre de mer,之后再给出问题,将上述整一段文本作为输入,要求模型给出答案。这种方式期望模型利用预训练阶段海量的文本数据积累和 Tranformer 的自注意力机制,理解问题和示例,然后仿照示例给出预测。
    笔者认为这种方式可行的根本原因是自然语言的灵活性和生成式模型的创造性,使得我们能够直接跟模型进行交互,把要做什么任务、任务示例直接 “打字告诉它”。在计算机视觉领域,好像很难做到类似的事情。
  • Few-shot,与 One-shot 类似,只是给的示例更多。

GPT-3 中的任务设定很惊艳,但是细想之下,也是无奈之举并且也有缺点。一方面,模型规模实在太大,微调来更新权重参数不可行,只好采用 few-shot 的方式。另一方面,模型权重不能更新,每次理解下游任务之后不能保存下来,也就是说每次做同一个下游任务都要给同样的例子。还有,下游任务的示例也不能太多,因为模型可能无法处理过长的输入序列。如果在我们的实际下游任务中确实有不少可供学习的样本,GPT-3 恐怕不是一个好的选择。所以,虽然 GPT-3 能做到的事情似乎听起来更接近 “人工智能”,但是相关的跟进工作并不多。

这应该是作者们充分挖掘模型能力,规避模型缺点,扬长避短设计出的任务设定,这种思路值得学习。

关于大规模预训练的调参、数据准备与清洗、工程实践等,GPT-3 论文中也有讨论,这里就不提了,有兴趣可以参考原文。

再后面关于实验、GPT-3 的不足以及可能的社会影响作者写了很多,本文主要关注算法部分,后面就不一一介绍了,同样请参考原文。

Ref

Prompting—ERNIE-Layout

类别:跨模态大模型(用于文档分类、信息抽取、文档问答等)

•ERNIE-Layout: Layout Knowledge Enhanced Pre-training for Visually-rich Document Understanding (EMNLP 2022)

•Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing (arxiv 2021)

模型试玩:https://huggingface.co/spaces/PaddlePaddle/ERNIE-Layout

Github: https://github.com/PaddlePaddle/PaddleNLP/tree/develop/applications/document_intelligence

随着众多行业的数字化转型,电子文档的结构化分析和内容提取成为一项热门的研究课题。电子文档包括扫描图像文件和计算机生成的数字文档两大类,涉及单据、行业报告、合同、雇佣协议、发票、简历等多种类型。智能文档理解任务以理解格式、布局、内容多种多样的文档为目标,包括了文档分类、文档信息抽取、文档问答等任务。与纯文本文档不同的是,文档包含表格、图片等多种内容,包含丰富的视觉信息。因为文档内容丰富、布局复杂、字体样式多样、数据存在噪声,文档理解任务极具挑战性。随着ERNIE等预训练语言模型在NLP领域取得了巨大的成功,人们开始关注在文档理解领域进行大规模预训练。百度提出跨模态文档理解模型 ERNIE-Layout,首次将布局知识增强技术融入跨模态文档预训练,在 4 项文档理解任务上刷新世界最好效果,登顶 DocVQA 榜首。同时,ERNIE-Layout 已集成至百度智能文档分析平台 TextMind,助力企业数字化升级。

原理介绍

对文档理解来说,文档中的文字阅读顺序至关重要,目前主流的基于 OCR(Optical Character Recognition,文字识别)技术的模型大多遵循「从左到右、从上到下」的原则,然而对于文档中分栏、文本图片表格混杂的复杂布局,根据 OCR 结果获取的阅读顺序多数情况下都是错误的,从而导致模型无法准确地进行文档内容的理解。

而人类通常会根据文档结构和布局进行层次化分块阅读,受此启发,百度研究者提出在文档预训模型中对阅读顺序进行校正的布局知识增强创新思路。TextMind 平台上业界领先的文档解析工具(Document Parser)能够准确识别文档中的分块信息,产出正确的文档阅读顺序,将阅读顺序信号融合到模型的训练中,从而增强对布局信息的有效利用,提升模型对于复杂文档的理解能力。

基于布局知识增强技术,同时依托文心 ERNIE,百度研究者提出了融合文本、图像、布局等信息进行联合建模的跨模态通用文档预训练模型 ERNIE-Layout。如下图所示,ERNIE-Layout 创新性地提出了阅读顺序预测和细粒度图文匹配两个自监督预训练任务,有效提升模型在文档任务上跨模态语义对齐能力和布局理解能力。

image (14).png

文心ERNIE-Layout以文心ERNIE为底座,融合文本、图像、布局等信息进行跨模态联合建模,创新性引入布局知识增强,提出阅读顺序预测、细粒度图文匹配等自监督预训练任务,升级空间解耦注意力机制。输入基于VIMER-StrucTexT大模型提供的OCR结果,在各数据集上效果取得大幅度提升,相关工作已被EMNLP 2022 Findings 会议收录。

▲ 文心ERNIE-Layout 技术框架

Embedding

Embedding 的输入包括:文本的token_ids,文本内容对应的 bounding box(包含 x1, x2,y1,y2,h,w),图片,以及图片对应的 bounding box。

其中 bounding box 的数值被转换到 0-1000 范围。而后通过一个 Embedding 来分别计算得到对应的 x1_embedding, x2_embedding, y1_embedding 等等 6 个 embeddings。

文字 Embedding

embeddings = (input_embedings + position_embeddings + x1 + y1 + x2 +
              y2 + h + w + token_type_embeddings)
# x1, y1, x2 , y2 , h , w : bounding box 各个值对应的 embedding
​
embeddings = self.layer_norm(embeddings)
text_embeddings = self.dropout(embeddings)
  • 其中采用可学习的 position_embeddings
  • 采用 Layout-Parser 对图片中的文本内容,根据阅读顺序进行排序,安排对应的 position_ids
  • Layout Embedding:the OCR tool provides its 2D coordinates with the width and height of the bounding box

图像 Embedding

图片被转换成 224* 224 的格式,经过 backbone 编码后,分割成了 7*7 个 patch。

x = self.visual(image)  # x [batch, 49, 256]
visual_embeddings = self.visual_act_fn(self.visual_proj(x)  # batch, 49, hidden_size

与文本 Embedding 相同,visual_embeddings 需要再加上 position_embeddingstoken_type_embeddignsbbox_embeddigns 等,得到最终图像 embedding。

预训练

  • Reading Order Prediction:对文字部分,判断token之间的先后阅读顺序。可以通过阅读顺序构建一个包含 01 的邻接矩阵,而后与 attention matrix 计算交叉熵。
  • Replaced Region Prediction:对于图片部分,有 10% 的概率替换图片 patch,通过 cls 位置的编码判断哪些 patch 被替换了
  • Masked Visual-Language Modeling:类似 MLM,只是这次我们可以用图片部分的embedding信息来预测被遮盖的文字内容。
  • Text-Image Alignment:随意覆盖一些文字,然后用一个线性层进行分类任务,判断文字是否被覆盖住了。

文心ERNIE-mmLayout为进一步探索不同粒度元素关系对文档理解的价值,在文心ERNIE-Layout的基础上引入基于GNN的多粒度、多模态Transformer层,实现文档图聚合(Document Graph Aggregation)表示。最终,在多个信息抽取任务上以更少的模型参数量超过SOTA成绩,相关论文被ACM MM 2022会议收录 。▲ 文心ERNIE-mmLayout 技术框架

Ernie-layout 整体采用 Transformer Encoder 架构,特点在于:

  • 借鉴了 DeBERTa 的解耦注意力,依靠额外的 Layout-Parser 来设计 position_ids。
  • 同时对文档图片及文档中的文字进行编码,并设计了4种图文结合的预训练方式。
  • 需要依靠额外的 OCR 工具来获得图片中的文字内容,及其对应位置信息。

以下是文档智能技术的一些应用场景展示:

  • 发票抽取问答
  • 海报抽取问答
  • 网页抽取问答
  • 表格抽取问答
  • 试卷抽取问答
  • 英文票据多语种(中、英、日、泰、西班牙、俄语)抽取问答
  • 中文票据多语种(中简、中繁、英、日、法语)抽取问答

Visual Prompting

(a)Fine-tuning adapts the entire model parameters.

(b)Linear probes adapt the model outputs (usually activations at the penultimate layer) by learning a linear layer.

(c)Prompting adapts the (downstream) dataset by reformulating the input and/or output.

相关论文:https://github.com/thunlp/PromptPapers

DETR :End to End Object Detection with Transformers

目标检测领域的里程碑式的工作

https://arxiv.org/abs/2005.12872

code:https://github.com/facebookresearch/detr Facebook AI(meta AI)

DETRDetection Transformers

文章题目:简单明了,包含两个关键词:端到端、transformer

目标检测领域:从目标检测开始火到detr都很少有端到端的方法,大部分方法最后至少需要后处理操作(NMS,non-maximum suppression非极大值抑制)。无论是proposal based方法、anchor based方法、non-anchor based方法,最后都会生成很多预测框,如何去除这些冗余的框就是NMS要做的事情。

问题:有了NMS,模型调参就会很复杂,而且即使训练好了一个模型,部署起来也非常困难(NMS不是所有硬件都支持)。所以一个简单的、端到端模型一直是大家梦寐以求的,而detr的出现解决了这些痛点。

一、Detr目标:

1、不需要proposal、不需要anchor,直接利用transformer这种全局建模的能力,把目标检测看做是集合预测问题

2、因为有了这种全局建模的能力,detr不会有那么多冗余框,最后出什么结果就是什么结果,不需要NMS做后处理,让模型的训练和部署简单不少

目的:不想让大家觉得目标检测是比图像分类难很多的任务,都可以用简单的,优雅的框架做出来

二、摘要

作者说,他们就是把目标检测的任务看成是一个集合预测问题:目标检测本来任务就是给定一个图像,预测一堆框,每个框不仅要知道的其坐标,还要知道框里包含物体的类别,这些框就是一个集合,不同的图像对应的集合也是不同的,给定一个图片,我要预测这个集合

因此这篇文章就是把目标检测做成一个端到端的框架,把之前特别依赖人的先验知识的部分删掉了(NMS部分、anchor),一旦把这两个部分拿掉之后,我们也不用费尽心思设计这种anchor,最后不会出现这么多框,不会用到NMS,也不会用到很多超参去调。两个贡献:1、使用新的目标函数,通过二分图匹配的方式,强制模型输出一组独一无二的预测(没有那么多冗余框,每个物体理想状态下就会生成一个框)。2、另外使用encoder-decoder的架构。

两个小贡献:

1、decoder还有另外一个输入learned object query,类似anchor的意思(给定这些object query之后,detr就可以把learned object query和全局图像信息结合一起,通过不同的做注意力操作,从而让模型直接输出最后的一组预测框)

2、想法&&实效性:并行比串行更合适,并不是检测一个大物体前必须先检测一个小物体,或从左到右检测,我们希望越快越好

DETR的好处:

1、简单性:想法上简单,不需要一个特殊的library,只要硬件支持transformer或CNN,就一定支持detr

2、性能:在coco数据集上,detr和一个训练非常好的faster RCNN基线网络取得了差不多的效果,模型内存和速度也和faster RCNN差不多

3、想法好,解决了目标检测领域很多痛点,写作好

4、别的任务:全景分割任务上detr效果很好,detr能够非常简单拓展到其他任务上

三、引言

1、目标检测任务:对每一个感兴趣的物体,去预测一些框,和物体类别,就是一个集合预测问题。

2、现在大多数好用的目标检测器,都是用间接的方式去处理集合预测问题,(1)比如proposal方式(如RCNN系列工作),(2)anchor方式(YOLO系列,focal loss),non-anchor based方法(物体中心点center net,FCOS),他们都没有直接做集合预测任务,而是设计一个替代(回归、分类)解决目标检测问题。所有这些方法性能受限于后处理操作(NMS),由于用了anchor和NMS导致检测器都非常复杂,难以优化和调参。

3、端到端的思想已经在别的很多任务里大范围使用,而且使任务更加简单好用,我们不要先验知识,就是要用一个端到端网络。

detr流程(训练):

1、CNN提特征

2、特征拉直,送到encoder-decoder中,encoder作用:进一步学习全局信息,为近下来的decoder,也就是最后出预测框做铺垫。直观的解释为什么需要使用transformer encoder呢?如果使用了transformer encoder,那么每一个点或者说每一个特征就会跟着图片里面的其他的特征有交互了,这样大概就知道那块是那个物体,对于同一个物体就应该只出一个框而不是好多框,所以全局的建模有利于移除冗余的框。

3、decoder生成框的输出,当你有了图像特征之后,还会有一个object query(限定了你要出多少框),通过query和特征在decoder里进行自注意力操作,得到输出的框(文中是100,无论是什么图片都会预测100个框)

4、生成的100个框如何与ground truth这个框做匹配并计算 loss? :二分图匹配,如上图,我们计算100个预测的框和2个GT框的matching loss,决定100个预测框哪两个是独一无二对应到红黄色的GT框,用匹配的框去算目标检测的loss。而没有匹配到的98个框就会被标记为没有物体。

5、推理1、2、3一致,第四步loss不需要,直接在最后的输出上用一个阈值卡一个输出的置信度,置信度比较大(>0.7的)保留,置信度小于0.7的当做背景物体。

结果:

1、detr对大物体预测很准,归功于transformer,能进行全局建模(原来使用anchor的话就会受限于anchor大小)

2、缺陷:对小物体效果不好(多尺度、多特征,可以提高小物体的检测)后续改进:Deformable DETR

3、detr训练很慢,500个epoch(coco大多数模型一般训练几十个epoch就行)

检测效果:

detr由于使用transformer全局建模,没有用anchor,想检测多大物体就检测多大,所以检测大物体效果较好。detr框架太简单,没有多尺度特征,没有FPN,没有复杂的目标检测头,所以在小目标检测效果不好

四、相关工作

目标检测:

目前大多数的检测器是根据初始猜测做预测:

1、two-stage:初始猜测是中间的proposal

2、one-stage:初始猜测是anchor或物体中心点

最近一篇论文做了详细比较,发现他们的性能和刚开始的初始猜测非常相关,怎么做后处理对性能影响至关重要

怎么后处理:

1、集合思想:可学习的NMS方法、关系型网络,可以利用自注意力方法去处理物体之间的联系,得出独一无二的预测,就不需要后处理的步骤(性能较低)

解决:人工干预:手工设计的场景特征帮助模型学习,但是detr目标是想让目标检测任务更加简单,不希望用到过多人工先验知识

2、循环检测器:encoder-decoder:让detr工作主要原因:transformer

五、方法

分两块:1、基于集合的目标函数怎么做,作者如何通过二分图匹配把预测的框和GT框连接在一起,算得目标函数 2、detr具体模型架构

目标函数部分:

detr模型最后输出是一个固定集合,无论图片是什么,最后都会输出n个(本文n=100)预测框

问题:detr每次都会出100个输出,但是实际上一个图片的GT的bounding box可能只有几个,如何匹配?如何计算loss?怎么知道哪个预测框对应GT框?

作者这里把这个问题转换成了一个二分图匹配的问题:

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。

加权二分图匹配可以认为是有ABC三个工人,以及xyz三个工作,每个工人去做xyz工作的花费不同,如何去为每一个个人安排一个工作,使得最后我们的花费最低,可以使用遍历的方法,亦可以有很多高效的方法:匈牙利算法。

另外scipy包提供的linear sum assignment可以完成这个最优排列。detr论文里:代码也用的linear sum assignment函数来计算对应的匹配关系,只需要提供一个cost matrix矩阵就可以。a,b,c看成100个预测框,x,y,z看成GT框, cost matrix 损失矩阵未必都是正方形,最后丢到这个函数里面得到一个最优匹配。

那么对于目标检测任务,cost matrix 损失矩阵的值应该放些什么?loss包含两部分:分类loss、出框的准确度。所以也就是遍历所有的预测的框,那这些预测的框和gt框去算两个loss,然后把这个loss放到cost matrix矩阵 就可以了。这样就得到了对应gt的预测框(一对一),进而计算loss,梯度回传更新模型参数。

detr主体网络框架:

输入图片大小:3*800*1066(3:rgb),首先使用卷积网络获得特征:2048*25*34,然后降维变成256*25*34,然后给transformer添加位置信息:大小也是256*25*34,特征+位置作为transformer输入,特征拉直: 256*25*34 ==》 850*256,850就是序列长度,256是向量维度。后面的transformer encoder就跟普通的transformer encoder一样,输出==输出,仍然是850*256,接下来送入decoder里面。不同于一般的decoder,这里的object queries是一个可学习的,100*256大小的向量。在decoder里面做cross attension。输入 object queries ,另外一个输入是来自encoder的全局特征850*256.这两个去做自注意力操作,得到一个100*256的特征的decoder输出。最后添加一个检测头全连接层(FFN),获得类别预测(91类)和框预测(4:框的中心的+高度宽度),获得了100个框,利用匈牙利算法跟gt匹配,然后求loss,更新模型。

六、实验

检测效果:detr由于使用transformer全局建模,没有用anchor,想检测多大物体就检测多大,所以检测大物体效果较好。detr框架太简单,没有多尺度特征,没有FPN,没有复杂的目标检测头,所以在小目标检测效果不好。

下面的表格给出了 DETR 与基线 Faster RCNN 的定量性能对比。最上面一部分的 Faster RCNN 的性能结果是 Detectron2 的实现,之所以将 Faster RCNN 分成两部分,是因为 DETR 中使用了近年来很多新的训练 trick,如 GIoU loss、更强的数据增强策略、更长的训练时间,因此作者团队添加这些策略重新训练了 Faster RCNN,以作公平的对比。

近年来的新的训练策略对于目标检测模型的提升非常明显。对比表格的第一、第二部分,完全相同的模型,只是用了更优的训练策略,基本能稳定涨两个点。在同样的训练策略、网络规模大小的情况下,DETR 比 Faster RCNN 高 1-2 个点。对比表格的后两部分可以观察到这一点,DETR 对比基线的 Faster RCNN 还是还是有提升的。

DETR 在大物体的检测上远超 Faster RCNN,但是在小物体的检测上却也低了不少。

表格的后三列分别是小、中、大物体的检测性能,可以观察到 DETR 在大物体的检测上更出色,但是对于小物体的检测甚至远不如 Faster RCNN。大物体检测性能的提升得益于 Transformer 结构的全局建模能力,且没有预置的固定 anchor 的限制,因此预测框想多大就多大。而 DETR 在小物体上表现不佳,是因为本文中 DETR 的模型还是一个比较简单的模型,没有做很多针对目标检测的优化设计,比如针对小物体、多尺度的 FPN 设计。DETR 的网络结构还有待后续工作来改进。

表 1 detr和faster RCNN的对比,+表示用更好的训练策略把三个模型重新训练一遍

gflops参数:每秒进行的浮点运算次数,flops越小,模型越小,跑起来越快?X。如果更关心速度,比较fps

首先我们来看对于 Encoder 的可视化,下图展示了对于一组参考点的 Encoder 注意力热力图的可视化,即参考点对于图像中所有其他点自注意力值的大小。可以观察到,Transformer Encoder 基本已经能够非常清晰地区分开各个物体了,甚至热力图已经有一点实例分割的 mask 图的意思了。在有一定遮挡的情况下(左侧两头牛),也能够清楚地分开哪个是哪个。这种效果正是 Transformer Encoder 的全局建模能力所带来的,每个位置能够感知到图像中所有的其他位置。因此能够区分出图像中的不同物体,从而对于一个物体,尽量只出一个预测框。

通过前面的可视化,我们已经看到,Encoder 学习了一个全局的特征,基本已经能够区分开图中不同的物体。但是对于目标检测来说,大致地区分开不同的物体是不够的,我们还需要精确的物体的边界框坐标,这部分就由 Decoder 来做。

下图在 Decoder 特征中对每个不同的物体做了注意力的可视化,比如左图中的两头大象分别由蓝色和橙色表示。可以观察到,Decoder 网络中对于每个物体的注意力都集中在物体的边界位置,如大象的鼻子、尾巴、象腿等处。作者认为这是 Decoder 在区分不同物体边界的极值点(extremities),在 Encoder 能够区分开不同的物体之后,Decoder 再来关注不同物体边界的具体位置,最终精准地预测出不同物体的边框位置。因此,Encoder-Decoder 的结构是必要的,它们各司其职,一个都不能少。

扩展到全景分割任务

作者同时还将该网络应用于全景分割任务中.增加一个分割的head就可以。

下图是20个object query可视化(n=100,这里只有20个)

object query 到底学了什么(绿色代表小的bounding box,红色代表大的横向bounding box,蓝色代表大的竖向bounding box)object query和anchor有些像,anchor是提前定一些bounding box,把预测和这些提前定好的bounding box对比,object query是可以学习的。以第一个 object query 来说:对于一个图片, object query 会去问图片的左下角有没有小物体,以及中间有没有横向的大物体。

为了说明端到端的 DETR 框架的简洁性,作者在论文末尾给出了 DETR 模型定义、推理的 “伪代码”,总共不到 50 行。之所以这里的伪代码要加引号,是因为其实这已经不算是伪代码了,而是直接可运行的 PyTorch 代码。当然这个版本缺少了一些细节,但也完全能够展现出 DETR 的流程了。该版本直接用来训练,最终也能达到 40 的 AP。读者可以对应伪代码再过一遍刚才介绍的 DETR 完成流程,体会一下一个端到端的目标检测框架有多幺简洁。

代码实现:

后续关于detr的改进工作:

1、Deformable DETR: Deformable Transformers for End-to-End Object Detection

2、Omni-DETR: Omni-Supervised Object Detection with Transformers

3、UP-DETR: Unsupervised Pre-training for Object Detection with Transformers

4、PnP-DETR: Towards Efficient Visual Analysis with Transformers

5、SMAC-DETR

6、DAB-DETR: Dynamic Anchor Boxes are Better Queries for DETR

7、Accelerating DETR Convergence via Semantic-Aligned Matching

8、DN-DETR: Accelerate DETR Training by Introducing Query DeNoising

9、Open-Vocabulary DETR with Conditional Matching

10、OW-DETR: Open-world Detection Transformer

多模态| ALBEF

视频:多模态论文串讲

https://arxiv.org/abs/2107.07651

code: https://github.com/salesforce/ALBEF

写在前面:最近看了很多多模态的工作,现有的设计有哪些不足?我们又该如何去改进呢?首先来看模型的结构,因为需要处理文本和图片,所以模型开始需要有两个分支,分别抽取图像和文本特征。但是在多模态领域,视觉特征的重要性远远大于文本特征,所以要使用更强大的vision Embed,比如vit,同时对于多模态任务,多模态之间的融合也是十分重要的,也要保证模态融合的模型也要尽可能的大,因此网络应该跟(c)相近。模型确定了,接下来如何去训练呢?我们知道CLIP模型使用了一个对比学习的loss:ITCloss,这个效果很好,所以可以使用。另外常见的两个loss: image text matching(ITM),另一个是masked language modeling(MLM) 也可以继续使用。再回到ALBEF论文,其实它就是按照上述思路进行的设计。

它由一个图像编码器、一个文本编码器和一个多模态编码器组成。文章提出了一种图像文本对比损失,在图像文本融合之前对图像文本进行统一表示建模。图像文本匹配损失和掩码语言建模损失被应用于学习图像和文本之间的多模态交互。为了改进噪声数据的学习,我们使用动量模型生成伪目标来作为训练期间的额外监督。

为了改进在噪声监督下的学习,作者提出了动量蒸馏(MoD) ,使模型能够利用一个更大的web数据集。在训练过程中,作者通过取模型参数的移动平均来保持模型的动量版本,并使用动量模型生成伪目标作为额外的监督。 动量蒸馏可以解释为一种在线自我蒸馏的形式,其中使用学生模型组成的集合作为老师。类似的方法已经在半监督学习、标签噪声学习以及最近的对比学习中进行了探索应用。与现有研究不同,本文从理论上和实验上表明,动量蒸馏是一种通用的学习算法,可以提高模型在许多V+L 任务上的性能。

Pre-training Objectives

作者对ALBEF进行了三个目标的预训练:单模态编码器上的图像-文本对比学习(ITC) 、掩蔽语言建模(MLM) 和多模态编码器上的图像-文本匹配(ITM) 。作者通过在线对比 hard negative挖掘来改进ITM。

Image-Text Contrastive Learning

图像-文本对比学习的目的是在融合预训练更好的单模态表示。它学习了一个相似性函数,使匹配的图像-文本对具有更高的相似性得分。和是将[CLS]嵌入映射到标准化的低维(256d)表示的线性变换。

受MoCo的启发,作者维护了两个队列来存储动量单模态编码器的最新的M个图像-文本表示。动量编码器的归一化特征记为和。作者定义了和。

对于每个图像和文本,作者计算softmax归一化的图像到文本和文本到图像的相似度如下:

其中,τ是一个可学习的温度参数。设和表示ground truth的one-hot形式相似性,其中负对的概率为0,正对的概率为1。图像文本对比损失定义为p和y之间的交叉熵H:

Masked Language Modeling

Masked Language Modeling 同时利用图像和上下文文本来预测mask词。作者以15%的概率随机mask输入token,并用特殊token [MASK]替换它们。设表示mask文本,表示模型对mask token的预测概率。MLM使交叉熵损失最小化:

其中是一个one-hot形式的词汇分布,ground truth token的概率为1。

Image-Text Matching

图像-文本匹配可以预测一对图像和文本是正的(匹配)还是负的(不匹配)。作者使用多模态编码器的输出嵌入的[CLS] token作为图像-文本对的联合表示,并附加一个全连接(FC)层,然后是softmax来预测一个两类概率。

其中,是一个表示ground truth标签的二维one-hot向量。

作者提出了一种基于零计算开销的ITM任务进行 hard negatives采样的策略。如果负的图像-文本对共享相似的语义,但细粒度细节不同,那么它们是很难的。作者利用对比相似性来寻找batch内的 hard negatives。

对于一个batch中的每一幅图像,作者按照对比相似性分布从同一batch中抽取一个负文本,其中与图像更相似的文本有更高的机会被采样。同样地,作者还为每个文本采样一个hard negative图像。

Momentum Distillation

用于预训练的图像-文本对大多是从网络中收集起来的,而且它们往往会有噪声。正样本对通常是弱相关的:文本可能包含与图像无关的单词,或者图像可能包含文本中没有描述的实体 。

对于ITC学习,图像的负样本文本也可能与图像的内容相匹配。对于MLM,可能存在其他与描述图像相同(或更好)的标注不同的词。然而,ITC和MLM的one-hot标签会惩罚所有负标签预测,不管它们的正确性如何。为了解决这个问题,作者提出从动量模型生成的伪目标中学习。动量模型是一个连续发展的教师模型,它由单模态和多模态编码器的指数移动平均版本组成。

在训练过程中,训练基础模型,使其预测与动量模型的预测相匹配。具体来说,对于ITC,作者首先使用动量单模态编码器的特征计算图像-文本相似性,这个可以认为是一个softmax score,不再是一个 one hot向量。这样在模型训练的时候,我们希望在训练原始model的时候,不只是让预测跟目标值one hot尽可能接近,也希望能够和动量模型的输出保持一致,这样就能达到一个比较好的折中点,很多信息从one hot label来学习,但是当one hot label是错误的或者是有噪声的时候,我们希望这个稳定的动量模型提供一些改进。