当前位置:首页|资讯|ChatGPT

深入浅出ChatGPT(一)关于非监督预训练的一切

作者:南玻斯瑞的生活号发布时间:2023-03-23

ChatGPT之犀利毋庸置喙。

我了解到的,现在很多的进行算法研发工作的团队,实际上是做的事情是看到学术界研究出来一把可以很好地砸钉子的锤子,然后就拿这把锤子来寻找有没有看起来像钉子的任务,哪怕那个任务实际上是颗螺丝钉,也要用锤子硬砸进去。

而我自己团队现在正在进行的研究,则是认真的分析了我们所面对的任务场景,确认它是一颗螺丝钉,虽然它和钉子有很多相似之处,但同样有着很多不同之处,所以我们要定制一把螺丝刀,而不是拿起现成的锤子就硬上。

当然ChatGPT更在另一个级别,它做出来了一把手电钻。

只是可惜这把手电钻只能处理NLP问题,不能直接应用在我们所做的ECS故障预测场景中。但是这把手电钻的研发过程,同样是有非常大的参考价值的,所以我写了这篇文章,梳理总结了一些我对ChatGPT的理解。

此外,在阅读这篇文章之前,建议大家先去看我之前(用ChatGPT)翻译的那篇Wolfram大佬的https://www.yuque.com/wangyunongnanbo/zdr6c2/gmit2k0f7yuyxqbn?#《ChatGPT做了什么,以及它为何有效》,那篇文章里从模型的脉络讲述了ChatGPT的基础工作原理,解释了ChatGPT是如何根据我们的输入来输出一段合理的回答。而我今天想从另一条脉络——特征,来讲一讲在我的理解当中,OpenAI怎么做出了这么犀利的ChatGPT。

ChatGPT的核心思想

根据OpenAI发布的资料,ChatGPT的核心思想可以总结为一句话、四个方面:

非监督预训练 + 多任务调优 + 人工反馈的强化学习 + 大参数Transformer模型。

在解释这句话之前,让我们先从一些基础的概念开始。

什么是好特征,什么是坏特征?

特征,简而化之的理解,就是编码,就是指一个输入数据,在计算机中、在算法模型中用一串什么样的数字来代表它。

模型,简而化之的理解,就是特征+分类器,分类器将输入数据转换成某种预期输出,特征则是帮助分类器来更好完成任务。

比方说输入文本,在电脑中是以ansic/unicode之类的编码表示的,事实上这种编码,也可以直接拿来作为特征输入到分类器中,但是效果通常会不好,因为ansic编码并不是一种好的特征。

好的特征,表达能力强,会极大的帮助到模型的训练,反之,差的模型表达就会阻碍模型的训练。

那什么叫好的特征,什么叫表达能力强呢?

我们举个例子。

假设我们现在还不知道要处理的任务是什么,但是我们已经知道输入的数据集如下:

A. catB. car

C. dogD. truck

现在我们需要对输入的单词进行编码,将其转换成算法模型可以理解(用专业一点的话说:可以将问题转换成矩阵计算,训练工作可以转换成对某个目标函数的最大化/最小化优化问题)的数据。

方案一:对输入单词做字典排序后按顺序编码,那我们会得到一个这样的样本空间:

方案二:出于我的常识,我觉得cat和dog应该在样本空间中离得更近,car和truck也应该离得更近,所以我设计了这样一套特征方案:

现在来看我们要处理的任务A:

____ is animal. ____ is vehicle.

那显然在这个任务下,cat和dog应该是一类,car和truck应该是一类。

那么在特征方案一中,为了在这个样本空间中正确的完成任务分类,我们需要一个类似这样的分类曲面:

在特征方案二中,我们需要一个类似这样的分类曲面:

显然方案二的分类曲面要更简单,2个参数就可以表达,方案一的分类曲面至少需要3个参数,模型参数更多,训练难度也会更大。

这个例子还可以进一步拓展,我们在数据集中再加入两个单词:camel,和wolf。

