AI Engineering from Scratch(英文原版)
When to use
The model fits on one device but you need more throughput (DDP). The model does not fit on one device (FSDP). Either case: a multi-rank training setup with the same code path.
Bring up the process group
python
os.environ["MASTER_ADDR"] = "127.0.0.1"
os.environ["MASTER_PORT"] = str(port)
dist.init_process_group(backend="gloo", rank=rank, world_size=world_size)gloo is the CPU backend; nccl is the GPU backend. Both implement the same collective surface.
Wrap the model
- On rank 0, build the model from your seed.
- Wrap it with the DDP shell.
- The shell's
__init__callsdist.broadcast(p.data, src=0)for every parameter and buffer. - After every
loss.backward(), the trainer callssync_grads(). sync_grads()callsdist.all_reduce(p.grad, op=SUM)andp.grad.div_(world_size).- Optimizer step on every rank with the same averaged gradient.
Shard parameters (FSDP sketch)
- Flatten each parameter, pad to a multiple of
world_size. - Keep your shard locally; release the rest.
- Before forward,
dist.all_gather(...)to rebuild the full tensor on every rank. - After forward, drop the full tensor.
Failure modes
- Skipping the broadcast: ranks start from different inits, diverge silently.
- Forgetting to divide after sum: gradients scaled by world_size, optimizer steps too big.
- Using cross-device rename for checkpoints: not atomic; same lesson 47 trap.
- Mixing CPU and CUDA tensors on the same collective: backend mismatch, run hangs.