🔄 Transformer架构深度解析

从注意力机制到源码实现

源码级别解析 · 源码解析 · AI基础架构
2026-04-25 | 每日技术深度解读

目录

本次演讲内容概览
  • Transformer背景与意义
  • 注意力机制详解
  • Encoder-Decoder架构
  • 源码级组件实现
  • 多模态扩展
  • 实践应用案例
  • 未来发展趋势

Transformer的诞生背景

2017年革命性突破
  • 传统序列模型:RNN/LSTM的局限性
  • 并行化计算需求
  • 长距离依赖问题
  • 注意力机制的成熟

Vaswani et al. "Attention Is All You Need" (2017)

Transformer的颠覆性意义

改变AI架构范式
  • 完全基于注意力机制
  • 摒弃循环和卷积
  • 优秀的并行化能力
  • 成为现代AI的基础架构

BERT、GPT、T5等模型的基石

Transformer核心优势

相比传统模型的优势
  • 🚀 训练效率:GPU并行计算
  • 🔍 上下文理解:全局注意力
  • ⚡ 推理速度:固定复杂度O(1)
  • 🎯 可扩展性:堆叠层数

Transformer整体架构

import torch
import torch.nn as nn
import torch.nn.functional as F

class Transformer(nn.Module):
    def __init__(self, src_vocab_size, tgt_vocab_size, d_model, nhead, 
                 num_encoder_layers, num_decoder_layers, dim_feedforward, dropout):
        super().__init__()
        
        # 词嵌入和位置编码
        self.src_embedding = nn.Embedding(src_vocab_size, d_model)
        self.tgt_embedding = nn.Embedding(tgt_vocab_size, d_model)
        self.positional_encoding = PositionalEncoding(d_model, dropout)
        
        # Transformer编码器和解码器
        encoder_layer = nn.TransformerEncoderLayer(
            d_model, nhead, dim_feedforward, dropout, batch_first=True)
        decoder_layer = nn.TransformerDecoderLayer(
            d_model, nhead, dim_feedforward, dropout, batch_first=True)
            
        self.encoder = nn.TransformerEncoder(encoder_layer, num_encoder_layers)
        self.decoder = nn.TransformerDecoder(decoder_layer, num_decoder_layers)
        
        # 输出层
        self.generator = nn.Linear(d_model, tgt_vocab_size)
        
    def forward(self, src, tgt, src_mask=None, tgt_mask=None):
        # 词嵌入 + 位置编码
        src_emb = self.positional_encoding(self.src_embedding(src))
        tgt_emb = self.positional_encoding(self.tgt_embedding(tgt))
        
        # 编码器-解码器
        memory = self.encoder(src_emb, src_mask)
        output = self.decoder(tgt_emb, memory, tgt_mask, src_mask)
        
        return self.generator(output)

完整的Transformer模型架构实现

注意力机制:Transformer的核心

模型的核心创新
  • 📋 Query-Key-Value机制
  • 🎯 点积注意力计算
  • 🔄 缩放点积注意力
  • 🔗 多头注意力并行

缩放点积注意力实现

def scaled_dot_product_attention(q, k, v, mask=None):
    """
    缩放点积注意力机制
    
    Args:
        q: Query矩阵 [batch_size, seq_len, d_k]
        k: Key矩阵 [batch_size, seq_len, d_k] 
        v: Value矩阵 [batch_size, seq_len, d_v]
        mask: 可选的掩码矩阵
    
    Returns:
        attention_output: 注意力输出 [batch_size, seq_len, d_v]
        attention_weights: 注意力权重 [batch_size, seq_len, seq_len]
    """
    d_k = q.size(-1)
    
    # 计算注意力分数 (Q * K^T) / sqrt(d_k)
    scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(d_k)
    
    # 应用掩码(如果存在)
    if mask is not None:
        scores = scores.masked_fill(mask == 0, -1e9)
    
    # Softmax归一化
    attention_weights = F.softmax(scores, dim=-1)
    
    # 加权求和
    output = torch.matmul(attention_weights, v)
    
    return output, attention_weights

注意力机制的核心数学实现

注意力机制的数学原理

数学公式与直觉理解
  • 🔢 注意力分数 = Q · K^T / √d_k
  • 🎯 软最大归一化:exp(score) / Σexp(score)
  • 📊 注意力权重:0-1之间,和为1
  • ⚡ 缩放因子:防止梯度消失

注意力机制可视化