方案一:

方案二:

这个时候,我们会发现,为了解之前提出的animal/vehicle分类问题,方案一原本的模型已经失效了,不能将样本正确分类,需要重新训练成一个更复杂的分类器:

但是方案二原本的模型依然是有效的,可以将样本正确分类。

这种情况,我们就称为采用方案二的模型的泛化能力比方案一强,能在原来没有处理过的数据上也取得良好的效果。


这个例子我们可以进一步拓展。

现在对于这个数据集,我们又有了一个新的任务B:

____ starts with C, ____ doen't start with C.

那为了解这个问题,我们需要的分类曲面又变成了这样:

方案一:

方案二:

这时候,我们发现原来两种方案下的模型都失效了,并且在这个问题下,方案一的特征表达反而比方案二更好。

这种情况,我们称之为解决特定任务的模型迁移到其他任务上失效了。

那为了能够在两个问题下都有好的特征表达,我又重新设计了方案三,可以看到方案三对于前面两个任务都有着很好的表达,对任务A有效的分类器如实线所示,对任务B有效的分类器如虚线所示。方案三在两个任务下对分类器训练的压力都很小。显然,这是一个比方案一和方案二都要好的特征表达设计方案。

通过这个简单的例子,我想说明特征的评价是不能脱离任务的,好的特征指的是在某个任务下对分类器压力小,更容易达到较好的分类效果的特征,而在某个任务下效果好的特征,在另外一个任务下效果未必会好。


如何进行特征设计

现在我们知道了特征好坏很重要,那接下来让我们看看该如何进行特征设计。

特征设计可以大致分为两个大的流派:前神经网络时代,和神经网络时代。

两者最主要的区别在于,特征与模型是否可训练。


前神经网络时代

前神经网络时代的诸多算法,LR、SVM、决策树(以及后续的随机森林、GBDT、XGBoost、LightGBM、CatBoost等等)、K-means、KNN等等,其共同的特点是,模型本身的算法是固定的,也许在某个环节你可以选择不一样的参数、不一样的架构(LOSS选择0-1 loss、绝对值loss、hinge loss、mse等等),但总体来说,当你确定了使用哪种模型、确定模型中的一些参数之后,这个模型就固定下来了。

在使用这些固定的模型时,由于模型本身没有太多可以优化调整的空间,特征通常就是算法研究者下功夫的重点了。通常,算法研究者会观察分析数据的特性(例如前面举例的方案二),再配合需要解决的问题以及问所使用的模型(例如前面的方案一配合任务B),来设计特征算子。

这种特征设计的典型例子有,在时序数据上使用的各种滑窗统计特征(min、max、std、峰度、偏度、熵等等),在图像数据上使用的检测边缘的Laplace算子、针对图像尺度不变性、旋转不变性设计的大名鼎鼎的SIFT算子(前CNN时代图像特征的神,后来就被CNN屠了)等等。

这个时代的特征和模型的共有特点就是:手工制定,且算法模型的调整空间不大,很多的工作都是围绕着特征设计展开(那个年代的灌水文通常是这样的:在xxx工作中使用的特征算子的计算公式为 x+1,我们经过探索,发现将这个特征算子改成 x+0.5 会在我们的数据集上效果更好。。。)

这种做法的好处,是经常可以有一些数学上看起来非常美、非常清晰的设计(比方说SVM,从数学上来说非常美,Vapnik的《统计学习理论》一书中围绕着SVM、核方法做出了非常优美的数学证明),此外在算力不强大、数据集不丰富的年代,很适合解决一些小规模问题。

但是同样有坏处:数学上有优美解的前提往往是一些强约束条件,而这些强约束条件在很多实际场景的数据集中并不能得到满足;手工设计特征或者算法通常只适用非常特定的数据集;手工设计特征需要消耗的精力、对设计者经验的要求都很高,越来越不适合数据规模越来越大的现在。


神经网络时代

