Contents
Map

04 ยท Pretraining at Scale

Distributed Training at Scale

View as:

Distributed Training at Scale

GPU & Hardware introduced data, tensor and pipeline parallelism and ZeRO. Frontier runs combine all of them - plus context and expert parallelism - across tens of thousands of GPUs, and they have to survive hardware failures every few hours. This note is about how those pieces fit together, how low-precision (FP8) training works, and how you know whether a run is efficient.

Learning objectives 60 min
By the end of this page you will be able to:
  • Explain 4D/5D parallelism (data/FSDP, tensor, pipeline, context, expert) and map each dimension onto the network hierarchy
  • Choose a parallelism layout for a given model size, sequence length and cluster
  • Explain how FP8 training works (formats, scaling granularity, what stays in higher precision)
  • Compute and interpret model FLOPs utilization (MFU)
  • Describe the fault-tolerance machinery a multi-week run needs
Prerequisites

The Parallelism Dimensions

DimensionWhat is splitCommunicationWhere it runs best
Data parallel (DP / FSDP / ZeRO)The batch; with FSDP also params, grads and optimizer stateAll-gather params, reduce-scatter grads (FSDP) or all-reduce grads (DDP)Across nodes - tolerant of lower bandwidth
Tensor parallel (TP)Individual weight matrices (heads, FFN columns/rows)All-reduce (or reduce-scatter + all-gather) twice per layerInside a node over NVLink - very bandwidth-hungry
Sequence parallel (SP)Activations for the norm and dropout regions along the sequence, alongside TPReplaces TP's all-reduces with reduce-scatter/all-gatherSame group as TP
Pipeline parallel (PP)Layers into stagesPoint-to-point activations between stagesAcross nodes; costs a "bubble" of idle time
Context parallel (CP)The sequence dimension for attention (ring attention)K/V blocks passed around a ring of GPUsLong-context training (128K+)
Expert parallel (EP)MoE experts across GPUsAll-to-all token dispatch and combineMoE models; needs fast all-to-all
flowchart TD
    subgraph CLUSTER["๐Ÿข Cluster (thousands of GPUs)"]
        direction TB
        subgraph DPG["๐Ÿ“‹ Data-parallel / FSDP replicas - across the slowest links"]
            direction LR
            subgraph PPG["๐Ÿšš Pipeline stages - across nodes"]
                direction LR
                subgraph NODE["๐Ÿ–ฅ๏ธ One node / NVLink domain"]
                    TPG["โœ‚๏ธ Tensor + sequence parallel<br/>(fastest links)"]
                    CPG["๐Ÿ”„ Context parallel"]
                    EPG["๐Ÿงฉ Expert parallel"]
                end
            end
        end
    end

    style TPG fill:#d8dfe8,stroke:#b0bac8
    style CPG fill:#dde4dc,stroke:#b0c4b0
    style EPG fill:#e8e0d4,stroke:#c8b89a

The layout rule: put the most communication-heavy dimension on the fastest links. TP talks every layer, so it stays inside an NVLink domain (8 GPUs on HGX servers, 72 on a GB200 NVL72 rack). DP/FSDP talks once per step (and overlaps with compute), so it spans the data-center network.

A published example - Llama 3 405B (16K H100s): TP = 8 within each server, PP = 16 across servers, CP up to 16 for long-context stages, and data parallelism across the rest, with a modified FSDP. Meta reported 38-43% MFU in BF16.

The pipeline bubble

With p pipeline stages and m micro-batches per step, a simple 1F1B schedule leaves each GPU idle for roughly (p - 1) / (m + p - 1) of the step. More micro-batches shrink the bubble; interleaved schedules (several smaller stages per GPU) and DeepSeek's DualPipe (which overlaps forward and backward chunks, and their communication) shrink it further.

Context parallelism

Attention's memory grows with sequence length, and at 128K tokens even FlashAttention's activations don't fit on one GPU for a large model. Ring attention splits the sequence across GPUs: each holds a chunk of queries and passes key/value chunks around a ring, computing blockwise attention as they arrive, overlapping communication with compute.

Expert parallelism

An MoE layer sends each token to its top-k experts, which live on different GPUs. That means two all-to-all exchanges per MoE layer (dispatch and combine). The costs to manage: load imbalance (a hot expert stalls everyone), and all-to-all bandwidth across nodes. DeepSeek-V3 limited each token to experts on at most 4 nodes and wrote custom communication kernels to overlap it with compute.


FP8 Training

Concept

Hopper and Blackwell GPUs run FP8 matrix multiplies at roughly twice their BF16 throughput. FP8 has two formats:

FormatExponent / mantissaTypical use
E4M34 / 3Weights and activations (forward) - more precision
E5M25 / 2Gradients (backward) - more range

