费曼说:学习一件事情最好的方式是做它的老师,这也是写这篇博文的目的,写这篇博文,即便有其他原因,但更多的还是写给自己,话不多说,让我们开始进入大模型吧
任务说明:任务说明
基座课程:斯坦福大学大规模语言模型课程
引言:本次我们要学习的内容是大模型的目标函数和优化算法的部分,我们对于三种自编码模型都做出了一定的概括,并且介绍了模型在训练中遇到的问题和解决的办法。
8.1 目标函数
主要是三类语言模型的目标函数:
1.只包含解码器的模型:给出上下文嵌入,输出一个token,如GPT-3、还有一些下游任务
2.只包含编码器的模型:如BERT,计算上下文嵌入矩阵
3.编码器解码器模型(如T5):编码输入,解码输出
8.1.1 Decoder-only 模型
输入一串字符序列,预测下一个字符。输入用softmax回归。
8.1.1.1 最大似然
![](https://i-blog.csdnimg.cn/blog_migrate/f2dc2c72a0fb5ea15769df8291bb6086.png)
8.1.2 Encoder-only 模型
上面的最大似然函数可以单向的考虑到上下文的相关性,类似接龙的手段。p(xi|xi-1)实际上是一种单向且单输入的概率分布,它的条件是上文是pi-1,有着一定的局限性。
但如果我们不需要生成接龙的文字,我们可以实现双向的上下文嵌入。
8.1.2.2 BERT
下面是BERT的双头注意力机制:
它可以根据输入序列中不同位置的信息之间的相关性,动态地计算每个位置与其他位置的权重,以便更好地捕捉序列中的重要信息。它允许模型在处理每个位置时,同时关注序列中的其他位置,而无需依赖于固定窗口大小或卷积核大小。
在自注意力机制中,每个位置的输入会通过三个线性变换(通常称为查询(Query)、键(Key)和值(Value))转换为查询向量、键向量和值向量。然后,通过计算查询向量和键向量之间的相似度得到每个位置与其他位置的注意力权重。最后,将注意力权重与对应位置的值向量进行加权求和,得到该位置的输出表示。
下面是模型输出,我们可以看到输出的是一个个词向量,需要再外接线性模型才能将输出的向量转化为各种我们需要的值。
BERT-laege 有16个注意头,模型的输入长度可有1024个单词长度,有355M个参数
8.1.2.2.1 掩码的语言模型
它其实说的是对于自然语言的输入我们如何加噪的一种方法,从而达到模型增强的效果。
首先介绍其中的噪声方法,噪声方法有两种,一种是一个特殊的token作为MASK,另一种是通过随机输入作为MASK。
下面就是建模:定义模型分布。给定输入和上下文嵌入,模型独立地预测每个token。
掩码:定义了一个噪声函数A(x1:L|x1:L)。下面是A的定义:
注意到噪声函数其中还有10%的概率用随机单词进行打乱,目的是为了增加模型的复原语句的能力。
8.1.2.2.2 下一句预测
[CLS]是每个句子的开头,输出向量用来接入Linear模型,来完成一些相关下游任务:如预测句子的积极性、根据提示给出答案所在的位置等,[SEP]是与之相接的下一个句子的开头。我们会将[CLS]的输出作为预测向量来计算下一句与上句是否相接:
8.1.2.2.3 是数据集*
主要的方式还是有50%的概率将句子打乱,来作为8.1.2.2.2 下⼀句预测的数据集
8.1.2.2.4 训练目标
BERT的训练目标介绍:
从数学公式中可以看到,训练的目标是MASK单词预测和下一句预测的交叉熵损失。
详细介绍如下:
BERT的损失函数由两个部分组成:Masked Language Model(MLM)损失和Next Sentence Prediction(NSP)损失。
-
MLM损失:MLM损失用于训练BERT模型对于遮盖(mask)的输入词语进行预测。在输入序列中,BERT会随机遮盖一些词语,然后模型需要根据上下文来预测这些被遮盖的词语。具体地,对于每个被遮盖的词语,模型会生成一个概率分布,并使用交叉熵损失函数来衡量模型输出与真实标签之间的差异。
-
NSP损失:NSP损失用于训练BERT模型对于两个句子之间的连续性进行预测。在训练数据中,每个样本都是由两个句子组成的。模型需要判断这两个句子是否是连续的,即是否是原文中的相邻句子。NSP损失使用二分类的交叉熵损失函数来衡量模型对于连续性预测的准确性。
总的损失函数是MLM损失和NSP损失的加权和,可以使用加权交叉熵损失函数进行计算。在实际训练中,通常会将MLM损失和NSP损失的权重进行调整,以平衡两者对于模型训练的影响。
总结:BERT将NLP系列成功变成预训练+微调的形式,可以说是人工智能领域的“一气化三清”了
8.1.2.3 RoBERTa
BERT的加强版:对BERT进行了一定的改进,在其基础上删除了下一句预测的目标函数,使用了更多数据训练,训练时间更长,准确性比BERT更高。
8.1.3 Encoder-decoder 模型
一种可以像BERT一样对输入进行双向编码,并像GPT一样对输出进行自回归解码的模型(auto-encoder)
8.1.3.1 BART (Bidirectional Auto-Regressive Transformers)
BART是一种encoder-decoder模型,使用与RoBERTa相同的编码器架构,也使用了同样的数据进行训练,但是对于噪声的添加做了以下的改进:
基于BERT,BART做了以下变换:
将掩码中的3/10尽数打乱,将所有子句打乱,实验结果显示:BART在排列/旋转上表现不佳。 文本填充始终良好。
8.1.3.2 T5 (Text-to-Text Transfer Transformer)
T5是另一种基于Transformer的架构。
预训练:给定一段文本,在随机位置分割为输入和输出。
无监督学习目标:预测下一邻接语句、BERT类型的任务、打乱输出、MASS类型的任务(可能是更多的MASK)、噪音&跨越(某段输入)、噪音&丢弃单词、随机跨越某段单词,并发现在噪音&跨越(某段输入)任务上表现较好。
还将所有经典的NLP任务放在⼀个统⼀的框架中,称为“Text-to-Text”任务:就是一对下游任务的集合。
4.2 优化算法
第一种:随机梯度下降法(SGD)
目前人工智能业界应用最广泛的算法,准确的说是小批量随机梯度下降,原理很入门:
我们需要关注的是SGD 的优化点:
原文总结的很好,这里不再解释了
1. 我们希望参数 可以快速收敛
2. 我们希望优化在数值上是稳定的
3. 我们希望内存高效(尤其是对于大模型)
这些点往往相互矛盾(例如,通过低精度训练,可以实现快速收敛、减少内存占用,但是会导致训练不稳定)
因此,我们可以从几个层次来进行优化:
针对经典优化:二阶方法、约束优化等。
针对机器学习:随机⽅法、隐式正则化+早停法
针对深度学习:初始化、归⼀化(更改模型架构)
针对⼤语⾔模型:由于稳定性问题,学习率和⼀些直觉(例如,
⼆阶⽅法)仍然有⽤,但要使⼤语⾔模型有效训练,还需要克服
许多其他独特的挑战。不幸的是,其中⼤部分内容都是特别的,
⼈们对此了解甚少。
![](https://i-blog.csdnimg.cn/blog_migrate/76f078fe3812c41725390fb356ee5a98.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4deed3352547c03e36c7d15cfa265984.png)
Adam(Adaptive Moment Estimation)是一种常用的优化算法,用于训练深度学习模型。它结合了自适应学习率和动量的概念,能够在不同参数和梯度的情况下自适应地调整学习率,并且具有较好的收敛性能。
Adam算法的运作过程如下:
-
初始化参数:设定学习率(learning rate)
动量系数(momentum)
和,以及
参数
。
-
计算梯度:根据损失函数对参数
求导,得到梯度
。
-
更新一阶矩估计:计算当前步数的一阶矩估计(即梯度的移动平均值),用于调整学习率。一阶矩估计通过指数加权平均的方式计算,具体地,对于每个参数
,更新其一阶矩估计为:
其中,
表示当前步数的一阶矩估计,
表示上一步的一阶矩估计,
为动量系数(通常取值较接近1)。
-
更新二阶矩估计:计算当前步数的二阶矩估计(即梯度的平方的移动平均值),用于自适应地调整学习率。二阶矩估计也通过指数加权平均的方式计算,具体地,对于每个参数
,更新其二阶矩估计为:
其中,
表示当前步数的二阶矩估计,
表示上一步的二阶矩估计,为动量系数(通常取值较接近1)。
-
偏差修正:由于初始步数的估计偏向于0,为了减轻这种偏差,需要对一阶矩估计和二阶矩估计进行偏差修正。具体地,对于一阶矩估计:
对于二阶矩估计:
其中,
表示当前的步数。
-
参数更新:根据一阶矩估计和二阶矩估计对参数进行更新。具体地,对于每个参数
,更新公式为:
其中,
为学习率,
为一个很小的数(如
)用于数值稳定性。
Adam算法通过自适应地调整学习率和动量,能够在不同参数和梯度的情况下获得较好的收敛性能,并且通常能够快速收敛到较好的局部最优解。它在深度学习的各种任务中广泛使用,并且被证明在实践中具有较好的效果。
第三种算法:AdaFactor
一种减少内存占用的算法,原理是不存储O(m,n)的矩阵,而是存储O(m+n)的矩阵
由于存储空间的压缩,它的收敛会存在一些问题,但是有利也有弊,它对像T5这样庞大的模型来说就比较试用。
第四种:混合精度训练
以我所见,这更像是一种训练的方式,默认的精度是:FP32(32位浮点),将主权重继续保持FP32的精度以此避免损失,其他运算都放到FP16的精度。
4.2.5 学习率
学习率预热是指在训练的初始阶段,逐渐增加学习率的大小,然后再按照正常的衰减策略进行调整。这样做的目的是为了在训练初期提高学习率,使得模型更容易收敛到较好的局部最优解。
Huang等人在2020年的研究中指出,层归一化(layer normalization)的梯度消失可能是使用Adam优化器训练Transformer模型时不稳定的一个潜在原因。层归一化是Transformer中常用的归一化技术,有助于减少模型中的内部协变量偏移,但也可能导致梯度在层间传播时消失。通过学习率预热,可以在训练初期提高学习率,有助于克服梯度消失问题,使得模型能够更好地训练和收敛。
学习率预热的具体实现方式可以是线性递增、指数递增或其他形式的递增策略。在预热阶段结束后,学习率会按照设定的衰减策略进行调整,通常是随着训练步数的增加而逐渐减小,以便模型更细致地搜索最优解。
总结起来,学习率预热是一种用于提高Adam优化器在训练Transformer模型时的稳定性和效果的技术。通过在训练初期逐渐增加学习率,可以克服层归一化的梯度消失问题,帮助模型更好地训练和收敛。
4.2.6 初始化
给定矩阵X,标准初始化(即Xavier初始化)是一种常用的权重初始化方法,用于初始化神经网络的参数。具体来说,对于形状为(m, n)的矩阵X,标准初始化会将其每个元素初始化为从均值为0、方差为1/sqrt(m)的正态分布中采样得到的随机数。
GPT-2和GPT-3通过额外的缩放权重进行初始化。这是为了在残差层中平衡梯度的大小,防止梯度消失或梯度爆炸的问题。具体来说,GPT-2和GPT-3中的缩放权重是一个可学习的参数,用于缩放残差块的输出。这样可以确保梯度在残差层中传播时保持适当的尺度,有助于训练的稳定性和效果。
对于T5,它在注意力矩阵中增加了一个额外的缩放因子。具体而言,T5的注意力矩阵经过缩放处理,缩放因子为1/sqrt(d_k),其中d_k是注意力头的维度。这个缩放因子的引入可以使得注意力矩阵在计算注意力权重时更稳定,有助于模型的训练和推理。
在GPT-3中,使用了一系列参数和训练策略。其中Adam参数设置如下:
- 批量大小:320万个token(约1500个序列)
- 使用梯度剪裁(gradient clipping)
- 线性学习率预热(前3.75亿个token)
- 余弦学习率衰减到10%
- 逐渐增加批大小
- 权重衰减设为0.1
这些参数的设置是为了优化GPT-3模型的训练过程。具体来说,使用较大的批量大小可以提高训练效率;梯度剪裁可以防止梯度爆炸;线性学习率预热和余弦学习率衰减可以控制学习率的变化,使得模型更好地收敛;逐渐增加批大小可以进一步提高训练效果;权重衰减可以控制正则化项的大小,防止模型过拟合。
总之,GPT-3在训练过程中使用了一系列参数和策略,其中包括Adam参数的设置、学习率的预热和衰减、批大小的逐渐增加以及权重衰减的设定。这些参数和策略的选择是为了优化模型的训练过程,提高模型的效果和稳定性。
总结:本次主要学习的是大模型的目标函数和优化器,涉及到很多的细节元素