而神经网络提出了一种完全不同的做法,最早、最原始的神经网络的基础思想是:输入数据可以表达为一个向量X,预期输出数据可以表达为一个向量Y1,以一个权重矩阵W去乘以X,可以得到一个实际输出向量Y,那么实际输出和预期输出之间的差距作为LOSS函数L,那么当数据集固定(也就是X和Y1固定时),L就变成了一个对W的函数:L= f(Y1-Y) = f(W·X-Y),然后我们就可以用梯度下降法去求解一个使得L最小化的W。

在这个结构当中,特征的提取和分类器的计算不再被视为截然的两个过程,两个计算步骤被直接融合为一个计算步骤。同时也引入了最重要的一个概念:模型训练。

神经网络只提供一个基础的计算结构、计算框架,然后你需要向其输入训练样本,根据训练样本的反馈,神经网络会去调整其中的具体参数,以求得到一个最优的解。


但是这个方法很快就被发现有着重大缺陷,它无法解决像异或问题这样的非线性可分问题(即,找不到一个W,使得输入X=(0,0),(0,1),(1,0),(1,1)时,其输出为Y=(0),(1),(1),(0).)。

然后神经网络有了第一次演化,从单层的神经网络演变成多层的神经网络,即Y= W1·W2·....·WN·X。对于这种结构的网络,直接求L对每个权重矩阵W的梯度是很复杂的,但借助求导公式的链式法则,我们可以很巧妙的把这个梯度计算问题转换成一个逐层计算偏导值的问题,这就是大名鼎鼎的后向传播算法(Back-propagation)。

至此,神经网络发展壮大所需要的基础就已经齐备了,它的基础思想是:假设1:在输入样本的空间当中,一定存在一个分类曲面(无论这个曲面有多复杂),可以将样本点合理的分到需要的类中去,假设2:通过足够复杂的神经网络的结构,一定可以得到一个对这个分类曲面的足够接近的逼近曲面(理论上来说,分段线性函数可以做到对任意连续曲面的逼近),假设3:通过梯度下降的方法,我们总可以找到这个能够逼近分类曲面的权重矩阵簇。目前这些假设尚未得到数学上的证明,但工程实践支持这些假设的成立。


在神经网络之前,特征算子、模型结构都需要人工设计,在神经网络之后,大家的主要精力只需要集中在模型结构的设计,然后通过输入数据、训练迭代让模型自动调优到一个最合适的参数。在神经网络之前,算法本身可调节的空间并不大,而神经网络的结构则有着非常大的可调整空间,对神经网络结构的探索也成了算法研究者最主要的工作内容。

神经网络并不严格将特征和分类器的计算分开,但是通常神经网络的结构中,无论前面的结构是如何设计的,最后都会接入一个全连接层将其转换成所需大小的向量,再接上一层softmax作为最终输出。所以通常,我们可以将这个最后一层全连接视为分类器,将神经网络前面的各层结构视为在进行特征提取。当然,我们也可以在任意中间层将神经网络一分为二,将前面的部分视为特征提取,将后面的部分视为分类器,这样中间这一层输出的向量就是我们从输入数据中提取到的特征。

通常在神经网络的训练过程中,特征提取的部分和分类器的部分是同时得到训练的,但我们也可以将其中部分权重(通常是特征提取部分)固定不参与训练,而只训练分类器的部分。

神经网络最强大的地方在于,它并没有制定某一种特征,而是提供了一个基础计算结构,通过数据的输入、反馈、迭代——简而言之就是训练——的过程,可以得到一个最优化的特征表达方案。但是,这个基础计算结构设计的好坏,会影响这个训练过程的难度,会决定你最终能优化到什么程度。


在神经网络时代,网络结构非常重要,因为网络结构决定了你最终提取出的特征,其特征空间有多复杂、你需要去逼近的那个分类曲面有多扭曲、你的模型训练难度有多高。

最原始最基础的神经网络计算单元就是全连接,也就是我们上面提到的,Y=W·X。