FP8's range is tiny, so every tensor needs a scale factor. The granularity of that scale is the main design choice:

  • Per-tensor scaling (NVIDIA Transformer Engine's original recipe): one scale per tensor, often computed from a history of recent maximum values ("delayed scaling"). Simple, but one outlier value wastes the range for the whole tensor.
  • Fine-grained scaling (DeepSeek-V3): per 1ร—128 tile for activations and per 128ร—128 block for weights, with higher-precision accumulation. It tolerates outliers and was used to train a 671B MoE in FP8 end to end.
  • Microscaling formats (MXFP8, and the 4-bit MXFP4/NVFP4 on Blackwell): the scale is part of the format - one shared scale per small block of values - so hardware applies it directly.

What stays in higher precision: master weights and optimizer state (FP32), and sensitive operations - embeddings, the output head, normalization, attention softmax, and often the MoE router.

DeepSeek-V3's full training took 2.788M H800 GPU-hours, which DeepSeek attributes in part to FP8 training and its communication/compute overlap.


Measuring Efficiency: MFU

MFU = achieved model FLOPs per second / peak hardware FLOPs per second
    = (6 ยท N ยท tokens_per_second) / (num_gpus ยท peak_flops_per_gpu)

Use the dense peak (vendor spec sheets often quote sparse numbers that are 2ร— higher) in the precision you actually train in. Rough bands for large dense models on H100-class GPUs:

MFUInterpretation
< 20%Something is wrong - data loading, tiny micro-batches, communication not overlapped, many small kernels
30-45%Typical for well-tuned large runs (Llama 3 405B: 38-43% in BF16)
> 50%Excellent; usually needs custom kernels and careful overlap

Hardware FLOPs utilization (HFU) also counts recomputed activations, so HFU โ‰ฅ MFU when activation checkpointing is on.


Fault Tolerance

At 16K GPUs, failures are routine. During a 54-day period of Llama 3 405B pretraining, Meta logged 466 job interruptions, 419 of them unexpected - most traced to GPU or HBM faults, with others from network, host and software issues. The run still achieved over 90% effective training time.

What a large run needs:

  • Frequent, fast checkpoints. Asynchronous, sharded saves (e.g. torch.distributed.checkpoint.async_save) so saving doesn't stall training; in-memory or local-SSD checkpoints between slower remote saves.
  • Automated detection and restart. Health checks, NCCL timeouts and watchdogs to catch hung collectives; spare nodes to swap in; automatic resume from the last checkpoint.
  • Deterministic data loading. The data loader must resume at exactly the right sample after a restart, or you silently repeat or skip data.
  • Straggler and silent-corruption detection. One slow GPU slows every synchronous step; silent data corruption shows up as unexplained loss spikes, so compare per-rank statistics and replay suspicious steps.

Check Yourself

Check yourself
0 / 4 answered
  1. Why is tensor parallelism normally kept within a single NVLink domain?
  2. A run has 16 pipeline stages and 16 micro-batches per step with a plain 1F1B schedule. Roughly what fraction of time is the pipeline bubble?
  3. Why did DeepSeek-V3 use fine-grained (tile and block) FP8 scaling instead of one scale per tensor?
  4. A cluster of 1,024 H100s trains a 70B dense model at 1.0M tokens/second. What is the MFU in BF16?

Exercises

Exercise - Choose a layout

You are pretraining a 70B dense model with an 8K context on 1,024 H100s (128 nodes of 8 GPUs, NVLink inside each node, 400 Gb/s InfiniBand per GPU between nodes). Mixed-precision AdamW needs ~16 bytes of model state per parameter.

Propose TP, PP and DP/FSDP degrees. Show that model state fits in 80 GB per GPU, and say which dimension you would add later for a 128K-context extension stage.

Solution

One reasonable layout: TP = 8 (one node), PP = 1 or 2, FSDP across the remaining 64-128 ways. Model state = 70e9 ร— 16 B โ‰ˆ 1.12 TB. With TP = 8 and FSDP = 128 (PP = 1), each GPU holds โ‰ˆ 1.12 TB / 1,024 โ‰ˆ 1.1 GB of sharded state plus gathered layer weights and activations - comfortable. For the 128K stage, add context parallelism (e.g. CP = 4-16) so attention activations for the long sequence fit, reducing the FSDP degree accordingly.

Exercise - Measure a small run

Take the GPT From Scratch lab, run it on one GPU, and compute its MFU from the logged tokens/second (use 6 ร— parameters for FLOPs per token and your GPU's dense BF16 peak). Then enable --compile and recompute. Why is MFU for a 10M-parameter model so much lower than for a 70B model?

Study Notes

Must-know:

  • Five parallelism dimensions: DP/FSDP, TP (+SP), PP, CP (ring attention), EP (all-to-all)
  • Map the chattiest dimension to the fastest links: TP inside an NVLink domain; DP/FSDP across the network
  • Pipeline bubble โ‰ˆ (p - 1)/(m + p - 1); shrink with more micro-batches, interleaving, DualPipe
  • FP8: E4M3 forward / E5M2 backward; scaling granularity (per-tensor, fine-grained, microscaling) is the key design choice; master weights and sensitive ops stay in higher precision
  • MFU = 6N ร— tokens/s รท (GPUs ร— dense peak); 30-45% is typical for well-tuned large runs
  • Failures are routine at scale; async sharded checkpoints, auto-restart and deterministic data loading are mandatory

References

Last reviewed: 2026-09

โšกAI-assisted content - always verify, always explore multiple perspectivesยท