liveBook · Manning

DistributedDataParallel

As explained in Graph Neural Networks in Action

DistributedDataParallel is a PyTorch API that runs replicated model processes across multiple GPUs or machines while synchronizing gradients.

PyTorch’s DistributedDataParallel (DDP) trains a model across multiple GPUs by giving processes different portions of the data and synchronizing their gradients. It is useful when one GPU is too slow for a large training workload. Unlike DataParallel, which replicates the model on each forward pass, DDP generally incurs less overhead and can also span multiple machines. section 7.8 section 7.8.1

A single-machine training workflow has five parts:

  • Initialize a process group, assign each process a GPU, and divide the data yourself; DDP does not split it automatically. section 7.8.1 section 7.8.2
  • Create the model and wrap it with DistributedDataParallel. section 7.8.1
  • In each process, run batches through the usual forward pass, loss calculation, backpropagation, and optimizer step. DDP synchronizes gradients so the processes update the same model. section 7.8.1 section 7.8.2
  • Coordinate completion where needed—for example, with dist.barrier() before the next epoch—and destroy the process group when training ends. section 7.8.1
  • Guard the script’s entry point when launching training processes. For multi-machine runs, also plan model loading and saving carefully. section 7.8.1

Two-GPU training examples

A PyTorch example trains a Flatten-and-Linear network on MNIST. It initializes communication with NCCL, uses mp.spawn to launch a process for each GPU, and assigns devices by process rank. A GCN variation uses the Amazon Products dataset and NeighborLoader on a dual-GPU system. section 7.8.2

Listing 7.2 Training using DDP
import torch 
import torch.distributed as dist 
import torch.multiprocessing as mp 
import torch.nn as nn 
from torch.nn.parallel import DistributedDataParallel    #1
from torch.utils.data import DataLoader    #2
from torchvision import datasets, transforms 

class Flatten(nn.Module): 
  def forward(self, input): 
    return input.view(input.size(0), -1) 

def train(model, trainloader, 
                 criterion, 
                 optimizer,
                 device):   #3
    model.train() 
    for batch_idx, (data, target) in enumerate(trainloader): 
      print(f'Process {device}, Batch {batch_idx}') 
       data, target = data.to(device), target.to(device) 
       optimizer.zero_grad() 
       output = model(data) 
       loss = criterion(output, target) 
       loss.backward() 
       optimizer.step() 

def main(rank, world_size):    #4
    filepath = '~/.pytorch/MNIST_data/'
    dist.init_process_group(   #5
    backend='nccl', 
    init_method='tcp://localhost:23456', 
    rank=rank,
    world_size=world_size    #6
    )

    torch.manual_seed(0)   #7
    device = torch.device(f'cuda:{rank}')    #8

    transform = transforms.Compose(
                        [transforms.ToTensor(),
                        transforms.Normalize((0.5,),
                        (0.5,))]
                        )

    trainset = datasets.MNIST(filepath ,                #9
                                download=True,          #9
                                train=True,             #9
                                transform=transform)    #9
    train_loader = DataLoader(trainset,           #10
                                batch_size=64,    #10
                                shuffle=True,     #10
                                num_workers=2)    #10

    model = nn.Sequential(Flatten(), nn.Linear(784, 10)).to(device) 
    model = DistributedDataParallel(model, device_ids=[rank])   #11

    criterion = nn.CrossEntropyLoss() 
    optimizer = torch.optim.SGD(model.parameters(), lr=0.01) 

    train(model, train_loader, criterion, optimizer, device)    #12

The training listing shows where the model is wrapped, how each process runs the training loop, and how distributed execution is launched. section 7.8.2

Choose DDP with the available hardware in mind. Moving from one GPU to multiple devices—or to a small cluster—adds planning, setup, and synchronization work alongside the potential training-speed benefit. section 7.4.1 section 7.8.1

How Graph Neural Networks in Action covers it

How deep it goes
Walks through process groups, manual data division, model wrapping, training, synchronization, and cleanup, then illustrates a two-GPU script.
Examples
Demonstrates MNIST training with a Flatten-and-Linear network and points to a GCN example using Amazon Products.
What it assumes
Assumes familiarity with PyTorch training and access to multiple GPUs; introduces process groups and rank-based device assignment.
What you can do after
Apply it via PyTorch DistributedDataParallel to run multi-GPU training while dividing data and coordinating processes.
How it connects
Connects DistributedDataParallel to DataParallel, batching, process groups, gradient synchronization, and NeighborLoader.

Also explained in

Compare how 2 books explain DistributedDataParallel →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Graph Neural Networks in Action. The section links point to the parts of the book it draws on.