Transformer模型-3-基本工作流程解析

Transformer模型-3-基本工作流程解析

Transformer模型自2017年提出以来,凭借其并行计算能力和长距离依赖建模优势,已成为自然语言处理(NLP)领域的基石架构。其核心工作流程通过自注意力机制(Self-Attention)和多头注意力(Multi-Head Attention)实现输入序列的动态编码与解码。本文将从输入层到输出层,详细拆解Transformer的完整工作流,并结合实现细节说明关键技术点的设计逻辑。

一、输入层:序列编码与位置嵌入

1.1 输入序列的词嵌入(Word Embedding)

Transformer的输入首先通过词嵌入层将离散的token(如单词或子词)映射为连续的向量表示。假设输入序列为 (X = [x1, x_2, …, x_n]),词嵌入层将每个token (x_i) 转换为维度为 (d{\text{model}}) 的向量 (ei \in \mathbb{R}^{d{\text{model}}})。例如,在英文NLP任务中,词表大小通常为3万左右,而 (d_{\text{model}}) 常见设置为512或768。

  1. import torch
  2. import torch.nn as nn
  3. # 示例:词嵌入层初始化
  4. vocab_size = 30000 # 词表大小
  5. d_model = 512 # 嵌入维度
  6. embedding_layer = nn.Embedding(vocab_size, d_model)
  7. # 输入序列(batch_size=2, seq_len=5)
  8. input_ids = torch.randint(0, vocab_size, (2, 5))
  9. embeddings = embedding_layer(input_ids) # 输出形状:[2, 5, 512]

1.2 位置编码(Positional Encoding)

由于Transformer缺乏递归结构,需通过位置编码注入序列顺序信息。位置编码采用正弦/余弦函数生成,公式如下:
[
PE(pos, 2i) = \sin\left(\frac{pos}{10000^{2i/d{\text{model}}}}\right), \quad
PE(pos, 2i+1) = \cos\left(\frac{pos}{10000^{2i/d
{\text{model}}}}\right)
]
其中 (pos) 为token位置,(i) 为维度索引。位置编码与词嵌入相加后作为模型输入:

  1. def positional_encoding(max_len, d_model):
  2. position = torch.arange(max_len).unsqueeze(1)
  3. div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))
  4. pe = torch.zeros(max_len, d_model)
  5. pe[:, 0::2] = torch.sin(position * div_term)
  6. pe[:, 1::2] = torch.cos(position * div_term)
  7. return pe
  8. max_len = 100
  9. pe = positional_encoding(max_len, d_model) # 形状:[100, 512]

二、编码器层:自注意力与前馈网络

2.1 自注意力机制(Self-Attention)

自注意力通过计算token间的相关性权重,动态捕捉序列内依赖关系。其核心步骤如下:

  1. 线性变换:输入 (X) 分别通过 (W^Q)、(W^K)、(W^V) 生成查询(Query)、键(Key)、值(Value)矩阵:
    [
    Q = XW^Q, \quad K = XW^K, \quad V = XW^V
    ]
    其中 (W^Q, W^K, W^V \in \mathbb{R}^{d{\text{model}} \times d_k}),通常 (d_k = d{\text{model}}/h)((h) 为头数)。

  2. 注意力分数计算
    [
    \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
    ]
    缩放因子 (\sqrt{d_k}) 用于防止点积结果过大导致softmax梯度消失。

  3. 多头注意力:将输入分割为 (h) 个子空间,并行计算自注意力后拼接结果:
    [
    \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, …, \text{head}_h)W^O
    ]
    其中 (\text{head}_i = \text{Attention}(Q_i, K_i, V_i))。

  1. class MultiHeadAttention(nn.Module):
  2. def __init__(self, d_model, num_heads):
  3. super().__init__()
  4. self.d_model = d_model
  5. self.num_heads = num_heads
  6. self.d_k = d_model // num_heads
  7. self.Wq = nn.Linear(d_model, d_model)
  8. self.Wk = nn.Linear(d_model, d_model)
  9. self.Wv = nn.Linear(d_model, d_model)
  10. self.Wo = nn.Linear(d_model, d_model)
  11. def forward(self, x):
  12. batch_size = x.size(0)
  13. Q = self.Wq(x).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
  14. K = self.Wk(x).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
  15. V = self.Wv(x).view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
  16. scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
  17. attn_weights = torch.softmax(scores, dim=-1)
  18. context = torch.matmul(attn_weights, V)
  19. context = context.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
  20. return self.Wo(context)

2.2 残差连接与层归一化

每个子层(自注意力、前馈网络)后均采用残差连接和层归一化(Layer Normalization):
[
\text{Output} = \text{LayerNorm}(X + \text{Sublayer}(X))
]
残差连接缓解梯度消失,层归一化稳定训练过程。

2.3 前馈网络(Feed-Forward Network)

前馈网络为两层全连接层,中间使用ReLU激活:
[
\text{FFN}(x) = \text{ReLU}(xW1 + b_1)W_2 + b_2
]
其中 (W_1 \in \mathbb{R}^{d
{\text{model}} \times d{\text{ff}}}),(W_2 \in \mathbb{R}^{d{\text{ff}} \times d{\text{model}}}),(d{\text{ff}}) 通常为 (4 \times d_{\text{model}})。

三、解码器层:掩码自注意力与编码-解码注意力

3.1 掩码自注意力(Masked Self-Attention)

解码器需防止未来信息泄露,因此对查询矩阵 (Q) 和键矩阵 (K) 的点积结果施加下三角掩码:

  1. def create_mask(seq_len):
  2. mask = torch.triu(torch.ones(seq_len, seq_len), diagonal=1) == 0
  3. return mask.float() # True位置保留,False位置掩码
  4. mask = create_mask(5) # 形状:[5, 5]

掩码后,softmax计算时忽略被掩码的位置。

3.2 编码-解码注意力(Encoder-Decoder Attention)

解码器通过编码-解码注意力关注编码器输出。查询矩阵 (Q) 来自解码器上一层的输出,键矩阵 (K) 和值矩阵 (V) 来自编码器最终输出。

四、输出层:线性变换与Softmax

解码器最终输出通过线性层映射到词表维度,再经softmax生成概率分布:
[
P(yi | y{<i}, X) = \text{softmax}(W{\text{out}} h_i + b{\text{out}})
]
其中 (hi) 为解码器最后一层的输出,(W{\text{out}} \in \mathbb{R}^{d_{\text{model}} \times \text{vocab_size}}})。

五、关键优化点与实践建议

  1. 批量处理与并行计算:利用GPU加速矩阵运算,避免循环计算注意力分数。
  2. 学习率预热(Warmup):初始阶段采用线性增长的学习率,防止模型参数震荡。
  3. 标签平滑(Label Smoothing):在分类任务中缓解过拟合,将真实标签的one-hot向量替换为平滑后的概率分布。
  4. 混合精度训练:使用FP16减少内存占用,结合动态损失缩放(Dynamic Loss Scaling)稳定训练。

六、总结

Transformer的工作流程通过自注意力机制实现动态上下文建模,结合多头并行、残差连接和层归一化构建高效深度网络。理解其内部协作逻辑对模型优化(如减少计算冗余)、定制化开发(如调整头数或隐藏层维度)具有重要指导意义。实际应用中,可结合百度智能云等平台提供的预训练模型和分布式训练工具,进一步加速开发周期。