Query (Q) Key (K) Value (V) │ │ │ ▼ ▼ ▼ [单词1, 单词2, ..., 单词n] [单词1, 单词2, ..., 单词n] [单词1, 单词2, ..., 单词n] │ │ │ └─────── Q·K^T ────────┘ │ ▼ [注意力分数矩阵] │ ▼ Softmax │ ▼ [注意力权重矩阵] │ └───────·V ────────► [上下文向量]

注意力机制的完整流程图

多头注意力机制

并行化的注意力
  • 🔄 多个注意力头并行计算
  • 🎯 每个头学习不同的关系模式
  • 📊 拼接后线性变换
  • 🔥 提升模型表达能力

多头注意力实现

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, nhead, dropout=0.1):
        super().__init__()
        assert d_model % nhead == 0, "d_model must be divisible by nhead"
        
        self.d_model = d_model
        self.nhead = nhead
        self.d_k = d_model // nhead
        self.d_v = d_model // nhead
        
        # 线性变换层
        self.w_q = nn.Linear(d_model, d_model)
        self.w_k = nn.Linear(d_model, d_model)
        self.w_v = nn.Linear(d_model, d_model)
        self.w_o = nn.Linear(d_model, d_model)
        
        self.dropout = nn.Dropout(dropout)
        
    def forward(self, query, key, value, mask=None):
        batch_size = query.size(0)
        
        # 线性变换
        Q = self.w_q(query).view(batch_size, -1, self.nhead, self.d_k).transpose(1, 2)
        K = self.w_k(key).view(batch_size, -1, self.nhead, self.d_k).transpose(1, 2)
        V = self.w_v(value).view(batch_size, -1, self.nhead, self.d_v).transpose(1, 2)
        
        # 计算多头注意力
        attn_output, attn_weights = scaled_dot_product_attention(Q, K, V, mask)
        
        # 拼接多头结果
        attn_output = attn_output.transpose(1, 2).contiguous().view(
            batch_size, -1, self.d_model)
        
        # 最终线性变换
        output = self.w_o(attn_output)
        
        return output, attn_weights

完整的多头注意力模块实现

位置编码:注入时序信息

解决序列顺序问题
  • 🔢 正弦-余弦编码公式
  • ⏰ 绝对位置信息
  • 🔄 相对位置感知
  • 📏 可学习位置编码

位置编码实现

class PositionalEncoding(nn.Module):
    def __init__(self, d_model, max_len=5000, dropout=0.1):
        super().__init__()
        self.dropout = nn.Dropout(dropout)
        
        # 创建位置编码矩阵
        position = torch.arange(max_len).unsqueeze(1)
        div_term = torch.exp(torch.arange(0, d_model, 2) * 
                           (-math.log(10000.0) / d_model))
        
        pe = torch.zeros(max_len, d_model)
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        
        # 增加batch维度
        self.register_buffer('pe', pe.unsqueeze(0))
        
    def forward(self, x):
        """
        Args:
            x: Tensor, shape [batch_size, seq_len, d_model]
        """
        x = x + self.pe[:, :x.size(1)]
        return self.dropout(x)

正弦-余弦位置编码的实现

位置编码的数学原理

Sinusoidal编码公式
  • 📐 偶数位置:sin(pos / 10000^(2i/d_model))
  • 📐 奇数位置:cos(pos / 10000^(2i/d_model))
  • 🎯 频率随维度增加而降低
  • ⚡ 线性变换保持相对位置关系

Encoder层结构

编码器的核心组件
  • 🔄 多头自注意力层
  • 📊 前馈神经网络
  • 🔗 残差连接
  • ⚡ 层归一化

Encoder层实现

class EncoderLayer(nn.Module):
    def __init__(self, d_model, nhead, dim_feedforward, dropout=0.1):
        super().__init__()
        
        # 多头自注意力
        self.self_attn = MultiHeadAttention(d_model, nhead, dropout)
        
        # 前馈神经网络
        self.linear1 = nn.Linear(d_model, dim_feedforward)
        self.dropout = nn.Dropout(dropout)
        self.linear2 = nn.Linear(dim_feedforward, d_model)
        
        # 层归一化
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        
        # Dropout
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)
        
    def forward(self, src, src_mask=None):
        # 自注意力 + 残差连接 + 层归一化
        src2 = self.self_attn(src, src, src, src_mask)[0]
        src = src + self.dropout1(src2)
        src = self.norm1(src)
        
        # 前馈网络 + 残差连接 + 层归一化
        src2 = self.linear2(self.dropout(F.relu(self.linear1(src))))
        src = src + self.dropout2(src2)
        src = self.norm2(src)
        
        return src

Encoder层的标准实现

残差连接与层归一化