全连接的优点是万能,理论上来说你可以只用全连接拟合出任意你想要的函数,但是为了充分训练全连接模型直到它真的逼近而不是在过拟合、无法收敛之类的问题上越跑越偏,训练需要的数据量可能是个无法想象的数字,不夸张的说,也许能超过这个宇宙的粒子数总和。

所以算法研究者们又设计了一些特定结构的基础单元。

其中最经典的就是CNN中的卷积连接层和Transformer中的多头注意力机制。

卷积连接

卷积连接层主要是针对输入数据为图像的情况下设计的。图像的基础特点是:1. 在二维空间上具有连续结构和语义信息,每个像素和相邻位置的像素之间具有相关性。2. 图像中的局部信息具有平移不变性、旋转不变性、缩放不变性等特点。

针对这样的特点,LeCun设计了最早的CNN网络LeNet-5(因为它有5层)。卷积连接是以一个一定大小(专业术语感知野)的卷积核扫描过输入图像,这个卷积核代表着一种特定的特征模式,当它和扫描位置的图像卷积结果大时,表明图像该位置的局部特征和这个卷积核代表的特征相似度越高,扫描完整张图像,就得到了这个卷积核代表的特征在整张图像不同位置上的强度。通常会同时使用多个不同的卷积核,每个卷积核代表一种特征。

例如下面这张图(引用自我的博士论文),上图是输入图像,下图是经过10个不同的卷积核扫描后得到的结果。可以明显看出,不同的卷积核检测出了不同的特征,横向/竖向/斜向的边缘、黑色/黄色的区域、白色背景等都有得到检测。

卷积连接可以视为对全连接的一种特化:将全连接大部分权重置零,只保留特定位置的权重,且多行间的权重采用共享权值,就得到了卷积连接。事实上,13年我在微软亚研院实习时,秦涛老师的组就尝试过从全连接中直接训练出类似卷积连接的结构出来,但当初的效果不是很好,我的个人猜想是当初的数据集还不够大,训练得不够充分。

Transformer

与CNN不同,Transformer最初设计来主要是处理在一维上具有连续结构和语义信息的序列数据(比如说人类语言)。

在Transformer之前,针对序列数据的主要设计思想是RNN,每次只计算相邻两个数据之间的相关性,将更之前的数据中含有的信息浓缩成一份先验输入。这种做法显然会导致更之前的数据会被遗忘,即使针对性的改进成LSTM也无法彻底解决这个问题。

而Transformer则采用了将整个序列铺平展开,计算每个位置的数据和每个其他位置的数据之间的相关性,得到一个更全局的语义信息的总结。

卷积连接中,计算局部信息所用的操作就是一个非常直白简单的卷积操作,其物理含义是非常易于理解的。Transformer中则设计了一个结构比较抽象的自注意力模块来提取两个位置的数据之间的相关性:三种代表不同信息的嵌入向量之和通过一个QKV矩阵的复杂计算,最后过一个softmax。卷积神经网络中,卷积连接通常后接池化连接以扩大感知野,最后接入一个全连接层。而Transformer中,自注意力模块后通常再接一个全连接层以进行全域信息总结。


CNN vs. Transformer

如果说从全连接到卷积连接是一种特化,那么从RNN到Transformer则可以看做一种泛化:RNN是特化的、只计算相邻位置的相关性(同时简化了相关性计算方式)的Transformer。

那为什么从全连接到卷积连接是特化后效果更好,从RNN到Transformer则是泛化后效果更好呢?

如果我们对比一下这四组结构,可以发现:

全练接是根据输入样本的全部数据集合计算得到一个值,而卷积连接是每次只根据样本中的一个数据局部子集计算得到一个值,然后将这个计算在多组数据局部子集上重复,最终得到多个值。

Transformer则是每次只根据样本中的一个数据局部子集计算得到一个值,然后将这个计算在多组数据局部子集上重复,最终得到多个值。

RNN是只根据样本中的一个数据局部子集计算得到一个值,即使重复多次这样的计算最后仍然是得到一个值。

