核心代码段:
def __init__(self, enc_voc_size, max_len, d_model, ffn_hidden, n_head, n_layers, drop_prob, device):
super().__init__()
self.emb = TransformerEmbedding(
d_model=d_model,
max_len=max_len,
vocab_size=enc_voc_size,
drop_prob=drop_prob,
device=device)
self.layers = nn.ModuleList([EncoderLayer(
d_model=d_model,
ffn_hidden=ffn_hidden,
n_head=n_head,
drop_prob=drop_prob)
for _ in range(n_layers)])
参数名 | 类型 | 作用域 | 典型值示例 | 数学意义 |
---|---|---|---|---|
enc_voc_size | int | 词嵌入层 | 5000 | 源语言词汇表维度 |
max_len | int | 位置编码 | 512 | 最大序列长度 |
d_model | int | 全模块 | 768 | 隐藏层维度空间 |
ffn_hidden | int | 前馈网络 | 3072 | 膨胀系数(通常4倍d_model) |
n_head | int | 注意力机制 | 12 | 并行注意力头数 |
n_layers | int | 编码器堆叠 | 6 | 深度网络层次 |
drop_prob | float | 正则化 | 0.1 | 神经元失活概率 |
device | str | 计算设备 | “cuda:0” | 张量运算载体 |
假设输入序列:
x = torch.randint(0, 5000, (32, 10)) # shape: [32,10]
src_mask = None
# 经过词嵌入层后
emb_out = self.emb(x) # shape: [32,10,768]
# 首层编码器处理
layer1_out = self.layers # shape保持[32,10,768]
def forward(self, x, src_mask):
x = self.emb(x) # 嵌入层融合
# 层次处理循环
for layer in self.layers:
x = layer(x, src_mask) # 特征空间变换
return x # 上下文感知表示
运算过程数学表达:
设第 l l l层处理函数为 E l E_l El,则整体编码过程可表示为:
h 0 = Embedding ( x ) + PositionalEncoding ( x ) h l = E l ( h l − 1 , M s r c ) , l = 1 , 2 , . . . , L Output = h L \begin{aligned} h_0 &= \text{Embedding}(x) + \text{PositionalEncoding}(x) \\ h_l &= E_l(h_{l-1}, M_{src}), \quad l=1,2,...,L \\ \text{Output} &= h_L \end{aligned} h0hlOutput=Embedding(x)+PositionalEncoding(x)=El(hl−1,Msrc),l=1,2,...,L=hL
其中 M s r c M_{src} Msrc为源序列掩码矩阵。
跳转到章节: 词元嵌入
每个EncoderLayer包含:
1. 多头自注意力机制
2. 残差连接+层归一化
3. 位置前馈网络
4. 二次残差连接+归一化
跳转到章节: 编码层解析
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
encoder = Encoder(...).to(device)
场景 | 配置参数示例 | 硬件要求 |
---|---|---|
机器翻译 | d_model=512, n_layers=6 | 16GB GPU |
文本摘要 | ffn_hidden=2048, n_head=8 | 24GB GPU |
语音识别 | max_len=3000 | 特殊硬件加速 |
1. 混合精度训练: 使用torch.cuda.amp
自动类型转换
2. 激活检查点: 通过torch.utils.checkpoint
节省显存
3. 内核融合: 使用PyTorch JIT编译优化计算图
4. 流水线并行: 当n_layers>12时建议分层部署
"""
@author : Hyunwoong
@when : 2019-12-18
@homepage : https://github.com/gusdnd852
"""
from torch import nn
# 从其他模块导入EncoderLayer和TransformerEmbedding类
from models.blocks.encoder_layer import EncoderLayer
from models.embedding.transformer_embedding import TransformerEmbedding
# 定义一个名为Encoder的类,它继承自nn.Module,用于实现Transformer模型的编码器部分
class Encoder(nn.Module):
def __init__(self, enc_voc_size, max_len, d_model, ffn_hidden, n_head, n_layers, drop_prob, device):
# 调用父类nn.Module的构造函数
super().__init__()
# 初始化词嵌入层,用于将输入序列转换为向量表示
self.emb = TransformerEmbedding(d_model=d_model, # 向量维度
max_len=max_len, # 序列最大长度
vocab_size=enc_voc_size, # 词汇表大小
drop_prob=drop_prob, # Dropout概率
device=device) # 设备配置(CPU或GPU)
# 初始化编码器层列表,包含多个EncoderLayer实例
self.layers = nn.ModuleList([EncoderLayer(d_model=d_model, # 向量维度
ffn_hidden=ffn_hidden, # 前馈神经网络隐藏层维度
n_head=n_head, # 多头注意力头数
drop_prob=drop_prob) # Dropout概率
for _ in range(n_layers)]) # 编码器层数
def forward(self, x, src_mask):
# 将输入序列x通过词嵌入层转换为向量表示
x = self.emb(x)
# 遍历编码器层列表,将向量表示x和源序列掩码src_mask依次通过每个编码器层
for layer in self.layers:
x = layer(x, src_mask)
# 返回经过编码器处理后的向量表示x
return x
参考: 项目代码