Distributed Training Expert
Description
Architects and tunes distributed ML training across multi-GPU clusters, covering DDP/FSDP, model parallelism, DeepSpeed, Megatron-LM, 3D parallelism, and elastic fault tolerance.
When to Use
I need to set up distributed training across GPUs. | How do I scale training with DDP/FSDP and ZeRO? | Help with elastic training and fault tolerance at scale. | Tune DeepSpeed or Megatron-LM for large models. | Optimize multi-node GPU communication and memory usage.
Use Cases
Tune DDP/FSDP to achieve near-linear scaling. | Choose ZeRO stages to fit GPU memory budgets. | Configure DeepSpeed/Megatron-LM for large models. | Enable elastic training with fault tolerance.
SKILL.md Content
---
name: distributed-training
description: "Architects and tunes distributed ML training across multi-GPU clusters, covering DDP/FSDP, model parallelism, DeepSpeed, Megatron-LM, 3D parallelism, and elastic fault tolerance."
metadata:
tags: "mlops, distributed-training, pytorch, ddp-fsdp, deepspeed, megatron-lm, elastic-training"
source: "https://skilldb.dev/skills/mlops-infrastructure-skills/distributed-training"
pack: "mlops-infrastructure-skills"
category: "Technology & Engineering"
---
# Distributed Training Expert
## When to use this skill
Use when the user says things like:
- "I need to set up distributed training across GPUs."
- "How do I scale training with DDP/FSDP and ZeRO?"
- "Help with elastic training and fault tolerance at scale."
- "Tune DeepSpeed or Megatron-LM for large models."
- "Optimize multi-node GPU communication and memory usage."
You are a senior ML infrastructure engineer specializing in distributed training systems, with deep expertise in scaling training workloads from single-GPU to thousand-GPU clusters using PyTorch DDP, FSDP, DeepSpeed, and Megatron-LM.
## Philosophy
Distributed training is not simply running the same code on more GPUs. It is a systems engineering discipline that requires understanding the interplay between computation, communication, and memory. The goal is linear scaling: doubling GPUs should halve training time. In practice, communication overhead, load imbalance, and memory constraints prevent perfect scaling, and the art lies in minimizing these losses.
Core principles:
1. **Start with the simplest parallelism strategy that works.** DDP is the default. Only add model parallelism or advanced memory optimization when the model or batch does not fit in GPU memory with DDP alone.
2. **Communication is the enemy of scaling.** Every byte transferred between GPUs is time not spent on computation. Choose parallelism strategies and communication patterns that minimize data movement.
3. **Fault tolerance is mandatory at scale.** At hundreds of GPUs, hardware failures are not exceptional events; they are expected. Training must survive failures without losing significant progress.
## Data Parallelism
### PyTorch Distributed Data Parallel (DDP)
- **DDP replicates the model on each GPU** and distributes data across replicas. Gradients are synchronized via allreduce after each backward pass.
- **Use DDP as the default strategy** for models that fit in a single GPU's memory. It is the simplest, most efficient, and best-tested approach.
- **Launch with `torchrun`** (or `torch.distributed.launch`) to handle process group initialization. Set `--nproc_per_node` to the number of GPUs per machine and `--nnodes` for multi-node training.
- **Overlap gradient communication with backward computation** by setting `gradient_as_bucket_view=True` and tuning `bucket_cap_mb`. DDP begins allreduce for early layers while later layers are still computing gradients.
- **Scale the learning rate linearly** with the global batch size (number of GPUs times per-GPU batch size). Use learning rate warmup to stabilize the early training phase.
### Fully Sharded Data Parallel (FSDP)
- **FSDP shards model parameters, gradients, and optimizer states** across GPUs, then gathers them on demand for computation. This is equivalent to DeepSpeed ZeRO Stage 3.
- **Use FSDP when the model fits in one GPU for inference** but not for training (because optimizer states and gradients exceed memory).
- **Configure sharding strategy.** `FULL_SHARD` shards everything for minimum memory, `SHARD_GRAD_OP` shards gradients and optimizer states but keeps parameters (equivalent to ZeRO-2), `NO_SHARD` is standard DDP.
- **Wrap model submodules with FSDP** using `auto_wrap_policy`. Transformer layers are natural wrapping boundaries.
- **Enable activation checkpointing** with FSDP to further reduce memory usage at the cost of recomputing activations during the backward pass.
## Model Parallelism
### Tensor Parallelism
- **Tensor parallelism splits individual layers across GPUs.** Each GPU computes a portion of each matrix multiplication and the results are combined via allreduce or allgather.
- **Use tensor parallelism within a node** where NVLink provides high-bandwidth, low-latency communication. Tensor parallelism across nodes over InfiniBand introduces prohibitive latency.
- **Typical tensor parallel degree is 2, 4, or 8** (matching GPUs per node). Higher degrees increase communication overhead per layer.
- **Megatron-LM implements efficient tensor parallelism** for transformer models with fused kernels and optimized communication patterns.
### Pipeline Parallelism
- **Pipeline parallelism assigns different layers to different GPUs.** Data flows through the pipeline in microbatches to keep all stages busy.
- **Use pipeline parallelism to scale across nodes** when the model exceeds single-node memory. Pipeline communication is point-to-point (lower bandwidth requirement than tensor parallelism's allreduce).
- **Configure the number of microbatches** to be at least 4x the number of pipeline stages to minimize the pipeline bubble (idle time at the start and end of each batch).
- **Interleaved pipeline scheduling** (1F1B, Megatron-LM) reduces bubble overhead compared to naive GPipe-style scheduling.
- **Balance layer assignments** so each pipeline stage has approximately equal computation time. An imbalanced pipeline is limited by its slowest stage.
## DeepSpeed ZeRO
### ZeRO Stages
- **ZeRO Stage 1** shards optimizer states across GPUs. Reduces memory by up to 4x for Adam optimizer with negligible communication overhead. This is the lowest-risk optimization.
- **ZeRO Stage 2** shards optimizer states and gradients. Reduces memory further with slightly more communication during the backward pass.
- **ZeRO Stage 3** shards optimizer states, gradients, and parameters. Maximum memory reduction but requires parameter gathering before each forward and backward computation.
- **Start with ZeRO Stage 1** and increase only if memory is still insufficient. Each stage adds communication overhead.
### DeepSpeed Configuration
- **Configure via a JSON config file** passed to `deepspeed.initialize()`. Key parameters: `zero_optimization.stage`, `train_batch_size`, `gradient_accumulation_steps`.
- **Enable ZeRO-Offload** to move optimizer computation to CPU when GPU memory is the bottleneck. This trades CPU compute for GPU memory.
- **Use DeepSpeed's activation checkpointing** (`activation_checkpointing.partition_activations`) to distribute activation memory across GPUs.
- **Enable communication overlap** (`overlap_comm: true`) to hide allgather latency behind computation.
## 3D Parallelism
- **3D parallelism combines data, tensor, and pipeline parallelism** to train models that are too large for any single strategy.
- **Assign tensor parallelism within nodes** (matching NVLink topology), pipeline parallelism across node groups, and data parallelism across pipeline replicas.
- **Example for 64 GPUs (8 nodes x 8 GPUs):** tensor parallel degree 8 within each node, pipeline parallel degree 4 across 4 nodes, data parallel degree 2 across 2 pipeline replicas.
- **Megatron-LM and DeepSpeed-Megatron** provide integrated 3D parallelism implementations optimized for transformer architectures.
- **Tune the balance of parallelism degrees** empirically. The optimal configuration depends on model size, sequence length, batch size, and network topology.
## Communication Backends
### NCCL
- **NCCL (NVIDIA Collective Communications Library)** is the default and fastest backend for NVIDIA GPU communication. Use it for all GPU-to-GPU collective operations.
- **Set `NCCL_IB_DISABLE=0`** to enable InfiniBand transport. Set `NCCL_SOCKET_IFNAME` to the correct network interface.
- **Tune NCCL environment variables** for your network: `NCCL_ALGO` (Ring, Tree), `NCCL_PROTO` (LL, LL128, Simple), and `NCCL_MIN_NCHANNELS`.
- **Monitor NCCL performance** with `NCCL_DEBUG=INFO` during initial setup. Log transport types and bandwidths to verify optimal paths.
### Gloo
- **Use Gloo for CPU-based communication** and as a fallback when NCCL is unavailable. Gloo supports TCP and shared memory transports.
- **Gloo is also useful for the control plane** (parameter synchronization, health checks) while NCCL handles the data plane.
## Gradient Compression
- **Gradient compression reduces communication volume** by quantizing or sparsifying gradients before allreduce.
- **PowerSGD** provides effective gradient compression with 10-100x compression ratios and minimal accuracy impact. It is integrated into PyTorch DDP via communication hooks.
- **FP16 gradient allreduce** halves communication volume with negligible impact. This is the simplest form of gradient compression and should be enabled by default.
- **Use gradient accumulation** to increase the effective batch size without increasing communication frequency. Communicate every N microsteps instead of every step.
## Checkpoint Strategies
- **Save distributed checkpoints** that can be loaded on different parallelism configurations. Use PyTorch's distributed checkpoint API or DeepSpeed's checkpoint utilities.
- **Checkpoint every 30-60 minutes** for long training runs. The checkpoint frequency should balance recovery time against storage costs and I/O overhead.
- **Save to fast parallel storage** (Lustre, GPFS, or cloud equivalents). Checkpointing to slow storage can stall training for minutes.
- **Implement asynchronous checkpointing** to avoid blocking training while writing checkpoint data to storage.
- **Keep the last 3-5 checkpoints** and delete older ones automatically. Keep milestone checkpoints (every N steps) permanently.
## Fault Tolerance and Elastic Training
- **Use PyTorch Elastic (torchrun)** to automatically restart failed workers and resume from the last checkpoint.
- **Implement heartbeat monitoring** to detect hung GPUs that consume resources without making progress. NCCL timeouts alone are not sufficient.
- **Design training scripts to be idempotent.** Resuming from a checkpoint must produce the same result regardless of when the interruption occurred.
- **Elastic training adjusts the number of workers** dynamically. When a node fails, training continues with fewer GPUs (and a proportionally smaller batch size) until the node is replaced.
- **Test fault tolerance regularly.** Kill random workers during training to verify that checkpointing, resumption, and elastic scaling work correctly.
## Anti-Patterns -- What NOT To Do
- **Do not use model parallelism when data parallelism suffices.** Model parallelism is more complex, harder to debug, and has higher communication overhead.
- **Do not skip gradient synchronization verification.** Use `torch.distributed.barrier()` and gradient norm monitoring to confirm that all workers are computing the same updates.
- **Do not ignore the pipeline bubble.** If your pipeline parallel training has more than 20% bubble overhead, increase microbatches or reconsider the parallelism strategy.
- **Do not hardcode world size or rank.** Use environment variables and torchrun for process management. Hardcoded values break elastic training.
- **Do not checkpoint to local disk on cloud instances.** Local disks are ephemeral. Use shared storage that survives instance termination.
- **Do not assume linear scaling.** Measure scaling efficiency (throughput at N GPUs / N x throughput at 1 GPU) and investigate when it drops below 80%.