点击箭头处“蓝色字”,关注我们哦!!
LLM Visualization是一个大语言模型 (LLM) 可视化网站,通过将论文天书做成了可交互的流程动画,清晰友好的演示了LLM 基本架构和运行细节,看完流程演示的我真的被LLM背后的伟大设计惊叹到,牛牛牛 http://llm-viz-cn.iiiai.com/llm
Transformer Explainer 是最新火起来的另一款可视化交互网站。它展示了基于 Transformer 的 GPT-2 模型的基本构成,以及数据在组件间的传输流程。比起llm-viz-cn相对来说细节少了一些,但也更好理解,建议大家自己来看的话可以先Explainer,再llm-viz-cn。https://poloclub.github.io/transformer-explainer/
今天的文章就联手这两大Top级工具,深入剖析Transformer的流程细节,通过图解,让我们更好的了解LLM智能的背后到底是什么名堂!
下面是今天文章涉及的专业术语,快速一瞥,阅读更丝滑哟
Transformer是什么
变压器(Transformer)是一种神经网络架构,从根本上改变了人工智能领域的方法论。它首次在2017年的开创性论文《注意力就是你所需要的》中被提出,自此成为深度学习模型的首选架构,为诸如OpenAI的GPT、Meta的Llama以及Google的Gemini等文本生成模型提供动力。除了文本领域,Transformer还被应用于音频生成、图像识别、蛋白质结构预测乃至游戏策略等领域,展示出其在众多领域的广泛适用性。
从根本上讲,文本生成型的Transformer模型基于下一个词预测的原理运作:给定用户提供的文本提示,接下来最有可能出现的词语是什么。
Transformer的核心创新和强大之处在于它们使用了自注意力机制,这使得它们能够处理整个序列,并比之前的架构更有效地捕捉长距离依赖关系。
GPT-2模型系列是文本生成型Transformer的突出例子。Transformer解释器由GPT-2(小)模型驱动,该模型拥有1.24亿个参数。虽然它不是最新或最强大的Transformer模型,但它与当前最先进的模型共享许多相同的架构组件和原则,这使得它成为理解基础概念的理想起点。
Transformer架构
每个文本生成型的变换器都包含以下三个关键组成部分:
嵌入(Embedding):文本输入被划分为更小的单位,称为令牌(tokens),这些令牌可以是单词或子词。这些令牌随后被转换成称为嵌入的数值向量,这些向量捕捉了单词的语义意义。嵌入使得模型能够理解文本中单词的深层含义。
变换器块(Transformer Block):这是模型的基本构建模块,负责处理和转化输入数据。每个块包括:
注意力机制(Attention Mechanism),这是变换器块的核心部分。它允许不同的令牌之间相互“交流”,捕捉词汇间的上下文信息和词语之间的关系。这意味着模型能理解一个词如何依赖于句子中的其他词。
多层感知机层(MLP Layer,Multilayer Perceptron Layer),这是一个前馈网络,对每个令牌独立操作。如果说注意力层的目的是在令牌间传递信息,那么MLP层的目标则是细化每个令牌的表示,增强其特征表达能力。
输出概率(Output Probabilities):最后,通过线性层和softmax层,处理过的嵌入被转化为概率形式。这一过程使模型能够预测序列中下一个令牌的可能性,从而做出基于上下文的预测。换句话说,模型通过分析之前的文本内容,可以智能地推测出接下来可能出现的单词,这对于生成连贯、有意义的文本至关重要。嵌入(Embedding)技术应用解析:
Embedding嵌入
假设我们打算使用一个Transformer模型来生成文本,比如我们输入这样的开头:“数据可视化使用户能够”。为了让模型理解和处理这个信息,我们需要先把这段文本转换成模型能够识别和操作的形式。这时,“嵌入”技术就大显身手了:它把文本转化成一种数值表示,让模型能够处理。将一个提示语句转化为嵌入向量,我们需要分四步走:分词(Tokenize)、获取词嵌入(Token Embeddings)、加入位置信息(Positional Encoding)、合并词嵌入与位置编码(Final Embedding)
步骤 1:分词(Tokenization)
首先,我们要把输入的文本拆分成一个个基本单位,这叫分词。比如将句子切分成单词或者更小的语言单元。
分词是将输入的文本拆分成更小、更容易管理的部分,我们称之为“token”(标记)。这些token可以是一个单词或子词。比如,"Data" 和"visualization" 各自对应一个独特的token,而 "empowers" 这个词则被切分为两个token。在训练模型前,会确定所有token的完整词汇表:GPT-2的词汇表有50,257个不同的token。现在我们将输入文本拆分成带有唯一ID的token后,就可以从嵌入中获取它们的向量表示了。
步骤 2. Token 嵌入(Token Embedding)
接下来,每个分词都需要转换成一个向量形式,这个过程称为获取词嵌入。这些向量能够捕捉到词汇的语义信息,相似意义的词在向量空间中会比较接近。
GPT-2小型版将词汇表中的每个token表示为一个768维的向量;这个向量的维度取决于模型的设计。这些嵌入向量存储在一个形状为(50,257, 768)的矩阵中,大约包含3900万个参数,这个庞大的矩阵使得模型能够为每个token赋予语义意义。
步骤 3. 位置编码(Positional Encoding)
因为顺序对于语言理解至关重要,所以需要为每个词嵌入加上位置编码,这样模型就能知道句子中各个词的相对位置。比如,“Data”在“visualization”前面,这种顺序关系通过位置编码体现出来。
嵌入层还会编码每个token在输入提示中位置的信息。不同的模型使用各种方法进行位置编码。GPT-2会从零开始训练自己的位置编码矩阵,并直接将其融入到训练过程中。
步骤 4. 最终嵌入(Final Embedding)
最后一步,我们将得到的词嵌入向量和对应的位置编码向量相加,从而获得最终的嵌入表示。这个综合的向量既包含了词的语义信息,也保留了它们在句子中的位置信息,是模型进行后续处理的理想输入格式。
这种组合表示既捕捉到了token的语义含义,又考虑到了它们在输入序列中的位置。
Transformer变压器块
变压器块是Transformer模型处理的核心部分,它结合了多头自注意力(Multi-Head Self-Attention)和多层感知器(Multi-Layer Perceptron)层。大多数模型由多个这样的块顺序堆叠而成。从第一个块到第十二个块,标记表示通过层层演变,使模型能够对每个标记建立复杂深入的理解。这种分层的方法使得输入信息的表示更加高级和抽象。
层归一化(Layer Normalization)
变换器(Transformer)模块的第一步是对该矩阵进行层归一化处理。这是对矩阵每列的值分别进行归一化的操作。归一化是深度神经网络训练中的一个重要步骤,它有助于提高模型在训练过程中的稳定性。
层次规范化有助于稳定训练过程并提升收敛速度。它通过对特征进行规范化,确保激活值的均值和方差保持一致,从而工作。这种规范化能缓解内部协变量转移问题,让模型更高效学习,并减少对初始权重的敏感性。在每个变换器模块中,层次规范化会被应用两次,一次在自注意力机制前,一次在多层感知机(MLP)层前。
我们的目标是使该列的平均值等于 0,标准差等于 1。为此,我们要找出该列的这两个量(平均值(μ)和标准差(σ)),然后减去平均值,再除以标准差。其目标是使该列的平均值等于 0,标准差等于 1。为此,我们找到该列的平均值(μ)和标准差(σ),然后减去平均值并除以标准差。
这里我们使用 E[x] 表示平均值,Var[x] 表示方差。方差就是标准差的平方。ε项(ε = 1×10-5)是为了防止除以零。
我们在聚合层中计算并存储这些值,因为我们要将它们应用于列中的所有值。最后,在得到归一化值后,我们将列中的每个元素乘以学习权重 (γ),然后加上偏置 (β) ,最终得到归一化值。
我们在输入嵌入矩阵(input embedding matrix) 的每一列上执行这一归一化操作,得到的结果就是归一化后的输入嵌入(normalized input embedding),并将其传递给自注意力(Self-Attention)层。
整体过程如下:
多头自注意力(Multi-Head Self-Attention)
多头自注意力机制Multi-Head Self-Attention让模型能够专注于输入序列中的相关部分,从而捕捉数据内部的复杂关系和依赖性。是变换器(Transformer)和 GPT 的核心。在这一阶段,输入嵌入矩阵中的各列相互 "对话"。到目前为止,在所有其他阶段,各列都是独立存在的。
自注意力(self-attention)层由几个头部组成,所以叫做多头自注意力(Multi-Head Self-Attention),我们现在只关注其中一个。
查询、键和值矩阵
图中展示了如何从原始嵌入中计算查询(Query)、键(Key)和值(Value)矩阵。
每个标记的嵌入向量被转换为三个向量:查询(Q)、键(K)和值(V)。这些向量是通过将输入嵌入矩阵与为Q、K、V学习到的权重矩阵相乘得到的。这里有一个类比帮助理解这三个矩阵:
查询(Q)就像是你在搜索引擎中输入的搜索词。标记着你想要获得的更多相关信息。
键(K)可以比作搜索结果窗口中每个网页的标题。它表示你想要查询的内容,关联到的标记。
值(V)则是搜索结果显示的实际网页内容。一旦我们的搜索词(查询Q)与相关的结果(键K)匹配上,我们就想获取最相关页面的内容(值V)。
通过使用这些Q、K、V值,模型能计算出注意力分数,该分数决定了在生成预测时每个标记应获得的关注程度。
掩码自注意力
掩码自注意力能让模型生成序列时,专注于输入信息中有用的部分,同时不让它“看到”未来的词语。
图中展示的是:利用查询、钥匙和值这三个矩阵来计算掩码自注意力的过程。
Attention Score:注意力评分:Query矩阵和Key矩阵相乘的结果(点积),能决定每个Query项与每个Key项的匹配度,产出一个方阵,这个方阵反映出所有输入词语之间的关系。
Masking掩码处理:在注意力矩阵的上三角部分应用掩码(图中灰色的部分),这样做是为了阻止模型访问未来的词语,把这些位置的值设置为负无穷大。这样一来,模型就必须学会在不“偷看”未来信息的情况下预测下一个词语。
Softmax操作:掩码处理后,通过softmax操作将注意力评分转化为概率。softmax会对每个注意力评分取指数。这样处理后,矩阵每一行的总和为1,每一行都显示出该行对应词语左侧所有其他词语的相关性。
Dropout丢弃法:丢弃法是一种正则化技术,通过在训练期间随机将模型权重的一部分设为零来防止神经网络过拟合。这促使模型学习更稳健的特征,减少对特定神经元的依赖,帮助网络更好地泛化到新、未见过的数据上。在模型推断时,丢弃法会关闭。这意味着我们实际上是在使用训练过的子网络的集合,从而提高模型性能。
Projection:投射
现在我们得到了自注意力(self-attention)层的输出。我们不是直接将这个输出传递到下一个阶段,而是将其与输入嵌入(input embedding)进行元素级相加。这个过程,用绿色垂直箭头表示,被称为 残差连接(residual connection) 或 残差路径(residual pathway) 。
残差连接Residual Connections最早于2015年在ResNet模型中引入,这一设计创新通过允许训练极深的神经网络彻底改变了深度学习。基本上,残差连接是绕过一层或多层的捷径,将某层的输入加到其输出上。这有助于缓解梯度消失问题,使得带有多个堆叠变换器模块的深层网络更容易训练。在GPT-2中,每个变换器模块内使用了两次残差连接:一次在MLP之前,一次之后,确保梯度能更顺畅地流通,并使反向传播时早期层能获得足够的更新。
在自注意力(self-attention)过程之后,我们会从每个头部得到输出。这些输出是受 Q 和 K 向量影响而适度混合的 V 向量。
要合并每个头部的输出向量(output vectors),我们只需将它们堆叠在一起即可。模型会利用遮蔽自注意力分数,将这些分数与“Value”矩阵相乘,从而获得自注意力机制的最终输出。GPT-2模型中有12个自注意力头,每个头都能捕捉到词语间不同的关系。这些头部的输出会被连接起来,然后经过一个线性映射处理。
MLP:多层感知机
图中展示的是如何使用MLP层将自注意力表示投射到更高维度中,以此增强模型的表现能力。
在自注意力的多个头部捕捉到输入词语间的多样关系后,这些被连接起来的输出会通过多层感知机(MLP)层,目的是提升模型的表现力。MLP模块包含两个线性变换,中间夹着一个GELU激活函数。第一个线性变换将输入的维度从768扩大四倍到3072。第二个线性变换则将维度减回到原来的768,确保后续层接收到的输入维度保持一致。与自注意力机制不同,MLP是独立处理每个词语的,它只是简单地将词语从一种表示形式映射到另一种形式。
动态流程如下:
归一化指数函数(Softmax)
Softmax操作不仅在前面的部分中作为自注意力的一部分使用,而且也会出现在模型的最后。
它的目的是将一个向量的值归一化,使其总和为 1.0。然而,这并不像除以总和那么简单。相反,每个输入值都要先进行指数化处理。
a = exp(x_1) a = exp(x_1)
这样做的效果是使所有值都为正。有了指数化值的向量后,我们就可以用每个值除以所有值的总和。这将确保所有数值之和为 1.0。由于所有指数化值都是正值,我们知道得出的值将介于 0.0 和 1.0 之间, 这就为原始值提供了一个概率分布。
这就是 softmax 的原理:简单地将数值指数化,然后除以总和。
不过,还有一个小问题。如果输入值很大,那么指数化后的值也会很大。我们最终会用一个很大的数除以一个很大的数, 这可能会导致浮点运算出现问题。
Softmax 运算的一个有用特性是,如果我们在所有输入值上添加一个常数,结果将是相同的。因此,我们可以找到输入向量中的最大值,然后将其从所有值中减去。这样就能确保最大值为 0.0, 从而使 softmax 在数值上保持稳定。
自注意力层中的 softmax 操作。我们的输入向量是自注意力矩阵的一行(但只到对角线)。
与层归一化一样,我们有一个中间步骤来存储一些聚合值以保持流程效率。
对于每一行,我们都会存储该行的最大值以及移位值和指数值的总和。然后,为了生成相应的输出行,我们可以执行一小套操作:减去最大值、指数化和除以总和。
为什么叫 "softmax"?这种操作的 "硬 "版本称为 argmax,简单地说,就是找到最大值, 将其设为 1.0,并将所有其他值设为 0.0。相比之下,softmax操作则是该操作的 "更柔和 "版本。由于softmax涉及指数运算,最大值被强调并推向 1.0。同时仍保持所有输入值的概率分布。这样就能获得更细致的表示,不仅能捕捉到最有可能的选项,还能捕捉到其他选型的相对可能性。
输出
当输入信息经过所有Transformer模块的处理后,会传递到最终的线性层,以便为预测词语做准备。这一层将最后的表示形式映射到一个50,257维的空间中,在这个空间里,词汇表中的每个词语都有一个对应的值,我们称之为对数几率(logit)。任何一个词语都可能是下一个单词,因此这个过程让我们能够简单地根据这些词语成为下一个词的可能性来排序。
"logits"这个名字来源于 "log-odds",即每个标记(token)的几率的对数。之所以使用 "对数", 是因为我们接下来应用的 softmax 会进行指数运算,将其转换为 "几率 "或概率。
为了将这些分数转换为良好的概率,我们对它们进行 softmax 操作,将这些对数几率转化为一个总和为1的概率分布。这样一来,我们就可以根据每个词语的可能性来选取下一个词语了。
在应用 softmax 之前,我们先用温度除以 logits(线性变换的输出)。由于 softmax 中的指数化会对较大的数字产生较大影响,因此将所有数字拉近会减少这种影响。
我们还可以使用温度参数来控制分布的 "平滑度"。温度越高,分布越均匀,温度越低,分布越集中在概率最高的标记上。
图中词汇表中的每个词语都会根据模型的输出对数几率被赋予一个概率。这些概率决定了每个词语作为序列中下一个词的可能性大小。
最后一步是从这个概率分布中抽取下一个词语。这里,temperature温度超参数起着关键作用。从数学角度讲,这是一个非常简单的操作:模型的输出对数几率直接除以温度值:
温度 = 1:对数几率除以1不会影响softmax输出结果,意味着模型按原概率选择词语。
温度 < 1:较低的温度会让模型变得更加自信且确定性更强,因为它会让概率分布变得更尖锐,生成的结果更加可预测。
温度 > 1:较高的温度则会使概率分布变得更为平滑,生成文本时包含更多随机性,有些人会称这种效果为模型的“创造性”。
可以尝试调整温度,亲身体验如何在确定性和多样性之间找到平衡!
好啦,今天的讲解就到这里,希望可以帮到大家!
扫码关注更多即时AI资讯
我们一起学AI!