@_rohit_tiwari_: https://x.com/_rohit_tiwari_/status/2063982924714901858

X AI KOLs Timeline 新闻

摘要

本文提供了大型语言模型中Transformer架构的可视化指南,涵盖自注意力、因果自注意力、掩码多头注意力以及输出层,并附有逐步解释和示例。

https://t.co/sq8zZ5YxTq
查看原文
查看缓存全文

缓存时间: 2026/06/09 08:50

LLM 视觉指南(第二部分):深入 Transformer 架构

在本系列的两篇文章中,我们将逐步讲解大型语言模型(LLM)架构的核心组件,使其易于理解,即使你是 AI 新手也没有关系。

系列路线图

第一部分:这一部分将展示书面语言如何被拆分为词元,然后转换为模型可以处理的输入嵌入向量。它解释了词元化、词元嵌入和位置嵌入。

第二部分:这一部分将展示这些输入嵌入向量如何通过 Transformer 模块产生输出。它涵盖了自注意力、因果自注意力和掩码多头注意力机制、前馈神经网络、如何选择下一个词元,以及训练如何随时间逐步改进模型。

在 **LLM 视觉指南(第一部分)**中,我们学习了大型语言模型(LLM)如何将人类语言转化为机器可以理解的东西。我们以句子“Every moment is a beginning“为例,将其切分为词元,分配数值 ID,并将其转换为称为词元嵌入的密集向量表示。我们还添加了位置嵌入,以便模型知道单词的确切顺序。

在第二部分中,我们将探讨:Transformer 模块输出层

现在,我将逐一解释 Transformer 模块的每个组件。

最重要的组件之一是掩码多头注意力。然而,在此之前,我们将首先了解自注意力和因果自注意力机制。理解这些概念将使我们更容易全面掌握掩码多头注意力的工作原理。我们还将介绍前馈神经网络、残差连接和层归一化,以了解 Transformer 模块的所有组件如何协同工作。

1. 自注意力机制

语言具有很强的上下文相关性。如果你读到单词“beginning“,它的确切含义在很大程度上取决于前面的单词。自注意力机制允许模型理解单词之间的关系。每个词元不是孤立地读取每个单词,而是查看其他词元并决定哪些词元最重要。

Attention(Q,K,V)=softmax(QKTdk).V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right).V

在第一部分中,我们已经在将词元嵌入和位置嵌入相加后创建了输入嵌入

示例:Every moment is a beginning

词元 ID:{“Every”: 15745, “moment”: 4205, “is”: 382, “a”: 261, “beginning”: 10526}

最终输入嵌入(词元嵌入 + 位置嵌入之和):

  • “15745” (位置 1):[-0.5880, 0.3486, 0.6603] + [-0.9178, 0.9045, -2.0975]

  • “4205” (位置 2):[-0.2196, -0.3792, 0.7671] + [1.1558, -1.2157, 0.1295]

  • “382” (位置 3):[-1.1925, 0.6984, -1.4097] + [ 1.0937, 0.2066, 3.1815]

  • “261” (位置 4):[ 0.1794, 1.8951, 1.3689] + [ 0.0967, 1.4086, 0.1915]

  • “10526” (位置 5):[-1.6033, -1.3250, 0.1784] + [ -0.1562, 0.2446, 4.0124]

执行逐元素相加后:

  • “15745” (位置 1):[-1.5058, 1.2531, -1.4372]

  • “4205” (位置 2):[ 0.9362, -1.5949, 0.8966]

  • “382” (位置 3):[-0.0988, 0.905 , 1.7718]

  • “261” (位置 4):[0.2761, 3.3037, 1.5604]

  • “10526” (位置 5):[-1.7595, -1.0804, 4.1908]

为了理解句子中的单词“beginning“,模型会关注像“moment“和“Every“这样的单词。这提供了上下文,并帮助模型捕捉到每个时刻都可以代表一个全新开始的概念。

步骤 1:为了实现这一数学过程,模型使用从输入嵌入中推导出的三个向量:查询(Q)键(K)值(V)

步骤 2:我们计算所有查询与键之间的点积,以衡量它们的匹配程度。

Attention Scores=QKT\text{Attention Scores} = QK^T

