Personal Knowledge Base

A long-term research and learning notebook for posts, notes, papers, projects, and research directions.

Skip to content
← Back to blog
Deep Learningpublished

Transformer 架构与训练详解

从整体架构、注意力机制到优化器与大规模预训练,系统梳理 Transformer 的组成和训练过程。

18 min read

Transformer 架构详解

背景与动机

Transformer 由 Google 在 2017 年的论文《Attention Is All You Need》中提出,目的是解决 RNN/LSTM 在处理长序列时的两大痛点:无法并行计算(每一步依赖上一步的输出)和长距离依赖遗忘(信息在长序列中会逐渐衰减)。Transformer 完全抛弃了循环结构,仅靠注意力机制来捕捉序列中任意位置之间的关系。


整体结构

Transformer 是一个**编码器-解码器(Encoder-Decoder)**结构,原始设计用于机器翻译:编码器读入源语言句子,解码器输出目标语言句子。

  • 编码器:由 N 个相同的层堆叠而成(原论文 N=6)
  • 解码器:同样由 N 个相同的层堆叠而成

现代变体如 BERT 只用编码器,GPT 只用解码器。

Transformer 架构图


一、输入处理

1. Token Embedding

输入文本首先被分词(tokenization),每个 token 被映射为一个高维向量(如 512 维)。这个向量是通过可学习的嵌入矩阵查表得到的,本身不含任何位置信息。

2. 位置编码(Positional Encoding)

由于 Transformer 没有循环结构,天然不知道词的前后顺序。为此,需要给每个位置注入位置信息。

原论文使用正弦/余弦函数生成位置向量:偶数维度用 sin,奇数维度用 cos,频率随维度变化。这种设计的好处是:模型能通过线性变换推断出相对位置关系,并且能泛化到训练时未见过的序列长度。

最终输入 = Token Embedding + Positional Encoding,两者直接相加。


二、编码器(Encoder)

每个编码器层包含两个子层:

子层 1:多头自注意力(Multi-Head Self-Attention)

自注意力的核心思想:对于序列中的每一个词,计算它与序列中所有其他词的"相关程度",然后根据这个相关程度对所有词的信息进行加权求和,得到该词的新表示。

具体计算步骤(Scaled Dot-Product Attention)

  1. 对每个输入向量,通过三个不同的线性变换矩阵,分别生成三个向量:Query(Q)、Key(K)、Value(V)
    • Q 代表"我想查询什么"
    • K 代表"我有什么信息可以被查询"
    • V 代表"如果被选中,我实际贡献的内容"
  2. 计算注意力分数:Q 与所有 K 做点积,得到一组原始分数,衡量每对词之间的相关性。
  3. 缩放:将分数除以 √d_k(d_k 是向量维度)。这是为了防止维度较大时点积结果过大,导致 softmax 进入梯度极小的饱和区。
  4. Softmax:将分数归一化为概率分布(所有位置的权重之和为 1)。
  5. 加权求和:用上述概率对所有 V 向量做加权求和,得到当前词的输出表示。

多头(Multi-Head)的意义:单组 Q/K/V 只能捕捉一种类型的关联。多头注意力将向量分成 h 份(原论文 h=8),在 h 个不同的"子空间"中分别做注意力计算,每个头可以学到不同的关联模式(如一个头关注语法依赖,另一个头关注语义相似性)。最后将 h 个头的输出拼接,再经过一个线性变换还原到原始维度。

子层 2:前馈神经网络(Feed-Forward Network, FFN)

每个位置独立地通过一个两层全连接网络:先将维度扩大(如 512 → 2048),经过 ReLU 激活,再压缩回原始维度(2048 → 512)。

这一步的作用是:注意力层负责"聚合信息",FFN 层负责"处理信息",对每个位置的表示做非线性变换,增强模型的表达能力。

残差连接与层归一化

每个子层的输出都套用了 Add & Norm 操作:

  • 残差连接(Residual Connection):输出 = 子层(x) + x。防止深层网络梯度消失,让训练更稳定。
  • 层归一化(Layer Normalization):对每个样本在特征维度上归一化,加速训练、稳定梯度。

三、解码器(Decoder)

解码器每层比编码器多一个子层,共三个子层:

子层 1:掩码多头自注意力(Masked Multi-Head Self-Attention)

解码器在生成第 t 个词时,只能看到位置 1 到 t-1 的已生成词,不能"偷看"未来的词(否则训练和推理行为不一致)。

实现方式是在注意力分数矩阵中,将未来位置的分数设为负无穷,经过 softmax 后这些位置的权重变为 0,相当于屏蔽掉未来信息。

子层 2:交叉注意力(Cross-Attention)

