Transformer 全家福:编码器与解码器——翻译官团队

张开发
2026/4/4 21:50:15 15 分钟阅读
Transformer 全家福:编码器与解码器——翻译官团队
Transformer 全家福编码器与解码器——翻译官团队Version B《从零到一造大脑AI架构入门之旅》专栏专栏定位面向中学生、大学生和 AI 初学者的科普专栏用大白话和生活化比喻带你从零理解人工智能本系列共 42 篇分为八大模块 模块一【AI 基础概念】(3 篇)AI/ML/DL 关系、学习方式、深度之谜 模块二【神经网络入门】(4 篇)神经元、权重、激活函数、MLP️ 模块三【深度学习核心】(6 篇)损失函数、梯度下降、反向传播、过拟合、Batch/Epoch/LR 模块四【注意力机制】(5 篇)从 Attention 到 Transformer 模块五【NCT 与 CATS-NET 案例】(8 篇)真实架构演进全记录 模块六【架构融合方法】(6 篇)如何设计混合架构⚙️ 模块七【参数调优实战】(6 篇)学习率、正则化、超参数搜索 模块八【综合应用展望】(4 篇)未来趋势与职业规划本文是模块四第 4 篇将带你理解 Transformer 的完整架构。 ‍作者简介NeuroConscious Research Team一群热爱 AI 科普的研究者专注于神经科学启发的 AI架构设计与可解释性研究。理念“再复杂的概念也能用大白话讲清楚”。项目地址https://github.com/wyg5208/nct.git官网地址https://neuroconscious.link作者 CSDNhttps://blog.csdn.net/yweng18NCT PyPIhttps://pypi.org/project/neuroconscious-transformer/⭐欢迎 Star⭐、Fork、贡献代码本文核心比喻翻译官团队——一人读懂原文一人写成译文⏱️阅读时间约 25 分钟学习目标理解 Transformer 的整体架构、编码器和解码器的区别、残差连接和 LayerNorm 文章摘要本文用翻译官团队比喻带你彻底搞懂 Transformer 的完整架构。翻译一本书时先有人读懂原文编码器再有人写成译文解码器。文章详细解释了编码器堆叠、解码器堆叠、交叉注意力、残差连接、LayerNorm 等关键组件并对比了 BERT仅编码器和 GPT仅解码器两种架构。适合零基础上手25 分钟理解 Transformer 的全貌。 你需要先了解阅读本文前建议你✅ 已读过前三篇注意力、自注意力、多头注意力✅ 理解 Q、K、V 的含义✅ 有过翻译或理解外语的经历如果还没读前文[点这里返回](16-多头注意力 8个脑袋同时思考_version_B.md) 正文一、从一个场景开始 翻译场景你接到一个任务翻译一本英文小说到中文。工作流程 小王阅读英文原文 → 理解内容✍️ 小李根据理解 → 写出中文译文问题为什么要两个人一个人不能同时做这两件事吗答案可以但分工更高效这就是 Transformer 的设计思想翻译工作流程 → Transformer 架构 ──────────────────────────────────── 小王读懂原文 → 编码器Encoder 小李写出译文 → 解码器Decoder 两人之间的交流 → 交叉注意力二、Transformer 整体架构2.1 完整架构图┌─────────────────────────────────────────────────────────────────────┐ │ Transformer 架构 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 输入源语言 │ │ │ │ │ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 输入嵌入 位置编码 │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 编码器层 × N │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ 多头自注意力 残差 LN │ │ │ │ │ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ 前馈网络 残差 LN │ │ │ │ │ └─────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ↓ 编码器输出记忆 │ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 目标嵌入 位置编码 │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 解码器层 × N │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ 带掩码自注意力 残差 LN │ │ │ │ │ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ 交叉注意力 残差 LN │←──┤ 编码器输出 │ │ │ └─────────────────────────────┘ │ │ │ │ ┌─────────────────────────────┐ │ │ │ │ │ 前馈网络 残差 LN │ │ │ │ │ └─────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 线性层 Softmax │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ↓ │ │ 输出概率分布下一个词的概率 │ │ │ └─────────────────────────────────────────────────────────────────────┘2.2 两大组件 编码器Encoder功能理解输入包含多头自注意力前馈神经网络残差连接 LayerNorm类比“读懂原文的人” 解码器Decoder功能生成输出包含带掩码自注意力交叉注意力前馈神经网络残差连接 LayerNorm类比“写出译文的人”三、编码器详解3.1 编码器层结构输入 │ ↓ ┌─────────────────────────────────────┐ │ 多头自注意力层 │ │ Multi-Head Self-Attention │ └─────────────────────────────────────┘ │ ← 残差连接 │ ↓ ┌─────────────────────────────────────┐ │ LayerNorm │ └─────────────────────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ 前馈神经网络 (FFN) │ │ Linear → GELU → Linear │ │ d_model → d_ff → d_model │ └─────────────────────────────────────┘ │ ← 残差连接 │ ↓ ┌─────────────────────────────────────┐ │ LayerNorm │ └─────────────────────────────────────┘ │ ↓ 输出3.2 前馈神经网络FFN结构classFeedForward(nn.Module):def__init__(self,d_model,d_ff,dropout0.1):super().__init__()self.netnn.Sequential(nn.Linear(d_model,d_ff),# 扩展nn.GELU(),# 激活nn.Dropout(dropout),nn.Linear(d_ff,d_model),# 压缩nn.Dropout(dropout))defforward(self,x):returnself.net(x)# 典型配置d_model512d_ff2048# 通常是 d_model 的 4 倍作用增加非线性增强表达能力在注意力之后进行加工3.3 残差连接和 LayerNorm残差连接输出 LayerNorm(x Sublayer(x)) 而不是 输出 LayerNorm(Sublayer(x))为什么需要问题深层网络梯度消失 解决残差连接让梯度可以直接流过 类比 就像高速公路的服务区 你既可以直接走到底 也可以在服务区休息 残差连接 直通车道LayerNorm vs BatchNormBatchNorm 对一个 batch 内的样本归一化 问题batch size 小时不稳定 LayerNorm 对一个样本的所有维度归一化 优势不依赖 batch size 更适合序列模型四、解码器详解4.1 解码器层结构目标输入 │ ↓ ┌─────────────────────────────────────┐ │ 带掩码多头自注意力层 │ ← 掩码只能看之前的位置 │ Masked Multi-Head Self-Attention │ └─────────────────────────────────────┘ │ ← 残差连接 │ ↓ ┌─────────────────────────────────────┐ │ LayerNorm │ └─────────────────────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ 交叉注意力层 │ ← Q 来自解码器 │ Cross-Attention │ ← K,V 来自编码器 └─────────────────────────────────────┘ │ ← 残差连接 │ ↓ ┌─────────────────────────────────────┐ │ LayerNorm │ └─────────────────────────────────────┘ │ ↓ ┌─────────────────────────────────────┐ │ 前馈神经网络 (FFN) │ └─────────────────────────────────────┘ │ ← 残差连接 │ ↓ ┌─────────────────────────────────────┐ │ LayerNorm │ └─────────────────────────────────────┘ │ ↓ 输出4.2 带掩码自注意力为什么需要掩码训练时 输入I love cats 目标我喜欢猫 生成欢时不能看到猫 否则就是偷看答案 掩码作用 位置 0 可以看[0] 位置 1 可以看[0, 1] 位置 2 可以看[0, 1, 2] ...掩码实现defcreate_causal_mask(seq_len):创建因果掩码下三角矩阵masktorch.tril(torch.ones(seq_len,seq_len))returnmask# [seq_len, seq_len]# 示例seq_len4maskcreate_causal_mask(seq_len)print(mask)# tensor([[1., 0., 0., 0.],# [1., 1., 0., 0.],# [1., 1., 1., 0.],# [1., 1., 1., 1.]])# 应用掩码scoresscores.masked_fill(mask0,-1e9)4.3 交叉注意力解码器如何参考编码器的输出编码器输出Memory [B, src_len, d_model] 解码器输入Target [B, tgt_len, d_model] 交叉注意力 Q ← 来自 Target解码器 K ← 来自 Memory编码器 V ← 来自 Memory编码器 解码器问哪些编码器位置和我相关 编码器答这些位置的表示五、三种架构变体5.1 Encoder-OnlyBERT┌─────────────────────────────────────┐ │ Encoder-Only │ │ (如 BERT) │ ├─────────────────────────────────────┤ │ │ │ 特点 │ │ - 只有编码器 │ │ - 双向注意力可以看到前后文 │ │ - 适合理解任务 │ │ │ │ 应用 │ │ - 文本分类 │ │ - 命名实体识别 │ │ - 问答系统 │ │ │ └─────────────────────────────────────┘5.2 Decoder-OnlyGPT┌─────────────────────────────────────┐ │ Decoder-Only │ │ (如 GPT) │ ├─────────────────────────────────────┤ │ │ │ 特点 │ │ - 只有解码器 │ │ - 单向注意力掩码只能看前文 │ │ - 适合生成任务 │ │ │ │ 应用 │ │ - 文本生成 │ │ - 对话系统 │ │ - 代码生成 │ │ │ │ NCT 就是这种架构 │ │ │ └─────────────────────────────────────┘5.3 Encoder-DecoderT5┌─────────────────────────────────────┐ │ Encoder-Decoder │ │ (如 T5, BART) │ ├─────────────────────────────────────┤ │ │ │ 特点 │ │ - 编码器 解码器 │ │ - 编码器双向解码器单向 │ │ - 适合序列到序列任务 │ │ │ │ 应用 │ │ - 机器翻译 │ │ - 文本摘要 │ │ - 问答生成 │ │ │ └─────────────────────────────────────┘六、完整代码实现importtorchimporttorch.nnasnnimportmathclassTransformerEncoderLayer(nn.Module):def__init__(self,d_model,n_heads,d_ff,dropout0.1):super().__init__()# 多头自注意力self.self_attnnn.MultiheadAttention(d_model,n_heads,dropoutdropout)# 前馈网络self.ffnnn.Sequential(nn.Linear(d_model,d_ff),nn.GELU(),nn.Dropout(dropout),nn.Linear(d_ff,d_model),nn.Dropout(dropout))# LayerNormself.norm1nn.LayerNorm(d_model)self.norm2nn.LayerNorm(d_model)self.dropoutnn.Dropout(dropout)defforward(self,x,src_maskNone):# 多头自注意力 残差 LayerNormattn_output,_self.self_attn(x,x,x,attn_masksrc_mask)xself.norm1(xself.dropout(attn_output))# FFN 残差 LayerNormffn_outputself.ffn(x)xself.norm2(xffn_output)returnxclassTransformerDecoderLayer(nn.Module):def__init__(self,d_model,n_heads,d_ff,dropout0.1):super().__init__()# 带掩码自注意力self.self_attnnn.MultiheadAttention(d_model,n_heads,dropoutdropout)# 交叉注意力self.cross_attnnn.MultiheadAttention(d_model,n_heads,dropoutdropout)# 前馈网络self.ffnnn.Sequential(nn.Linear(d_model,d_ff),nn.GELU(),nn.Dropout(dropout),nn.Linear(d_ff,d_model),nn.Dropout(dropout))# LayerNormself.norm1nn.LayerNorm(d_model)self.norm2nn.LayerNorm(d_model)self.norm3nn.LayerNorm(d_model)self.dropoutnn.Dropout(dropout)defforward(self,x,memory,tgt_maskNone,memory_maskNone):# 带掩码自注意力attn_output,_self.self_attn(x,x,x,attn_masktgt_mask)xself.norm1(xself.dropout(attn_output))# 交叉注意力attn_output,_self.cross_attn(x,memory,memory,attn_maskmemory_mask)xself.norm2(xself.dropout(attn_output))# FFNffn_outputself.ffn(x)xself.norm3(xffn_output)returnx# 使用示例d_model512n_heads8d_ff2048encoder_layerTransformerEncoderLayer(d_model,n_heads,d_ff)decoder_layerTransformerDecoderLayer(d_model,n_heads,d_ff)srctorch.randn(10,32,d_model)# [seq_len, batch, d_model]tgttorch.randn(8,32,d_model)# 编码memoryencoder_layer(src)# 解码outputdecoder_layer(tgt,memory)print(f编码器输出{memory.shape})print(f解码器输出{output.shape}) 一句话总结 核心结论编码器理解输入解码器生成输出。残差连接和 LayerNorm 是深层网络的稳定器。记忆口诀编码器来理解文 解码器来生成字。 残差连接传梯度 LayerNorm 保稳定。✍️ 课后作业选择题每题 10 分1. BERT 使用什么架构A. Encoder-Only ✅B. Decoder-OnlyC. Encoder-DecoderD. 没有 Transformer2. 解码器的自注意力为什么需要掩码A. 加快计算B. 防止偷看未来 ✅C. 减少参数D. 增加准确率3. 残差连接的作用是A. 增加参数B. 防止梯度消失 ✅C. 减少计算量D. 增加非线性4. NCT 使用什么架构A. Encoder-OnlyB. Decoder-Only ✅C. Encoder-DecoderD. RNN5. 交叉注意力中K 和 V 来自A. 解码器B. 编码器 ✅C. 输入嵌入D. 输出层 下一篇预告 下一篇文章题目为什么 Transformer 这么强——对比 CNN 和 RNN我们会学到CNN、RNN、Transformer 的对比Transformer 的优势不同架构的适用场景 本文属《从零到一造大脑AI架构入门之旅》专栏第四模块第四篇作者NeuroConscious Research Team更新时间2026 年 3 月版本号V1.0-B图文并茂版

更多文章