【笔记】大模型算法架构
前言
随着人工智能技术的飞速发展,大模型算法及其架构已成为推动科技前沿的重要力量。它们不仅能够处理海量的数据,还具备强大的表征学习能力,能够应对日益复杂的场景需求。本章节将介绍大模型算法及其架构,带您了解其背后的原理、技术创新以及在实际应用中的广阔前景。
目标
学完本课程后,您将能够:
掌握transformer架构和计算流程
了解transformer优化点
掌握FlashAttention、PagedAttention
了解GLM、LLaMA模型结构
目录
1.深度学习算法发展及瓶颈
2.Transformer详解
3.Transformer中的问题及优化方式
4.大语言模型架构介绍
5.多模态大模型架构介绍
6.MoE结构介绍
1.深度学习算法发展及瓶颈
深度学习发展历程
1957年感知器的出现到ILSVRC中诞生的一系列网络,深度学习从简单的二分类到部分领域超越人类。
stage1
感知器
通过线性加权和阈值判断来实现二分类任务
stage2
MLP和反向传播
MLP,网络能够处理更加复杂的非线性问题。
反向传播,为训练多层神经网络提供了有效的手段
stage3
CNN和RNN
CNN卷积神经网络,引入卷积核和池化操作,在计算机视觉领域应用广泛
RNN循环神经网络,引入循环连接,使得网络能够处理序列数据,在自然语言处理领域应用广泛。
stage4
快速发展
视觉方面,ILSVRC中诞生了一系列优异的网络,如AlexNet、GoogleNet、VGG、ResNet等
NLP领域,基于RNN系列网络和Seq2Seq结构的学习算法,在一些领域超越人类
典型神经网络单元
DNN
CNN
卷积神经网络 Convolutional Neural Network
是一种专门用于图像处理的神经网络,它可以自动提取图像中的特征,从而实现图像分类、目标检测等任务。
GNN
图神经网络 Graph Neuron Network
是一种用于处理图形数据的神经网络模型。它可以对图形数据进行分类、聚类、预测等任务。图神经网络在社交网络分析、化学分析分析、推荐系统等领域有广泛的应用。
RNN
循环神经网络 Recurrent Neural Network
循环神经网络是一种可以处理序列数据的神经网络,它可以自动学习序列中的规律和模式,从而实现语音识别、自然语言处理等任务。
典型网络结构
基于CNN、RNN等基础结构诞生的诸多学习算法,如FCN、VGG、GoogleNet等在一些特定领域效果极佳,甚至可以超越人类。
批注:
传统深度学习诞生了很多效果很好的模型结构,如:VGG、Unet、GAN、ResNet等。
大模型阶段
随着计算能力的提升和数据量的增长,训练更大更深的神经网络成为了可能。以GPT系列、LLaMA、GLM等为代表的TRM架构大模型,通过海量的数据和计算资源,训练出了具有强大生成能力和泛化能力的模型。
这些模型不仅能够在单一任务上取得优异性能,还能够通过微调的方式,快速适应新的任务和数据。
stage5
Transformer
Transformer的出现终结了RNN和CNN的时代,基于transformer的优势诞生了Bert、GPT、ViT等效果极佳的算法。
stage6
得益于transformer的可扩展性和算力的发展,模型体积进一步扩大,诞生了GPT4、GLM、stablediffusion等参数量以十亿为单位的模型
思考
基于CNN、RNN的传统深度学习算法在某些(语音识别、图像分类、文本理解等)领域已经超过了人类,为何还要给予Transformer设计更大的模型?
为什么目前大模型都是TRM架构而不是CNN和RNN?
传统深度学习算法的问题
传统深度学习算法在某些领域已经超过了人类,但是依然存在诸多问题。
扩展性差
泛化能力受限
复杂任务上表现差
多模态能力不足
扩展性问题
传统网络结构可以通过不断堆叠RNN和CNN等结构来增加网络深度,一定程度上可以提升模型效果。然而,随着网络深度的增加,模型训练会变得困难,且容易出现过拟合问题。
添加CNN相关结构后,模型当前层在输入输出维度可能会发生改变。
VGG、ResNet等网络的结构相对固定,缺乏灵活性。在应对不同规模和复杂度的任务时,可能需要调整网络结构以适应不同的需求。然后,这种调整通常需要大量的实验和调参工作。
ResNet结构及参数
层数越多,准确率越高。
参数变化:
泛化能力受限
传统深度学习网络结构,受限于网络设计的复杂性和训练数据的局限性,它们的性能都高度依赖于训练数据的分布。
如果训练数据和测试数据在分布上存在显著差异(即数据分布偏移),那么这些网络结构的泛化能力可能会收到严重影响。
这些网络结构通常是为了特定任务(如图像分类)设计,并且在相应的基准数据集上进行了优化。然而,当它们被应用到其他任务或数据集时,可能需要进行大量的修改和调整。
复杂任务上表现差
传统深度学习模型参数量较少(大多<1B),学习能力较弱,通常是为某一任务设计并训练的,而复杂任务多为一些综合性任务。
大模型在处理复杂任务上效果依然有待提升,但是通过思维链等方式可以提升效果,且远超传统小模型。
多模态能力不足
传统深度学习在处理多模态数据时,通常需要在某个阶段将不同模态的特征进行融合,不同模态的数据在语义上可能存在差异。受限于传统深度学习模型的学习能力和泛化能力,模型可能难以适应未见过的多模态数据,或者在处理新的多模态任务时表现不佳。
传统深度学习在语音合成、文本描述生成、视频检索等单一领域效果尚可,但是在文本生成图片、视频等复杂领域能力极差。
2.Transformer详解
2.1 Transformer介绍
起点-Transformer
Transformer是谷歌在2017年做机器翻译任务的《Attention is all you need》的论文中提出的,目前大多数大模型的基础架构为Transformer。最初在自然语言处理(NLP)任务重取得了显著的成功,并逐渐扩展到其他领域如计算机视觉等。
Transformer结构能够捕获输入序列中的长距离依赖关系,同时兼具了更好的并行计算能力。这一结构使得深度学习模型参数突破了1亿,为大型模型的构建奠定了基础。随后,BERT等预训练模型的推出进一步推动了大模型的发展,使得模型参数量快速增长,并在多个自然语言处理任务上取得了显著的性能提升。
Transformer模型结构
Transformer有Encoder和Decoder两部分组成。
Encoder包含N=6个月相同的layer,layer指的就是途中左侧的单元。最左边有哦哥“N x”,指的是N个,如果N=6的话,对应的就是6个。
Decoder也包含N=6个相同的layer。
参考文章:Attention is All You Need
批注:
Encoder中的layer结构都是相同的,但他们没有共享参数。每个layer都可以分解成两个sub-layer的输出维度d_model=512。
从编码器输入的句子首先会经过一个自注意力(Self-Attention)层,这层帮助编码器在对每个单词编码时关注输入句子的其他单词。
自注意力层的输出会传送到前馈(feed-forward)神经网络中。每个位置的单词对应的前馈神经网络完全一样(译注:另一种解读就是一层窗口为一个单词的一维卷积神经网络)。
解码器中也有编码器的自注意力(Self-Attention)层和前馈(feed-forward)层。除此之外,这两个层之间还有一个注意力层,用来关注输入句子的相关部分(和seq2seq模型的注意力作用相似)。
参考链接:https://blog.csdn.net/longxinchen_ml/article/details/86533005。
Transformer工作流程:获取输入
首先将每个输入单词通过Embedding转换为词向量,然后与每一个单词的位置Embedding相加得到每一个单词的表示向量X,最终,每个单词都被嵌入为一个512维的向量。
批注:
每一行是一个单词的表示X。
Transformer工作流程:将输入传入Encoder
将得到的单词表示向量矩阵传入Encoder中,经过6个Emcoder block后可以得到句子所有单词的编码信息矩阵C。
每一个Encoder block输出的矩阵维度与输入完全一致。
批注:
X_n×d:输入矩阵,n是句子中单词数量,d表示向量的维度,论文中d=512。
Transformer工作流程:将编码矩阵传递给Decoder
将Encoder输出的编码信息矩阵C传递到Decoder中,Decoder依次会根据当前翻译过的1~i的单词翻译第i+1个单词。
在整个过程中,翻译到第i+1个单词的时候,需要通过Mask(掩盖)操作遮盖住第i+1之后的单词。
2.2 Transformer中的输入
Transformer的输入
Transformer中的输入X是由单词Embedding和位置编码(Positional Encoding)相加得到的。
单词Embedding
单词的Embedding有多种方式可以得到,例如可以采用Word2Vec、Glove等算法与训练得到,也可以在Transformer中训练得到。
位置编码
对于Transformer来说,由于句子中的词语都是同时进入网络进行处理,顺序信息在输入网络时就已丢失。因此,Transformer是需要额外的处理来告知每个词语的相对位置的。其中的一个解决方案是位置编码(Position Encoding),将能表示位置信息的编码添加到输入中,让网络知道每个词的位置和顺序。
PE_(pos,2i)=sin(pos/10000^2i/d_model)
PE_(pos,2i+1)=cos(pos/10000^2i/d_model)
其中,pos表示单词在句子中的位置,d表示PE的维度(与词Embedding一样),2i表示偶数的维度,2i+1表示基数维度(即2i<=d,2i+1<=d)。
批注:
为什么是sin和cos:对于每个位置i和每个维度d,使用正弦和余弦函数交替地生成位置编码,其中波长形成一个几何级数。这种编码方式不仅与序列中每个位置的绝对值有关,还由于三角函数的性质,使得位置a+b的向量可以表示成位置a和位置b的向量的组合,从而提供了表达相对位置信息的可能性。对于固定长度的间距k,PE(pos+k)可以用PE(pos)计算得到。
位置编码
位置编码的重要性:当输入序列较短时,模型在没有位置编码时依然有较高的准确率;当输入序列长度较长时,没有位置编码近乎随机排列。
位置编码的特点:
每个词的编码是唯一的。
对于任意句子,任何两个时刻输入的距离一致。
可以泛化到更长的句子中。
绝对位置编码和相对位置编码:
绝对位置编码:为每个位置分配一个唯一的编码向量。向量是固定的,与输入序列内容无关。
相对位置编码:其中每个位置被编码为一个偏移量,表示该位置与其他位置之间的相对距离。
思考
Transformer中的位置编码属于哪种编码?
替换为另一种编码方式是否会更好?
2.3 Transformer注意力机制
自注意力机制:Self-Attention
什么是自注意力机制?
例如,下列句子是要翻译的句子:
The animal didn’t cross the street because it was too tired
“it”在这个句子是指什么?它指的是“street”还是“animal”?这对于人类来说是一个简单的问题,但是对于算法则不是。
当模型处理这个单词“it”的时候,自注意力机制会允许“it”与“animal”建立联系。
自注意力机制的强大作用
随着模型处理输入序列的每个单词,自注意力会关注整个序列的所有单词,帮助模型对本单词更好地进行编码。
批注:
如果你熟悉RNN(循环神经网络),回忆一下它是如何维持隐藏层的。RNN会将它已经处理过的前面的所有单词/向量的表示与它正在处理的当前单词/向量结合起来。而自注意力机制会将所有相关单词的理解融入到我们正在处理的单词中。
当我们在编码器#5(栈中最上层编码器)中编码“it”这个单词的时候,注意力机制的部分会去关注“The Animal”,将它的表示的一部分编入“it”的编码中。
第一步:生成查询向量、键向量和值向量
第一步:这三个向量是通过词嵌入与三个权重矩阵相乘后创建的。
批注:
这三个向量是通过词嵌入与三个权重矩阵相乘后创建的。这些新向量在维度上比词嵌入向量更低,他们的维度是64,而词嵌入和编码器的输入/输出向量的维度是512.但实际上不强求维度更小,这只是一种基于架构上的选择,它可以使多头注意力(multiheaded)的大部分计算保持不变。
X1与WQ权重矩阵相乘得到q1,就是与这个单词相关的查询向量。最终使得输入序列的每个单词都创建一个查询向量、一个键向量和一个值向量。
什么是查询向量、键向量和值向量?它们都是有助于计算和理解注意力机制的抽象概念。学员们对此也有疑问。???
第二步:计算得分
第二步:计算得分。这里使用点积计算。
批注:
计算自注意力的第二步是计算得分。假设我们在为这个例子中的第一个词“机器”计算自注意力向量,我们需要拿输入句子中的每个单词对“机器”打分。这些分数决定了在编码单词“机器”的过程中有多重视句子的其它部分。这些分数是通过打分单词(所有输入句子的单词)的键向量与“机器”的查询向量相点积来计算的。所以如果我们是处理位置最靠前的词的注意力的话,第一个分数是q1和k1的点积,第二个分数是q1和k2的点积。
第三步:归一化
第三步:归一化,将分数除以8(向量维度的平方根),然后通过Softmax计算每一个单词对于其它单词的attention系数。
Softmax的作用是使所有单词的分数归一化,得到的分数都是正直且和为1.
批注:
8是论文中使用的键向量的维数64的平方根,这会让梯度更稳定。这里也可以使用其它值,8只是默认值。
这个Softmax分数决定了每个单词对编码当下位置(“机器”)的贡献。显然,已经在这个位置上的单词将获得最高的Softmax分数,但有时关注另一个与当前相关的单词也会有帮助。
第四步:对加权值向量求和
第四步,在编码某个单词时,将所有单词的表示(值向量)进行加权求和,而权重是通过该词的表示(键向量)与被编码词表示(查询向量)的点积并归一化得到,即第三步得到的结果。
然而实际中,这些计算是以矩阵形式完成的。
批注:
将每个值向量乘以Softmax分数(这是为了准备之后将它们求和)。这里的直觉是希望关注语义上相关的单词,并弱化并弱化不相关的单词(例如,让它们乘以0.001这样的小数)。
对加权值向量求和(自注意力的另一种解释就是在编码某个单词时,就是将所有单词的表示(值向量)进行加权求和,而权重是通过该词的表示(键向量)与被编码词表示(查询向量)的点积并通过Softamx得到),然后即得到自注意力层在该位置的输出(在我们的例子中是对应第一个单词)。
这样自注意力的计算就完成了。得到的向量就可以传给前馈神经网络。然后实际中,这些计算是以矩阵形式完成的,以便算得更快。那我们接下来就看看如何用矩阵实现的。
通过矩阵运算实现自注意力机制(1)
第一步是计算查询矩阵、键矩阵和值矩阵。为此,我们将输入的词嵌入到矩阵X中,将其乘以我们训练的权重矩阵( W^Q ,W^K ,W^V)。
X矩阵中的每一行对应于输入句子中的一个单词。
通过矩阵运算实现自注意力机制(2)
Attention(Q,K,V)=softmax(Q×K^T/√d_k)×V=Z
最后,由于处理的是矩阵,可以将步骤2到步骤4合并为一个公式来计算自注意力层的输出。
多头注意力机制
论文为了进一步完善自注意力层,增加一种叫做“多头”注意力(”multi-headed” attention)的机制。
通过这种机制可以进一步提高注意力层的性能。
一方面扩展了模型专注于不同位置的能力。
另一方面,它给出了注意力层的多个“表示子空间”。
提高注意力层的性能
在两方面提高了注意力层的性能
批注:
通过增加一种叫做”多头“注意力(”multi-headed” attention)的机制,论文进一步完善了自注意力层,并在两方面提高了注意力层的性能:
1、它扩展了模型专注于不同位置的能力。在上面的例子中,虽然每个编码都在z1中有或多或少的体现,但是它可能被实际的单词本身所支配。如果我们翻译一个句子时,比如“The animal didn't cross the street because it was too tired”,我们会想知道“it”指的是哪个词,这时模型的“多头”注意机制会起到作用。
2、它给出了注意力层的多个“表示子空间”(representation subspace)。接下来我们将看到,对于“对头”注意机制,我们有多个查询/键/值权重矩阵集(Transformer使用八个注意力头,因此我们对于每个编码器/解码器有八个矩阵集合)。这些集合的每一个都是随机初始化的,在训练之后,每个集合都被用来将输入词嵌入(或来自较低编码器/解码器的向量)投影到不同的表示子空间中。
八次权重矩阵运算
如果我们做与上述相同的自注意力计算,只需八次不同的权重矩阵运算,我们就会得到八个不同的Z矩阵。
批注:
在“多头”注意机制下,我们为每个头保持独立的查询/键/值权重矩阵,从而产生不同的查询/键/值矩阵。和之前一样,我们拿X乘以WQ/WK/WV矩阵来产生查询/键/值矩阵。
如果我们做与上述相同的自注意力计算,只需八次不同的权重矩阵运算,我们就会得到八个不同的Z矩阵。
这给我们带来了一点挑战。前馈层不需要8个矩阵,它只需要一个矩阵(由每一个单词的表示向量组成)。所以我们需要一种方法把这八个矩阵压缩成一个矩阵。那该怎么做?
八个矩阵压缩成一个矩阵
其实可以直接把这些矩阵拼接在一起,然后用一个附加的权重矩阵W0与它们相乘。
计算过程集中在一起看
1、这是我们的输入句子
2、编码每一个单词
3、将其分成8个头、将矩阵X或R乘以各个权重矩阵
4、通过输出查询/键/值(Q/K/V)矩阵计算注意力
5、将所有注意力矩阵Z拼接起来,然后乘以权重矩阵W0来产生该层的输出
注:除了第#0个编码器,其他编码器都不需要词嵌入。它可以直接将前一层的输出作为输入(矩阵R)。
批注:
得到8个输出矩阵Z0-Z7之后,Multi-Head Attention将它们拼接在一起(Concat),然后传入一个Linear层,得到Multi-Head Attention最终的输出Z。
Multi-Head Attention 输出的矩阵Z与其输入的矩阵X的维度时一样的。
即然我们已经摸到了注意力机制的这么多“头”,那么让我们重温之前的例子,看看我们在例句中编码“it”一词时,不同的注意力“头”集中在哪里。
2.4 Transformer细节介绍
残差连接和层归一化
在每个编码器中的每个子层(自注意力、前馈网络)的周围都有一个残差连接,并且跟随者一个“层-归一化”步骤。
批注:
在每个编码器中的每个子层(自注意力、前馈网络)的周围都有一个残差连接,并且跟随者一个“层-归一化”步骤([1607.06450] Layer Normalization)
细化这个模块
去可视化这些向量以及这个和自注意相关联的层-归一化操作,那么看起来就像左边这张图一样。
一个2层的Encoder
批注:
如果我们想象一个2层编码-解码结构的transformer,它看起来会像这张图一样。
Decoder与Encoder区别
Decoder:
包含两个Multi-Head Attention子层。
第一个Multi-Head Attention子层采用了Masked操作。
第二个Multi-Head Attention子层的K,V矩阵使用Encoder的编码信息矩阵C进行计算,而Q使用上一层的输出进行计算。
第一个Multi-Head Attention
Decoder block的第一个Multi-Head Attention采用了Masked操作。
在翻译的过程中是顺序翻译的,即翻译完第i个单词,才可以翻译第i+1个单词。
通过Masked操作可以防止第i个单知道i+1单词之后的信息。
第二个Multi-Head Attention
Decoder block第二个Multi-Head Attention变化不大,主要的区别在于其中Self-Attention的K,V矩阵不是基于上一层输出计算的,而是使用Encoder的编码信息矩阵C计算的。
根据Encoder输出的编号信息矩阵C计算得到K和V,根据上一层的输出Z计算Q,其余计算方法与之前描述一致。
这样做的好处是在Decoder的时候,每一个单词都可以利用到Encoder中所有单词的信息。
编码器输出到解码器
编码器通过处理输入序列开启工作。顶端编码器的输出之后会转化为一个包含向量K(键向量)和V(值向量)的注意力向量集。
在完成编码阶段后,则开始解码阶段。解码阶段的每个步骤都会输出一个序列的元素(在这个例子里,是英语翻译的句子)。
批注:
即然我们已经谈到了大部分编码器的概念,那么我们基本上也就知道解码器是如何工作的了。但最好还是看看解码器的细节。编码器通过处理输入序列开启工作。顶端编码器的输出之后会变转化为一个伯阿汉向量K(键向量)和V(值向量)的注意力向量集。这些向量将被每个解码器用于自身的“编码-解码注意力层”,而这些层可以帮助解码器关注输入序列哪些位置合适。
解码器不断输出
加下来的步骤重复了这个过程,直到到达一个特殊的终止符号,它表示transformer的解码器已经完成了它的输出。每个步骤的输出在下一个时间被提供给底端解码器,并且就像编码器之前做的那样,这些解码器会输出它们的解码结果。另外,就像我们对编码器的输入所做的那样,会嵌入并添加位置编码给那些解码器,来表示每个单词的位置。
批注:
而那些解码器中的自注意力层表现的模式与编码器不同:在解码器中,自注意力层只允许处理输出序列中更靠前的那些位置。在Softmax步骤前,它会把后面的位置给隐去(把他们设为-inf)。这个“编码-解码注意力层”工作方式基本就像多头自注意力层一样,只不过它是通过在它下面的层来创造查询矩阵,并且从编码器的输出中取得键/值矩阵。
解码器输出到Linear层在到Softmax层
解码组件组后会输出一个实数向量。我们如何把浮点数变成一个单词?这便是线性变换层要做的工作,它之后就是Softmax层。
批注:
解码组件最后会输出一个实数向量。我们如何把浮点数变成一个单词?这便是线性变换层要做的工作,它之后就是Softmax层。线性变换层是一个简单的全连接神经网络,它可以把解码组件产生的向量投射到一个比它大得多的、被称作对数几率(logits)的向量里。不妨假设我们的模型从训练集中学习一万个不同的英语单词(我们模型的“输出词表”)。因此对数几率向量为一万个单元格长度的向量——每个单元格对应个某一个单词的分数。接下来的Softmax层便会把那些分数变成概率(都为正数、上限1.0)。概率最高的单元格被选中,并且它对应的单词被称作为这个时间步的输出。
2.5 Transformer在视觉领域的应用
计算机视觉中的Transformer
Transformer被引入计算机视觉领域后,在图像分类和目标检测等多个领域效果出众。
在计算机视觉中使用Transformer的相关工作主要有两种模型架构。
Transformer结构;
Hybrid模型,将CNN与Transformer相结合的混合结构。
ViT
ViT(Vision Transformer)算法中尝试将标准的Transformer结构直接应用于图像,并对整个图像分类流程进行最少的修改。具体来说,ViT算法中,会将整幅图像拆分成小图像块,然后把这些小图像块的线性嵌入序列作为Transformer的输入送入网络,然后使用监督学习的方式进行图像分类的训练。
ViT模型结构
ViT参考BERT,共设置了三种模型变体(增加了Huge实体),如下所示。例如ViT-L/16,代表Large变体,输入patch size为16.
混合模型:使用ResNet50输出的特征图,不同stage会得到不同大小的特征图,即生成不同长度序列。
ViT工作流程
Swin Transformer
Vision Transformer问题:
视觉实体变化大,在不同场景下视觉Transformer性能未必很好
图像分辨率高,像素点多,Transformer基于全局自注意力的计算导致计算量较大
Swin Transformer的主要思想是把建模能力很强的transformer和视觉信号的先验联系起来,这些先验具有层次性、局部性和平移不变性,具体做法是用shifted window来建立分层特性图,有了分层特性图就可以用FPN/Unet等结构去做密集预测的任务,而且计算量与图片尺寸成正比。
批注:
Swin Transformer中滑窗操作包括不重叠的local window,和重叠的cross-window。将注意力计算限制在一个窗口中,一方面能引入CNN卷积操作的局部性,另一方面能节省计算量。
思考
在实际使用过程中Transformer可能会有哪些问题?
算力层面
算法层面
3.Transformer中的问题及优化方式
3.1 Transformer的优缺点
Transformer优势
并行计算:自注意力机制允许模型同时处理所有位置的输入。
全剧信息:自住利益机制,可以计算全局的依赖关系。
长距离依赖:通过自注意力机制,可以直接计算任意两个位置之间的依赖关系,无论是短距离还是长距离,都能有效捕捉。
扩展性强:模块化设计,且模块间耦合度低。
批注:
传统RNN和CNN在处理数据时,需要按时间步或卷积核大小依次计算,这使得它们无法完全并行化。而Transformers模型中的自注意力机制允许模型同时处理所有位置的输入,从而大大提高了计算效率。
传统的RNN在处理长序列时,容易出现梯度小时或爆炸的问题,导致难以捕捉长距离的依赖关系。而Transformer通过自注意力机制,可以直接计算任意两个位置之间的依赖关系,无论是短距离还是长距离,都能有效捕捉,这对于处理长文本序列非常有利。
CNN在处理序列数据时,通常只能捕捉局部信息,而Transformer通过自注意力机制,可以计算全局的依赖关系,从而更好地捕捉全局信息。
Transformer采用编码器-解码器架构,每个模块都由多个相同的层组成,每层都包含多头自注意力机制和前馈神经网络。这种模块化设计使得Transformer更易于扩展和调整,可以根据不同的任务需求进行定制。
Transformer中存在的问题
位置编码:Transformer中所使用的为绝对位置编码。
缺少相对位置信息。
计算:
Q、K、V的存储会占用大量显存;
Q、K、V的计算会进行大量的IO;
注意力机制计算量庞大。
Self-Attention计算复杂度(1)
对于标准Transformer中的自注意力层的计算量:
Q、K、V矩阵计算:O(n)
注意力矩阵计算:O(n**2)
Self-Attention计算复杂度(2)
SoftMax:O(1)
加权求和:O(n**2)
对于整体Transformer来说计算复杂度为O(n**2),n为序列长度,可见随着输入序列的增加,计算量呈平方式的增加。
3.2 位置编码
RoPE介绍
ROPE,即旋转位置编码(Rotary Position Embedding)。核心思想是通过旋转机制对序列中的每个位置进行编码。具体来说,它将序列中的每个位置表示为嵌入空间中的旋转,从而允许模型理解标记的绝对位置及相对距离。这种编码方式既保留了绝对位置信息,又考虑了标记之间的相对关系,使得模型能够更好地捕捉语言的语法和语义细微差别。
序列长度灵活
减少token间的依赖关系
相对位置信息
RoPE功能
RoPE的核心思想是利用复数域中的旋转操作来表示位置信息。在复数平面上,一个复数可以表示为一个向量,该向量的长度代表复数的模,而向量与实轴正方向的夹角则代表复数的辐角。RoPE通过将位置信息映射为复数的辐角,并利用旋转矩阵对这些复数进行旋转操作,从而实现对位置信息的编码。
在模型训练过程中,RoPE会为每个输入的位置生成一个唯一的复数表示,然后将这些复数与对应的单词嵌入相加,得到包含位置信息的单词嵌入。由于旋转矩阵的引入,不同位置的单词在编码后会具有不同的表示,从而保留了位置信息的绝对性。
此外,RoPE还考虑了对单词的局部依赖性。在文本中,一个单词的意义往往与其周围的单词有关。因此,RoPE通过旋转矩阵对位置信息进行编码时,不仅考虑了当前位置的信息,还考虑了其与前一个位置的相对位置关系。这种编码方式使得模型能够更好地理解文本中的上下文信息,提高了模型的性能。
RoPE计算流程
计算流程:
先获取第一个token Enhance的query和key向量,维度为d。
且分为d/2个二维向量。
通过旋转矩阵得到位置编码后的向量。
https://arxiv.org/pdf/2104.09864
ALiBi
ALiBi位置编码的主要特点是通过引入线性偏差(linear biases)来捕捉位置信息。这种方法使得模型能够在训练时处理较短的序列,并在测试时对更长的序列进行外推。这对于处理不同长度的序列数据非常有用,尤其是当测试数据中的序列长度超过训练数据中的最大序列长度时。
在ALiBi位置编码中,模型会学习一种线性变换,将位置信息嵌入到输入序列的嵌入表示中。这种线性变换使得模型能够捕捉到序列中元素之间的相对位置关系,从而提高了模型对序列数据的处理能力。
ALiBi原理
ALiBi位置编码的原理是通过向Transformer的自注意力机制的输入中添加一个线性偏置项来实现对相对位置的编码。具体来说,对于每个输入位置i和每个输出位置j,计算一个线性偏置项b_ij = i – j,这个偏置项反映了输入和输出之间的相对位置关系。然后,将这个偏置项添加到自注意力机制的输入上,使得模型在计算注意力权重时能够考虑到位置信息。
ALiBi位置编码的有点在于它不需要任何额外的参数,因此不会增加模型的复杂性。同时,由于它是基于线性偏置项的,因此可以轻松地集成到现有的Transformer模型中。此外,ALiBi编码还可以与其他的位置编码方法(如绝对位置编码或旋转位置编码)相结合,以进一步提高模型的性能。
3.3 GRMM
算力瓶颈
在大模型中(基于Transformer架构),通常认为模型中的计算主要来源于自注意力层。
Transformer中的计算量主要来自于全连接和自注意力层。
当输入序列长度足够时,自注意力层的计算量会远超全连接层。
随着计算量的增加,模型训练的瓶颈不仅会出现在运算能力上,还会出现在读写速度、网络带宽等方面。
如何减少训练所需时间?
基于硬件IO和算法计算复杂度优化:
GMEE
GlashAttention
Paged Attention
K、V cache
稀疏化注意力矩阵
。。。。。。
矩阵乘法优先介绍
矩阵乘法的定义为:C = A * B
朴素矩阵乘法的时间复杂度为O(n**3)
矩阵乘法优化:
算法优化,从数学角度优化矩阵计算的中间过程,如Strassen算法和Coppersmith-Winograd算法。
实现过程优化,优化矩阵计算时和硬件的交互。
批注:
参考:https://github.com/flame/how-to-optimize-gemm/wiki#the-gotoblasblis-approach-to-optimizing-matrix-matrix-multiplication—step-by-step
优化过程(1)
A.shape=(M,K)
B.shape=(K,N)
矩阵乘法操作与硬件交互次数:
FLOPs: 2MNK
内存访问次数:4MNK
for (int m = 0; m < M; m++) {
for (int n = 0; n < N; n++) {
C[m][n] = 0;
for (int k = 0; k < K; k++) {
C[m][n] += A[m][k] * B[k][n];
}
}
}
批注:
A、B矩阵在计算过程中各读取一次
C矩阵读写各一次
优化过程(2)
将输出的计算拆分为1 * 4的小块(向量化),即将维度拆分为两部分。计算该块输出时,需要使用A矩阵的1行,和B矩阵的4列。
FLOPs:2MNK
内存访问次数:MNK(3+1/4)
for (int m = 0; m < M; m++) {
for (int n = 0; n < N; n += 4) {
C[m][n + 0] = 0;
C[m][n + 1] = 0;
C[m][n + 2] = 0;
C[m][n + 3] = 0;
for (int k = 0; k < K; k++) {
C[m][n + 0] += A[m][k] * B[k][n + 0];
C[m][n + 1] += A[m][k] * B[k][n + 1];
C[m][n + 2] += A[m][k] * B[k][n + 2];
C[m][n + 3] += A[m][k] * B[k][n + 3];
}
}
}
优化过程(3)
继续拆分输出的M维度,从而在内侧循环中计算4 * 4输出。
FLOPs:2MNK
内存访问次数:MNK(2+1/2)
for (int m = 0; m < M; m += 4) {
for (int n = 0; n < N; n += 4) {
C[m + 0][n + 0..3] = 0;
C[m + 1][n + 0..3] = 0;
C[m + 2][n + 0..3] = 0;
C[m + 3][n + 0..3] = 0;
for (int k = 0; k < K; k++) {
C[m + 0][n + 0..3] += A[m + 0][k] * B[k][n + 0..3];
C[m + 1][n + 0..3] += A[m + 1][k] * B[k][n + 0..3];
C[m + 2][n + 0..3] += A[m + 2][k] * B[k][n + 0..3];
C[m + 3][n + 0..3] += A[m + 3][k] * B[k][n + 0..3];
}
}
}
优化过程(4)
减少C的访存次数,将累加计算存放到寄存器中,在(内循环)操作结束后再写入内存。
FLOPs:2MNK
内存访问次数:
MN+(1/2)MNK
for (int m = 0; m < M; m += 4) {
for (int n = 0; n < N; n += 4) {
C[m + 0..3][n + 0..3] = 0;
C[m + 0..3][n + 0..3] = 0;
C[m + 0..3][n + 0..3] = 0;
C[m + 0..3][n + 0..3] = 0;
for (int k = 0; k < K; k += 4) {
temp[m + 0..3][n + 0..3] += A[m + 0..3][k + 0] * B[k + 0][n + 0..3];
temp [m + 0..3][n + 0..3] += A[m + 0..3][k + 1] * B[k + 1][n + 0..3];
temp [m + 0..3][n + 0..3] += A[m + 0..3][k + 2] * B[k + 2][n + 0..3];
temp [m + 0..3][n + 0..3] += A[m + 0..3][k + 3] * B[k + 3][n + 0..3];
}
C[m + 0..3][n + 0..3] = temp[m + 0..3][n + 0..3]
……
}
}
优化过程(5)
相比于最原始的矩阵乘法计算,通过减少访存的方式提升8倍。但是整个过程中存在一些问题和一些可以进一步优化的点。
问题及优化:
随着矩阵尺寸增大,对于AB的非连续访问会导致Cache Miss。
内存布局优化。
使用SSE指令集进行进一步加速优化。
3.4 Attention优化
计算限制
硬件层面限制模型训练时长的因素:
算力限制:算力需求高且多为矩阵运算,如进行尺寸较大的CNN运算。此类运算可以硬件利用率高。
内存限制:逐点运算操作,多为非矩阵运算,如激活函数、dropout、mask、softmax、BN和LN。
https://arxiv.org/pdf/2205.14135
DRAM、HBM、SRAM介绍
DRAM:动态随机存取存储器。它是最常见的系统内存,即平常所说的内存。容量大,价格低,但速度较慢。
HBM:高带宽内存,带宽非常高,容量也较大;适合处理大型数据集和复杂的计算任务。
SRAM:静态随机存取存储器,SRAM的速度非常快,但价格也相对较高。SRAM通常用于需要高速缓存(cache)的场合,如CPU的L1和L2缓存。
https://arxiv.org/pdf/2205.14135
Attention在硬件层面上的计算流程
每次操作都会将数据在HBM和SRAM之间进行复制。
反复在HBM中读写数据会增加不必要的时长。
FlashAttention
FlashAttention算法是一种新型的注意力算法,它的设计初衷是为了优化传统注意力机制在计算效率、内存消耗以及硬件利用上的不足。
FlashAttention算法的主要优化原理包括内存访问优化、矩阵运算优化、分块处理以及可能的硬件加速。
在内存访问优化方面,FlashAttention通过减少内存访问次数来提高计算效率,避免了传统注意力机制中频繁的内存读写带来的延迟。
FlashAttention计算流程
FlashAttention算法通过有效利用GPU的SRAM资源,实现了在处理长序列时的内存节省和计算加速。
https://arxiv.org/pdf/2205.14135
FlashAttention实现过程
在具体的实现上,FlashAttention算法采用了分块处理(tilling)和迭代式计算Softmax的策略。
首先,它将输入的Query、Key和Value分割成大小为Br和Bc的块。
然后,在外循环中遍历Key和Value的块,将其加载到GPU的快速缓存(SRAM)中,在内循环中,遍历Query的块,也加载到SRAM中。
在SRAM中计算每个Query块与当前块的局部注意力分数,并计算局部注意力分数的Softmax值,更新全局统计量。最后,使用全局统计量缩放并聚合局部Attention输出,得到最终的Attention输出。
FlashAttention作用
FlashAttention可以将内存开销降低到线性级别,并实现了2-4倍的加速,同时避免了对中间结果的频繁读写,从而提高了计算效率。
但是,FlashAttention仍然不如优化的矩阵乘法(GEMM)操作块,只达到理论最大FLOPs的25-40%。
FlashAttention2
FlashAttention2在FlashAttention的基础上进行了进一步的改进。主要的改进点包括:
并行计算和线程式工作分配的优化:FlashAttention2通过优化并行计算和线程束工作分配,提高了在处理长序列时的效率和吞吐量。这种优化使得FlashAttention2能够更好地利用GPU资源,减少了内存访问和同步操作,从而进一步提升了模型的训练和推理速度。
减少了non-matmul FLOPs的数量:FlashAttention2通过优化算法,减少了非矩阵乘法(non-matmul)浮点运算的数量,特别是消除了1中频繁的rescale操作。
FlashAttention2在正向传递中实现了约2倍的速度提升,达到了理论最大吞吐量的73%。
FlashAttention2在反向传递中达到了理论最大吞吐量的63%。
批注:
虽然non-matmul FLOPs仅占总浮点运算数量的一小部分,但这一改进对于提升整体性能仍然具有重要意义。
4.大语言模型架构介绍
GLM
GLM(General Language Model,通用语言模型)架构是一种基于Transformer架构的语言模型,它主要针对自然语言处理任务进行设计和优化,可以用于各种NLP任务,如文本分类、情感分类、自然语言生成等。
GLM模型的设计目标是通过一种通用的预训练框架来解决自然语言理解、无条件生成和有条件生成等任务。它的训练目标时自回归空白填充,即从文本序列中采样文本片段(span),对其进行掩码(mask),然后要求模型对这些被掩码的片段进行自回归恢复。
GLM结构介绍
利用自回归填空的思想,基于Transformer的编码器实现了同时在NLU和有无条件生成任务上较好的表现。
对于输入文本中随机地空白/删除连续的标记跨度,并按照自回归预训练的思想来训练模型来依次重建这些跨度。
https://arxiv.org/pdf/2103.10360
批注:
跨度打乱和2D位置编码:不同的跨度的顺序是打乱的;2D位置编码包括了token在原始句子中的位置和token在跨度中的位置。
GLM结构介绍(2)
文本原始输入:x1,x2,x3,x4,x5,x6,随机筛选部分跨度的token进行mask,原句子中的位置用mask表示。
筛选跨度长度的方式是使用lambda为3的泊松分布进行抽样。
PartA部分:x1,x2,M,x4,M,其中M表示mask的跨度。
https://arxiv.org/pdf/2103.10360
GLM结构介绍(3)
对挑选出的跨度token进行随机排序,跨度的起始位置加入tokens。
PartB部分:S,x5,x6,x3
拼接PartA和PartB作为输入。
x1,x2,M,x4,S,x5,x6,S,x3
https://arxiv.org/pdf/2103.10360
批注:
GLM将Part A和Part B拼接到了一起。对于Part B中的一个token,他有两个位置信息,一个是它在原始文本中的位置,另外一个是它在文本片段中的位置。为了表示这个信息,GLM提出了二维位置编码。这个二维位置编码由片段间位置编码(intra-position encoding)和片段内位置编码(inner-position encoding)组成。
GLM结构介绍(4)
注意力:
PartA部分内的各token可以互相注意。
PartB部分的tokens可以注意到PartA和PartB中已经生成的token。
https://arxiv.org/pdf/2103.10360
模型结构调整细节
调整了LN和残差连接的顺序。
对于token的预测输出用的是单个的线性层。
将激活函数由ReLU调整为了GeLUs
ChatGLM
ChatGLM在GLM-130B的基础上持续进行文本和代码预训练并通过有监督微调等技术实现人类意图对齐,具备文案写作、信息抽取、角色扮演、问答、对话能力等。
此外,还有基于ChatGLM-6B开源大语言模型,这个模型有着62亿个参数,它采用了General Language Model(GLM架构,并且通过模型量化技术,可以在普通的显卡上运行(只需6GB显存)。
ChatGLM2-6B技术改进
SwiGLU激活函数。
RoPE,旋转位置编码。
Multi-Query Attention。
Multi-Query Attention
Multi-Query Attention(MQA),是多查询注意力的一种变体,也是利用自回归解码的一种注意力机制。与MHA不同的是,MAQ让所有的头之间共享一份Key和Value矩阵,每个头只单独保留了一份Query参数,从而减少Key和Value矩阵的参数量。
LLaMA
LLaMA(Large Language Model Meta AI),由Meta AI发布的一个开放且高效的大型基础语言模型,共有7B、13B、33B、65B)四种版本。其数据集来源都是公开的数据集,无任何定制数据集,保证了其工作与开源兼容和可复现,整个训练数据集在token化之后大约包含1.4T的token。
LLaMA的性能非常优异:具有130亿参数的LLaMA模型在大多数基准上可以胜过GPT-3(参数量达1750亿)。
LLaMA模型结构
LLaMA由Transformer中的decoder堆叠而成,并进行了一系列的优化:
Tokenizer:BPE算法。
RMS Pre-Norm:对每一个Transformer的子层输入都进行归一化,使用RMSNorm归一化函数。
SwiGLU:在前馈神经网络(FFN)使用SwiGLU激活函数替换了Transformer中的ReLU激活函数来提升性能
RoPE:RoPE可以兼顾相对位置和绝对位置的信息以提高模型的泛化能力。
使用causal mask保证每个位置只能看到前面的tokens.
LLaMA2
LLaMA2在预训练语料上比LLaMA增加了40%,增至2万亿个token,且训练数据汇总的文本来源更加的多样化。此外,LLaMA2对应的微调模型是在超过100万条人工标注的数据下训练而成。
LLaMA2的上下文长度比LLaMA扩大了一倍,从2048个token拓展至4096个token。更长的上下文窗口意味着更多的聊天用例可被采用,进而模型的理解能力得以提升。
LLaMA2
使用Grouped-Query Attention(GQA)代替Multi-Head Attention(MHA)。
Reward Model:
llama2训练了两个独立的奖励模型,一个针对帮助性helpfulness进行了优化,另一个针对安全safety进行了优化。
Group Query Attention
自回归模型生成回答时,需要前面生成的KV缓存起来,来加速计算。
多头注意力机制(MHA)需要的缓存量很大。GQA将查询头分成了G个组,每个组共享一个公共的键(K)和值(V)投影。
当G=1时,等价于MQA
当G=H时,等价于MHA
批注:
Multi-Query Attention指出多个头之间可以共享KV对,Group Query Attention没有像MQA一样极端,将query分组,组内共享KV,效果接近MHA,速度上与MQA可比较。
5.多模态大模型架构介绍
DALL-E
DALL-E 2是一个可以根据自然语言描述生成逼真的图像和艺术品的AI应用,由OpenAI团队开发。
它使用CLIP、Prior和decoder模型组合来生成图像,其质量取决于文本提示的具体性。
https://cdn.openai.com/papers/dall-e-2.pdf
DALL-E 2的工作流程:
首先,将文本prompt输入到经过训练以将prompt映射到表征空间的文本编辑器中;
接下来,称为先验的模型将文本编码映射到相应的图像编码,该图像编码捕获编码中包含的prompt的语义信息;
最后,图像编码模型随机生成图像,该图像是该语义信息的视觉表现。
https://cdn.openai.com/papers/dall-e-2.pdf
DALL-E 2结构
DALL-E 2中模型由两部分组成:CLIP模型图像生成模型;
预训练CLIP模型用于生成文本和图像编码。
Prior阶段:对于一个文本x,经由CLIP可以产生text embedding和Image embedding,产生的text embedding和Image embedding,产生的text embedding经过autoregressive或difussion的prior模型生成Image embedding,这一个阶段用CLIP中生成的Image embedding对其做监督。
Decoder阶段:用于从Image embedding中解码出图像。
批注:
Prior阶段这样做的目的是:等在做推理的时候,即使只有文本特征,也可以生成比较好的图像特征。
CLIP
CLIP模型包括一个视觉部分和一个语言部分。
视觉部分使用了卷积神经网络(CNN)和自注意力机制(self-attention),以提取图像中的特征。这有助于模型理解和识别图像中的关键元素和细节。
语言部分则使用了一个Transformer模型,以处理文本数据。这允许模型理解和分析文本中的语义和上下文信息。
https://arxiv.org/pdf/2103.00020
图像生成模型
Prior模块,根据CLIP中输出的文本编码生成对应的图像编码。
Autoregressive网络
扩散模型
Decoder模块,还原出真实原片。
VAE
扩散模型
GILDE
批注:
总结来说,prior负责让生成的图片符合文本意思,而decoder让生成的图片具备了多样性。
视频生成
OpenAI Sora模型,能够根据用户的文本提示创建最长60秒的逼真视频。相比于其他视频生成共计,Sora所生成的视频根据连贯性、真实性,但模型并未开源。
Open-Sora是一个开源项目,为Sora可能使用的开发流程提供高性能实现,包括数据处理、训练和部署的完整Sora复现架构解决方案。
Open-Sora训练流程
Sora:使用了一个视频压缩网络,将不同尺寸的视频压缩成一个隐空间(latent space)的时空块序列(temporal patch),然后是哟哦那个了Difussion Transformer进行去噪,最后进行解码生成视频。
Open-Sora根据Sora所可能使用到的一些模块将Sora训练流程设计为下:
Open-Sora
目前Open-Sora提供以下功能:
完整的Sora复现架构:包含从数据处理到训练推理全流程。
动态分辨率:训练时可直接训练任意分辨率的视频,无需进行缩放。
多种模型结构:由于Sora实际模型结构未知,Open-Sora实现了adaLN-zero、cross attention、in-context conditioning(token concat)等3种常见的多模态模型结构。
多种视频压缩方法:用户可自行选择使用原始视频、VQVAE(视频原生的模型)、SD-VAE(图像原生的模型)进行训练。
多种并行训练优化:支持Colossal-AI的AI大模型系统优化能力,及UIysses和FastSeq的混合序列并行。
6.MoE结构介绍
多领域任务处理
以往神经网络模型基本上是针对单一场景处理专业问题,每个模型可能只被应用在一个或者少数几个任务中。
是否可以让一个模型处理多个领域的任务呢?
批注:
在实际的数据分布中,存在着很多天然的子集,如不同的domain、topic、不同的语言、不同的模态等等,在使用单个模型进行学习,且模型capacity较小的情况下,不同子集会起到噪声的作用,干扰模型的拟合,导致模型训练较慢、泛化困难。
对于传统的学习模型来说,训练的主要目的是使最终模型能够在不同的场景下执行多种任务。但这种训练方式也使得模型在对相应场景进行权重更新的同时,也会影响到模型对其他场景的权重。这种权重的互相影响称为干扰效应(interference effect)。干扰效应越强,模型的学习速率(Learning Speed)越慢,而且最终模型的泛化行(Generalization)也会越差。
MoE(Mixture-of-Experts)
混合专家模型,英文叫Mixture of Expert,MoE是一种模型设计策略,它通过将多个模型(称为“专家”)直接结合在一起,以获得更好的预测性能。
在大模型中,MoE方案可以有效地提高模型的容量和效率。一般而言,大模型的MoE有一个门控机制和一套门控输出机制来合并和平衡专家的选择,用于决定每个专家对最终预测的;有一套专家选择机制,会根据门控机制的输出选择一部分专家进行预测。
为什么引入MoE
模型规模是提升模型性能的关键因素之一,这也是为什么今天的大模型能取得成功。在有限的计算资源预算下,用更少的训练步数训练一个更大的模型,往往比用更多的步数训练一个较小的模型效果更佳。
MoE的一个显著优势是它们能够在远少于Dense模型所需的计算资源下进行有效的预训练。这意味着在相同的计算预算条件下,您可以显著扩大模型或数据集的规模。特别是在预训练阶段,与稠密模型相比,混合专家模型通常能够更快地达到相同的质量水平。
MoE-Vanilla MoE
专家系统:用于学习不同的数据。输入数据经过每个专家系统,分别会输入一个输出值,再该图中,每个输出标记为Oi。
Gating Network:决定每个专家系统输出在随机选择器里的权重。它为每个输出分配的权重为Pi。该网络同样可以被训练。
随机选择器:获取多个专家系统的当前输出,结合权重获得最终输出结果。
批注:
1991年的论文,使用多个模型(即专家,专家)去学习,使用一个门网络(gating network)来决定每个数据应该被哪个模型去训练,这样就可以减轻不同类型样本之间的干扰。
损失函数的选择
对于一个输入样本c,第i个专家的输出为o_i^c,Ground truth即真实值是d^c,则损失函数为:
其中p_i^c为Gating Network分配给每个专家的权重,相当于多个专家齐心协力得到当前样本的输出。
但是存在一个问题——不同的专家之间的互相影响会非常大,一个专家的参数改变了,其他的都会跟着改变,即所谓牵一发而动全身。
因此研究人员在此基础上进行了改进损失函数。
将p_i^c提前,使得每个数据样本尽可能被每一个专家处理,每个专家单独计算损失函数,然后再加权求和得到总体的loss,鼓励不同专家的竞争。
批注:
就是让不同的expert单独计算loss,然后在加权求和得到总体的loss。这样的话,每个专家,都有独立判断的能力,而不用依靠其他的expert来一起得到预测结果。
上面的两个loss function,其实长得非常像,但是一个是鼓励合作,一个是鼓励竞争。
Sparse MoE
在前Transformer时代,使用RNN构造的神经网络很难做到很深,且硬件利用率也不高。Googole Brain提出使用稀疏的MoE结构来将模型容量做大的方法,即:训练时使用海量Expert,推理时激活少数Expert。
稀疏门控专家混合层
专家网络:MoE层是由一组专家网络组成,每个专家被设计为具有相同架构的前馈网络,但参数是独立的。
门控网络:MoE层包含一个可训练的门控网络,其输出是一个稀疏的n维向量。门控网络的作用是为每个输入示例选择一组专家。
批注:
专家本身就是神经网络,每个都有自己的参数。虽然原则上只要求专家接受相同大小的输入并产生相同大小的输出,但在本文的初步研究中,将自己限制在以下情况:模型是具有相同架构的前馈网路,但具有单独的参数。
Softmax Gating
对于给定的输入x,用G(x)和E_i(x) 表示门控网络的输出和第i个专家网络的输出 。MoE模块的输出y可以写成如下:
Softmax门控:非稀疏门控函数的一个简单选择是将输入乘以可训练的权重矩阵Wg,然后应用Softmax函数:
Noisy Top-K Gating
Sparse MoE使用了Noisy Top-K Gating,它向Softmax门控网络添加两个组件:稀疏性和噪声,实现步骤如下:
输入变换:输入x通过门控网络的权重矩阵𝑊𝑔进行变换。
噪声添加:在变换后的输入上添加高斯噪声,以引入随机性。
Top-K选择:应用一个选择机制,仅保留噪声输入中门控分数最高的k个值,并将其与值设置为负无穷大(或其他低值),这样在应用softmax函数时,这些位置的输出会接近零。
Softmax归一化:对包含噪声和Top-K选择的输入应用softmax函数,以生成最终的门控输出。
批注:
噪声注入:在计算门控分数之前,Noisy Top-K Gating向输入添加可调的高斯噪声。这种噪声有助于打破对称性,使不同的专家可以在训练过程中学习不同的特征。
端到端训练:尽管引入了噪声,Noisy Top-K Gating仍然可以通过反向传播算法进行端到端训练,因为噪声是在训练过程中学习的参数。
Noisy Top-K Gating优势
稀疏激活:通过仅激活门控分数最高的k个专家,Noisy Top-K Gating 实现了稀疏性,这意味着在任何给定时间只有网络的一小部分被用于计算。
负载均衡:噪声的引入有助于在专家之间更均匀地分配负载,因为噪声可以鼓励门控选择不同的专家集合,而不是总是倾向于相同的专家。
计算效率:由于只有k个专家被激活,因此可以显著减少所需的计算量,这对于大型模型尤其重要。
动态选择:Noisy Top-K Gating允许模型动态地根据输入特征选择最合适的专家,这增加了模型的灵活性。
改进的泛化:噪声和稀疏性可能有助于模型避免过拟合,因为它鼓励模型学习更加泛化的特征表示。
批注:
也有缺点,微调时出现过拟合,加载模型时需要加载全部expert,所以显存占用大。
Expert Balancing
不同expert在竞争的过程中,会出现“赢者通吃”的现象:前期表现好的expert会更容易被Gating Notwork选择,导致最终只有少数几个experts真正起作用。
为解决此问题,Sparse MoE额外增加了一个Loss,来缓解这种不平衡现象,公式如下:
其中X代表的是一个batch的样本,把一个batch所有样本的gating weights加起来,然后计算变异系数(confficient of variation)。
批注:
17、18年时,当时数据集的特征比较集中,也会导致专家不平衡的现象。目前没办法完全解决这个问题,只能是缓解。
GShard
GShard是Google发布的首个Transform架构与MoE结合的模型架构。
Transformer编码层油两个连续层组成,即一个自注意力层,后面跟着一个位置前馈层。解码器添加了第三个交叉注意力层,该层关注编码器的输出。通过条件计算稀疏地缩放Transformer,将每个其他前馈层替换为Position-wise Mixture of Experts(MoE)层。
Encoder/Decoder是由多个Transformer块组成的,MoE层每隔一个块替换一个FNN层,也就是在N/2个块修改模型。
批注:
之前的moe是把每个样本分到不同的expert,transform架构中是把每个token分到不同的expert。
Top-K gating
门控网络可能会使用Top-K gating机制,这意味着对于每个输入token,只有概率最高的K个专家会被选中进行计算。Gshard使用的K是2,即top-2.
Gshard中门控函数满足两个条件:
平衡负载
可高效率的大规模并行计算
批注:
希望MoE层能够稀疏地激活给定令牌的专家。一个简单的解决方案是根据softmax概率分布选择top-K专家。然而,众所周知,这种方法会导致训练的负载不平衡问题。在训练过程中看到的大多数令牌将被分配给少数专家,只为少数(忙碌的)专家积累了非常大的输入缓冲区,而其他专家则未得到训练,从而减慢了训练速度。与此同时,许多其他专家根本没有得到充分的训练。一个更好的门控函数设计可以更均匀地处理负担分配给所有专家。
如果按顺序执行门控功能,则实现平衡负载将是相当简单的。对于给定E个专家的输入批中所有N个令牌,单独的门控函数的计算成本至少为0(NE)。然后,在研究中,N的数量级为千,门控函数的顺序实现将使大部分计算资源在大多数时间处于空闲状态。因此,需要一个有效的门控函数并行实现来利用许多器件。
Swith Transformer
Switch Transformer是由Google Brain在2022年发布的具有1.6万亿参数的MoE模型,包含2048个expert。
批注:
Transformer中的前馈全连接子层(Feed-Forward Network,FFN)视为Expert,使用多个FNN代替原来单一的FFN,并且使用了最简单的路由选择策略,将K设置为1,即不同的输入只会选择一个FFN进行计算。这样相比较于原来的结构,计算量只增加了路由选择的计算量,而新增的计算量相比较于原来的计算量而言可以忽略,这样就实现了增大模型参数的同时维持相对不变的计算量。
简化稀疏路由
混合专家模型(MoE):x表示每一个token的输入,则通过路由权重计算得到的logits为h(x),门控值(gated value)通过所有专家的logits使用softmax计算得到。输出y来自不同的专家的加权和,权重即路由门控值得到。
Switch Routing
该模型使用了一个创新的路由策略,即每次只发给一个专家,这样可以简化路由计算量的同时保证模型的性能。这样做的优势:
路由计算量减少,只有一个expert激活;
expert中的batch_size(专家容量)至少减半;
简化路由的实现,减少传统MoE方法中通信的代价。
GLaM
GLaM是由Google发布一个MoE模型。
该模型可以被认为具有不同的子模型(或专家),每个字模型都专门用于不同的输入。每一层的专家由一个门控网络控制,该门控网络根据输入数据激活专家。对于每个token(通常是一个词或词的一部分),门控网络选择两个最合适的专家来处理数据。
完整的GLaM总共有1.2T参数,每个MoE包含64个专家,总共32个MoE层。
但在推理期间,动态路由从64个专家网络中选择的两个,每个输入token经过这两个专家网络进行预测。
批注:
预测时,模型只会激活97B的参数(2个专家网络),占总参数的8%。
与GShard MoE Transformer类似,谷歌用MoE层替换其他transformer层的单个前馈网络(人工神经网络最简单的一层,如上图蓝色方框中的Feedforward或FFN)。MoE层有多个专家,每个专家都是具有相同架构但不同权重参数的前馈网络。
尽管MoE层有很多参数,但专家是稀疏激活的,这意味着对于给定的输入token,只使用两个专家,这样做的优势是在限制计算的同时给模型提供更多的容量。在训练期间,每个MoE层门控网络都经过训练,使用它的输入来激活每个token的最佳两位专家,然后将其用于推理。对于MoE层的E专家来说,这本质上提供了Ex(E-1)个不同前馈网络组合的集合,而不是经典Transformer中的一个组合,从而带来更大的计算灵活性。
最终学习到的token表示来自两个专家输出的加权组合,这使得不同的专家可以激活不同类型的输入。为了能够扩展到更大的模型,GLaM架构中的每个专家都可以跨越多个计算设备。
Mixtral of Experts
Mixtral的开发团队在24年年初发布了Mixtral 8x7B,这是一款高质量的稀疏混合专家模型(SMoE),拥有开放的权重。
Mixtral是一种稀疏混合专家网络。它是一个仅解码的模型,其中前馈块从8组不同的参数集合中选择。在每一层,对于每个词元,一个路由器选择这些组合中的两组专家网络来处理词元并将其输出相加。
单个Mixtral模型结构
批注:
Top-2
滑动窗口注意力
Mixtral 7B使用了滑动窗口注意力,以有效处理任意长度的序列。
批注:
每个token最多可以关注来自上一层的W个token(上图中,W=3)。请注意,滑动窗口之外的token仍然影响下一个单词预测。但是对于整个网络来说(图3)它可以观看到全部长度的语句。
在每个注意力层,信息可以向前移动W个token。因此,在k层注意力之后,信息最多可以向前移动k个xW个token
MoE的优缺点
训练:
与稠密模型相比,相同计算资源下,MoE可以实现更大的参数量,性能可能较好。
与相同参数量的稠密模型相比,训练速度更快。
微调阶段,泛化能力不足,易引起过拟合。
推理:
推理时使用较少的expert,计算资源使用较少,可以实现高吞吐量。
推理速度更快。
推理时需要加载全部的模型,对显存要求非常高。
MoE的常见并行计算方法
分区策略 模型权重(参数) 数据
数据并行:
模型权重在每个节点上复制
全量数据在所有节点之间分割
模型并行:
模型权重在节点之间分割
全量数据在每个节点上复制
模型和数据并行:
模型权重复制为几组,在组内节点中进行分割
全量数据分割为几个不同批次;
每个批次在对应模型权重组内的各个节点上复制
专家和数据并行:
各个专家被放置在不同的节点上,每个节点拥有不同的专家
全量数据在所有节点之间分割
专家、模型和数据并行:
每个专家被放置在一组节点上,该专家权重在节点间分割
全量数据分割为几个不同批次;
每个批次在对应模型权重组内的各个节点上复制
本章总结
本章节介绍了transformer的结构与计算流程和transformer的优化方向,以及常见大模型架构。
————————————
仅用于本人学习
来源:网络