训练稳定性的关键
  • 🔗 残差连接:y = x + F(x)
  • ⚡ 梯度流动优化
  • 📊 层归一化:均值为0,方差为1
  • 🎯 缓解梯度消失/爆炸

Decoder层结构

解码器的独特设计
  • 🔍 掩码自注意力(防止信息泄漏)
  • 🔄 编码器-解码器注意力
  • 📊 前馈神经网络
  • 🔗 残差连接+层归一化

Decoder层实现

class DecoderLayer(nn.Module):
    def __init__(self, d_model, nhead, dim_feedforward, dropout=0.1):
        super().__init__()
        
        # 掩码自注意力
        self.self_attn = MultiHeadAttention(d_model, nhead, dropout)
        # 编码器-解码器注意力
        self.multihead_attn = MultiHeadAttention(d_model, nhead, dropout)
        
        # 前馈网络
        self.linear1 = nn.Linear(d_model, dim_feedforward)
        self.dropout = nn.Dropout(dropout)
        self.linear2 = nn.Linear(dim_feedforward, d_model)
        
        # 层归一化
        self.norm1 = nn.LayerNorm(d_model)
        self.norm2 = nn.LayerNorm(d_model)
        self.norm3 = nn.LayerNorm(d_model)
        
        # Dropout
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)
        self.dropout3 = nn.Dropout(dropout)
        
    def forward(self, tgt, memory, tgt_mask=None, memory_mask=None):
        # 掩码自注意力
        tgt2 = self.self_attn(tgt, tgt, tgt, tgt_mask)[0]
        tgt = tgt + self.dropout1(tgt2)
        tgt = self.norm1(tgt)
        
        # 编码器-解码器注意力
        tgt2 = self.multihead_attn(tgt, memory, memory, memory_mask)[0]
        tgt = tgt + self.dropout2(tgt2)
        tgt = self.norm2(tgt)
        
        # 前馈网络
        tgt2 = self.linear2(self.dropout(F.relu(self.linear1(tgt))))
        tgt = tgt + self.dropout3(tgt2)
        tgt = self.norm3(tgt)
        
        return tgt

Decoder层的完整实现

掩码机制的重要性

防止信息泄漏
  • 🚫 解码器不能看到未来信息
  • 🔍 掩码自注意力:只允许关注当前位置及之前
  • 🎯 因果关系保持
  • 📊 下三角掩码矩阵

掩码生成函数

def generate_square_subsequent_mask(sz):
    """
    生成下三角掩码矩阵
    
    Args:
        sz: 序列长度
    
    Returns:
        mask: 下三角掩码矩阵 [sz, sz]
    """
    mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)
    mask = mask.float().masked_fill(mask == 0, float('-inf'))
    mask = mask.masked_fill(mask == float(1), float(0.0))
    return mask

def create_padding_mask(seq, pad_idx=0):
    """
    创建填充位置掩码
    
    Args:
        seq: 输入序列 [batch_size, seq_len]
        pad_idx: 填充token的索引
    
    Returns:
        mask: 填充掩码 [batch_size, 1, 1, seq_len]
    """
    return (seq == pad_idx).unsqueeze(1).unsqueeze(2)

两种掩码的生成方法

前馈神经网络

位置独立的特征提取
  • 📊 两个线性层 + ReLU激活
  • ⚡ 扩展维度:d_model → d_ff → d_model
  • 🎯 每个token独立处理
  • 🔄 可学习的非线性变换

前馈网络实现

class FeedForward(nn.Module):
    def __init__(self, d_model, dim_feedforward, dropout=0.1):
        super().__init__()
        
        # 线性层扩展
        self.linear1 = nn.Linear(d_model, dim_feedforward)
        self.dropout = nn.Dropout(dropout)
        self.linear2 = nn.Linear(dim_feedforward, d_model)
        
    def forward(self, x):
        """
        前向传播
        
        Args:
            x: 输入张量 [batch_size, seq_len, d_model]
        
        Returns:
            输出张量 [batch_size, seq_len, d_model]
        """
        # 线性变换 → ReLU → Dropout → 线性变换
        return self.linear2(self.dropout(F.relu(self.linear1(x))))

标准前馈网络实现

层归一化详解

训练稳定的技术
  • 📊 均值归一化:μ = E[x]
  • 📊 方差归一化:σ² = E[(x-μ)²]
  • ⚡ y = (x - μ) / √(σ² + ε) * γ + β
  • 🎯 可学习的缩放和平移参数

层归一化实现

