导航

Akshay解释Transformer的六张图

Posted on 2024-06-14 10:36  蝈蝈俊  阅读(331)  评论(0编辑  收藏  举报

LightningAI 的首席数据科学家Akshay(https://x.com/akshay_pachaar)做了六张图解释Transformer,相当清晰明了。

一、Embeddings(词嵌入)

词嵌入是使用一组数字对每个token(大约一个词)进行有意义的表示。

这种嵌入是我们作为语言模型的输入提供的,即下面过程:

原始文本 → Tokenization(标记化) → Embeddings(词嵌入) → 模型

标记化(Tokenization)

将文本分解为单词或子词。

  • 输入句子 "I love Tennis."
  • 标记化将这个句子分解为更小的单位,称为标记(tokens)。在这个例子中,标记化过程将句子分解为四个标记:"I"、"Love"、"Tennis" 和 "."

词嵌入(Embeddings)

将这些单词或子词转换为数值向量,以便进行进一步的计算和分析。

  • 每个标记被映射到一个高维向量。这个向量是一个数值数组,表示标记的特征。在图中,"I"、"Love"、"Tennis" 和 "." 分别被映射到不同的向量。
  • 这些向量的具体数值在图中以蓝色表示,例如 "I" 对应的向量是 [0.89, 0.45, 0.67, ..., 0.32, 0.04]。

二、捕捉文本的上下文和含义

语言建模的核心思想是理解语言中的结构和模式。
通过对句子中的单词(tokens)建模,我们可以捕捉文本的上下文和含义。

语言模型在处理自然语言时,必须理解整个句子的上下文,才能正确理解句子中各个部分之间的关系。

我们看看句子中箭头的连接:

“网球”(Tennis)与“拉斐尔·纳达尔”(Rafael Nadal)之间的关联。

拉斐尔·纳达尔是一位著名的网球运动员,所以句子表达了讲述者对网球的热爱以及对拉斐尔·纳达尔的崇拜之间的联系。

为了理解这句话,语言模型需要意识到“网球”和“拉斐尔·纳达尔”之间的关系。讲述者提到“网球”时,紧接着谈论了“拉斐尔·纳达尔”,表示他对这位网球明星的喜爱。语言模型在处理这样的句子时,需要捕捉这种关系,理解讲述者是在表达对网球和纳达尔的共同喜爱。

在自然语言处理中,语言模型必须能够识别和理解词语之间的上下文关系,以准确地解读句子含义。这也表明了语言模型需要具备上下文理解的能力,不仅仅是逐词处理。

三、Attention

自我关注(Attention)是一种帮助建立这些关系的通信机制,表达为概率分数。

每个token都会给自己最高分,并根据它们的相关性给其他tokens分数。

您可以将其视为一个有向图(Directed Graph)。

左边的矩阵展示了每个单词对其他单词(包括自己)的注意力概率分数。

这些分数表示一个单词应该多大程度上关注自己和邻近的单词。例如,“I”对自己的注意力分数是0.7,对“love”的注意力分数是0.2,依此类推。

右边的图则是将左边的矩阵可视化成了一个有向图。

每个节点代表一个单词,边上的权重表示注意力分数。例如,从“I”到“love”的边权重是0.2,从“I”到“tennis”的边权重是0.06。图中的箭头表示注意力的方向和大小,帮助我们更直观地理解注意力机制是如何在单词之间分配注意力的。

四、注意力机制中的KQV

我们必须理解 3 个关键术语:

  • 查询向量 Keys
  • 关键向量 Queries
  • 价值向量 Values

这些向量是通过将输入嵌入乘以三个可训练的权重矩阵而创建的。

输入令牌嵌入(Input Token Embedding):

图的左下角有一个橙色矩形,标记为“\(X\)”,表示输入令牌的嵌入向量。

可训练权重矩阵(Trainable Weight Matrices):

图中有三个不同颜色的矩阵:紫色的 \(\_\)、青色的 \(\_\) 和橙色的 \(\_\) 。这些是可训练的权重矩阵,分别用于生成查询(Query)、键(Key)和值(Value)。

查询(Query):

输入向量 $$ 乘以权重矩阵 \(\_\) 得到查询向量 $$(用紫色矩形表示),公式为 \(= \cdot \_Q\)

查询向量表示输入令牌在寻找什么。

键(Key):

输入向量 $$ 乘以权重矩阵 \(/_\) 得到键向量 $$(用青色矩形表示),公式为 \(K=X \cdot W\_K\)

键向量表示输入令牌包含什么信息。

值(Value):

输入向量 $$ 乘以权重矩阵 \(\_\) 得到值向量 $$(用橙色矩形表示),公式为 \(V=X \cdot W\_V\)

值向量表示输入令牌将提供什么信息。

这些向量 $$、$$ 和 $$ 是自注意力机制中非常重要的组成部分,它们用于计算注意力权重(每个输入令牌与其他令牌之间的相关性),从而实现上下文信息的捕获(决定每个输入令牌在上下文中的重要性和关联性)。

五、自注意力(Self-Attention)机制

让我们更全面地了解输入嵌入是如何与KQV结合以获得实际的注意力分数的。

获取KQV后,我们将它们合并以创建一组新的上下文感知嵌入

输入嵌入(Input Embeddings):

图中左侧的橙色矩阵表示输入的嵌入向量,这里有三个词:"I"、"love" 和 "tennis"。

注意力头(Attention Head):

自注意力机制依赖于三个不同的权重矩阵:查询(Query,W_Q)、键(Key,W_K)和值(Value,W_V)。

查询矩阵(Query Matrix,Q):

输入嵌入与查询权重矩阵 W_Q 相乘,生成查询矩阵 Q(图中紫色矩阵)。
公式为 \(Q = X * W\_Q\)

键矩阵(Key Matrix,K):

输入嵌入与键权重矩阵 W_K 相乘,生成键矩阵 K(图中蓝色矩阵)。
公式为 \(K = X * W\_K\)

值矩阵(Value Matrix,V):

输入嵌入与值权重矩阵 W_V 相乘,生成值矩阵 V(图中黄色矩阵)。
公式为 \(V = X * W\_V\)

注意力得分(Attention Scores):

查询矩阵 Q 与键矩阵 K 的转置相乘,再除以一个缩放因子(通常是键矩阵的维度的平方根 \(d_k\)),得到注意力得分 S。
公式为 \(S = softmax(Q * K\_T / sqrt(d_k))\)
图中灰色矩阵展示了计算后的注意力得分。

注意力输出(Attention Output):

注意力得分矩阵 S 与值矩阵 V 相乘,生成最终的注意力输出(图中绿色矩阵)。这个输出包含了输入词汇在上下文中的信息,即“上下文感知嵌入(Context aware Embeddings)”。

自注意力机制通过计算查询、键和值之间的相似性来决定输入序列中每个词的重要性,从而生成包含上下文信息的嵌入表示。这个机制在自然语言处理中非常有效,因为它可以捕捉到序列中词与词之间的关系。

PyTorch 实现

使用 PyTorch,可以清晰看到实现:

import torch
import torch.nn as nn
from torch.nn import functional as F

class SelfAttention(nn.Module):
    """ 单头自注意力机制 """

    def __init__(self, head_size):
        super().__init__()
        # 初始化key、query和value的线性层,且不使用偏置项
        self.key = nn.Linear(n_embd, head_size, bias=False)
        self.query = nn.Linear(n_embd, head_size, bias=False)
        self.value = nn.Linear(n_embd, head_size, bias=False)
        
        # 注册一个缓冲区,用于存储一个下三角矩阵,
        # 这个矩阵将用于掩蔽未来的标记,以防止模型在训练时看到未来的信息。
        self.register_buffer('tril', torch.tril(torch.ones(block_size, block_size)))
        
        # 初始化Dropout层,防止过拟合。
        # Dropout层会在训练过程中随机将部分神经元的输出设为0,从而减少模型对特定神经元的依赖,增强模型的泛化能力。
        self.dropout = nn.Dropout(dropout)

    def forward(self, x):
        B, T, C = x.shape  # 批量大小,序列长度,嵌入维度
        
        # 计算key、query和value矩阵
        k = self.key(x)
        q = self.query(x)
        
        # 计算注意力得分
        wei = q @ k.transpose(-2, -1) * k.shape[-1]**-0.5  # 按照头大小的平方根进行缩放
        wei = F.softmax(wei, dim=-1)  # 应用softmax获取注意力权重
        
        # 将注意力权重应用于value矩阵
        v = self.value(x)
        out = wei @ v  # 值的加权和
        
        return out

总结

通过Akshay的数据科学家图解,我们可以清晰地理解从词嵌入开始,经过标记化、生成向量,到自注意力机制中KQV的生成和注意力得分的计算,再到最终的上下文感知嵌入的创建全过程。

这种系统性的解释不仅帮助我们理解语言模型的内部工作原理,也展示了Transformer在自然语言处理中捕捉词与词之间关系的强大能力。