Skip to main content

parallelism

Recommend a VALID ParallelismConfig and REJECT unsupported EP/CP/TP/ETP/PP combos BEFORE a GPU run. Auto-fire whenever the user: asks how to configure or pick a parallelism mode (expert/context/tensor/expert-tensor/pipeline parallelism, EP/CP/TP/ETP/PP, DDP/FSDP/HSDP); sets or asks about --expert_parallel_size / --context_parallel_size / --tensor_parallel_size / --expert_tensor_parallel_size / --pipeline_parallel_size / --pipeline_split / --pipeline_schedule / ep_scope / ep_size / cp_size / tp_size / expert_tp_size / pp_size / nvlink_domain_size; asks "which parallelism for this MoE / dense model / seq len / 8-GPU node / multi-node" or how to compute data_parallel_size; or hits a parallelism error/hang (DeepEP combine deadlock, NCCL hang, "must divide", "node-local", "not supported", ep4 "DeepEP dispatch groups" rejection, ParallelismConfig raise). Wrong advice wastes multi-GPU runs — this is the gate.

Datos de origen

Repositorio
whitecircle/halo
Última actividad en el origen
2 de octubre de 2026 a las 23:46
Idioma detectado de SKILL.md
inglés
Estrellas
816
Forks
38

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
2 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
parallelism
description
Recommend a VALID ParallelismConfig and REJECT unsupported EP/CP/TP/ETP/PP combos BEFORE a GPU run. Auto-fire whenever the user: asks how to configure or pick a parallelism mode (expert/context/tensor/expert-tensor/pipeline parallelism, EP/CP/TP/ETP/PP, DDP/FSDP/HSDP); sets or asks about --expert_parallel_size / --context_parallel_size / --tensor_parallel_size / --expert_tensor_parallel_size / --pipeline_parallel_size / --pipeline_split / --pipeline_schedule / ep_scope / ep_size / cp_size / tp_size / expert_tp_size / pp_size / nvlink_domain_size; asks "which parallelism for this MoE / dense model / seq len / 8-GPU node / multi-node" or how to compute data_parallel_size; or hits a parallelism error/hang (DeepEP combine deadlock, NCCL hang, "must divide", "node-local", "not supported", ep4 "DeepEP dispatch groups" rejection, ParallelismConfig raise). Wrong advice wastes multi-GPU runs — this is the gate.
allowed-tools
["Read","Grep","Glob"]
# Parallelism configuration gate Recommend a **valid** `ParallelismConfig` (`src/distributed/parallelism_config.py`) and **reject** unsupported combos before the user burns GPU hours. Be exact — the full reference matrix with per-row source citations is in **[matrix.md](matrix.md)**. Read it before giving a verdict on any non-trivial combo. ## PP is not available in this release The verdict on any `pipeline_parallel_size > 1` request is **not runnable — shard with EP/TP/CP**. The schedule engine is not shipped: `parallelism_config_from_args` (`src/training/parallelism_args.py`) rejects `pipeline_parallel_size > 1` at config time, before any rank math, and `PipelineRuntime` raises `NotImplementedError` on construction. What ships is the seam — the config surface, the rank math, the validators, the trainer gates, the stage/loss/checkpoint contracts — so every PP row below describes a validator or contract, never a launchable topology (`agent-docs/parallelism/pipeline-parallelism.md`). ## Source of truth - `src/distributed/parallelism_config.py` — the dataclass + `__post_init__` → `_validate()` sub-validators. Every config-time `raise` lives here. - `src/trainers/mixins/ep_introspection.py` `_setup_ep_gradient_checkpointing` — a **runtime** re-check of the multi-group >2-rank EP guard for hand-built configs that skipped validation (config-time raise is `_validate_single_domain_multigroup_ep`). - `CLAUDE.md` "## Parallelism" table + DeepEP / trainer-support notes. - User docs to cross-link: `agent-docs/parallelism/{expert,context,tensor,expert-tensor}-parallelism.md`, `agent-docs/parallelism/{data-parallelism,multi-node,data-loading}.md`. ## Key facts (from the code) - **The allowlist decides.** `SUPPORTED_AXIS_SETS` is checked first, before any rank math: plain DP, each axis alone (**EP, ETP, TP, CP, PP**), and **EP+TP, EP+CP, EP+ETP, PP+EP, PP+ETP**. Anything else is rejected with the mechanism from `AXIS_SET_MECHANISMS`, or a generic "no validated composition" when unlisted. The three PP entries are admitted by the allowlist but unreachable — the release gate above rejects `pp_size > 1` first. - `ep_group_size = ep_size * expert_tp_size` (the full EP process group). - `stage_world_size = world_size // pp_size`, then `data_parallel_size = stage_world_size // max(tp_size, cp_size, expert_tp_size)`; if that max is 1, `dp_size = stage_world_size`. **EP alone never reduces DP** (EP is orthogonal to DP). Only TP, CP, ETP, and PP reduce distinct-batch count. - Locality unit is `nvlink_domain_size` (auto = `gpus_per_node`; set it only on NVL72/MNNVL). "Node-local" below means "within one NVLink domain". - `ep_scope` defaults to `"auto"` in both the dataclass and on the CLI/YAML (`src/args/distributed_args.py`). `"auto"` resolves to `node` if `ep_group_size <= nvlink_domain_size`, else `global`. - PP flags parse but nothing runs: `--pipeline_parallel_size`, `--pipeline_microbatches`, `--pipeline_schedule` (`1f1b` | `gpipe`), `--pipeline_split`. ## How to pick a mode 1. **Dense (non-MoE) model?** EP/ETP do nothing — use **TP** (memory/large hidden) or **CP** (long seq), else plain FSDP2 DDP (`dp_size = world_size`). 2. **MoE model?** Start with **EP** (orthogonal to DP, keeps full DP). For finer expert sharding add **ETP** (EP+ETP); EP+TP shards attention only, and TP+ETP is rejected. For long sequences on MoE use **EP+CP** (node-local EP only). 3. **Long sequence, OOM on activations?** add **CP** (Ulysses, node-local). CP reduces DP by `cp_size`. 4. **Weights/attention too big for one GPU?** **TP** (node-local DTensor). TP reduces DP by `tp_size`. 5. **Model too deep for one rank, across nodes?** **PP** is the axis for it — the outermost one, the only one meant to cross NVLink domains — but it is **not available in this release** (above). Shard the depth with **EP** (MoE) or **TP**, widen the job, or cut `max_length`; never advise a `pipeline_parallel_size > 1` run. 6. Compute `dp_size` with the formula above and sanity-check it's >= 1 and the global batch is what you intend. ## Hard node-local / divisibility constraints - TP, CP, ETP must be **NVLink-local**: each must divide `nvlink_domain_size` and be `<= nvlink_domain_size`. - `ep_group_size` must divide its scope and not exceed it: `nvlink_domain_size` for `node`; for `global`, `stage_world_size` (`world_size // pp_size`), which it must also tile as equal contiguous per-domain blocks. - EP+TP: `ep_size` must be a multiple of `tp_size`, so each EP group spans whole TP groups. On one NVLink domain that means `ep_size=2` (`ep2+tp2` on 8 = four 2-rank EP groups) or an EP group that fills the domain (`ep8+tp2` on 8); `ep4+tp2` on 8 is the racy topology and is rejected. Above one domain multi-group EP+TP is rejected — use one global EP group (`ep_size == world_size`, `ep_scope: global`). - `world_size % gpus_per_node == 0` and `world_size % nvlink_domain_size == 0`. ## REJECT THESE (verdict = do not run) - **TP + CP** (`tp_size>1 and cp_size>1`) — DTensor mesh conflicts with CP groups. - **TP + ETP**, with or without EP (`tp_size>1 and expert_tp_size>1`) — attention-TP and expert-TP are mutually exclusive; use EP+TP **or** pure/EP+ETP. - **ETP + CP** (`expert_tp_size>1 and cp_size>1`) — ETP sub-EP dispatch groups break CP sequence reconstruction. - **Multi-group >2-rank EP on one NVLink domain** — the predicate is `num_nvlink_domains == 1 and ep_size > 2 and nvlink_domain_size > ep_group_size` (`is_racy_single_domain_multigroup_ep`): DeepEP combine barriers race FSDP2's DP-wide NCCL. **Rejected at config time** (`_validate_single_domain_multigroup_ep`); the trainer re-checks hand-built configs. Use `ep_size=2`, `ep_size = nvlink_domain_size` (the **domain**, not the node — they differ on NVL72), or `ep4 + etp2` — the supported 4-way expert split across 8 GPUs, since `ep_group_size = ep_size * expert_tp_size` fills the domain. `ep4 + tp2` lands on the same rejection: attention TP leaves `ep_group_size` untouched. The measured evidence and the two buffer failure modes live once, in **[matrix.md](matrix.md)** → row *Multi-group >2-rank EP on one NVLink domain*; every other skill links there instead of restating them. - **EP+CP with `ep_scope="global"`** (cross-NVLink-domain EP) — incompatible with CP. - **Node-local EP+CP where `ep_group_size != nvlink_domain_size`** — EP must be NVLink-orthogonal to CP. - **Any node-local size exceeding / not dividing the NVLink domain** (TP, CP, ETP, or `ep_group_size`) — "must divide" / "cannot exceed domain" raises. - **TP with indivisible attention heads** (`num_attention_heads % tp_size != 0`, or non-MLA GQA `num_key_value_heads % tp_size != 0`) — a split inside a head corrupts attention; `parallelize_attention.py` raises. - **HSDP with TP / ETP / EP** — `_validate_hsdp` rejects all three; **PP+HSDP** is refused by `_validate_pipeline_parallel`. HSDP wraps the standard DP path only: **pure DP or CP**. (EP already shards over the EP group; PP cannot restrict a 2-D mesh to a stage's rank block.) - **Every PP pairing outside the expert axes** — `PP+TP`, `PP+CP`, `PP+EP+TP`, `PP+EP+CP`, `PP+EP+ETP` (`PP+EP` and pure `PP+ETP` are admitted by the allowlist, both together are not; PP itself is not available in this release). Plus these PP-specific config-time raises: `pp_split` length mismatch or an entry < 1 (the sum-vs-layer-count check runs later, at model split); a stage that is not a whole NVLink domain; a 1-rank stage; `fsdp_shard_ep1_experts=False`; `use_hsdp=True`; `fsdp_reshard_after_forward=True`; `fsdp_reshard_after_backward=False`; `fsdp_defer_grad_sync=True`; `lowp_precision != "bf16"`; expert LoRA; and a PP-only knob (`pp_split`/`pp_microbatches`/`pp_schedule`) set at `pp_size=1`. At trainer construction PP also rejects `save_sharded_ep`, PEFT/LoRA, a live `ref_model`, `activation_offloading`, reentrant gradient checkpointing, `torch_compile`, a missing `max_length`, an image-bearing VLM run, and `per_device_eval_batch_size != per_device_train_batch_size`. Full list: `matrix.md`. - **`fsdp_shard_ep1_experts=False` with TP or CP**, and **`fsdp_reshard_after_forward=True` wherever an expert-distribution group exists** — the gate is `is_ep_mode` (`ep_group_size > 1`), so pure ETP (`ep_size=1`, `expert_tp_size>1`) is rejected alongside EP — **or with TP at `dp_size>1`**; **`fsdp_defer_grad_sync=True` with TP at `dp_size==1`** (no FSDP2 wrap to defer) **or with `fsdp_reshard_after_forward=True`** (the held unsharded gradient is the state ZeRO-3 shards — defer under ZeRO-2). `_validate_fsdp_settings` raises; QLoRA refuses every FSDP shaping knob at trainer construction. - **Expert LoRA with ETP** (`expert_tp_size > 1` + `expert_lora`) — `_validate_expert_tp` raises: the replicated adapter half would take a partial, never-synced gradient. - **LoRA/PEFT with TP** (`tp_size > 1`) — adapters are plain tensors outside the TP graph, so the replicated matrix diverges per rank and the sharded one is corrupted by the TP grad sync. `_validate_lora_tp_compatibility` (`src/trainers/mixins/validation.py`) raises at trainer construction, **native EP expert LoRA included** (its own message: the expert adapters live on the EP-distributed weights, which every TP gate skips by param identity). CP and pure ETP leave attention unsharded, so LoRA is fine there. - **CP with a trainer that doesn't support it** (DPO, KTO, GRPO online/offline/env/SDPG, reward, classification, distillation, embedding) — see matrix.md trainer table. - **PP with a trainer that doesn't support it** (online/env GRPO, SDPG, both distillation trainers, embedding) — `_supports_pp`. Moot while the release gate above rejects `pp_size > 1` first, but it is the gate a PP-capable trainer will be declared against. When rejecting, cite the exact reason and offer the nearest valid alternative (e.g. "ep_size=4 on 8 GPUs is rejected at config time → use ep_size=2, ep_size=8 (the whole domain), or ep4+etp2; EP+TP does not help — attention TP leaves `ep_group_size` at 4"). ## Sources of truth `matrix.md` + `agent-docs/parallelism/` document the supported/rejected combos. The code is the **ultimate** authority: `src/distributed/parallelism_config.py` (the validators) and `src/trainers/mixins/ep_introspection.py` (the runtime EP-GC setup guard) decide what actually raises or deadlocks — when a doc, this skill, or memory disagrees, or you are unsure, read those files before advising. (`CLAUDE.md`: docs-first, the code wins.) Related skill: `data` (sharded dataset ↔ `data_parallel_size`).
Ver en GitHub