class LayerNorm(nn.Module):
    def __init__(self, d_model, eps=1e-6):
        super().__init__()
        self.eps = eps  # 数值稳定性
        self.gamma = nn.Parameter(torch.ones(d_model))  # 缩放参数
        self.beta = nn.Parameter(torch.zeros(d_model))   # 平移参数
        
    def forward(self, x):
        """
        层归一化前向传播
        
        Args:
            x: 输入张量 [batch_size, seq_len, d_model]
        
        Returns:
            归一化后的张量
        """
        mean = x.mean(-1, keepdim=True)  # 计算均值
        std = x.std(-1, keepdim=True)   # 计算标准差
        
        # 归一化
        x_norm = (x - mean) / (std + self.eps)
        
        # 缩放和平移
        return self.gamma * x_norm + self.beta

LayerNorm的数学实现

完整的Encoder堆叠

多层编码器架构
  • 📊 N个相同的Encoder层堆叠
  • 🔄 每层包含自注意力+前馈网络
  • 🔗 残差连接保持梯度流动
  • ⚡ 深度网络的信息传递

完整Encoder实现

class TransformerEncoder(nn.Module):
    def __init__(self, encoder_layer, num_layers, norm=None):
        super().__init__()
        self.layers = nn.ModuleList([copy.deepcopy(encoder_layer) for _ in range(num_layers)])
        self.num_layers = num_layers
        self.norm = norm
        
    def forward(self, src, src_mask=None):
        """
        前向传播
        
        Args:
            src: 输入序列 [batch_size, seq_len, d_model]
            src_mask: 源序列掩码
        
        Returns:
            编码器输出 [batch_size, seq_len, d_model]
        """
        output = src
        
        # 逐层通过Encoder层
        for layer in self.layers:
            output = layer(output, src_mask)
            
        # 最终层归一化(如果存在)
        if self.norm is not None:
            output = self.norm(output)
            
        return output

完整Encoder的堆叠实现

完整的Decoder堆叠

多层解码器架构
  • 📊 N个相同的Decoder层堆叠
  • 🔍 每层包含掩码自注意力+编码器-解码器注意力+前馈网络
  • 🎯 逐步构建上下文信息
  • ⚡ 深度序列建模

完整Decoder实现

class TransformerDecoder(nn.Module):
    def __init__(self, decoder_layer, num_layers, norm=None):
        super().__init__()
        self.layers = nn.ModuleList([copy.deepcopy(decoder_layer) for _ in range(num_layers)])
        self.num_layers = num_layers
        self.norm = norm
        
    def forward(self, tgt, memory, tgt_mask=None, memory_mask=None):
        """
        前向传播
        
        Args:
            tgt: 目标序列 [batch_size, seq_len, d_model]
            memory: 编码器输出 [batch_size, src_len, d_model]
            tgt_mask: 目标序列掩码
            memory_mask: 编码器掩码
        
        Returns:
            解码器输出 [batch_size, seq_len, d_model]
        """
        output = tgt
        
        # 逐层通过Decoder层
        for layer in self.layers:
            output = layer(output, memory, tgt_mask, memory_mask)
            
        # 最终层归一化(如果存在)
        if self.norm is not None:
            output = self.norm(output)
            
        return output

完整Decoder的堆叠实现

词嵌入与位置编码的组合

输入表示的构建
  • 📊 词嵌入:语义信息表示
  • ⏰ 位置编码:时序信息注入
  • ➕ 相加组合:保持信息完整性
  • 🎯 d维向量表示序列信息

嵌入层实现

class EmbeddingWithPositional(nn.Module):
    def __init__(self, vocab_size, d_model, max_len=5000, dropout=0.1):
        super().__init__()
        
        # 词嵌入层
        self.embedding = nn.Embedding(vocab_size, d_model)
        
        # 位置编码
        self.positional_encoding = PositionalEncoding(d_model, max_len, dropout)
        
        # 初始化权重
        self._init_weights()
        
    def _init_weights(self):
        """
        初始化权重
        """
        # 初始化词嵌入权重
        nn.init.normal_(self.embedding.weight, mean=0, std=self.embedding.embedding_dim**-0.5)
        
        # 初始化位置编码权重
        # 使用相同的初始化策略
        pe_weight = self.positional_encoding.pe.squeeze(0)
        nn.init.normal_(pe_weight, mean=0, std=1.0)
        
    def forward(self, x):
        """
        前向传播
        
        Args:
            x: 输入token序列 [batch_size, seq_len]
        
        Returns:
            嵌入+位置编码后的表示 [batch_size, seq_len, d_model]
        """
        # 词嵌入
        embedded = self.embedding(x) * math.sqrt(self.embedding.embedding_dim)
        
        # 添加位置编码
        return self.positional_encoding(embedded)

