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

PyTorch Lightning多GPU(3卡DDP)训练性能不及单GPU的问题排查

PyTorch Lightning多GPU(3卡DDP)训练性能不及单GPU的问题排查

我最近搭了一个PyTorch Lightning的测试模型,专门用来对比3卡DDP多GPU训练(简称3G)和单GPU训练(简称1G)的耗时情况,但结果一直是单GPU训练比多GPU更快。

我尝试过的调整方案

  • 从较小的批次大小(16)调整到较大的批次大小(256)
  • 尝试添加最多8个额外的隐藏层
  • 在Trainer参数中调整accumulate_grad_batches的值

可惜这些调整都没带来任何改善。我怀疑可能是我的模型太简单,导致多GPU训练的优势发挥不出来,但我刚接触多GPU训练,不敢轻易下定论,而且我的实验也没得到正向结果。我在Stack Overflow上看到过类似问题,但大多是解决报错的,而我想搞清楚为什么用PyTorch Lightning时性能会这么拉胯。

我的问题

这个测试案例里有没有什么关键问题,导致单GPU训练反而比多GPU训练表现更好?

以下是我的测试代码:

import pytorch_lightning as pl
from pytorch_lightning import LightningModule, LightningDataModule
from torch import nn
from torch.utils.data import Dataset, DataLoader
import torch
import time
import wandb
from pytorch_lightning.loggers import WandbLogger
import pynvml

class SimpleDataset(Dataset):
    def __init__(self, size):
        self.size = size

    def __len__(self):
        return self.size

    def __getitem__(self, idx):
        # Generate some random data
        x = torch.randn(1, 10)
        y = torch.randn(1)
        return x, y

class SimpleDataModule(LightningDataModule):
    def __init__(self, batch_size, size):
        super().__init__()
        self.batch_size = batch_size
        self.size = size

    def setup(self, stage=None):
        self.dataset = SimpleDataset(self.size)

    def train_dataloader(self):
        return DataLoader(self.dataset, batch_size=self.batch_size, shuffle=True)

    def val_dataloader(self):
        return DataLoader(self.dataset, batch_size=self.batch_size)

class SimpleModel(LightningModule):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(10, 256)
        self.fc2 = nn.Linear(256, 256)
        self.fc3 = nn.Linear(256, 256)
        self.fc4 = nn.Linear(256, 1)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = torch.relu(self.fc3(x))
        x = self.fc4(x)
        return x

    def training_step(self, batch, batch_idx):
        x, y = batch
        y_pred = self(x)
        loss = nn.MSELoss()(y_pred, y)
        self.log('train_loss', loss)

        # Get individual GPU utilization
        pynvml.nvmlInit()
        utilization = []
        for i in range(pynvml.nvmlDeviceGetCount()):
            handle = pynvml.nvmlDeviceGetHandleByIndex(i)
            utilization.append(pynvml.nvmlDeviceGetUtilizationRates(handle).gpu)
        pynvml.nvmlShutdown()

        # Log individual GPU utilization
        for i, util in enumerate(utilization):
            self.log(f'gpu_{i}_utilization', util)

        return loss


    def validation_step(self, batch, batch_idx):
        x, y = batch
        y_pred = self(x)
        loss = nn.MSELoss()(y_pred, y)
        self.log('val_loss', loss)
        return loss

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=0.01)

data_module = SimpleDataModule(batch_size=256, size=5000)
model = SimpleModel()

start_time = time.time()

wandb_logger = WandbLogger(project='simple_model')

trainer = pl.Trainer(strategy='ddp', devices=3, max_epochs=200, accumulate_grad_batches=3, logger=wandb_logger)

trainer.fit(model, data_module)
if trainer.is_global_zero:
    end_time = time.time()
    elapsed_time = end_time - start_time
    print(f"Training completed in {elapsed_time:.2f} seconds")

相关指标

我用Weights and Biases跟踪了GPU使用率,想从中找到问题所在。结果显示3G训练时GPU使用率波动很大,而1G训练时使用率相对稳定。我觉得这可能是问题的核心,但不知道该怎么解决。下图是相关的监控结果:

Weights and Biases GPU监控图表

有没有什么明显的代码问题,修复后能让3G训练的性能超过1G?

备注:内容来源于stack exchange,提问作者CCranney

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:54:28