A minimal tutorial for running Distributed Data Parallel (DDP) PyTorch training on the University of Michigan Great Lakes cluster.
This demo trains a small CNN on MNIST using 2 GPUs on a single node in the spgpu partition.
| File | Description |
|---|---|
train_ddp.py |
Minimal DDP training script (MNIST + small CNN) |
scripts/train_ddp.sbatch |
SLURM batch script for Great Lakes |
environment.yml |
Conda/mamba environment with PyTorch + CUDA 12.1 |
- A Great Lakes account with Duo MFA enabled
- A SLURM account (billing allocation) — find yours with
accountspayableor check the Great Lakes user guide - SSH access:
ssh <uniqname>@greatlakes.arc-ts.umich.edu
ssh <uniqname>@greatlakes.arc-ts.umich.edu
git clone https://github.com/behradrabiei/greatlake_training_tutorial.git
cd greatlake_training_tutorialYou can also clone to /scratch/<your_account> for faster I/O during training.
module load mamba/py3.12
mamba env create -f environment.ymlThis creates a ddp-demo environment with PyTorch, torchvision, and CUDA 12.1 support.
Request an interactive GPU session:
salloc --account=YOUR_SLURM_ACCOUNT \
--partition=spgpu \
--nodes=1 \
--ntasks-per-node=1 \
--gres=gpu:1 \
--cpus-per-task=4 \
--mem=48G \
--time=00:30:00Then activate the environment and check CUDA:
module load mamba/py3.12
source activate ddp-demo
python -c "import torch; print('CUDA available:', torch.cuda.is_available())"Exit the interactive session when done: exit
Open scripts/train_ddp.sbatch and replace YOUR_SLURM_ACCOUNT with your actual SLURM account name:
#SBATCH --account=your_account_nameFrom the repo root:
sbatch scripts/train_ddp.sbatchSLURM will print a job ID, e.g. Submitted batch job 12345678.
squeue -u $USER
tail -f logs/ddp-<jobid>.outWhen the job succeeds, the log should show something like:
Starting DDP training: world_size=2, rank=0, local_rank=0
Epoch 1/2 - loss: 0.2341
Epoch 2/2 - loss: 0.0892
Training complete.
Key things to verify:
world_size=2confirms both GPUs are participating- Loss decreases across epochs
- Job completes in a few minutes
- SLURM allocates 1 node with 2 GPUs via
scripts/train_ddp.sbatch srunlaunches the job on the allocated compute nodetorchrunstarts 2 processes (one per GPU) and setsRANK,LOCAL_RANK,WORLD_SIZEtrain_ddp.pyinitializes NCCL, wraps the model inDistributedDataParallel, and usesDistributedSamplerso each GPU sees a different shard of MNIST
Login node --sbatch--> SLURM --> spgpu node
|
srun + torchrun
/ \
GPU 0 GPU 1
(rank 0) (rank 1)
\ /
NCCL sync
If you have a machine with 2+ GPUs:
torchrun --standalone --nproc_per_node=2 train_ddp.pyEdit constants at the top of train_ddp.py:
EPOCHS— number of training epochs (default: 2)BATCH_SIZE— per-GPU batch size (default: 64)NUM_WORKERS— DataLoader workers per process (default: 2)
To use more GPUs on a single node, update both the sbatch script (--ntasks-per-node, --gres=gpu:N, --mem) and ensure nproc_per_node matches.
| Problem | Fix |
|---|---|
Job rejected with QOSMinGRES |
You submitted to a GPU partition without requesting GPUs. Ensure --gres=gpu:2 is set. |
Job rejected with InvalidAccount |
Replace YOUR_SLURM_ACCOUNT with your real account name. |
CUDA available: False in interactive test |
Make sure you requested a GPU with salloc --gres=gpu:1 and are on a compute node, not a login node. |
ModuleNotFoundError: torch |
Run module load mamba/py3.12 && source activate ddp-demo before running Python. |
| NCCL / distributed errors | Confirm --ntasks-per-node matches --gres=gpu:N and nproc_per_node. |
For more help, see the Slurm user guide and PyTorch on Great Lakes.
This tutorial covers single-node, multi-GPU DDP. Multi-node training requires additional setup (MASTER_ADDR, MASTER_PORT, --nodes>1) and is not included here.