词嵌入与位置编码的组合实现

Transformer的超参数选择

模型配置的关键
  • 📊 d_model:隐藏层维度(512, 768, 1024)
  • 🎯 nhead:注意力头数(通常为d_model的因数)
  • 📏 num_layers:层数(6, 12, 24)
  • ⚡ dim_feedforward:前馈网络扩展维度(4×d_model)

不同规模Transformer配置

模型规模d_modelnheadnum_layersdim_feedforward参数量
小型51286204886M
中型76812123072345M
大型1024162440961.1B
超大型20483248819210.5B

计算复杂度分析

性能与资源需求
  • 📊 注意力复杂度:O(n²·d)
  • ⚡ 前馈网络:O(n·d²)
  • 💾 内存占用:O(n²·d)
  • 🎯 实时推理:固定延迟O(1)

复杂度计算函数

def calculate_transformer_complexity(config):
    """
    计算Transformer的计算复杂度和参数量
    
    Args:
        config: 配置字典
    
    Returns:
        complexity_dict: 复杂度信息
    """
    d_model = config['d_model']
    nhead = config['nhead']
    num_layers = config['num_layers']
    dim_feedforward = config['dim_feedforward']
    seq_len = config['seq_len']
    
    # 注意力机制复杂度
    attention_complexity = num_layers * seq_len**2 * d_model
    
    # 前馈网络复杂度  
    ff_complexity = num_layers * seq_len * d_model * dim_feedforward
    
    # 总计算复杂度
    total_complexity = attention_complexity + ff_complexity
    
    # 参数量计算
    embedding_params = config['vocab_size'] * d_model
    output_params = config['vocab_size'] * d_model
    
    # 层参数
    layer_params = (
        d_model * d_model * 4 +  # QKV线性层
        d_model * d_model +      # 输出层
        d_model * dim_feedforward * 2 +  # 前馈网络
        d_model * 6              # 层归一化
    )
    
    total_params = embedding_params + output_params + num_layers * layer_params
    
    return {
        'attention_complexity': attention_complexity,
        'ff_complexity': ff_complexity,
        'total_complexity': total_complexity,
        'total_params': total_params
    }

Transformer复杂度分析工具

训练优化技术

提升训练效率
  • 🔥 混合精度训练(FP16/BF16)
  • 📊 梯度累积
  • ⚡ 学习率调度:Warmup + Cosine
  • 🎯 分布式训练:Data Parallel

混合精度训练实现

import torch.cuda.amp as amp

class MixedPrecisionTrainer:
    def __init__(self, model, scaler=None):
        self.model = model
        self.scaler = scaler or amp.GradScaler()
        
    def train_step(self, batch, criterion, optimizer):
        """
        混合精度训练步骤
        
        Args:
            batch: 训练数据批次
            criterion: 损失函数
            optimizer: 优化器
        
        Returns:
            loss: 损失值
        """
        # 数据移到GPU
        src, tgt = batch
        src, tgt = src.cuda(), tgt.cuda()
        
        # 自动混合精度上下文管理器
        with amp.autocast():
            # 前向传播
            output = self.model(src, tgt)
            
            # 计算损失
            loss = criterion(output.view(-1, output.size(-1)), tgt.view(-1))
            
        # 反向传播(缩放)
        self.scaler.scale(loss).backward()
        
        # 梯度裁剪
        self.scaler.unscale_(optimizer)
        torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=1.0)
        
        # 参数更新
        self.scaler.step(optimizer)
        self.scaler.update()
        
        # 清空梯度
        optimizer.zero_grad()
        
        return loss.item()

混合精度训练实现

推理优化技术

实时推理性能
  • ⚡ KV Cache:缓存Key-Value对
  • 🎯 束搜索(Beam Search)
  • 📊 贪婪解码
  • 🔥 模型量化(INT8/FP16)

KV Cache实现