可以看到,其实全练接和RNN在结构上是更走向两个极端的,全练接感知样本数据的全集,而RNN约等于最终只看了一个数据子集(其他数据子集的信息被浓缩了,而浓缩的另一个名字就是信息丢失),而CNN和Transformer其实是更类似的结构:对整体输入做扫描,每次扫描时只关注局部信息,最终将每次扫描的结果组合起来,得到一个全局的描述。

但CNN和Transformer相比,CNN对信息的损失会更大一些,因为CNN重复的数据局部子集是有丢失的,处于不相邻位置上的数据组成的子集是不会被纳入计算的。而Trasnformer则是对全部子集都进行计算(不过CNN通过池化层的方法逐渐增大了感知野,最终还是将全集信息进行了整合,但这个过程中同样存在信息的浓缩与丢失问题)。

在这个全集-全部子集的集合-部分子集的集合-子集的链条上,越靠左的,感知的信息越全域,参数量越大,训练难度越大,充分训练需要的数据量越大,而越靠右,感知的信息越局部,参数量越小,整体表达能力越弱,越容易过拟合。

总结来看,Transformer中的嵌入编码加上自注意力模块的设计,使得它能够很好的作为一种用于训练从序列数据中提取特征的网络结构。那么从这个逻辑来看,Transformer应该天然也可以应用在图像上,因为图像也可以认为是一个序列数据,只不过有着特殊的跳接机制,而事实上ViT模型的效果恰恰证明了这一点。


预训练+调优

现在我们了解到,当前神经网络时代的常用做法是,设计好网络的结构,然后输入足够的数据去进行充分的训练。前面我们大概讨论了网络结构对训练能优化到什么程度有着很重要的作用,而使用什么样的数据集去进行训练,对于最终优化程度的作用是同等(甚至更加)重要的。

在我们一开始举的例子当中,在初始只有四个单词的数据集上,我们显然只能优化到方案二的程度,只有在扩充后六个单词的数据集上,我们才能优化到方案三的程度。

这是因为,网络的结构,只是决定了模型学习数据分布的能力,但是用来训练的数据集,才真正决定了最终有哪些数据分布被学习到。所以通常来说,用来训练的数据集越大,模型最终的训练效果越好。

但是在某个特定任务的数据集中,其数据量往往是有限的,模型未必能得到充分的训练,这时候一个常被采用的策略就是预训练+调优。

先将模型在另一个(通常是数据量更大的)数据集上进行训练,然后再在我们需要解决的任务上进行训练。这里又通常有四种做法,一种是整个网络结构都不变,特征提取和分类器的参数全部调优,第二种是网络结构不变,特征提取部分权重不变,只对分类器部分参数做调优,第三种是网络结构也发生变化,特征提取部分结构不变,分类器部分结构变化,整体调优,第四种是特征提取部分结构不变且权重固定,分类器结构变化且权重调优。

这里基本上可以理解为,通过预训练获得一个较好的特征表达,然后再在这个特征表达的基础上对模型进行进一步的优化,以最终获得较好的效果。


而由于数据标注通常要消耗很多人力,所以为了能够获得一个用于预训练的、数据量足够大的数据集,更常用的方法是采用非监督预训练的方法。用于非监督学习的数据集,通常相当于只需要进行数据的收集,而不需要进行数据的标注,所以可以做到比标注好的有监督数据集的数据量大很多。

但是进行非监督预训练时,(结合我在之前举得例子来说,就是只告诉你现在有一个6个单词的数据集,但没有提供任何任务标注信息),由于没有特定的预期输出,就需要我们设计一个专门针对非监督预训练的任务,并且期望这个非监督学习任务优化出来的特征表达,在后续我们想要进行的具体任务上也有好的效果。

在我前面举的例子中就已经提到过,一种特征,在某个任务下好,并不一定在另一个任务下也好。所以这里的预训练任务不是能随意设计的。

如何设计预训练任务,尤其是非监督预训练任务?

