Обучение с несколькими графическими процессорами медленнее, чем обучение с одним графическим процессором, с использованиPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Обучение с несколькими графическими процессорами медленнее, чем обучение с одним графическим процессором, с использовани

Сообщение Anonymous »

Я собрал фиктивную модель молнии Pytorch специально для сравнения времени, необходимого для завершения обучения с несколькими графическими процессорами (3 графических процессора, использующих DDP, называемых 3G) и обучения с одним графическим процессором (называемых 1G). Проблема в том, что процесс обучения 1G всегда короче, чем процесс обучения 3G.
Некоторые варианты, которые я пробовал:
< ol>
[*]Я перешел от меньшего размера партии (16) к большему (256).
[*]Я экспериментировал с добавлением до 8 дополнительных скрытых слоев.
[*]Я экспериментировал с аккумулировать_град_батчи в параметрах трейнера.

К сожалению, ни одна из этих настроек не привела к каким-либо улучшениям. Возможно, моя модель слишком проста для того, чтобы процесс с несколькими графическими процессорами был лучше, но я слишком новичок в обучении с несколькими графическими процессорами, чтобы заявить об этой проблеме, и мои эксперименты не привели к каким-либо улучшениям. Я видел варианты этого вопроса о переполнении стека, но они обычно направлены на устранение ошибок. В моем случае мне интересно, почему производительность так снижается, особенно при использовании кода молнии pytorch.
Мой вопрос: Есть ли какие-либо ключевые проблемы с этим фиктивным примером, который приведет к тому, что процесс с одним графическим процессором превзойдет процесс с несколькими графическими процессорами?

Код: Выделить всё

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")
Некоторые показатели: я использовал веса и смещения, чтобы отслеживать использование графического процессора, чтобы посмотреть, прольет ли это свет на проблему. Оно показало, что процесс обучения 3G с течением времени использовал спорадическое использование графического процессора, в то время как процесс обучения 1G оставался относительно постоянным. Я подозреваю, что это и есть суть проблемы, но неясно, как это будет исправлено. Скриншот этих результатов приведен ниже.
Изображение

Есть ли в коде какой-либо явный недостаток, исправление которого позволило бы процессу обучения 3G превзойти процесс обучения 1G?

Подробнее здесь: https://stackoverflow.com/questions/792 ... ning-dummy
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»