DL:Transformer 的基本原理与 PyTorch 实现
Transformer 是深度学习中最重要的模型结构之一。它最初用于自然语言处理任务,后来逐渐扩展到图像、语音、多模态、代码生成、推荐系统和强化学习等领域,成为现代大模型的核心基础结构。
传统循环神经网络(RNN)按时间步依次处理序列,能够利用上下文信息,但难以完全并行计算,也容易受到长距离依赖问题影响。
Transformer 不再依赖循环结构,而是使用注意力机制(Attention Mechanism),让序列中的每个位置都可以直接关注其他位置,从而更高效地建模上下文关系。
图 1:从 RNN 到 Transformer
可以简单理解为:
• RNN:按顺序逐步读
• Transformer:同时看全局关系
Transformer 的核心思想是:让模型根据任务需要,自动判断序列中哪些位置更重要,并把相关信息加权汇总起来。
一、为什么需要 Transformer
序列数据中,元素之间往往存在上下文关系。
例如,在句子:
这部电影虽然前半段节奏很慢,但结尾非常精彩。如果只看“很慢”,模型可能认为这是负面评价;如果结合后面的“但结尾非常精彩”,模型就需要理解转折关系,并综合判断整体语义。
RNN 通过隐藏状态逐步传递历史信息:
其中:
• xₜ 表示第 t 个时间步输入
• hₜ₋₁ 表示上一时间步隐藏状态
• hₜ 表示当前时间步隐藏状态
• f 表示循环单元的状态更新函数
这种结构的问题在于:
• 序列必须按时间顺序逐步处理,难以充分并行
• 远距离信息需要经过多个时间步传递
• 长序列中容易出现梯度消失或信息衰减
• 每个位置对其他位置的依赖关系不够直接
Transformer 采用了不同思路。
它让每个位置直接和序列中所有位置建立联系,再根据相关性大小分配注意力权重。
例如,在句子中:
这部电影虽然前半段节奏很慢,但结尾非常精彩。模型在理解“精彩”时,可以直接关注“结尾”“但”“电影”等相关词,而不必像 RNN 那样一步步传递信息。
图 2:RNN 与 Transformer 处理序列方式的对比
因此,Transformer 的优势主要体现在:
• 能直接建模长距离依赖
• 更适合并行计算
• 能根据上下文动态分配注意力
• 适合大规模数据和大模型训练
• 可扩展到文本、图像、语音和多模态任务
二、Transformer 的整体结构
Transformer 最初采用编码器—解码器结构(Encoder–Decoder Architecture),用于机器翻译等序列到序列任务。
整体结构可以概括为:
输入序列 → 编码器 → 上下文表示 → 解码器 → 输出序列
其中:
• 编码器负责理解输入序列
• 解码器负责根据已生成内容和编码器输出生成目标序列
• 注意力机制负责建模不同位置之间的依赖关系
图 3:Transformer 的编码器—解码器结构
1、编码器
编码器(Encoder)接收输入序列,并把每个位置转换成包含上下文信息的表示。
一个 Transformer 编码器通常由多个相同结构的编码器层堆叠而成。每个编码器层主要包含两部分:
多头自注意力层 → 前馈神经网络层
并配合:
• 残差连接
• 层归一化
• Dropout
可以写成:
输入表示→ 多头自注意力→ 残差连接与层归一化→ 前馈神经网络→ 残差连接与层归一化→ 输出表示编码器的目标是:让每个位置的表示都融合整个输入序列中的相关信息。
2、解码器
解码器(Decoder)用于生成输出序列。它通常也由多个相同结构的解码器层堆叠而成。
每个解码器层主要包含三部分:
掩码多头自注意力层 → 编码器—解码器注意力层 → 前馈神经网络层
其中:
• 掩码自注意力用于防止模型看到未来位置
• 编码器—解码器注意力用于关注输入序列信息
• 前馈神经网络用于进一步变换特征
在文本生成任务中,解码器必须按顺序生成 token。生成第 t 个 token 时,模型只能使用前面已经生成的 token,而不能提前看到未来答案。
因此,解码器中的自注意力通常需要使用因果掩码(Causal Mask)。
3、Transformer 的三种常见变体
虽然原始 Transformer 是编码器—解码器结构,但现代模型常见三种形式:
• Encoder-only:只使用编码器
• Decoder-only:只使用解码器
• Encoder–Decoder:编码器和解码器同时使用
图 4:Transformer 的三种常见结构形式
它们适合不同任务:
• Encoder-only:适合理解类任务,如文本分类、句子匹配、命名实体识别
• Decoder-only:适合生成类任务,如语言模型、代码生成、对话生成
• Encoder–Decoder:适合输入到输出的转换任务,如机器翻译、摘要生成
例如:
• BERT 属于典型 Encoder-only 架构
• GPT 属于典型 Decoder-only 架构
• T5 属于典型 Encoder–Decoder 架构
三、自注意力机制的基本思想
自注意力机制(Self-Attention)是 Transformer 的核心。
它的目标是:让序列中的每个位置根据需要关注序列中的其他位置,并把相关信息加权汇总起来。
假设输入序列为:
我 喜欢 深度 学习当模型处理“学习”这个词时,它可能需要关注“深度”;当处理“喜欢”时,它可能需要关注“我”和后面的内容。
自注意力机制不是固定写死哪些词重要,而是通过训练自动学习注意力权重。
可以简单理解为:
自注意力 = 对序列内部不同位置之间的相关性进行建模
1、Query、Key 和 Value
自注意力机制中,每个输入位置都会生成三个向量:
• 查询向量(Query,Q)
• 键向量(Key,K)
• 值向量(Value,V)
可以理解为:
• Query:当前位置想找什么信息
• Key:每个位置提供什么检索线索
• Value:每个位置真正提供的信息内容
对于输入表示 X,可以通过线性变换得到:
其中:
• X 表示输入序列表示矩阵
• W_Q 表示生成 Query 的权重矩阵
• W_K 表示生成 Key 的权重矩阵
• W_V 表示生成 Value 的权重矩阵
• Q、K、V 分别表示查询、键和值矩阵
图 5:自注意力机制中的 Query、Key、Value
从直观角度看:
• Q 和 K 用来计算“相关性”
• V 用来提供“被汇总的信息”
2、缩放点积注意力
Transformer 中最常用的是缩放点积注意力(Scaled Dot-Product Attention)。
它的计算过程可以分为三步:
计算相关性得分 → Softmax 转成权重 → 对 Value 加权求和
公式为:
其中:
• Q 表示查询矩阵
• K 表示键矩阵
• V 表示值矩阵
• Kᵀ 表示 K 的转置
• dₖ 表示 Key 向量维度
• √dₖ 用于缩放点积结果
• softmax 用于把相关性得分转换为注意力权重
为什么要除以 √dₖ?
当向量维度 dₖ 较大时,QKᵀ 的数值可能变大,导致 softmax 进入饱和区,使梯度变小。除以 √dₖ 可以缓解这个问题,使训练更稳定。
四、多头注意力机制
单个注意力头可以学习一种关系模式,但序列中的关系往往不止一种。
例如,在一句话中,模型可能需要同时关注:
• 主语和谓语之间的关系
• 修饰词和中心词之间的关系
• 代词和指代对象之间的关系
• 远距离语义依赖
• 局部相邻词关系
多头注意力(Multi-Head Attention)通过多个注意力头并行计算,让模型从不同子空间学习不同类型的关系。
图 6:多头注意力机制
每个注意力头可以写为:
其中:
• headᵢ 表示第 i 个注意力头
• WᵢQ、WᵢK、WᵢV 表示第 i 个头对应的投影矩阵
• Q、K、V 表示原始查询、键和值矩阵
多个注意力头的结果会拼接起来,再经过一次线性变换:
其中:
• h 表示注意力头数量
• Concat 表示拼接操作
• Wᴼ 表示输出投影矩阵
可以简单理解为:
• 单头注意力:从一个角度看序列关系
• 多头注意力:从多个角度同时看序列关系
五、位置编码:让模型知道顺序
Transformer 的自注意力机制本身并不按顺序处理 token。它可以同时看到整个序列,但这也带来一个问题:
如果不额外提供位置信息,模型并不知道哪个词在前,哪个词在后。
因此,Transformer 需要位置编码(Positional Encoding)来注入顺序信息。
图 7:位置编码如何注入顺序信息
最经典的位置编码使用正弦和余弦函数:
其中:
• pos 表示 token 在序列中的位置
• i 表示维度索引
• d_model 表示模型隐藏维度
• PE 表示位置编码
位置编码会与 token embedding 相加:
其中:
• E 表示 token embedding
• PE 表示位置编码
• X 表示加入位置信息后的输入表示
从直观角度看:
• Token Embedding 告诉模型“这个词是什么”
• Position Encoding 告诉模型“这个词在哪里”
现代 Transformer 也常使用可学习位置编码、相对位置编码、旋转位置编码等变体,但基本目标相同:让模型能够感知顺序。
六、Transformer 层的组成
一个标准 Transformer 编码器层通常由两大模块组成:
• 多头自注意力模块
• 前馈神经网络模块
并配合残差连接和层归一化。
图 8:Transformer 编码器层结构
1、多头自注意力模块
多头自注意力负责让每个位置与其他位置交互信息。
输入为 X,输出为:
其中:
• X 同时作为 Q、K、V
• Z 表示自注意力输出
• MultiHeadAttention 表示多头自注意力计算
这里写作 (X,X,X),是因为自注意力中 Query、Key、Value 都来自同一个序列。
2、残差连接与层归一化
为了稳定训练,Transformer 会使用残差连接(Residual Connection)和层归一化(Layer Normalization)。
简化写法为:
其中:
• X 表示模块输入
• Z 表示注意力模块输出
• X + Z 表示残差连接
• LayerNorm 表示层归一化
• X₁ 表示归一化后的输出
残差连接可以帮助信息和梯度更顺畅地传递,层归一化可以让训练更加稳定。
3、前馈神经网络模块
Transformer 中的前馈神经网络通常是逐位置应用的多层感知机。
可以写为:
其中:
• x 表示某个位置的表示
• W₁、W₂ 表示两层线性变换的权重
• b₁、b₂ 表示偏置
• σ 表示非线性激活函数,例如 ReLU 或 GELU
• FFN 表示前馈神经网络模块
注意,FFN 是对每个位置独立应用的。它不会直接混合不同位置的信息;不同位置之间的信息交互主要由注意力机制完成。
4、完整编码器层
一个简化的 Transformer 编码器层可以写成:
其中:
• X 表示输入表示
• X₁ 表示经过注意力模块后的中间表示
• Y 表示编码器层输出
• MultiHeadAttention 表示多头自注意力
• FFN 表示前馈神经网络模块
多个编码器层堆叠后,就形成了 Transformer 编码器。
七、PyTorch 实现:使用 Transformer 做文本分类
下面使用 PyTorch 构建一个简化版 Transformer 文本分类模型。为了突出 Transformer 的基本结构,示例使用小型中文样例数据集,按字符级别建模,完成正面 / 负面情感分类。
图 9:Transformer 文本分类的训练与预测流程
这个示例的目标不是训练高性能中文情感分析模型,而是帮助理解:
文本编号 → 嵌入表示 → 位置编码 → Transformer 编码器 → 分类输出
1、导入库
import mathimport torchimport torch.nn as nn from torch.utils.data import Dataset, DataLoader这里使用:
• math 用于计算位置编码
• torch 构建张量与训练流程
• torch.nn 定义神经网络层
• Dataset 和 DataLoader 构建数据集与批量读取
2、准备样例数据
samples = [ ("这部电影很好看", 1), ("演员表演非常精彩", 1), ("剧情紧凑我很喜欢", 1), ("这家餐厅味道不错", 1), ("服务态度很好", 1), ("这部电影太难看了", 0), ("剧情拖沓让人失望", 0), ("演员表演很糟糕", 0), ("这家餐厅味道很差", 0), ("服务态度不好", 0),]其中:
• 标签 1 表示正面情感
• 标签 0 表示负面情感
为了简化实现,这里按字符构建词表。真实任务中通常会使用分词器、子词编码、预训练词向量或预训练大模型。
3、构建字符表与编码函数
# 构建字符表:将所有文本中的字符去重并排序chars = sorted(set("".join(text for text, _ in samples))) # 创建字符到ID的映射(从1开始,0留给填充符)char_to_id = {char: idx + 1 for idx, char in enumerate(chars)} # 填充符ID为0pad_id = 0 # 编码函数:将文本字符串转换为对应ID列表def encode_text(text): return [char_to_id[char] for char in text]其中:
• char_to_id 用于把字符映射为整数编号
• pad_id=0 表示填充符
• encode_text() 用于把文本转换为编号序列
4、定义数据集与批处理函数
# 定义情感分析数据集类class SentimentDataset(Dataset): def __init__(self, samples): self.samples = samples # 存储 (文本, 标签) 样本列表 def __len__(self): return len(self.samples) # 返回数据集大小 def __getitem__(self, index): text, label = self.samples[index] # 获取样本 ids = encode_text(text) # 文本转ID序列 return ( torch.tensor(ids, dtype=torch.long), # ID序列张量 torch.tensor(label, dtype=torch.long) # 标签张量 ) # 自定义批处理函数:将同一batch中的序列填充到相同长度def collate_fn(batch): sequences, labels = zip(*batch) # 分离ID序列和标签 lengths = [len(seq) for seq in sequences] max_len = max(lengths) # 当前batch中最大序列长度 # 创建填充后的张量,初始全为pad_id padded = torch.full( size=(len(sequences), max_len), fill_value=pad_id, dtype=torch.long ) # 将每个序列填充到相应位置 for i, seq in enumerate(sequences): padded[i, :len(seq)] = seq labels = torch.stack(labels) # 堆叠标签为张量 return padded, labels其中:
• SentimentDataset 定义单个样本的读取方式
• collate_fn 用于把不同长度句子填充到同一长度
• padded 的形状为 batch_size × sequence_length
• labels 的形状为 batch_size
构建 DataLoader:
# 创建情感分析数据集实例dataset = SentimentDataset(samples) # 创建数据加载器:每批4个样本,打乱顺序,使用自定义的填充函数train_loader = DataLoader( dataset, batch_size=4, shuffle=True, collate_fn=collate_fn)5、定义位置编码
下面实现经典正弦—余弦位置编码。
# 位置编码(Transformer 中用于注入序列位置信息)class PositionalEncoding(nn.Module): def __init__(self, d_model, max_len=100): super().__init__() # 初始化位置编码矩阵 (max_len, d_model) pe = torch.zeros(max_len, d_model) # 位置索引 (0,1,2,...,max_len-1),形状 (max_len,1) position = torch.arange(0, max_len, dtype=torch.float32).unsqueeze(1) # 计算分母项:10000^(2i/d_model) 的倒数,即 exp(-(2i/d_model)*ln(10000)) # 对偶数维使用 sin,奇数维使用 cos div_term = torch.exp( torch.arange(0, d_model, 2, dtype=torch.float32) * (-math.log(10000.0) / d_model) ) # 填充偶数索引列(0,2,4,...)用 sin pe[:, 0::2] = torch.sin(position * div_term) # 填充奇数索引列(1,3,5,...)用 cos pe[:, 1::2] = torch.cos(position * div_term) # 增加 batch 维度:形状 (1, max_len, d_model) pe = pe.unsqueeze(0) # 注册为缓冲区(不参与梯度更新,但随模型保存和移动) self.register_buffer("pe", pe) def forward(self, x): # x: (batch, seq_len, d_model) seq_len = x.size(1) # 添加位置编码(截取前 seq_len 个位置) return x + self.pe[:, :seq_len, :]其中:
• d_model 表示 embedding 维度
• max_len 表示最大序列长度
• pe 保存不同位置的位置编码
• register_buffer() 表示 pe 不是可训练参数,但会随模型一起保存和移动设备
• x 的形状为 batch_size × sequence_length × d_model
6、定义 Transformer 文本分类模型
# 基于 Transformer 编码器的文本分类器class TransformerTextClassifier(nn.Module): def __init__( self, vocab_size, # 词汇表大小 d_model=32, # 嵌入和 Transformer 隐藏维度 nhead=4, # 多头注意力头数 num_layers=2, # 编码器层数 dim_feedforward=64, # 前馈网络维度 num_classes=2, # 分类类别数 max_len=100 # 最大序列长度(位置编码) ): super().__init__() # 词嵌入层:padding_idx=0 的 token 向量不参与训练 self.embedding = nn.Embedding( num_embeddings=vocab_size, embedding_dim=d_model, padding_idx=pad_id ) # 位置编码层 self.pos_encoding = PositionalEncoding(d_model=d_model, max_len=max_len) # Transformer 编码器层配置 encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, nhead=nhead, dim_feedforward=dim_feedforward, batch_first=True # 输入形状为 (batch, seq, feature) ) # 堆叠多层编码器 self.encoder = nn.TransformerEncoder( encoder_layer=encoder_layer, num_layers=num_layers ) # 分类头:将池化后的向量映射到类别 logits self.classifier = nn.Linear(d_model, num_classes) def forward(self, x): # x: (batch, seq_len) token ID 序列 padding_mask = (x == pad_id) # 标记 padding 位置为 True # 词嵌入 + 位置编码 x = self.embedding(x) # (batch, seq_len, d_model) x = self.pos_encoding(x) # Transformer 编码器(自动使用 padding_mask 忽略填充位置) encoded = self.encoder( x, src_key_padding_mask=padding_mask # 形状 (batch, seq_len) ) # 输出 (batch, seq_len, d_model) # 计算有效 token 的平均值(忽略 padding) valid_mask = ~padding_mask # (batch, seq_len) valid_mask = valid_mask.unsqueeze(-1) # (batch, seq_len, 1) pooled = (encoded * valid_mask).sum(dim=1) / valid_mask.sum(dim=1) # (batch, d_model) # 分类输出 logits = self.classifier(pooled) # (batch, num_classes) return logits这个模型结构可以概括为:
字符编号→ Embedding→ 位置编码→ TransformerEncoder→ 平均池化→ Linear 分类其中:
• Embedding 把字符编号转换为向量
• 位置编码提供顺序信息
• TransformerEncoder 建模上下文关系
• padding_mask 避免模型把填充符当作有效字符
• 平均池化把序列表示汇总为句子表示
• Linear 输出分类 logits
需要注意,这里是 Encoder-only 结构,适合文本分类这类理解任务。
7、创建模型、损失函数和优化器
# 词汇表大小 = 字符映射数 + 1(因为 char_to_id 从 1 开始,pad_id=0)vocab_size = len(char_to_id) + 1 # 实例化 Transformer 文本分类器模型model = TransformerTextClassifier( vocab_size=vocab_size, # 词汇表大小 d_model=32, # 嵌入和 Transformer 隐藏维度 nhead=4, # 注意力头数 num_layers=2, # Transformer 编码器层数 dim_feedforward=64, # 前馈网络内部维度 num_classes=2, # 输出类别数(正面/负面) max_len=100 # 最大序列长度(位置编码)) # 交叉熵损失函数(适用于多分类)criterion = nn.CrossEntropyLoss()# Adam 优化器,学习率 0.001,优化模型所有参数optimizer = torch.optim.Adam(model.parameters(), lr=0.001)其中:
• vocab_size 表示词表大小
• d_model=32 表示向量维度
• nhead=4 表示使用 4 个注意力头
• num_layers=2 表示堆叠 2 个编码器层
• num_classes=2 表示二分类
• CrossEntropyLoss 用于分类任务
• Adam 用于参数更新
模型最后输出 logits,不需要手动添加 Softmax。
8、训练模型
num_epochs = 30 # 训练轮数 for epoch in range(num_epochs): model.train() # 设置为训练模式 total_loss = 0.0 # 累计损失 # 遍历训练数据加载器 for batch_x, batch_y in train_loader: logits = model(batch_x) # 前向传播,得到预测 logits loss = criterion(logits, batch_y) # 计算交叉熵损失 optimizer.zero_grad() # 清空旧梯度 loss.backward() # 反向传播 optimizer.step() # 更新参数 total_loss += loss.item() * batch_x.size(0) # 累加本批次损失(加权) # 计算本轮平均损失 avg_loss = total_loss / len(dataset) # 每 10 轮输出一次平均损失 if (epoch + 1) % 10 == 0: print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {avg_loss:.4f}")训练过程仍然遵循深度学习的标准闭环:
前向传播 → 计算损失 → 清空旧梯度 → 反向传播 → 参数更新
其中:
• model(batch_x) 表示前向传播
• criterion(logits,batch_y) 表示计算分类损失
• optimizer.zero_grad() 清空旧梯度
• loss.backward() 计算梯度
• optimizer.step() 更新参数
9、预测新句子
def predict_sentiment(text): """预测单条文本的情感(正面/负面)""" model.eval() # 切换到评估模式 # 将文本编码为ID张量,并添加batch维度(形状: 1, seq_len) ids = torch.tensor( encode_text(text), dtype=torch.long ).unsqueeze(0) with torch.no_grad(): # 禁用梯度计算 logits = model(ids) # 模型前向传播,得到logits pred = logits.argmax(dim=1).item() # 取概率最大类别的索引 return "正面" if pred == 1 else "负面" # 1->正面, 0->负面测试预测:
print(predict_sentiment("电影非常精彩"))print(predict_sentiment("服务太差了"))可能输出:
正面负面由于这里的数据集很小,模型只是演示 Transformer 的基本流程,不能代表真实中文情感分析系统的效果。真实任务通常需要更大规模数据、更稳定的训练策略,以及预训练模型。
10、查看张量形状
可以打印一个批次的形状,帮助理解 Transformer 的输入输出。
# 取一个批次数据,用于观察中间张量形状batch_x, batch_y = next(iter(train_loader)) # 通过模型的嵌入层embedded = model.embedding(batch_x) # (batch, seq_len, d_model)# 添加位置编码encoded_input = model.pos_encoding(embedded) # 形状不变 print("输入编号形状:", batch_x.shape) # (batch, seq_len)print("嵌入后形状:", embedded.shape) # (batch, seq_len, d_model)print("加入位置编码后形状:", encoded_input.shape) # 与 embedding 形状相同 # 直接通过完整模型前向传播得到 logitswith torch.no_grad(): logits = model(batch_x) # (batch, num_classes) print("输出 logits 形状:", logits.shape) # (batch, 2)可能看到类似结果:
输入编号形状: torch.Size([4, 8])嵌入后形状: torch.Size([4, 8, 32])加入位置编码后形状: torch.Size([4, 8, 32])输出 logits 形状: torch.Size([4, 2])其中:
• 4 表示 batch_size
• 8 表示当前批次填充后的序列长度
• 32 表示 d_model
• 2 表示两个类别的 logits
八、Transformer 的适用场景、局限与扩展方向
Transformer 是当前深度学习中最重要的通用结构之一。它不只用于自然语言处理,也广泛应用于视觉、多模态、语音、代码和科学计算等领域。
图 10:Transformer 的适用场景、局限与扩展方向
1、适用场景
Transformer 常用于:
• 文本分类
• 机器翻译
• 文本摘要
• 对话生成
• 代码生成
• 图像分类
• 图像生成
• 语音识别
• 多模态理解与生成
其中,大语言模型和多模态模型大多以 Transformer 或其变体为基础。
2、主要优势
Transformer 的主要优势包括:
• 能直接建模长距离依赖
• 更适合并行计算
• 注意力机制可动态选择重要信息
• 可扩展到大规模数据和模型
• 适合文本、图像、语音和多模态任务
• 已成为现代大模型的重要基础结构
与 RNN 相比,Transformer 不需要逐时间步递归计算,因此在大规模训练中更具优势。
3、主要局限
Transformer 也有明显局限:
• 自注意力计算成本随序列长度快速增长
• 长文本处理需要较大显存和计算资源
• 大模型训练成本很高
• 对数据规模和工程系统依赖较强
• 注意力权重并不总能直接解释模型决策
• 生成模型可能出现幻觉、偏见和安全问题
标准自注意力的计算复杂度通常与序列长度平方相关。若序列长度为 n,注意力矩阵大小约为:
因此,长序列建模是 Transformer 的重要挑战之一。
4、扩展方向
从基础 Transformer 出发,可以继续学习:
• BERT:编码器结构,适合理解任务
• GPT:解码器结构,适合生成任务
• T5:编码器—解码器结构,适合文本到文本任务
• Vision Transformer:将 Transformer 用于图像任务
• Swin Transformer:使用窗口注意力改进视觉建模
• Longformer:面向长文本的稀疏注意力结构
• Transformer-XL:改进长距离上下文建模
• MoE Transformer:使用专家混合机制扩展模型容量
这些结构虽然形式不同,但都围绕一个核心问题展开:如何更高效、更稳定、更可控地建模大规模上下文关系?
📘 小结
Transformer 通过自注意力机制直接建模序列中不同位置之间的关系,并通过多头注意力、位置编码、前馈网络、残差连接和层归一化构成可扩展的深度网络结构。它突破了 RNN 顺序计算的限制,成为大语言模型、多模态模型和现代深度学习系统的重要基础。
“点赞有美意,赞赏是鼓励”