这是编码器和解码器之间的桥梁。Q 来自解码器的上一子层输出,K 和 V 来自编码器的最终输出。通过这一机制,解码器的每个位置可以"查询"并聚合整个源序列的信息,实现对输入的动态关注。

子层 3:前馈神经网络

与编码器相同。


四、输出层

解码器最后一层的输出经过一个线性层(将维度映射到词表大小)和 Softmax,得到每个词的生成概率。训练时用交叉熵损失,推理时用贪心解码或束搜索(Beam Search)逐词生成。

Transformer 详细训练过程


一、训练的本质目标

训练的核心是通过大量数据,不断调整模型中所有可学习参数(权重矩阵),使得模型的输出分布尽可能接近真实数据分布。所有参数通过反向传播(Backpropagation)+ 梯度下降来更新。

Transformer 中可学习的参数包括:

  • 所有注意力层的 Q、K、V 投影矩阵及输出矩阵
  • 所有 FFN 层的两个权重矩阵和偏置
  • 层归一化的缩放参数 γ 和偏移参数 β
  • Token Embedding 矩阵
  • 输出线性层的权重矩阵

二、训练任务类型

不同架构的 Transformer 使用不同的训练任务,训练目标直接决定了模型学到什么能力。

1. 序列到序列任务(原始 Encoder-Decoder,如机器翻译)

给定源句子 X,训练模型生成目标句子 Y。

Teacher Forcing 机制:训练时解码器的每一步输入,用的是真实的目标词而不是模型上一步预测的词。例如翻译目标是"I love you",第二步输入就是真实的"I",而不管模型第一步是否预测正确。这样做的好处是训练信号稳定,收敛快;代价是训练和推理存在"暴露偏差"(推理时用自己预测的词,可能积累误差)。

损失函数是对目标句子每个位置的交叉熵损失求平均:

Loss = − (1/T) × Σ log P(y_t | y_1...y_, X)

2. 掩码语言模型(MLM,以 BERT 为代表的 Encoder-only)

随机遮盖输入序列中约 15% 的 token,让模型预测被遮盖的词。这是一种完形填空式的训练,模型可以同时看到上下文(双向)。

被选中的 token 的处理方式:

  • 80% 的概率替换为 [MASK]
  • 10% 的概率替换为随机词(增加鲁棒性)
  • 10% 的概率保持不变(防止模型只关注 MASK 位置)

损失只计算被遮盖位置的预测误差,其余位置不计入损失。

3. 自回归语言模型(CLM,以 GPT 为代表的 Decoder-only)

训练目标是:给定前面所有词,预测下一个词。对序列中每个位置都计算损失:

Loss = − (1/T) × Σ log P(x_t | x_1...x_)

这是当前大语言模型(LLaMA、GPT 系列等)最主流的预训练方式,数据利用率高,每个 token 都贡献梯度。


三、完整训练流程(以翻译任务为例逐步展开)

第一步:数据准备与批处理

分词(Tokenization):原始文本通过 BPE(Byte Pair Encoding)或 WordPiece 等算法切分为 subword token,并映射为整数 ID。

Padding 与 Masking: 一个 batch 内的句子长度不同,需要将短句补齐(Padding)到统一长度。为了不让注意力计算中 padding 位置干扰真实 token,需要构造 Padding Mask:在计算注意力分数时,将 padding 位置的分数设为负无穷,使其 softmax 权重为 0。

典型 batch 大小:原论文约等效于 25000 个源 token + 25000 个目标 token(通过动态组合不同长度的句子实现)。


第二步:前向传播(Forward Pass)

数据流经整个模型,最终得到每个位置的预测概率分布。

编码器侧

  1. 源句子 token ID → Embedding 矩阵查表 → 加上位置编码
  2. 依次通过 N 个编码器层,每层执行:自注意力 → Add&Norm → FFN → Add&Norm
  3. 得到源句子的上下文表示矩阵(形状:batch × src_len × d_model)

解码器侧

  1. 目标句子(右移一位,首位加 [BOS] 开始符)→ Embedding + 位置编码
  2. 依次通过 N 个解码器层,每层执行:
    • 掩码自注意力(只看自身之前的位置)→ Add&Norm
    • 交叉注意力(Q 来自解码器,K/V 来自编码器输出)→ Add&Norm
    • FFN → Add&Norm
  3. 最后一层输出 → 线性变换 → Softmax → 每个位置上词表大小的概率分布

损失计算: 将预测概率分布与真实标签(one-hot)计算交叉熵,在时间步和 batch 上取平均,得到标量损失值。

常见优化:Label Smoothing(标签平滑)——将真实标签从 hard 的 1/0 变为 0.9/0.1 这样的软分布,防止模型过于自信,提升泛化能力。原论文使用 ε=0.1 的标签平滑。


