GPT-2,作为早期的大型语言模型之一,以其强大的文本生成能力而闻名。本文将深入剖析 GPT-2 的架构,通过详细的步骤,揭示它是如何理解和生成文本的。我们将从分词(Tokenization)开始,逐步深入到嵌入层(Embedding Lookup)、位置编码(Positional Encoding)、Transformer块(Transformer Block)以及最后的输出层(Final Output),一步步解开 GPT-2 的运作原理。理解 GPT-2 的架构,不仅能帮助我们更好地应用它,也能为我们理解更先进的大型语言模型打下坚实的基础。
1. 分词(Tokenization):语言理解的第一步
在 GPT-2 处理任何文本之前,首要步骤是 分词(Tokenization)。这一步将输入的文本分解成更小的单元,称为 token。GPT-2 使用一种叫做 Byte Pair Encoding (BPE) 的算法来实现 分词。
BPE 的基本思想是:一开始,每个字符都是一个 token,然后算法会迭代地将最常出现的 token 对合并成一个新的 token,直到达到预定的 token 数量。例如,对于句子 “What is the capital of France?”,经过 BPE 分词后,可能得到如下的 token 序列:[‘What’, ‘Ġis’, ‘Ġthe’, ‘Ġcapital’, ‘Ġof’, ‘ĠFrance’, ‘?’]。其中,’Ġ’ 表示空格。每个 token 都会被赋予一个唯一的数字 ID,例如:[2061, 318, 262, 3139, 286, 4881, 30]。这些 ID 才是 GPT-2 真正能够理解和处理的。
BPE 的优势在于,它能够有效地处理未登录词(out-of-vocabulary words)。例如,如果 GPT-2 在训练集中从未见过单词 “unseen”,BPE 仍然能够将其分解成已知的 token,例如 [‘un’, ‘seen’],从而理解其含义。
2. 嵌入层(Embedding Lookup):将 Token 转化为向量
在 分词 之后,GPT-2 需要将这些数字 ID 转化为更丰富的向量表示,以便模型能够更好地理解 token 之间的关系。这个过程称为 嵌入层查找(Embedding Lookup)。GPT-2 维护一个 嵌入矩阵(Embedding Matrix),其维度为 [50257 × 768],其中 50257 是 GPT-2 的词汇表大小,768 是每个 token 的嵌入向量的维度。
嵌入矩阵 本质上是一个查找表,每一行对应一个 token 的嵌入向量。例如,单词 “What” 对应的嵌入向量可能是 [-0.1643, 0.0957, -0.2844, …],这是一个 768 维的向量,代表了 “What” 在高维空间中的语义信息。这些嵌入向量是通过训练学习得到的,能够捕捉 token 之间的语义相似性。
嵌入层查找 的过程非常简单:对于每个 token ID,GPT-2 只需要在 嵌入矩阵 中找到对应的行,并提取出该行的向量即可。这样,输入的文本就被转化成了一个由 768 维向量组成的序列。例如,“What is the capital of France?” 经过 嵌入层查找 后,会变成一个 [7 x 768] 的矩阵。
3. 位置编码(Positional Encoding):理解词语的顺序
Transformer 架构(GPT-2 的基础)的一个特点是它并行处理输入序列中的所有 token。这意味着模型本身并不知道 token 在序列中的位置。为了让 GPT-2 能够理解词语的顺序,我们需要引入 位置编码(Positional Encoding)。
位置编码 是一种将 token 的位置信息添加到其嵌入向量的方法。GPT-2 使用一个 位置编码矩阵(Positional Encoding Matrix),其维度为 [1024 × 768],其中 1024 是 GPT-2 可以处理的最大序列长度,768 是嵌入向量的维度。位置编码矩阵 的每一行对应一个位置的 位置编码向量。
GPT-2 将 token 的嵌入向量和对应位置的 位置编码向量 相加,得到最终的输入表示。例如,句子中第一个词的嵌入向量 E₀ 和 位置编码矩阵 的第一行 P₀ 相加,得到 Final_Embedding₀ = E₀ + P₀。
为什么要相加而不是连接呢?相加可以理解为在原有的语义空间中,根据位置信息进行向量的平移。连接则会增加向量的维度,可能导致模型需要学习更多的参数。相加是一种更简洁有效的方法。
位置编码 的设计非常巧妙,它能够使得模型学习到词语之间的相对位置关系。例如,如果两个词的距离为 k,那么它们的 位置编码向量 的差值只与 k 有关,而与它们在句子中的绝对位置无关。
4. Transformer 块(Transformer Block):模型的核心
Transformer 块 是 GPT-2 的核心组件,负责处理输入序列中的信息,并学习 token 之间的复杂关系。GPT-2 由多个相同的 Transformer 块 堆叠而成,例如,GPT-2 small 有 12 个 Transformer 块,GPT-2 medium 有 24 个,GPT-2 large 有 36 个,GPT-2 XL 有 48 个。
每个 Transformer 块 主要包含以下几个部分:
- 层归一化(Layer Normalization):对输入向量进行归一化,使其均值为 0,标准差为 1。这有助于稳定训练过程,并提高模型的泛化能力。
- 掩码多头自注意力(Masked Multi-Head Self-Attention):这是 Transformer 块 的核心。它允许模型关注输入序列中不同位置的 token,并学习它们之间的依赖关系。掩码 的作用是防止模型在生成文本时看到未来的信息,保证模型只能基于之前的 token 来预测下一个 token。多头 的意思是,模型使用多个不同的 注意力头 并行地计算注意力权重,每个 注意力头 关注不同的特征,从而提高模型的表达能力。
- 前馈神经网络(Feed Forward Network, FFN):一个简单的全连接神经网络,用于对每个 token 的表示进行进一步的非线性变换。
- 残差连接(Residual Connection):将输入直接添加到输出中,有助于缓解梯度消失问题,并提高模型的训练效率。
让我们深入了解一下掩码多头自注意力机制:
- 计算 Query (Q), Key (K), Value (V): 对于每个 token 的嵌入向量 E(i),我们使用三个不同的权重矩阵 W_Q, W_K, W_V 将其分别映射到 Query, Key, Value 向量。Query 表示 token 想要查询的信息,Key 表示 token 可以提供的信息,Value 表示 token 携带的实际信息。
- 计算注意力分数 (Attention Score):对于每个 token i,我们计算它与所有其他 token 的注意力分数。注意力分数的计算公式为:Score = Q(i) × K(j)^T / √d_k,其中 d_k 是 Key 向量的维度。注意力分数表示 token i 对 token j 的关注程度。
- 应用掩码 (Mask):为了防止模型看到未来的信息,我们对注意力分数应用一个 掩码。具体来说,我们将所有未来位置的注意力分数设置为负无穷大,这样在经过 Softmax 函数后,这些位置的注意力权重会变为 0。
- 计算注意力权重 (Attention Weight):我们对注意力分数应用 Softmax 函数,将其转化为概率分布。注意力权重表示 token i 对所有其他 token 的关注比例。
- 计算加权平均 (Weighted Average):我们使用注意力权重对 Value 向量进行加权平均,得到最终的输出表示。这个输出表示包含了所有其他 token 的信息,并根据注意力权重进行了加权。
- 多头 (Multi-Head):我们将上述过程重复多次,使用不同的权重矩阵 W_Q, W_K, W_V。每个 注意力头 关注不同的特征,并将它们的输出连接起来,再经过一个线性变换,得到最终的输出表示。
前馈神经网络(FFN)的工作原理:
FFN(x) = GELU(xW₁ + b₁)W₂ + b₂
其中:
- x:输入向量
- W₁:第一层权重矩阵 [d_model × d_ff]
- b₁:第一层偏置向量 [d_ff]
- W₂:第二层权重矩阵 [d_ff × d_model]
- b₂:第二层偏置向量 [d_model]
- d_model:模型维度(例如,768)
- d_ff:FFN 内部维度(通常是 4 × d_model)
- GELU:一种激活函数,类似于 ReLU,但更平滑
FFN 的作用是对每个 token 的表示进行进一步的非线性变换,提高模型的表达能力。
5. 输出层(Final Output):生成最终的文本
经过多个 Transformer 块 的处理,GPT-2 最终会得到每个 token 的最终表示。为了生成文本,GPT-2 需要将这些表示映射回词汇表空间。
GPT-2 使用一个线性层将每个 token 的最终表示映射到一个维度为 50257 的向量,其中 50257 是词汇表的大小。这个向量的每个元素表示 GPT-2 预测该 token 是词汇表中每个单词的概率。
然后,GPT-2 对这个向量应用 Softmax 函数,将其转化为概率分布。Softmax 函数确保所有概率之和为 1。
最后,GPT-2 根据这个概率分布选择下一个 token。最简单的方法是选择概率最高的 token。但为了增加生成文本的多样性,GPT-2 通常会使用一些更复杂的采样方法,例如 温度采样(Temperature Sampling) 或 Top-k 采样(Top-k Sampling)。
- 温度采样:通过调整 Softmax 函数的温度参数,可以控制生成文本的随机性。温度越高,生成文本越随机;温度越低,生成文本越确定。
- Top-k 采样:每次只从概率最高的 k 个 token 中进行采样,避免选择概率过低的 token,从而提高生成文本的质量。
举个例子:
假设 GPT-2 的词汇表包含以下单词:[“the”, “Paris”, “London”, “France”, “is”]。经过线性层和 Softmax 函数后,GPT-2 预测下一个 token 的概率分布为:
- “the”: 0.12
- “Paris”: 0.85
- “London”: 0.05
- “France”: 0.07
- “is”: 0.02
如果使用概率最高的 token,那么 GPT-2 会选择 “Paris” 作为下一个 token。
总结
本文详细介绍了 GPT-2 的架构,从 分词 到 嵌入层,再到 位置编码 和 Transformer 块,最后到 输出层,一步步揭示了它是如何理解和生成文本的。理解 GPT-2 的架构,不仅能帮助我们更好地应用它,也能为我们理解更先进的大型语言模型打下坚实的基础。尽管 GPT-2 已经相对老旧,但其核心架构思想仍然被广泛应用于现代大型语言模型中。例如,Transformer 块 中的 自注意力机制,以及 位置编码 的思想,都为后来的模型提供了重要的借鉴。通过深入学习 GPT-2 的架构,我们可以更好地理解现代大型语言模型的运作机制,并为未来的研究和应用做好准备。未来,随着大模型技术的不断发展,我们期待出现更多更强大的模型,能够更好地理解和生成文本,为人类的生活和工作带来更多便利。