这一块目前没有太多理论上的证明,但是有一些工程实践上的经验性结论。这里我可以尝试做出一些讨论。

在没有预训练的情况下,相当于知道输入输出,求对输入输出条件概率分布P(output|input)的最大似然估计。而在有预训练的情况下,相当于增加了一个隐变量feature,先做对输入和特征的条件概率分布P(feature|input)的最大似然估计,再做对特征和输出的条件概率分布P(output|feature)的最大似然估计。所以一个简单的预训练任务的设计理念就是:希望特征和输入之间的分布保持一致,相同/相似/相关的输入具有更接近的特征,不相同/不相似/不相关的输入之间具有更远的特征。

常见的非监督预训练的基础思想,是希望特征之间能以更简洁的结构(通常是更低的维度)来保持和输入数据之间相似的分布。为了做到这一点,一种常用的做法是希望能从特征中重建出输入,这样显然特征保持了和输入数据一致的分布。

之前我们提到过,特征就是将输入数据用一串数据来表达,那么该如何理解这一串数据呢。

一种基础的理解,是认为存在一个特征空间,这个空间中有N个特征向量R,而将输入数据X表达为一个N维的特征V后,实际上可以将这个特征理解为一组权重系数,对特征空间中的每个向量以这组权重系数做加权和之后,就可以得到对这个输入数据的重建。通常认为,这个特征空间中的特征向量之间如果是正交的,那么得到的特征表达会更好——相似的输入数据的特征也会相似,不相似的输入数据的特征也同样不相似。

然而,想要这种特性成立,通常对矩阵特性有一些要求(非负、非奇异等等),更像是一种理论上的理想化推导(真空球形鸡),而在很多现实世界的实际数据集当中,并不能得到一个数学上优美的解,只能退而求其次的寻找尽可能最优的解。


在继续讲下去之前,先插入一段关于信息熵的基础概念:

根据香农的无失真信源编码定理,想要表达一定量的信息,其编码长度是有下限的,以01编码来编码的话,最短编码长度即为log2(H),H为信源的信息熵。信息熵的计算公式为信源每个可能的符号的出现概率乘以该符号信息量之和。单个符号的信息量,可以简单理解为该符号所消除掉的不确定性,计算公式为log2(1/p),p为该符号出现的概率。

举个例子来说,投一个骰子,出现1的概率为1/6,当我投出一颗骰子得到1后,获得的信息量即为log2(6),而投骰子这个信源整体的信息熵即为6*1/6*log2(6)=log2(6),而想要用01编码对骰子出现的每一个结果做一个编码,则需要用到的最短编码长度为log2(6)=2.58,即用2位定长01编码不太够(只能编码到4),用3位定长01编码又有剩余(能编码到8)。


结合信源编码定理来看特征编码,会发现特征编码有两种可能的情况。

一种是特征的维度小于输入数据的维度,此时特征编码可表达的信息量是小于输入数据的,这种情况我们称为特征稠密化。这种情况下,是无法从特征无损重建出输入数据的,一定会有信息损失掉。通常在实践上认为,在有信息损失的情况下,要求从特征重建出的输入能够尽量保持对输入的接近,或者能够保持重建后数据之间的区分度,可以强迫模型学习到输入数据的分布中更关键的部分,而抛弃掉噪音分布、不重要的部分。

这种做法就是目前非监督预训练的主流做法。而通常判定此时特征好坏的方法通常有两种方法:一种是生成式,直接对比重建后的结果和输入数据之间的相似度,希望相似度最大化。一种是对比式:每次输入两个样本,对比这两个样本重建后的相似度,对比式又有两种做法,一种正样本法是这两个样本之间视为相关,即使这两个样本本身相差很大,也希望他们的特征相似度最大化,另一种负样本法是这两个样本之间视为不相关,希望他们的特征相似度最小化。输入的这两个样本又有两种常用处理方法:一种是输入人工或规则组织过的样本对(ChatGPT就是这么做),另一种是输入一个样本,和在这个样本上做随机扰动后的数据增强样本(何凯明这边SimSiam的做法)。