第三步:反向传播(Backward Pass)

损失值对所有参数求梯度,使用链式法则从输出层反向逐层传播。

注意力层的梯度是整个 Transformer 反向传播中最复杂的部分,因为:

  • Softmax 的梯度需要考虑所有位置的相互影响
  • 多头注意力中每个头的梯度要分别计算再汇总
  • 残差连接使梯度可以直接绕过子层流向更浅的层,有效缓解梯度消失

梯度裁剪(Gradient Clipping):计算所有参数梯度的 L2 范数,若超过阈值(如 1.0),则等比例缩小所有梯度。防止梯度爆炸,在训练早期尤为重要。


第四步:参数更新(Optimizer)

原始 Transformer 使用 Adam 优化器,结合了动量(一阶矩)和自适应学习率(二阶矩),适合 Transformer 的稀疏梯度场景。

学习率调度(Learning Rate Schedule)——这是 Transformer 训练的关键设计:

原论文使用Warmup + 衰减策略:

  • Warmup 阶段(前 4000 步):学习率从 0 线性增大到峰值。原因是训练初期参数随机,梯度方向不稳定,过大的学习率会导致震荡甚至发散。
  • 衰减阶段:学习率按步数的 -0.5 次方衰减,逐渐降低。

公式为:lr = d_model^ × min(step^, step × warmup_steps^)

这意味着:峰值学习率约为 d_model^ × warmup_steps^,对于 d_model=512、warmup=4000,峰值约为 0.0007。


四、训练稳定性的关键技术

Dropout

原论文在多处施加 Dropout(概率 0.1):

  • 每个子层的输出(Add 之前)
  • Attention 权重矩阵(防止注意力过度集中于少数位置)
  • Embedding 加完位置编码之后

训练时随机置零一部分神经元,推理时关闭。

层归一化的位置

原论文是 Post-LN(先子层运算,再 Add&Norm)。但后来研究发现 Pre-LN(先 Norm 再子层运算,再残差相加)训练更稳定,不需要 warmup,现代大模型(GPT-2 之后)普遍采用 Pre-LN。

权重初始化

注意力层和 FFN 层的权重用 Xavier 初始化;Embedding 层用均匀分布初始化。初始化直接影响前向传播时各层的方差,不合理的初始化会导致信号在深层网络中消失或爆炸。


五、大规模预训练的特殊考量

现代 LLM(百亿到千亿参数)的训练与原始 Transformer 在工程层面有巨大差异:

混合精度训练(Mixed Precision)

  • 前向和反向传播用 FP16/BF16(16位浮点)以节省显存、加快计算
  • 优化器状态(Adam 的一阶矩、二阶矩)和参数主副本保留 FP32,防止精度损失累积
  • BF16 比 FP16 数值范围更大,不容易出现溢出,是当前主流选择

分布式训练

  • 数据并行(Data Parallel):每张 GPU 保存完整模型,处理不同 batch,梯度 AllReduce 同步
  • 张量并行(Tensor Parallel):将单个矩阵乘法拆分到多张 GPU 上(如 Megatron-LM)
  • 流水线并行(Pipeline Parallel):将不同层分配到不同 GPU,形成流水线
  • ZeRO 优化(DeepSpeed):将优化器状态、梯度、参数分片存储到不同 GPU,突破单卡显存限制

梯度累积(Gradient Accumulation)

若显存不足以支持大 batch,可以每 k 步才做一次参数更新,相当于将 k 个小 batch 的梯度累加后再更新,等效于更大的 batch size。

数据课程(Data Curriculum)

训练数据不是随机打乱就行,精心设计的数据顺序(如从简单到复杂,或按质量过滤)对最终性能有显著影响。


六、过拟合的防控

手段说明
Dropout训练时随机丢弃神经元,防止共适应
Label Smoothing软化目标分布,防止过度自信
Weight DecayAdam + L2 正则,惩罚过大的权重
Early Stopping监控验证集损失,适时停止
数据增强回译(back-translation)等手段扩充训练数据

七、训练阶段总结

原始数据
   ↓ 分词 + 构建词表
Token ID 序列
   ↓ Embedding + 位置编码
向量序列
   ↓ 编码器 × N 层
源语言上下文表示
   ↓ 解码器 × N 层(Teacher Forcing)
每个位置的 logits
   ↓ Softmax
预测概率分布
   ↓ 与真实标签计算交叉熵
损失标量
   ↓ 反向传播(链式法则)
各参数的梯度
   ↓ 梯度裁剪
安全梯度
   ↓ Adam + 学习率调度
更新后的参数
   ↓ 循环迭代
收敛的模型

整个训练过程就是不断重复这个循环,用数以亿计的样本一步步把随机初始化的参数塑造成能够理解和生成语言的模型。