You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch模型GPU训练性能远逊于CPU的问题求助

问题:CPU训练的PyTorch模型在GPU/TPU上性能大幅下降

在CPU上训练的小型PyTorch模型验证准确率约0.91,但训练速度较慢。仅对代码做GPU适配修改后在Google Colab的GPU上运行(其余代码完全一致),尽管训练轮次更多,模型验证准确率仅约0.71,性能大幅下降。尝试Colab提供的TPU时也存在同样问题,运行环境为Google Drive,怀疑是浮点精度问题。

代码示例

CPU训练代码

# Train the false colour model
epochs = 5
loss_func = nn.MSELoss()
optimizer = optim.AdamW(params = mymodel_false.parameters(), lr = 0.0004)

losses = []
for epoch in range(epochs):
    for i, (input_img, target_img) in enumerate(train_loader_false):
        # Zero the gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        output_img = mymodel_false(input_img)
        loss = loss_func(output_img, target_img)
        loss.backward()
        optimizer.step()

        losses.append(loss)
        print(f"Epoch: {epoch}, Loss: {loss}")

GPU训练代码

# Train the false colour model
device = torch.device("cuda")
model = model.to(device)
epochs = 5
loss_func = nn.MSELoss()
optimizer = optim.AdamW(params = mymodel_false.parameters(), lr = 0.0004)

losses = []
for epoch in range(epochs):
    for i, (input_img, target_img) in enumerate(train_loader_false):
        # Zero the gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        input_img = input_img.to(device)
        output_img = mymodel_false(input_img)
        target_img = target_img.to(device)
        loss = loss_func(output_img, target_img)
        loss.backward()
        optimizer.step()

        losses.append(loss)
        print(f"Epoch: {epoch}, Loss: {loss}")

排查与解决方案

1. 模型设备迁移的变量名错误(最可能原因)

GPU代码中,你执行了model = model.to(device),但后续训练调用的是mymodel_false,这意味着实际训练的还是CPU上的原始模型,GPU上的模型从未被使用。这会导致GPU训练时模型参数始终处于初始状态,自然性能暴跌。

修正方式:将模型迁移代码改为:

mymodel_false = mymodel_false.to(device)

2. 浮点精度一致性检查

CPU与GPU的浮点精度默认可能存在差异,若模型、数据的dtype不统一,会导致训练过程中的精度损失:

  • 确保模型和所有张量使用相同的dtype(例如torch.float32),迁移设备时显式指定:
    mymodel_false = mymodel_false.to(device, dtype=torch.float32)
    input_img = input_img.to(device, dtype=torch.float32)
    target_img = target_img.to(device, dtype=torch.float32)
    
  • 若Colab默认开启了混合精度训练,可能会导致精度丢失,可显式关闭或使用torch.cuda.amp规范处理混合精度:
    from torch.cuda.amp import GradScaler, autocast
    
    scaler = GradScaler()
    # 训练循环内修改:
    optimizer.zero_grad()
    with autocast():
        output_img = mymodel_false(input_img)
        loss = loss_func(output_img, target_img)
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()
    

3. 固定随机种子消除训练随机性差异

GPU/TPU训练时,数据加载、底层运算的随机性可能与CPU不同,导致训练数据分布或权重更新轨迹不一致:

import torch
import numpy as np
import random

def set_seed(seed=42):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

set_seed()

在训练前调用该函数,确保CPU、GPU、TPU训练的随机性一致。

4. TPU适配的额外要求

TPU对PyTorch的适配需要依赖torch_xla库,单纯迁移设备无法正常工作,需调整代码:

  • 安装torch_xla:
    !pip install torch_xla[tpu] -f https://storage.googleapis.com/tpu-pytorch/wheels/torch_xla-latest-cp310-cp310-linux_x86_64.whl
    
  • 调整训练循环适配TPU:
    import torch_xla.core.xla_model as xm
    
    device = xm.xla_device()
    mymodel_false = mymodel_false.to(device)
    
    # 训练循环内优化器步骤需改为:
    loss.backward()
    xm.optimizer_step(optimizer)
    

内容的提问来源于stack exchange,提问作者Calvin Adams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:33:24