Best for
- Choosing between DDP, FSDP2, DeepSpeed ZeRO stages 1/2/3, or Megatron-LM
- Training Mixture-of-Experts (MoE) models: expert parallelism, all-to-all, load balancing
- OOM errors on multi-GPU training runs
vasilyu1983/AI-Agents-public/frameworks/shared-skills/skills/ai-distributed-training/SKILL.md
Guides multi-GPU pre-training: DDP, FSDP2, ZeRO, tensor/pipeline/expert parallelism, fp8/Muon. Use when scaling a run, training MoE, or reproducing GPT-2 on rented GPUs.
Decision brief
Operational focus: picking and implementing the right parallelism strategy, not the theory. Covers data parallelism through FSDP/ZeRO/tensor+pipeline parallelism, memory-efficient attention, mixed precision at scale, activation checkpointing, rented-GPU cost discipline, and repr…
In this controlled same-task single run, enabling ai-distributed-training changed the output from 4141 non-whitespace characters and 10 headings to 3982 characters and 7 headings. Matches among 8 signals extracted from the pinned source changed from 0 to 0. Both actual outputs are shown; this is a structural observation, not a quality score or a universal performance claim.
Design and implement a representative production change for a TypeScript webhook retry service. Include the key code or pseudocode, tradeoffs, and verification steps. The deliverable must specifically reflect this user intent: Guides multi-GPU pre-training: DDP, FSDP2, ZeRO, tensor/pipeline/expert parallelism, fp8/Muon. Use when scaling a run, training MoE, or reproducing GPT-2 on rented GPUs.

Baseline: 4141 non-whitespace characters, 10 headings, and 32 list items.

