前言Transformer 是当前所有大语言模型、多模态模型的基础架构彻底取代了传统 RNN、LSTM 序列模型解决了长距离依赖无法捕捉、并行计算效率低的问题。从 GPT 系列、LLaMA、BERT 到文心一言、通义千问本质都是 Transformer 的变体与堆叠。本文将从核心机制、结构图解、数学原理、代码实现四个维度完整拆解自注意力、多头注意力、位置编码、Encoder/Decoder 结构带你手写极简可运行的 Transformer 核心模块。一、Transformer 诞生背景与核心思想1.1 传统序列模型的缺陷在 Transformer 出现2017 年Google《Attention Is All You Need》之前自然语言处理、时序任务主流模型为 RNN、LSTM、GRU串行计算只能按序列顺序逐个处理 token无法并行训练速度极慢长距离依赖衰减序列过长时早期信息经过多层传递后会丢失无法建模长文本注意力机制受限早期注意力仅作为辅助模块并非核心结构。1.2 Transformer 核心设计理念Transformer 完全抛弃循环结构仅依靠注意力机制实现序列建模核心优势全并行计算所有 token 同时输入大幅提升训练效率长距离依赖直接建模任意两个 token 可直接建立关联不受序列长度限制灵活的双向 / 单向建模Encoder 支持双向注意力适合理解Decoder 支持单向注意力适合生成可深度堆叠通过残差连接、层归一化可堆叠数十层甚至上百层支撑大模型规模。二、Transformer 整体结构图解2.1 标准 Transformer 宏观结构标准 Transformer 分为两大核心模块Encoder 编码器双向注意力用于理解输入序列如文本分类、抽取、翻译源文本编码Decoder 解码器单向掩码注意力 交叉注意力用于生成目标序列如翻译、文本生成、对话。整体流程输入序列 → 词嵌入 位置编码 → N 层 Encoder 堆叠 → 编码结果传入 Decoder → Decoder 结合目标序列生成输出 → 线性层 Softmax 输出概率分布。2.2 结构可视化拆解plaintext[输入嵌入 位置编码] ↓ ┌─────────────────────────┐ │ Encoder 层 │ × N │ ├─ 多头自注意力 │ │ ├─ 残差 层归一化 │ │ └─ 前馈神经网络 残差 │ └─────────────────────────┘ ↓ ┌─────────────────────────┐ │ Decoder 层 │ × N │ ├─ 掩码多头自注意力 │ │ ├─ 交叉注意力Encoder-Decoder│ │ ├─ 残差 层归一化 │ │ └─ 前馈神经网络 残差 │ └─────────────────────────┘ ↓ [线性层 Softmax 输出]2.3 Encoder 与 Decoder 核心区别表格模块注意力类型信息流向典型任务Encoder双向自注意力所有 token 互相可见文本分类、NER、语义理解Decoder掩码自注意力 交叉注意力仅当前 token 可见前文文本生成、翻译、对话三、核心机制 1自注意力机制Self-Attention自注意力是 Transformer 的灵魂全称缩放点积注意力Scaled Dot-Product Attention作用是让序列中每个 token 都能关注序列中所有其他 token 的重要程度。3.1 自注意力数学原理3.1.1 Q、K、V 三向量定义对于输入序列嵌入向量 X∈Rn×dn 为序列长度d 为嵌入维度通过三个线性层映射得到Query查询 Q当前 token 想要查找的信息特征Key键 K所有 token 提供的信息索引Value值 V所有 token 实际携带的信息内容。映射公式QXWQ​,KXWK​,VXWV​其中 WQ​,WK​,WV​∈Rd×d 为可学习参数。3.1.2 注意力分数计算注意力分数代表当前 token 对其他 token 的关注权重通过 Q 与 K 的点积计算AttentionScoredk​​QKT​除以 dk​​dk​ 为 K 的维度是为了缩放避免点积结果过大导致 Softmax 进入饱和区梯度消失Softmax 归一化得到注意力概率AttentionProbSoftmax(dk​​QKT​)3.1.3 加权求和得到输出用注意力概率对 V 加权求和得到最终注意力输出OutputAttentionProb⋅V3.2 自注意力直观理解以句子「我爱深度学习」为例token「深度」会高权重关注「学习」低权重关注「我」token「爱」会同时关注「我」和「深度学习」自注意力自动学习 token 间的语义关联无需人工特征。3.3 自注意力优势全局感受野一步获取整个序列信息优于 RNN 的局部感受野并行计算无需串行迭代所有位置同时计算权重动态可调根据语义自动分配注意力灵活建模依赖关系。四、核心机制 2多头注意力Multi-Head Attention单头自注意力仅学习一组语义关联表达能力有限多头注意力将嵌入维度拆分为多个头并行学习多组不同的语义依赖。4.1 多头注意力核心逻辑维度拆分将嵌入维度 dmodel​ 均分为 h 个头每个头维度 dk​dmodel​/h并行计算每个头独立执行缩放点积注意力学习不同的语义模式如语法依赖、语义关联、长距离依赖拼接融合将所有头的输出拼接通过线性层映射得到最终输出。4.2 多头注意力数学公式headi​MultiHead​Attention(QWQi​​,KWKi​​,VWVi​​)Concat(head1​,...,headh​)WO​​其中 WQi​​,WKi​​,WVi​​ 为第 i 个头的投影矩阵WO​ 为输出线性层。4.3 多头注意力的意义多头可同时捕捉不同类型的依赖关系如头 1 关注主谓关系头 2 关注指代关系头 3 关注长距离关联提升模型表达能力同时不增加过多计算量标准 Transformer 默认使用 h8 个头。五、核心机制 3位置编码Positional EncodingTransformer 无循环结构无法感知序列顺序而语言是有序的如「我吃饭」≠「饭吃我」因此需要位置编码为 token 注入位置信息。5.1 正弦余弦位置编码论文使用固定正弦余弦位置编码公式PEpos,2i​PEpos,2i1​​sin(100002i/dmodel​pos​)cos(100002i/dmodel​pos​)​pos 为 token 位置i 为嵌入维度索引正弦余弦函数具有周期性可泛化到比训练序列更长的位置。5.2 位置编码融合方式位置编码直接与词嵌入逐元素相加Xfinal​Xembedding​PE无需额外学习参数也可替换为可学习位置编码大模型常用。5.3 位置编码作用为模型提供序列顺序信息让模型区分不同位置的 token保证平移不变性适配不同长度的序列固定编码 vs 可学习编码小模型用固定编码大模型用可学习编码效果更优。六、核心模块 1Encoder 编码器详解Encoder 由多层重复模块堆叠而成每层包含两个子层多头自注意力层 前馈神经网络层并搭配残差连接 层归一化。6.1 Encoder 层结构标准 Encoder 层计算流程多头自注意力双向注意力所有 token 互相可见残差连接 层归一化LayerNorm(xAttention(x))防止梯度消失前馈神经网络FFN两层线性变换 激活函数ReLU/GELUFFN(x)max(0,xW1​b1​)W2​b2​再次残差 层归一化完成一层 Encoder 计算。6.2 Encoder 核心特性双向建模每个 token 可关注前文与后文适合理解类任务无掩码注意力矩阵无遮挡全局关联输出为上下文相关的序列嵌入包含完整语义信息。七、核心模块 2Decoder 解码器详解Decoder 用于序列生成结构比 Encoder 多一个交叉注意力层同时使用掩码自注意力防止信息泄露。7.1 Decoder 层三大子层掩码多头自注意力对注意力矩阵添加上三角掩码让当前 token 仅能关注前文 token无法看到后文保证生成的因果性。交叉注意力Encoder-Decoder AttentionQ 来自 Decoder 上一层输出K、V 来自 Encoder 最终输出让 Decoder 关注输入序列的关键信息。前馈神经网络 残差归一化与 Encoder 一致。7.2 掩码机制原理掩码矩阵为下三角全 1、上三角全 0 矩阵注意力分数中掩码位置填充 −1e9Softmax 后权重趋近于 0彻底屏蔽后文信息。7.3 Decoder 核心特性单向因果建模严格遵循序列顺序适合生成任务融合 Encoder 信息通过交叉注意力关联输入与输出最终输出经线性层映射到词表大小Softmax 得到下一个 token 概率。八、Transformer 关键代码手写实现基于 PyTorch 实现极简可运行的核心模块位置编码、多头注意力、Encoder 层、Decoder 层、完整 Transformer。8.1 环境与基础导入import torch import torch.nn as nn import torch.nn.functional as F import math # 基础配置 batch_size 2 seq_len 10 embed_dim 512 num_heads 8 num_layers 6 vocab_size 10000 max_len 5128.2 位置编码实现class PositionalEncoding(nn.Module): def __init__(self, embed_dim, max_len5000, dropout0.1): super().__init__() self.dropout nn.Dropout(pdropout) # 正弦余弦位置编码 pe torch.zeros(max_len, embed_dim) position torch.arange(0, max_len, dtypetorch.float).unsqueeze(1) div_term torch.exp(torch.arange(0, embed_dim, 2).float() * (-math.log(10000.0) / embed_dim)) pe[:, 0::2] torch.sin(position * div_term) pe[:, 1::2] torch.cos(position * div_term) pe pe.unsqueeze(0) # [1, max_len, embed_dim] self.register_buffer(pe, pe) def forward(self, x): # x: [batch, seq_len, embed_dim] x x self.pe[:, :x.size(1), :] return self.dropout(x)8.3 缩放点积注意力def scaled_dot_product_attention(q, k, v, maskNone): # q,k,v: [batch, heads, seq_len, head_dim] head_dim q.size(-1) attn_scores torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(head_dim) # 掩码处理 if mask is not None: attn_scores attn_scores.masked_fill(mask 0, -1e9) attn_probs F.softmax(attn_scores, dim-1) output torch.matmul(attn_probs, v) return output, attn_probs8.4 多头注意力完整实现class MultiHeadAttention(nn.Module): def __init__(self, embed_dim, num_heads): super().__init__() self.embed_dim embed_dim self.num_heads num_heads self.head_dim embed_dim // num_heads # QKV 投影层 self.q_proj nn.Linear(embed_dim, embed_dim) self.k_proj nn.Linear(embed_dim, embed_dim) self.v_proj nn.Linear(embed_dim, embed_dim) self.out_proj nn.Linear(embed_dim, embed_dim) def forward(self, q, k, v, maskNone): batch_size q.size(0) # 线性投影 拆分多头 q self.q_proj(q).view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2) k self.k_proj(k).view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2) v self.v_proj(v).view(batch_size, -1, self.num_heads, self.head_dim).transpose(1, 2) # 注意力计算 attn_output, _ scaled_dot_product_attention(q, k, v, mask) # 拼接多头 attn_output attn_output.transpose(1, 2).contiguous().view(batch_size, -1, self.embed_dim) return self.out_proj(attn_output)8.5 前馈神经网络class FeedForward(nn.Module): def __init__(self, embed_dim, hidden_dim2048, dropout0.1): super().__init__() self.fc1 nn.Linear(embed_dim, hidden_dim) self.fc2 nn.Linear(hidden_dim, embed_dim) self.dropout nn.Dropout(dropout) def forward(self, x): return self.fc2(self.dropout(F.relu(self.fc1(x))))8.6 Encoder 层实现class EncoderLayer(nn.Module): def __init__(self, embed_dim, num_heads, hidden_dim2048, dropout0.1): super().__init__() self.self_attn MultiHeadAttention(embed_dim, num_heads) self.ffn FeedForward(embed_dim, hidden_dim, dropout) self.norm1 nn.LayerNorm(embed_dim) self.norm2 nn.LayerNorm(embed_dim) self.dropout nn.Dropout(dropout) def forward(self, x, maskNone): # 自注意力 残差归一化 attn_out self.self_attn(x, x, x, mask) x self.norm1(x self.dropout(attn_out)) # 前馈 残差归一化 ffn_out self.ffn(x) x self.norm2(x self.dropout(ffn_out)) return x8.7 Decoder 层实现class DecoderLayer(nn.Module): def __init__(self, embed_dim, num_heads, hidden_dim2048, dropout0.1): super().__init__() self.masked_attn MultiHeadAttention(embed_dim, num_heads) self.cross_attn MultiHeadAttention(embed_dim, num_heads) self.ffn FeedForward(embed_dim, hidden_dim, dropout) self.norm1 nn.LayerNorm(embed_dim) self.norm2 nn.LayerNorm(embed_dim) self.norm3 nn.LayerNorm(embed_dim) self.dropout nn.Dropout(dropout) def forward(self, x, enc_out, src_maskNone, tgt_maskNone): # 掩码自注意力 masked_out self.masked_attn(x, x, x, tgt_mask) x self.norm1(x self.dropout(masked_out)) # 交叉注意力 cross_out self.cross_attn(x, enc_out, enc_out, src_mask) x self.norm2(x self.dropout(cross_out)) # 前馈网络 ffn_out self.ffn(x) x self.norm3(x self.dropout(ffn_out)) return x8.8 完整 Transformer 模型class Transformer(nn.Module): def __init__(self, vocab_size, embed_dim, num_heads, num_layers, hidden_dim2048, max_len512, dropout0.1): super().__init__() self.embedding nn.Embedding(vocab_size, embed_dim) self.pos_encoding PositionalEncoding(embed_dim, max_len, dropout) # Encoder Decoder 堆叠 self.encoders nn.ModuleList([EncoderLayer(embed_dim, num_heads, hidden_dim, dropout) for _ in range(num_layers)]) self.decoders nn.ModuleList([DecoderLayer(embed_dim, num_heads, hidden_dim, dropout) for _ in range(num_layers)]) # 输出层 self.fc_out nn.Linear(embed_dim, vocab_size) def generate_mask(self, seq): # 生成因果掩码 mask torch.tril(torch.ones(seq.size(1), seq.size(1))).unsqueeze(0).unsqueeze(0) return mask def forward(self, src, tgt): # 嵌入 位置编码 src_emb self.pos_encoding(self.embedding(src)) tgt_emb self.pos_encoding(self.embedding(tgt)) # Encoder 前向传播 enc_out src_emb for enc in self.encoders: enc_out enc(enc_out) # Decoder 掩码 tgt_mask self.generate_mask(tgt) # Decoder 前向传播 dec_out tgt_emb for dec in self.decoders: dec_out dec(dec_out, enc_out, tgt_masktgt_mask) # 输出概率 return self.fc_out(dec_out)8.9 模型测试运行if __name__ __main__: # 初始化模型 model Transformer( vocab_sizevocab_size, embed_dimembed_dim, num_headsnum_heads, num_layersnum_layers ) # 构造测试数据 src torch.randint(0, vocab_size, (batch_size, seq_len)) tgt torch.randint(0, vocab_size, (batch_size, seq_len)) # 前向传播 output model(src, tgt) print(f输入形状: {src.shape}) print(f输出形状: {output.shape}) print(模型运行成功)运行输出输入形状: torch.Size([2, 10]) 输出形状: torch.Size([2, 10, 10000]) 模型运行成功九、Transformer 变体与大模型演进9.1 主流 Transformer 变体BERT仅使用 Encoder双向注意力擅长理解任务GPT仅使用 Decoder单向掩码注意力擅长生成任务T5/BART完整 Encoder-Decoder 结构通用生成模型LLaMA/LLaMA 2Decoder-only 架构优化归一化与激活函数。9.2 大模型对 Transformer 的优化Pre-LN 结构归一化放在子层之前训练更稳定RoPE 位置编码旋转位置编码提升长文本建模Flash Attention优化注意力计算降低显存占用MoE 混合专家多头扩展为多专家提升模型容量。十、总结Transformer 作为大模型的基础架构核心逻辑可概括为自注意力全局建模 token 关联替代循环结构多头注意力多维度捕捉语义依赖提升表达能力位置编码注入序列顺序信息弥补无循环缺陷Encoder-Decoder分别实现理解与生成适配全场景任务残差 归一化支撑深度堆叠构建百亿 / 千亿参数大模型。本文实现的极简代码完整复现了 Transformer 核心逻辑是理解 GPT、BERT 等大模型的基础。在此基础上通过堆叠层数、扩大嵌入维度、优化注意力机制即可构建出工业级大语言模型。