步骤 3:结果按键维度 dk 的平方根进行缩放,以在训练期间保持值稳定。

Scaled Attention Scores=QKTdk\text{Scaled Attention Scores} = \frac{QK^T}{\sqrt{d_k}}

步骤 4:应用 softmax 以获得注意力权重。

Attention Weights=softmax(QKTdk)\text{Attention Weights} = \text{softmax}\left( \frac{QK^T}{\sqrt{d_k}} \right)

步骤 5:计算上下文向量。

Context Vectors=Attention Weights⋅V=Attention(Q,K,V)\text{Context Vectors} = \text{Attention Weights} \cdot V = \text{Attention}(Q, K, V)

完整的自注意力:

经过注意力处理后,每个词元现在包含了从序列中其他词元收集到的信息。这是 Transformer 的核心思想。

因果掩码:隐藏未来词元

在标准自注意力中,每个词元可以关注所有其他词元。但在逐词生成文本的语言模型中,在预测期间,未来词元不应可见。

因果自注意力机制使用一个掩码来防止词元关注未来词元。允许的注意力模式形成一个下三角矩阵,确保每个词元只能关注自身和序列中较早的词元。

[1000011000111001111011111]\begin{bmatrix} 1 & 0 & 0 & 0 & 0 \ 1 & 1 & 0 & 0 & 0 \ 1 & 1 & 1 & 0 & 0 \ 1 & 1 & 1 & 1 & 0 \ 1 & 1 & 1 & 1 & 1 \end{bmatrix}

  • 1 表示允许关注。

  • 0 表示禁止关注。

这是通过掩蔽禁止位置并在应用 softmax 函数之前将其注意力分数替换为负无穷来实现的。经过 softmax 后,这些位置的注意力概率为 0,从而防止模型关注未来词元。

这确保了:

  • 词元 1 只看自己。

  • 词元 2 看词元 1 和 2。

  • 词元 3 看词元 1、2 和 3。

现在每个词元只能关注自身和前面的词元。

2. 掩码多头注意力机制

单个注意力头捕获语言中众多不同关系的能力有限。多个注意力头允许模型同时学习不同的模式。为了同时捕获语法、含义、长距离依赖关系以及主宾语关系,模型使用了掩码多头注意力。多个注意力头并行运行,以不同的方式看待完全相同的句子。

对于“Every moment is a beginning“,不同的头可能关注不同的细微差别:

  • 注意力头 1(含义): 连接“moment“ ←→ “beginning” 以理解更新的概念。

  • 注意力头 2(语法): 连接“Every“ ←→ “moment” 以理解“Every“在修饰“moment“。

  • 注意力头 3(结构): 连接“is“ ←→ “beginning” 以锚定句子的主要陈述。

工作原理:

  • 输入嵌入被拆分为较小的部分,称为头。

  • 每个头在其自己的维度上独立执行注意力。

  • 所有头的输出被连接在一起。

  • 一个最终的线性层将这些多样化的信息合并为一个统一的、上下文丰富的表示。

3. 前馈神经网络(FFN)

注意力允许词元在序列中通信并混合信息。但在收集到这些信息后,每个词元仍然需要单独处理以学习复杂模式。这就是前馈网络(通常称为 FFN 或 MLP 模块)的作用。

前馈神经网络通常由两个线性层组成,中间有一个激活函数(如 GELU),临时扩展隐藏维度以帮助模型学习更复杂的模式。

  • 线性层: 临时扩展隐藏维度(通常增加 4 倍),为模型提供空间以学习高度复杂的模式。

  • 激活函数: 引入非线性,使模型能够理解复杂的、非直接的关系。

  • 第二个线性层: 将维度压缩回原始大小。

4. 残差连接

随着网络变得更深,在反向传播过程中,梯度(用于训练模型的信号)可能会变得极小或极大,这被称为梯度消失或梯度爆炸问题。当梯度消失时,较早的层学习非常缓慢,因为训练信号逐渐减弱。

残差连接(或跳跃连接)解决了这个问题。该层不是学习一个全新的表示,而是学习一个残差更新,然后将其添加到原始输入中。

Output=x+Sublayer(x)\text{Output} = x + \text{Sublayer}(x)