With Skill: 3982 non-whitespace characters, 7 headings, and 33 list items.
| Observation | Without Skill | With Skill |
|---|---|---|
| Source-signal coverage | 0/8: none | 0/8: none |
| Output structure | 4141 chars · 10 headings · 32 list items · 1 code blocks | 3982 chars · 7 headings · 33 list items · 5 code blocks |
| Verification and caution signals | 12 verification signals · 5 risk/limitation signals | 12 verification signals · 3 risk/limitation signals |
Use the ai-distributed-training Skill pinned at c95ab14ef8cf for my task. Follow its source-specific constraints around `ai-distributed-training`, `distributed`, `training`, `systems`, then return the finished deliverable with explicit assumptions, verification, failure conditions, and limits. Do not treat the Skill text as a factual source or claim that a single demonstration proves universal performance.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Declared | Source record | Install path and trigger |
| Claude Code | Declared | Source record | Install path and trigger |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/vasilyu1983/AI-Agents-public --skill "frameworks/shared-skills/skills/ai-distributed-training"Inspect the Agent Skill "ai-distributed-training" from https://github.com/vasilyu1983/AI-Agents-public/blob/53f6cb73ea53a2646e3e7d4665062ad66f3683ac/frameworks/shared-skills/skills/ai-distributed-training/SKILL.md at commit 53f6cb73ea53a2646e3e7d4665062ad66f3683ac. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
1. Confirm scale and budget: how many GPUs, which provider, on-demand or spot, target hours. 2. Profile at small scale: run nsys or torch.profiler on 1-2 GPUs before adding more. 3. Pick parallelism strategy: data parallel (DDP) - FSDP/ZeRO - tensor+pipeline only as needed. 4. E…
model = DistributedDataParallel(model, deviceids=[localrank]) python
Review the “ASCII Flow” section in the pinned source before continuing.
Activate when the user asks about:
Single-GPU pre-training build, data pipelines, tokenization - ai-pretraining
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 98/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 80 | Source | Repository attention, not individual Skill quality |
| Compatibility | 2 platforms | Source | Declared in the catalog source record |
| Usage guide | tested outcome page | Tested | Generated or reviewed according to the visible evidence level |
Pinned source
Operational focus: picking and implementing the right parallelism strategy, not the theory. Covers data parallelism through FSDP/ZeRO/tensor+pipeline parallelism, memory-efficient attention, mixed precision at scale, activation checkpointing, rented-GPU cost discipline, and reproducing GPT-2 124M as the canonical sanity check.
Profile before you scale. Debug on the smallest GPU that fits. Stop the instance when done.
single GPU (debug/prototype)
└─ DDP: replicate model, all-reduce gradients — linear scale up to ~8 GPUs
└─ FSDP2 / ZeRO: shard optimizer state, gradients, params across GPUs
└─ tensor parallelism: split weight matrices across GPUs (intra-node)
└─ pipeline parallelism: split layers across nodes (inter-node)
└─ context parallelism: shard the sequence dim (long context)
└─ expert parallelism: route MoE experts across GPUs (all-to-all)
└─ N-D parallelism: DP + TP + PP + CP + EP (frontier MoE)
profile-before-scale
└─ nsys / torch.profiler → find bottleneck (compute? memory? dataloader?)
└─ fix bottleneck at small scale, then scale
Activate when the user asks about:
nsys or torch.profiler on 1-2 GPUs before adding more.| Decision | Default Move | Promote When | Avoid |
|---|---|---|---|
| Parallelism for ≤8 GPUs | DDP or FSDP2 (ZeRO-2 equiv) | Model does not fit in one GPU | Jumping to tensor parallel before model is too large |
| Parallelism for >8 GPUs | FSDP2 (ZeRO-3 equiv) or DeepSpeed ZeRO-3 | Multiple nodes needed | Mixing FSDP + DeepSpeed naively |
| FSDP version | FSDP2 (fully_shard, DTensor) | All new PyTorch projects | FSDP1 (FullyShardedDataParallel) — deprecated since PyTorch 2.11 |
| MoE routing at scale | Expert parallelism + all-to-all | Sparse MoE, experts exceed one GPU | TP on experts before EP (all-to-all is cheaper on NVLink) |
| Attention kernel | FlashAttention-2/3 | A100+ / H100 (FA3 = Hopper) | xformers as default (verify support for your GPU) |
| Mixed precision | bf16 | A100 / H100 (native bf16) | fp16 on A100+ (bf16 is safer; less loss spike risk) |
| Low-precision training | fp8 (H100 TransformerEngine/torchao) | Proven recipe + per-tile scaling | nvfp4/fp8 without loss-vs-bf16 validation |
| Optimizer | AdamW | Default, well-understood | — |
| Optimizer (frontier) | Muon / MuonClip | Matmul params, want ~1.3–1.5× token efficiency | Muon on embeddings/scalars (keep those on AdamW) |
| Gradient checkpointing | Always on for large models | Any model >1B params | Disabled when GPU memory is not a constraint |
| Optimizer state sharding | ZeRO-1 | Memory pressure from optimizer | ZeRO-3 when params fit on one GPU |
| Compile | torch.compile on the model | Want MFU; using torchtitan/FSDP2 | Leaving eager mode on long production runs |
| Framework for ≤7B pre-training | litgpt or torchtitan | Need Megatron-grade scale | Rolling your own training loop before reading existing frameworks |
| Dev / debug GPU | Smallest A10G or L4 that fits | Need bf16 native | H100/B200/Rubin for debugging (cost bloat) |
| Production training GPU | H100; B200/GB200 NVL72 for frontier; Rubin NVL72 where available | Need fp8/nvfp4 + NVLink-domain scale | Renting Blackwell/Rubin to debug a 124M model |
| Checkpoint storage | S3-compatible object store + DCP async | Spot instances (checkpoint every N steps) | Local disk only (lost on preemption) |
Each worker holds a full model replica. Forward + backward runs independently per GPU. AllReduce synchronizes gradients. Scales well up to ~64 GPUs before communication becomes the bottleneck. Memory cost: full model + optimizer state on every GPU.
# PyTorch DDP minimal setup
model = DistributedDataParallel(model, device_ids=[local_rank])
PyTorch-native. Shards parameters, gradients, and optimizer state across all workers. Use FSDP2 (fully_shard) for all new work — the original FullyShardedDataParallel (FSDP1, FlatParameter-based) is deprecated as of PyTorch 2.11. FSDP2 shards each parameter individually as a DTensor (Shard(dim=0)), giving simpler/inspectable sharded state dicts, cleaner composition with TP/PP/CP via DeviceMesh, and tight torch.compile integration.
ZeRO-stage equivalents map onto reshard_after_forward:
reshard_after_forward=False → keep params gathered after forward (ZeRO-2-like: shard grads + optimizer state, trade memory for fewer all-gathers)reshard_after_forward=True (default) → re-shard params after forward (ZeRO-3-like: shard params + grads + optimizer state)# FSDP2 (PyTorch >=2.11). Shard each transformer block, then the root.
from torch.distributed.fsdp import fully_shard, MixedPrecisionPolicy
mp = MixedPrecisionPolicy(param_dtype=torch.bfloat16, reduce_dtype=torch.float32)
for block in model.layers:
fully_shard(block, mp_policy=mp)
fully_shard(model, mp_policy=mp)
FSDP1 (FullyShardedDataParallel + ShardingStrategy.FULL_SHARD/SHARD_GRAD_OP/NO_SHARD) still appears in older tutorials; migrate to FSDP2. Checkpoints are compatible across the two, but the construction API is not.
| Stage | What is Sharded | Memory Reduction | Overhead |
|---|---|---|---|
| ZeRO-1 | Optimizer state | ~4x vs baseline | Low |
| ZeRO-2 | Optimizer state + gradients | ~8x vs baseline | Low |
| ZeRO-3 | Optimizer state + gradients + params | ~64x vs baseline | Communication cost |
ZeRO-Infinity extends stage 3 to NVMe offload. Use only when GPU memory is genuinely exhausted — disk bandwidth becomes the bottleneck.
Splits weight matrices across GPUs within a node (column/row parallel linear). Requires high-bandwidth NVLink. Megatron-LM implements Transformer-specific tensor parallel (TP) with sequence parallel (SP) for activation memory reduction. Best for models that cannot fit even with full sharding, or where communication budget allows.
Splits model layers across nodes (or GPU groups). Interleaved schedules (1F1B) reduce pipeline bubble overhead. Adds complexity: microbatch sizing, bubble fraction tuning. Typically combined with TP and DP in 3-D parallelism (Megatron-LM, nanotron).
DualPipe (DeepSeek-V3, 2024) is a bidirectional pipeline schedule that fully overlaps forward/backward compute with communication, driving the bubble toward zero — the reference design for large MoE training where cross-node all-to-all would otherwise dominate.
Mixture-of-Experts models activate only a few experts per token, so total params (e.g. 1T) vastly exceed activated params (e.g. 32B). Expert parallelism (EP) places different experts on different GPUs; the router dispatches each token to its experts via all-to-all communication (dispatch), then a second all-to-all gathers results (combine). EP composes with DP/TP/PP/CP as an extra mesh dimension.
Key concerns specific to MoE training:
torch.distributed provides the all-to-all primitives.FlashAttention (Dao et al., 2022/2024): reorders attention computation to avoid materializing the full N×N attention matrix. Result: O(N) memory vs O(N²), significant speedup on A100/H100.
# PyTorch ≥2.3: select the Flash backend via the current API
from torch.nn.attention import sdpa_kernel, SDPBackend
with sdpa_kernel(SDPBackend.FLASH_ATTENTION):
out = F.scaled_dot_product_attention(q, k, v)
# (torch.backends.cuda.sdp_kernel(...) is the deprecated pre-2.3 form)
FlashAttention-3 (2024) targets H100 with further hardware-specific optimizations. xformers provides memory_efficient_attention as an alternative with broader GPU support.
bf16 (bfloat16) is the safe default for A100+ and H100. Same exponent range as fp32 (avoids the overflow spikes common in fp16), 16-bit mantissa precision. torch.cuda.amp.autocast(dtype=torch.bfloat16) or pass torch_dtype=torch.bfloat16. Gradient scaler (torch.cuda.amp.GradScaler) is needed for fp16 but not for bf16.
fp8 is now production-proven on Hopper (H100), not just emerging. DeepSeek-V3 trained at fp8 with fine-grained scaling — per-token 1×128 / per-block 128×128 tiles plus high-precision CUDA-core accumulation — keeping the loss within ~0.25% of bf16. Use TransformerEngine or torchao float8 for the linear layers; keep a bf16/fp32 master copy of weights and the optimizer state. Validate loss-vs-bf16 on your workload before committing a long run.
nvfp4 / fp4 arrives with Blackwell. The B200/GB200 add hardware FP4 (including NVIDIA's NVFP4, 16-element micro-scaled blocks with e4m3 scales, vs MXFP4's 32-element UE8M0 blocks). It has moved past pure research: NVIDIA pre-trained a 12B model on 10T tokens with NVFP4 matching the fp8 baseline (arXiv 2509.25149), and MXFP4 needed ~36% more tokens to reach the same loss — so NVFP4 is the stronger FP4 format. Still validate against bf16/fp8 on your own workload before a long run; the recipe (which tensors stay higher-precision, scaling, outlier handling) is less battle-tested than fp8.
torch.compile(model) (TorchInductor) fuses kernels and is essential for competitive MFU on modern hardware. It composes with FSDP2 and is on by default in torchtitan. Compile once outside the training loop; expect a warm-up cost on the first steps. Pair with bf16/fp8 — most of the published MFU numbers assume compile is on.
torch.utils.checkpoint.checkpoint(function, *args) recomputes activations during the backward pass instead of storing them. Reduces activation memory by ~sqrt(layers), adds ~33% compute overhead. Use on every transformer block for large models.
Selective checkpointing (checkpointing only the memory-expensive ops like attention) is supported in FSDP via checkpoint_wrapper.
AdamW remains the default and the best-understood choice. Its memory cost (two fp32 moments ≈ 2× params) is what ZeRO/FSDP optimizer-state sharding targets.
Muon / MuonClip is the notable frontier shift since 2024. Muon (Keller Jordan, originating in modded-nanoGPT speedruns) applies Newton–Schulz orthogonalization to 2-D matmul weight matrices, treating each weight as a matrix rather than a flat vector. It delivers roughly 1.3–1.5× token efficiency over AdamW on pre-training and holds the modded-nanoGPT GPT-2 speed records. "Muon is Scalable for LLM Training" (arXiv 2502.16982) supplied the two fixes — weight decay and per-parameter update-scale adjustment — that make it work at scale without bespoke tuning. By 2026 it trains trillion-param MoE in production: MuonClip (a stability-clamped variant) pre-trained Moonshot's Kimi K2 (1T-param MoE, 15.5T tokens; arXiv 2507.20534), and Muon now also underpins DeepSeek-V4 (arXiv 2606.19348 names Muon explicitly for faster convergence and stability) and GLM-4.5/GLM-5 (Zhipu/Z.ai; GLM-5's paper, arXiv 2602.15763, adds a "Muon Split" per-head orthogonalization plus a zero-redundancy distributed Muon implementation), plus Karpathy's nanochat. It is a serious AdamW replacement at frontier scale, not a speedrun curiosity. Re-verify against the primary report before quoting exact figures — these are recent releases and details can be revised.
Practical notes:
| Framework | Best For | Notes |
|---|---|---|
| litgpt | Research, ≤70B, HF-compatible | Clean PyTorch; easy to read |
| torchtitan | PyTorch-native large-scale | Meta's reference; FSDP2 + CP |
| nanotron | Efficient 3-D parallel | HuggingFace; powers BLOOM/IDEFICS training |
| levanter | TPU / JAX | Google; Chinchilla-optimal recipes |
| Megatron-LM | >70B, tensor+pipeline+data | NVIDIA; most complex, most scalable |
| modded-nanoGPT | Learning / GPT-2 reproduction | Keller Jordan; speed records; Muon optimizer |
| llm.c | Minimal C/CUDA GPT-2 | Karpathy; educational; fastest GPT-2 |
| nanochat | End-to-end small-model train+chat | Karpathy; uses Muon; modern reference loop |
| Megatron-Core / NeMo | Modular TP+PP+DP+EP building blocks | NVIDIA; library form of Megatron-LM for MoE + fp8 |
Target: ~3.28 loss on FineWeb/Hellaswag after ~10B tokens.
Using llm.c or modded-nanoGPT:
Full GPT-2 124M with full convergence checks: ~$100-300 depending on GPU type and provider.
For sharded training (FSDP2, TP, PP), a single-rank state_dict is the wrong pattern — it forces an all-gather of the full model onto one rank and serializes saving. Use torch.distributed.checkpoint (DCP):
dcp.async_save offloads the write so training continues while the checkpoint flushes to storage — critical on spot instances where every minute of stall is wasted cost.import torch.distributed.checkpoint as dcp
state = {"model": model, "optim": optimizer} # FSDP2 DTensors handled natively
dcp.async_save(state, checkpoint_id=f"s3://bucket/run/step-{step}")
cost ≈ $/GPU-hr × num_GPUs × training_hours
Example: 4×A100 80GB at $2.50/GPU-hr × 10 hours = $100
| Run Type | GPUs | Hours | Est. Cost |
|---|---|---|---|
| GPT-2 124M debug (single GPU) | 1×A10G | 2-4 h | $1-3 |
| GPT-2 124M full run | 4×A100 | 8-12 h | $80-150 |
| GPT-2 124M fast (H100 cluster) | 8×H100 | 1-2 h | $80-160 |
| 7B model pre-training (100B tok) | 8×A100 | ~100 h | ~$2000 |
| Frontier MoE / large dense (fp8/fp4) | GB200 or Rubin NVL72 | varies | rack-scale; reserve/quote pricing |
Always check current spot pricing on RunPod, Lambda Labs, Vast.ai, or Modal before budgeting. Spot/interruptible discounts are typically 30-70% off on-demand.
torch.profiler; check torch.cuda.memory_summary().fully_shard) or inherit unmaintained APIs.state_dict from sharded training: all-gathers the whole model onto one rank and stalls every other GPU. Use DCP (dcp.async_save) instead.See data/sources.json for curated primary sources across:
Before applying this skill on a non-trivial task, read learnings.consolidated.md in this directory (and learnings.md if present).
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to learnings.md via agents-skills-feedback-loop/scripts/append_learning.py. Do not modify SKILL.md itself.
Frequently asked questions
Operational focus: picking and implementing the right parallelism strategy, not the theory. Covers data parallelism through FSDP/ZeRO/tensor+pipeline parallelism, memory-efficient attention, mixed precision at scale, activation checkpointing, rented-GPU cost discipline, and repr…
The source record exposes this install command: npx skills add https://github.com/vasilyu1983/AI-Agents-public --skill "frameworks/shared-skills/skills/ai-distributed-training". Inspect the command and pinned source before running it.
The pinned source record declares support for: codex, claude code.
Alternatives
vasilyu1983/AI-Agents-public
Configures Claude Code hooks and Codex hooks.json/notify callbacks. Use when adding guardrails, preflight, audit trails, worktree automation, or budget enforcement.
vasilyu1983/AI-Agents-public
Guides iOS testing with XCTest, XCUITest, Swift Testing, simctl, and xcresult. Use when choosing destinations, controlling flakes, or parsing test artifacts for native apps.
vasilyu1983/AI-Agents-public
Scans public GitHub repos for agent skills, dev practices, and code patterns. Use when enriching skills, setting team policy, or researching a build domain.
vasilyu1983/AI-Agents-public
Designs and audits UI/UX systems with usability and accessibility requirements. Use when shaping flows, design systems, interaction patterns, or WCAG-aware product behavior.