class KVCache:
    def __init__(self, batch_size, max_len, d_model, nhead, device):
        """
        KV缓存初始化
        
        Args:
            batch_size: 批次大小
            max_len: 最大序列长度
            d_model: 模型维度
            nhead: 注意力头数
            device: 设备
        """
        self.batch_size = batch_size
        self.max_len = max_len
        self.d_model = d_model
        self.nhead = nhead
        self.d_k = d_model // nhead
        
        # 初始化KV缓存 [batch_size, nhead, max_len, d_k]
        self.k_cache = torch.zeros(batch_size, nhead, max_len, self.d_k, device=device)
        self.v_cache = torch.zeros(batch_size, nhead, max_len, self.d_k, device=device)
        
        self.current_len = 0
        
    def update(self, k, v):
        """
        更新KV缓存
        
        Args:
            k: 新的Key [batch_size, seq_len, nhead, d_k]
            v: 新的Value [batch_size, seq_len, nhead, d_k]
        """
        # 更新缓存
        self.k_cache[:, :, self.current_len:self.current_len+k.size(1), :] = k
        self.v_cache[:, :, self.current_len:self.current_len+v.size(1), :] = v
        
        # 更新当前长度
        self.current_len += k.size(1)
        
    def get_kv(self):
        """
        获取当前KV缓存
        
        Returns:
            k, v: Key和Value缓存
        """
        return self.k_cache[:, :, :self.current_len, :], self.v_cache[:, :, :self.current_len, :]

KV缓存的高效实现

Transformer在NLP中的应用

自然语言处理的基石
  • 📚 机器翻译:Encoder-Decoder架构
  • 🔍 文本分类:只使用Encoder
  • 🎯 问答系统:双向理解
  • 🔄 文本生成:自回归解码

BERT:双向Encoder

预训练语言模型
  • 🔄 纯Encoder架构
  • 🔍 双向注意力:同时关注前后文
  • 🎯 MLM任务:掩盖词预测
  • 💪 大规模预训练:百亿参数

BERT架构简略实现

class BertEncoder(nn.Module):
    def __init__(self, vocab_size, d_model, nhead, num_layers, dim_feedforward):
        super().__init__()
        
        # 词嵌入 + 位置编码 + 段落编码
        self.embedding = nn.Embedding(vocab_size, d_model)
        self.positional_encoding = PositionalEncoding(d_model)
        self.token_type_embedding = nn.Embedding(2, d_model)  # 0:句子A, 1:句子B
        
        # 多层Transformer Encoder
        encoder_layer = nn.TransformerEncoderLayer(
            d_model, nhead, dim_feedforward, batch_first=True)
        self.encoder = nn.TransformerEncoder(encoder_layer, num_layers)
        
        # 输出层
        self.pooler = nn.Linear(d_model, d_model)
        
    def forward(self, input_ids, token_type_ids=None):
        if token_type_ids is None:
            token_type_ids = torch.zeros_like(input_ids)
            
        # 嵌入组合
        embeddings = self.embedding(input_ids)
        position_embeddings = self.positional_encoding(embeddings)
        type_embeddings = self.token_type_embedding(token_type_ids)
        
        # 组合嵌入
        embeddings = embeddings + position_embeddings + type_embeddings
        
        # 通过Encoder
        sequence_output = self.encoder(embeddings)
        
        # 池化层(取[CLS] token)
        pooled_output = self.pooler(sequence_output[:, 0, :])
        
        return sequence_output, pooled_output

BERT核心架构实现

GPT:自回归Decoder

生成式语言模型
  • 📝 纯Decoder架构
  • 🔄 自回归生成:一个词一个词生成
  • 🎯 因果掩码:防止信息泄漏
  • 💪 大规模预训练:百亿参数

GPT架构简略实现

class GPTDecoder(nn.Module):
    def __init__(self, vocab_size, d_model, nhead, num_layers, dim_feedforward):
        super().__init__()
        
        # 词嵌入 + 位置编码
        self.embedding = nn.Embedding(vocab_size, d_model)
        self.positional_encoding = PositionalEncoding(d_model)
        
        # 多层Transformer Decoder
        decoder_layer = nn.TransformerDecoderLayer(
            d_model, nhead, dim_feedforward, batch_first=True)
        self.decoder = nn.TransformerDecoder(decoder_layer, num_layers)
        
        # 输出层
        self.lm_head = nn.Linear(d_model, vocab_size)
        
    def forward(self, input_ids, past_key_values=None):
        # 嵌入 + 位置编码
        embeddings = self.embedding(input_ids)
        embeddings = self.positional_encoding(embeddings)
        
        # 生成因果掩码
        seq_len = input_ids.size(1)
        tgt_mask = generate_square_subsequent_mask(seq_len).to(input_ids.device)
        
        # 如果有past_key_values,使用缓存
        if past_key_values is not None:
            # 使用缓存的KV和新的输入
            memory = past_key_values
        else:
            memory = embeddings
            
        # 通过Decoder
        output = self.decoder(embeddings, memory, tgt_mask=tgt_mask)
        
        # 计算logits
        logits = self.lm_head(output)
        
        return logits, past_key_values

GPT核心架构实现

T5:统一文本到文本框架

