AB

LLV Visualization 拆解

2025-07-24

https://bbycroft.net/llm

基于 Nano GPT 的可视化推理过程,模型得到的训练是对字符串进行排序

步骤一:Embedding

这一步的输出是切分好的 Token 数组,对于现代 LLM 我们可以认为他是 Prompt,也可以是 LLM 的输出结果的前半部份, LLM 经过一系列运算会得到这一系列 Token 对应的最大概率下一个Token。

输入 Token 数组(长度为 CC,这是个超参数)的每一个元素会得到 Token 的编码值和当前的索引值(Position)。由编码值计算出 Token Embed 向量(长度为 TT ,这个 TT 的实际含义是时间,我们先简单理解为次序),由索引值计算出 Position Embed 向量(长度为 TT ),然后将这两个向量相加得到真正的输入 Input Embed 矩阵(size=C×Tsize = C \times T)。

步骤二:归一化

这一步将输入的 Input Embedding 矩阵的每一列归一化,所谓归一化,在 Nano GPT 当中就是将这一列的均值调整为 0,方差(标准差)调整为 1。具体拆解如下:

  1. 计算出每一列的均值 E[x]E[x] 和方差 Var[x]Var[x]
  2. 对 Input Embedding 的每一个元素都在原位进行如下计算,这里的 ϵ=105\epsilon = 10^{-5} ,主要作用是防止除零。减去均值除以标准差,然后乘以一个经过学习的权重,加上一个偏置值,归一化就完成了。

xE[x]Var[x]+ϵγ+β\frac{x - E[x]}{\sqrt{Var[x]} + \epsilon } \cdot \gamma + \beta

步骤三:Self Attention

自注意力层也许是 Transformer 和 GPT 的核心,这一步会让 Input Embedding 中的列相互交流,而在这之前,每一列都是独立存在的。自注意力层由多个头组成(Nano GPT 有三个),可以先只看一个。

第一步,我们要从 Input Embedding 的每一列 T 中生成三个向量,这些向量是 Q、K、V 向量。生成这些向量的步骤是做向量乘法,每一个输出单元是输入向量的线性组合。例如生成 Q 向量时,我们将 Q 权重矩阵的每一行和 Input Embedding 的当前列(T)相乘,得到一个向量,再加上一个 Q 偏移量(Q Bias),就得到了 Q向量。Q、K、V 向量均使用这种方法生成。

生成完成之后,我们需要考虑如何处理 Q(Query)、K(Key)、V(Value)。从名称上来看,我们也许可以将 Q(关键字)应用于 K(字典),得到 V(最终值)。自注意力层基本上也是这样,不过需要通过权重来实现:将 Q、K 取点积,然后归一化处理,与 V 相乘,再将结果相加,得到结果。具体如下

  1. 将当前 Q(例如第 6 列,t=5t=5)和之前所有列的 K 计算点积,除以A\sqrt{A},其中 AA 是 QKV 向量的长度。结果将存储到注意力矩阵的第六行(t=5t=5)当中,点积可以衡量向量相似度,相似度低则点积很大,相似度高则点积很小或者为负;除以长度则是为了避免很大的值在归一化后占据主导地位。
  2. 对生成的注意力矩阵做 softmax 操作,规范化到总和为 1
  3. 取注意力矩阵 softmax 后的结果,每一个元素与对应的 V 向量逐一相乘,得到输出的 V。

以上就是单个注意力头的处理过程,其主要目标就是通过 Q 向量与当前和过往所有的 K 向量进行比较来查找与 Q 相关的信息,然后从 V 中提取出这部分信息

步骤四:Projection

自注意力层处理完成之后,从每个头中得到了输出,一些混合了 Q、K 向量影响的 V 向量。为了组合这些输出,我们将他们堆叠在一起,例如从 3 个头输出的长度为 A=16A = 16 转换为 1 个长度为 C=48C = 48 的向量。也就是说,在 GPT 中,一个头内的向量长度等于 C/NC / NCC 是输入 Input Embedding 的向量长度, NN 是头的数量。这样,当我们将它们的结果组合在一起时,就得到了原来的长度 CC

在 Projection 层中,我们按列矩阵(权重矩阵)和头向量的乘法,添加一些偏置,得到初步结果。再将初步结果与最早的 Input Embeddding 求和,这一步被称为残差连接(residual connection),这一步在深度神经网络中同样很关键。

步骤五:MLP

MLP(multi-layer perceptron 多层感知机,一种前馈神经网络 Feed Forward Neural Network) 是 Transformer 的后半部份,在 Nano GPT 当中是一个具有两层的简单神经网络。在进入 MLP 之前同样需要做一遍和之前LLM Visualization 笔记#步骤二:归一化一样的归一化操作,均值、方差和偏移。