在掩码多头注意力和 FFN 层周围使用残差连接,有助于 Transformer 训练更深的网络、稳定梯度并保留原始单词信息。

5. 层归一化

当数据经过许多层时,激活值可能会变得过大或过小,从而减慢学习速度。层归一化通过独立归一化每个词元的特征来稳定这些值,帮助在训练期间将激活保持在一个稳定的范围内。

对于一个词元嵌入:

x=[x1,x2,x3]x = [x_1, x_2, x_3]

LayerNorm 计算:

均值:

μ=1n∑xi\mu = \frac{1}{n}\sum x_i

方差:

σ2=1n∑(xi−μ)2\sigma^2 = \frac{1}{n}\sum (x_i - \mu)^2

归一化的输出,其中 epsilon 是一个很小的数,用于防止除以零:

x^i=xi−μσ2+ε\hat{x}_i =\frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}

层归一化在每个 Transformer 模块内部应用多次。这使得训练显著更快、更可靠。

Transformer 模块

一个 Transformer 模块汇集了 Transformer 架构的主要组件。GPT 模型通过堆叠多个这样的模块构建而成,使得词元表示在每一层变得更加信息丰富。现代 GPT 模型采用预归一化(pre-norm)设计,即在注意力和前馈操作之前应用层归一化。

通过 Transformer 模块的流程如下:

  • 层归一化 对输入表示进行归一化,以提高训练稳定性。

  • 掩码多头注意力 允许每个词元从自身和前面的词元收集信息,同时阻止访问未来词元。

  • 残差连接(Add) 将原始输入加回注意力输出,有助于保留信息并改善梯度流动。

  • 层归一化 在进一步处理之前重新归一化更新后的表示。

  • 前馈网络(FFN) 应用非线性变换以学习更复杂的模式和关系。

  • 残差连接(Add) 将第二个层归一化之前的输入加到 FFN 输出上,在保留信息的同时融入新的变换。

注意: 在训练期间,通常在注意力和前馈操作之后应用 Dropout。这有助于减少过拟合并提高模型的泛化能力。

现代 GPT 模型将许多 Transformer 模块一个叠一个地堆叠。每个模块都优化词元表示。

输出层

在通过所有 Transformer 模块之后,模型为每个词元生成一个上下文感知的表示。模型为每个词元位置生成 logits,但对于下一个词元生成,它使用序列中最后一个位置的 logits,在此示例中是“beginning“。

然后,这个表示通过输出层:

  • 线性层(逆嵌入) 最终的向量被投影到一个大小与模型词汇表相匹配的向量中。得到的值称为 logits,每个可能的词元都有一个 logit,模型可以从这些词元中生成下一个。

  • Softmax 函数 Logits 被转换为整个词汇表上的概率分布。每个值现在代表模型对某个特定词元作为序列中下一个词元的估计概率。

然后,模型可以选择下一个词元。例如,如果词元“.“具有最高概率,它可能会被选为预测。

由于大型语言模型一次生成一个词元,预测的词元被附加到原始输入中。

序列:

Every moment is a beginning

变为:

Every moment is a beginning .

这个更新后的序列被反馈回模型,模型重复相同的过程:词元化、词元嵌入、位置嵌入、Transformer 模块和输出层,以预测下一个词元。通过重复这个循环,模型逐步生成文本,一次一个词元。

Star 并克隆 GitHub 仓库!

从零开始用 PyTorch 构建一个类似 ChatGPT 的 LLM,逐步讲解。

代码 → https://github.com/analyticalrohit/llms-from-scratch

喜欢这篇文章吗?请务必 ❤️ 点击喜欢按钮。

知道有人会觉得这篇文章有帮助吗?请务必 🔄 分享这篇文章。

相似文章

@currying: 非常棒的13页讲解!

X AI KOLs Timeline

一条推文重点介绍了《理解Transformer与注意力机制》,这是一篇13页的论文,从应用数学的角度解释了Transformer架构和注意力机制。

理解大型语言模型

arXiv cs.CL

本章回顾了当前对大型语言模型的理解,讨论了它们的Transformer架构、类似人类认知的涌现能力,以及关于LLM是真正理解还是仅仅模拟理解的争论。