多任务统一架构
  • 🔄 Encoder-Decoder架构
  • 🎯 任务前缀:翻译、总结、问答
  • 📊 自监督预训练:掩码语言建模
  • 💪 多任务统一:一个模型解决多种任务

Transformer在计算机视觉中的应用

CV领域的革命
  • 🖼️ Vision Transformer (ViT)
  • 🎯 DETR: 端到端目标检测
  • 📊 Image Captioning: 图像描述生成
  • 🔍 自监督视觉预训练

Vision Transformer (ViT)

纯Transformer图像分类
  • 🖼️ 图像分割为固定大小的patches
  • 🔑 Patch嵌入 + 位置编码
  • 🔄 Transformer Encoder处理序列
  • 🎯 分类头:CLS token

ViT实现

class VisionTransformer(nn.Module):
    def __init__(self, image_size, patch_size, d_model, nhead, num_classes, num_layers):
        super().__init__()
        
        self.image_size = image_size
        self.patch_size = patch_size
        self.num_patches = (image_size // patch_size) ** 2
        self.d_model = d_model
        
        # Patch嵌入层
        self.patch_embedding = nn.Conv2d(3, d_model, kernel_size=patch_size, stride=patch_size)
        
        # 位置编码 + CLS token
        self.positional_encoding = nn.Parameter(torch.zeros(1, self.num_patches + 1, d_model))
        self.cls_token = nn.Parameter(torch.zeros(1, 1, d_model))
        
        # Transformer Encoder
        encoder_layer = nn.TransformerEncoderLayer(d_model, nhead, batch_first=True)
        self.encoder = nn.TransformerEncoder(encoder_layer, num_layers)
        
        # 分类头
        self.head = nn.Linear(d_model, num_classes)
        
        # 初始化
        self._init_weights()
        
    def forward(self, x):
        # 图像分块 [B, 3, H, W] → [B, num_patches, d_model]
        B, C, H, W = x.shape
        x = self.patch_embedding(x)  # [B, d_model, H/p, W/p]
        x = x.flatten(2)  # [B, d_model, num_patches]
        x = x.transpose(1, 2)  # [B, num_patches, d_model]
        
        # 添加CLS token
        cls_tokens = self.cls_token.expand(B, -1, -1)
        x = torch.cat([cls_tokens, x], dim=1)
        
        # 位置编码
        x = x + self.positional_encoding
        
        # 通过Encoder
        x = self.encoder(x)
        
        # 分类:使用CLS token
        cls_output = x[:, 0, :]
        logits = self.head(cls_output)
        
        return logits

Vision Transformer架构实现

多模态Transformer

跨模态理解与生成
  • 🖼️ Vision-Language预训练:CLIP
  • 🎯 跨模态检索:文本-图像匹配
  • 📊 图像描述生成:图文对齐
  • 🔄 多模态融合:交叉注意力机制

CLIP模型架构

图文对比学习
  • 🖼️ 图像分支:ViT图像编码器
  • 📝 文本分支:Transformer文本编码器
  • 🎯 对比损失:图文相似度最大化
  • 💪 零样本分类:无需训练数据

CLIP损失函数

def clip_loss(image_features, text_features, temperature=0.07):
    """
    CLIP对比损失函数
    
    Args:
        image_features: 图像特征 [batch_size, d_model]
        text_features: 文本特征 [batch_size, d_model]
        temperature: 温度参数
    
    Returns:
        loss: 对比损失
    """
    # 计算相似度矩阵
    logits_per_image = (image_features @ text_features.t()) * math.exp(temperature)
    logits_per_text = logits_per_image.t()
    
    # 对比损失
    batch_size = image_features.shape[0]
    labels = torch.arange(batch_size, device=image_features.device)
    
    # 图像到文本的损失
    loss_i = F.cross_entropy(logits_per_image, labels)
    
    # 文本到图像的损失
    loss_t = F.cross_entropy(logits_per_text, labels)
    
    # 平均损失
    return (loss_i + loss_t) / 2.0

CLIP对比损失实现

Transformer的训练策略

大规模预训练方法
  • 📊 自监督预训练:MLM/NSP
  • 🎯 迁移学习:预训练+微调
  • ⚡ 混合精度训练:FP16/BF16
  • 🔥 分布式训练:DP/PP/TP

预训练数据规模

海量数据的重要性
  • 📚 Common Crawl:万亿token级别
  • 🎯 BooksCorpus:100亿token
  • 🔄 Wikipedia:40亿token
  • 💪 总计:数千亿token

微调技术对比

不同微调策略
  • 🎯 全参数微调:最优效果,资源消耗大
  • ⚡ LoRA:低秩适配,参数量少
  • 📊 P-Tuning:可提示学习
  • 🔄 Prefix Tuning:前缀微调

LoRA实现

低秩适配微调
  • 📊 低秩分解:W = W0 + BA
  • ⚡ 只训练BA,冻结W0
  • 💪 参数量:r(d_model + d_dim)
  • 🎯 r通常为4-64

LoRA实现

class LoraLinear(nn.Module):
    def __init__(self, in_features, out_features, rank=8, lora_alpha=16):
        super().__init__()
        
        # 原始权重(冻结)
        self.weight = nn.Parameter(torch.zeros(out_features, in_features), requires_grad=False)
        
        # LoRA低秩适配
        self.lora_A = nn.Parameter(torch.zeros(rank, in_features))
        self.lora_B = nn.Parameter(torch.zeros(out_features, rank))
        
        # 缩放因子
        self.lora_alpha = lora_alpha
        
        # 初始化
        nn.init.kaiming_uniform_(self.weight, a=math.sqrt(5))
        nn.init.zeros_(self.lora_B)
        nn.init.kaiming_uniform_(self.lora_A, a=math.sqrt(5))
        
    def forward(self, x):
        # 原始线性变换 + LoRA适配
        base_output = F.linear(x, self.weight)
        lora_output = F.linear(F.linear(x, self.lora_A), self.lora_B)
        
        # 应用缩放
        return base_output + (lora_output * self.lora_alpha / self.lora_A.size(0))

LoRA线性层实现

推理优化实践

实时部署的关键
  • ⚡ KV Cache优化:减少内存占用
  • 🎯 量化:INT8/FP4降低精度
  • 📊 知识蒸馏:小模型保持性能
  • 🔄 Speculative Decoding:推测解码

Transformer的性能基准

不同规模的性能对比
  • 📊 小型模型(100M-1B):适合单GPU
  • 🎯 中型模型(1B-10B):多GPU训练
  • 💪 大型模型(10B+):分布式训练
  • ⚡ 推理速度:token/秒

主流Transformer模型性能对比

模型参数量训练数据任务性能推理速度
BERT-base110M16B tokensSOTA文本理解1K tokens/s
GPT-3175B300B tokens强大文本生成50 tokens/s
T5-large770M1T tokens多任务SOTA200 tokens/s
ViT-Large658MImageNet-21KSOTA图像分类100 images/s

Transformer的未来发展

技术演进方向
  • 🔥 更高效的架构:稀疏注意力
  • 🎯 更长的序列:线性注意力
  • 📊 更小的模型:模型压缩
  • 🔄 多模态融合:统一理解

稀疏注意力机制

降低计算复杂度
  • 📊 局部注意力:只关注附近token
  • 🎯 全局注意力:随机采样
  • 🔄 动态注意力:根据内容选择
  • ⚡ 复杂度:O(n·d)而非O(n²·d)

线性注意力

超长序列处理
  • 📊 使用核函数:K(x,y)=exp(x·T·y)
  • 🎯 复杂度:O(n·d²)
  • 🔄 支持序列长度:10K+ tokens
  • ⚡ 适合:长文档、代码分析

模型的压缩与蒸馏

高效部署方案
  • 📊 知识蒸馏:大模型教小模型
  • 🎯 量化:FP16→INT8→INT4
  • 🔄 剪枝:移除不重要的参数
  • ⚡ 推理速度提升:10-100倍

多模态统一模型

未来的AI范式
  • 🖼️ 图像-文本-音频-视频理解
  • 🎯 跨模态检索与生成
  • 📊 统一表示空间
  • 💪 一个模型处理所有任务

总结:Transformer的影响

AI架构的范式革命
  • 🔄 从循环到注意力:架构范式转换
  • 📊 并行化训练:GPU友好设计
  • 🎯 全局上下文:长距离依赖
  • 💪 AI生态:成为现代AI基础设施

实践建议

使用Transformer的最佳实践
  • 🎯 选择合适规模:任务需求vs计算资源
  • ⚡ 利用预训练模型:避免从零训练
  • 📊 微调策略:LoRA/Full Fine-tuning
  • 🔄 推理优化:KV Cache/量化

参考资料

  • 原始论文: https://arxiv.org/abs/1706.03762
  • PyTorch实现: https://pytorch.org/docs/stable/nn.html#transformer
  • Hugging Face Transformers: https://huggingface.co/docs/transformers
  • 代码实现: https://github.com/SCCSMARTCODE/attention-is-all-you-need-from-scratch

感谢阅读!
访问 https://atcfu.com/ai-articles/transformer-architecture/ 回顾本文