Python:AI大模型Transformer架构的CPU和GPU版本前向推理代码实现

Transformer是目前最常见的AI大语言模型架构,以下是Transformer架构的CPU和GPU版本前向推理代码实现,并且会会自动计算推理时间。我们可以比较两者的性能差异,感受使用GPU所带来的性能提升。为了降低示例的硬件运行门槛,我们需要简化层数和头数。比如,定义一个小型的Transformer模型,比如有12层,每层有12个注意力头,隐藏层维度为768,这样比较接近BERT-base的结构。

代码实现流程:

  1. 定义模型结构:基于Transformer的模型,指定参数如层数、头数、隐藏维度等。

  2. CPU版本:模型在CPU上,输入数据在CPU,用time模块记录时间。

  3. GPU版本:模型在CUDA上,数据移动到CUDA,用CUDA事件或同步后的时间记录。

  4. 生成示例输入,如随机的token IDs。

  5. 执行前向推理,测量并打印时间。

  6. 确保代码正确,比如模型结构正确,张量尺寸正确,时间测量准确。

import torch
import torch.nn as nn
import math
import time

# 公共配置参数
config = {
    "vocab_size": 50257,       # GPT-2的词汇表大小
    "seq_len": 1024,           # 序列长度
    "batch_size": 8,           # 批大小
    "d_model": 768,            # 隐藏层维度
    "nhead": 12,               # 注意力头数
    "num_layers": 12,          # Transformer层数
    "dim_feedforward": 3072,   # FFN维度
    "device": "cpu"            # 初始设备设置
}

class PositionalEncoding(nn.Module):
    def __init__(self, d_model, max_len=5000):
        super().__init__()
        pe = torch.zeros(max_len, d_model)
        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        self.register_buffer('pe', pe)

    def forward(self, x):
        x = x + self.pe[:x.size(1)]
        return x

class TransformerModel(nn.Module):
    def __init__(self, config):
        super().__init__()
        self.embedding = nn.Embedding(config["vocab_size"], config["d_model"])
        self.pos_encoder = PositionalEncoding(config["d_model"])
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=config["d_model"],
            nhead=config["nhead"],
            dim_feedforward=config["dim_feedforward"],
            # batch_first=False  # PyTorch默认使用(seq_len, batch, features)
            batch_first=True  # PyTorch默认使用(seq_len, batch, features)
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=config["num_layers"])
        self.fc = nn.Linear(config["d_model"], config["vocab_size"])

    def forward(self, src):
        src = self.embedding(src) * math.sqrt(config["d_model"])
        src = self.pos_encoder(src)
        # src = src.permute(1, 0, 2)  # 转换为(seq_len, batch, features)
        output = self.transformer(src)
        return self.fc(output)

# CPU版本
def cpu_version():
    config["device"] = "cpu"
    torch.set_num_threads(8)  # 设置CPU线程数
    
    model = TransformerModel(config).to(config["device"])
    model.eval()
    
    # 生成随机输入
    inputs = torch.randint(0, config["vocab_size"], 
                         (config["batch_size"], config["seq_len"])).to(config["device"])
    
    # 预热
    with torch.no_grad():
        _ = model(inputs)
    
    # 正式计时
    start_time = time.time()
    with torch.no_grad():
        _ = model(inputs)
    elapsed = time.time() - start_time
    
    print(f"CPU推理时间: {elapsed:.4f}秒")

# GPU版本
def gpu_version():
    if not torch.cuda.is_available():
        print("CUDA不可用")
        return
    
    config["device"] = "cuda"
    torch.backends.cudnn.benchmark = True  # 启用cuDNN基准优化
    
    model = TransformerModel(config).to(config["device"])
    model.eval()
    
    # 生成随机输入
    inputs = torch.randint(0, config["vocab_size"], 
                         (config["batch_size"], config["seq_len"])).to(config["device"])
    
    # 预热
    with torch.no_grad():
        for _ in range(3):  # 多次预热确保CUDA初始化完成
            _ = model(inputs)
    
    # 精确计时
    starter = torch.cuda.Event(enable_timing=True)
    ender = torch.cuda.Event(enable_timing=True)
    
    starter.record()
    with torch.no_grad():
        _ = model(inputs)
    ender.record()
    torch.cuda.synchronize()
    
    elapsed = starter.elapsed_time(ender) / 1000  # 转换为秒
    print(f"GPU推理时间: {elapsed:.4f}秒")

if __name__ == "__main__":
    print("运行CPU版本:")
    cpu_version()
    
    print("\n运行GPU版本:")
    gpu_version()

代码说明:

  1. 模型架构:

    • 使用标准的Transformer编码器架构
    • 包含词嵌入层、位置编码层、12层Transformer编码器和最后的线性输出层
    • 参数配置参考GPT-2的小型配置
  2. CPU版本特点:

    • 使用纯CPU计算
    • 设置8个CPU线程进行并行计算
    • 使用Python标准库time进行计时
  3. GPU版本特点:

    • 自动检测CUDA可用性
    • 使用CUDA事件进行精确计时
    • 启用cuDNN基准优化加速计算
    • 进行多次预热确保CUDA上下文初始化完成
  4. 性能差异:

    • 实际性能取决于具体硬件配置
    • GPU版本通过并行计算和硬件加速获得显著优势

代码运行示例:

  • 运行环境:CPU为Ryzen 9 7945HX(16核心32线程),GPU为NVIDIA Geforce RTX 4060 8G显存,操作系统为Win 11 64位专业版
    在这里插入图片描述
    对比CPU,使用GPU,可以带来20倍的性能提升。

注意:

  1. 首次运行GPU版本会有CUDA上下文初始化时间
  2. 实际应用中需要根据硬件调整batch_size和序列长度
  3. 对于生产环境建议使用混合精度训练和推理优化
  4. 更复杂模型需要配合模型并行和流水线并行技术
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值