在 MLP 中,我们将长度为 C=48C = 48 的列向量进行下面四个步骤:

  1. 将 MLP 权重矩阵(包含偏置行向量的线性变换矩阵)应用于归一化之后的输入,得到一个长度为 4×C4 \times C 的 MLP 矩阵;
  2. 将 GELU 激活函数应用于 MLP 矩阵的每个元素;
  3. 将 MLP Projection 权重矩阵(另一个包含偏置列向量的线性变化矩阵)应用于上一步的结果,得到和原先尺寸一致的 MLP 结果(T×CT \times C);
  4. 和之前的自注意力层一样,将 MLP 的结果以元素为单位与上一层的结果相加(残差连接),得到最终结果。

MLP 完成之后,Transformer 的任务就结束了。Transformer 是任何一个 GPT 模型的主要部分,并且会被多次重复,一个块输出并输入到下一个块,并继续进行残差连接。

我们很难确切地说出每层在做什么,但有一些大致的想法:早期的层倾向于学习较低层次的特征,后期的层则学会识别和理解更高层次的抽象概念。例如在自然语言处理中,较低的层可能在学习语法规则、句法、简单的词语关联,较高的层可能会捕捉更复杂的语义关系、篇章结构和上下文语义。

当然这里需要强调一下,GPT 是基于 Transformer Decoder 的模型,所以上述的 Transformer 只是 Decoder 的部分。

步骤六:Softmax

Softmax 不但是自注意力层的一部分,也将在模型的最后部分出现。其目标是获取一个向量并将其值规范化,使它们的和为1.0。但 Softmax 不是简单的将每个值除以向量的总和。

每个值首先需要被指数化,然后将指数化的值除以指数化值的总和,这可以保证值的总和为 1.0。由于所有指数化的值都是正数,所以结果必然在 0.0 和 1.0 之间;这就是 softmax 的基本流程。

exp(xi)exp(xi)\frac{\exp(x_i)}{\sum\exp(x_i)}

这里有个小问题,如果输入的值(xix_i)比较大,那么指数值也会变大,如果将一个大数除以另一个大数,可能导致浮点数运算出现问题,这里我们需要利用 softmax 的一个特性:如果给所有输入值加上一个常量,结果将保持不变。因此,我们可以给输入值(xix_i)减去向量中最大的数(max(X)\max(X)),这样可以确保最大值是 0.0,softmax 在数值上保持稳定。

在自注意力层当中,softmax 操作的输入向量是矩阵的一行。为了操作方便,我们创建了一个中间矩阵,用于存储一些便于运算的结果,例如向量的 max(X)\max(X)exp(ximax(X))\sum\exp(x_i - \max(X))

为什么叫 “softmax” 呢?因为存在一个硬核版本是 argmax,他的结果是找到最大值,设置为 1.0,并将其他值赋为 0.0,相比之下 softmax 会更 ”soft“。由于 softmax 是用了指数运算,最大值会被强调并接近 1.0,同时在整个输入值域上保持概率分布,允许捕捉最有可能的选择,保留其他选项的可能性。

因此,softmax 操作会被 QKV 的注意力层使用,还会在最后的输出部分使用。

步骤七:Output

最后的 Transformer 结果经过一次归一化处理,然后再经过 LM Head 权重矩阵的线性变换(这次没有偏置值),目标是将列向量长度从 CC 变为 nvocab=3nvocab = 3,nvocab 实际上是词汇表的长度。这实际上为每个词生成了一个分数,这个分数被称为 logits。

logits 来源于 log-odds(对数几率),也就是每个 Token 的几率的对数。之所以是 log odds,是因为 softmax 操作会将值进行指数运算以转换为概率值(odds)。

softmax 之后,我们得到了模型分配给每个单词的概率。在这个特定的模型当中(nano-gpt),他实际上已经学会了如何排序三个字母,所以概率结果偏向正确答案。

我们一般会让 LLM 随着时间步进,此时,使用最后一列(最后一个 Token 对应的列)来确定添加到序列的下一个 Token。例如,输入了 6 个,使用第六列的概率。这一列的结果是一系列的概率值,我们需要从中挑选一个作为序列中的下一个。一般来说,我们根据概率值来随机选择一个 Token,概率更高的标记更容易被选中。

这里有一个超参数是 Temperature,较高的温度会使得分布更均匀,较低的温度可以使分布集中在概率更高的标记上。Temperature 的生效方式是在 logits 应用 softmax 之前先除以 Temperature,让所有概率数字变得更接近。

总结

回头来看,Transformer Decoder 由多头自注意力层和前馈神经网络层组成,主要的能力是根据历史的 Token 串预测下一个 Token 在字典中索引的概率。自注意力层的功能是从 Embedding 向量通过线性变换拆分出 QKV 三个向量,Q、K 向量做点积再与 V 相乘。我们可以在推理过程中看到大量的线性变换矩阵,这些矩阵大多是在训练过程中产出。在使用标注数据不断训练的过程中,神经网络会不断更新这些矩阵,以拟合训练数据的标注。