但还有一种情况是特征的维度大于输入数据的维度,此时特征编码可表达的信息量是大于输入数据的。此时特征编码的信息密度相对于输入数据来说变稀疏了,这种做法我们一般就称之为稀疏化。

稀疏化的做法在早年机器学习的研究中还有见到,但近年越来越少了。核心还是在于数据集越来越大,本身输入数据信息量就在不断膨胀,若还要在特征维度上进一步稀疏膨胀,特征维度、模型参数空间会过于庞大,即使其表达能力上限更高,也缺少足够的数据训练抵达这个上限。所以相比于稀疏化,现在的主流做法还是稠密化。

但是稀疏化并非就没有可取之处。根据我的经验来看,当输入数据中存在多个分布混杂,而非一个统一分布时,采用稀疏化的做法有助于分离出多个分布的信息并加以学习,在一些特定场景下稀疏化的效果也许会优于稠密化。


预训练+调优的策略还涉及到另外一个问题,也就是迁移学习所研究的,当用于预训练的数据集,和后续调优的数据集在分布上差异较大时,预训练再调优的方法能否以及如何做到比直接训练的效果更好。

这个问题并没有一个统一的答案,OpenAI在GPT模型中采用了大规模无监督数据集预训练+多任务调优的策略并且证明了效果很好,但这并不代表这种策略就可以适用所有的场景。GPT这样做有效是因为NLP问题有其特性。

OpenAI眼中的NLP问题

在此前学界的传统研究方案中,NLP问题是被拆分为一个个具体的问题的,如翻译、缩写、扩写、问答等。基于传统的认知,在不同任务下,最优的特征表达方案应该不一样,就像前面我们举的方案一和方案二在两个问题下效果各不相同一样。

但是OpenAI认为,所有的NLP问题,其实都可以表达成一个对话任务,即,输入一段语言文本,输出一段语言文本。这使得所有的NLP问题应当可以通用一套架构,共用一套特征表达方案。这个方案应当可以做到在多种任务下都可以有很好的效果,换句话说就是,OpenAI认为在NLP问题中,存在一个方案三,可以兼容不同的任务,并且这个方案三,是可以被找到的。

但是想要找到这个能对不同任务效果都好的方案三,需要非常大量的数据集来进行训练。而有监督数据集的工作量太大,同等人力下,构建出非监督数据集可以比有监督数据集大很多个量级。在19年,OpenAI通过GPT-1的相关实验,确认了非监督预训练+调优的策略在NLP问题上是行之有效的,非监督预训练确实可以提供额外的分布信息,从而确定了要往这个方向持续投入。

后来,OpenAI构建了一个非常巨大的、分布足够广的非监督数据集,根据OpenAI自己公布的资料,有数百万人参与了这个数据集的构建。随后,他们优化了对如何进行非监督预训练+调优的具体细节,例如在预训练环节,生成式预训练之外,又进行了对比式预训练,在预训练中,除了组织正样本对之外,还采用了同批次其他数据视为负样本的策略;在调优环节,设计了针对多任务的少样本训练策略,设计了基于人类反馈的强化学习调优策略,增加了模型输出对结果置信度的评分函数等等。在工程方面,更是组建了超大计算集群,设计了多种大规模模型的并行化调度策略,从17年到22年,历时五年,最终得到了现在这个强大的ChatGPT。

结语

在开篇我提到ChatGPT的核心思想是非监督预训练 + 多任务调优 + 人工反馈的强化学习 + 大参数Transformer模型。这篇文章里,我主要围绕着非监督预训练这一点展开了讨论。另外三个方面也有很多值得讨论的细节,不过这篇文章的篇幅已经够长了,我会另起几篇文章来讨论,感谢大家的阅读。

致谢

感谢为我提供openai账号的亲爱的老婆~

感谢总是过来骚扰我的可爱的小猫咪(附上奇怪猫条照片一张)~




Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1