Skip to content

Commit d11a6ac

Browse files
authored
feat(training): launch canonical performance recipes (#4620)
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
1 parent bb7870f commit d11a6ac

15 files changed

Lines changed: 1883 additions & 620 deletions

File tree

scripts/performance/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
## NOTE: This directory will change a lot over the coming weeks
44

5-
- Scripts defined in `scripts/performance` are recipes optimized for performance. These scripts can launch pre-training experiments on Slurm based clusters.
5+
New runs of exact exported flat recipes should use `scripts/training/train.sh --recipe <function_name>`. The launcher
6+
discovers text pretraining, text SFT/PEFT, Qwen-VL pretraining, and Wan pretraining recipes automatically and selects
7+
their forward step. This directory remains the compatibility path for selector-based invocation, dataset replacement,
8+
topology resizing, and specialized benchmark controls. The training launcher preserves total GPU-count validation,
9+
the recipe process environment, and mock-data defaults for text SFT/PEFT; it does not inject offline defaults. The
10+
performance compatibility launcher continues to own its benchmark offline environment.
11+
Cluster-specific CPU/NUMA binding, Slurm segment sizing, NCCL fabric settings, and `srun` arguments remain user
12+
supplied.
13+
14+
- Scripts defined in `scripts/performance` launch performance-optimized experiments on Slurm-based clusters.
615

716
## Performance recipe configs
817

@@ -11,7 +20,7 @@ launcher resolves recipes from that package by model, task, GPU count, GPU type,
1120
and config variant.
1221

1322
`setup_experiment.py` launches `bootstrap.py` on each rank. The bootstrap resolves and
14-
applies recipe-owned process settings before importing Torch, then replaces itself with
23+
applies recipe-owned process settings before importing the training loop, then replaces itself with
1524
either `run_script.py` for flat performance recipes or `run_recipe.py` for model recipes.
1625
Each training entrypoint therefore executes only once.
1726

scripts/training/README.md

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,22 @@ Megatron Bridge training provides a small public Slurm launcher:
66
./scripts/training/train.sh [launch options] [runner options] [KEY=VALUE overrides]
77
```
88

9-
`train.sh` invokes `setup_experiment.py` on a Slurm login node. Library recipes run through `run_recipe.py`; an exact
10-
flat performance recipe name is translated to the selector interface already supported by `run_script.py`. The setup
11-
layer owns resources, the container, explicitly forwarded environment variables, and explicit mounts. Without an
12-
active virtual environment, the shell entry point creates an isolated `nemo-run` environment rather than resolving
13-
the full GPU training dependency set on the login node.
9+
`train.sh` invokes `setup_experiment.py` on a Slurm login node and submits `run_recipe.py` directly through Slurm. The
10+
setup layer only owns resources, the container, explicitly forwarded environment variables, and explicit mounts.
11+
Recipe selection, dataset construction, and ConfigContainer overrides are resolved inside the training environment.
12+
Without an active virtual environment, the shell entry point creates an isolated `nemo-run` environment rather than
13+
resolving the full GPU training dependency set on the login node.
1414

1515
`launch_with_nemo_run.py` and `launch_with_sbatch.sh` remain available for their existing specialized workflows; `train.sh` is the compact recipe-oriented path.
1616

1717
## Selection rules
1818

19-
Choose exactly one of a complete recipe or a model selector. `--recipe` and `--model` are mutually exclusive. The mode
20-
is inferred from a conventional complete recipe name; pass one of `--mode pretrain`, `--mode sft`, `--mode lora`, or
21-
`--mode dora` when using `--model` or when the name does not encode it.
19+
Choose exactly one of a complete recipe or a model selector. `--recipe` and `--model` are mutually exclusive. A complete
20+
recipe is discovered automatically from its exported function name, whether it is a library or benchmark recipe;
21+
there is no separate source flag. A model selector requires one of `--mode pretrain`, `--mode sft`, `--mode lora`, or
22+
`--mode dora`; a conventional complete recipe name infers its mode when `--mode` is omitted.
2223

23-
### Complete recipe
24+
### Library recipe
2425

2526
A complete recipe already identifies the model and default training configuration, so do not also pass `--model`:
2627

@@ -48,38 +49,61 @@ requested adapter scheme.
4849
--mode pretrain --dataset mock
4950
```
5051

51-
The default forward step is `llm_step`. Pass `--step-func NAME` explicitly for a recipe that needs another registered
52-
forward step. Common training, sequence-length, parallelism, optimization, and checkpoint fields also have convenience
53-
flags such as `-ms`/`--max_steps`, `-sl`/`--seq_length`, `-tp`/`--tensor_model_parallel_size`, and `--save_dir`.
54-
Use trailing `KEY=VALUE` overrides for every other `ConfigContainer` field.
52+
### Benchmark recipe
5553

56-
### Performance recipe
54+
The training launcher can run exact exported recipes from `src/megatron/bridge/perf_recipes`, including text
55+
pretraining, text SFT/PEFT, Qwen-VL pretraining, and Wan pretraining. The total allocation must match the GPU count
56+
encoded by the recipe name; the user selects the node shape, and the Slurm partition must provide the requested
57+
hardware:
5758

58-
Pass the complete exported performance recipe name through the same `--recipe` option; recipe type is inferred:
59+
`benchmark` is the unified runner's user-facing term. The existing `perf_recipes` package and `scripts/performance/`
60+
compatibility paths retain their legacy names.
5961

6062
```bash
6163
./scripts/training/train.sh \
6264
--nodes 2 --gpus-per-node 8 \
6365
--account ACCOUNT --partition PARTITION \
64-
--container-image /path/to/container.sqsh \
65-
--env HF_TOKEN \
66-
--recipe qwen3_30b_a3b_pretrain_16gpu_h100_bf16_config
66+
--container-image IMAGE \
67+
--recipe qwen3_30b_a3b_pretrain_16gpu_h100_bf16_config \
68+
--mode pretrain
6769
```
6870

69-
The GPU count encoded in the recipe name must equal `--nodes × --gpus-per-node`; the user-provided
70-
`--gpus-per-node` determines the node shape. This compact route supports exact exported recipe names only;
71-
model-family selectors and advanced performance-launcher controls remain on `scripts/performance` during migration.
72-
The launcher discovers the exact public export from source and derives the existing runner selectors from its name;
73-
the performance parser and runner remain unchanged. Use an image containing the same Bridge revision and recipe
74-
export. Two SFT/PEFT names exported by both recipe packages retain their existing library route. Forward `HF_TOKEN`
75-
with `--env HF_TOKEN` when the selected recipe needs online Hugging Face access.
71+
Benchmark recipes provide canonical defaults for their dataset, parallelism topology, batch sizes, sequence length,
72+
precision, dispatcher, CUDA-graph settings, and process environment. Trailing `KEY=VALUE` overrides are applied to their
73+
`ConfigContainer` in the same way as library recipes; an overridden run no longer represents the canonical benchmark
74+
configuration. Benchmark recipes retain their selected dataset type, so `--dataset` is not supported on this path.
75+
Recipe environment defaults are installed before the launcher enters the training stack; values explicitly set by the
76+
shell or Slurm environment retain precedence.
77+
78+
The launcher does not infer offline mode, cluster-specific CPU/NUMA binding, Slurm segment sizing, or NCCL fabric
79+
settings from the recipe name. Supply those deployment settings explicitly through the target cluster's launcher
80+
configuration, repeated `--srun-arg` options, or exported values forwarded with `--env NAME`.
81+
82+
The runner selects the registered text, multimodal, audio, omni, or diffusion forward step from the recipe identity,
83+
regardless of which recipe package exports it. The compatibility launcher at
84+
`scripts/performance/setup_experiment.py` remains available for selector-based invocation, dataset replacement, and
85+
specialized legacy controls that are not part of the compact training CLI.
86+
87+
Text SFT/PEFT benchmark recipes retain the flat runner's mock-data default. Qwen-VL and Wan recipes retain their
88+
model-specific dataset configuration. Exported benchmark PEFT recipes are fixed LoRA configs; DoRA remains available
89+
through configurable library recipes. Explicit benchmark dataset replacement remains on the compatibility launcher.
90+
91+
Five legacy duplicate names resolve to the benchmark definition; their library workloads remain available through
92+
the corresponding generic recipe aliases. New recipe names should be unique across both packages.
93+
94+
Text recipes default to `llm_step`; all recipes infer their modality-specific forward step from the same registry.
95+
Pass `--step-func NAME` to override that selection. Common training,
96+
sequence-length, parallelism, optimization, and checkpoint fields also have convenience flags such as
97+
`-ms`/`--max_steps`, `-sl`/`--seq_length`, `-tp`/`--tensor_model_parallel_size`, and `--save_dir`. Use trailing
98+
`KEY=VALUE` overrides for every other `ConfigContainer` field.
7699

77100
## Dataset selection
78101

79-
`--dataset` accepts source selectors and named dataset presets rather than internal dataset config class names.
102+
For library recipes, `--dataset` accepts source selectors and named dataset presets rather than internal dataset config class names.
80103
Each name selects a `DatasetConfig` preset; the config type selects the existing runtime builder. Trailing
81104
`dataset.*` overrides are applied directly after preset selection. Use typed fields for source, preprocessing, packing,
82105
and loader settings; use `dataset.dataset_kwargs={...}` only for extra options consumed by a dataset implementation.
106+
Benchmark recipes retain their recipe-owned dataset and reject `--dataset`.
83107

84108
| Value | Kind | Mode | Behavior |
85109
|---|---|---|---|
@@ -139,7 +163,8 @@ shared mounted storage.
139163

140164
The hosted VLM names use the existing Hugging Face dataset adapters and retain the processor and in-batch packing
141165
settings from the selected VLM recipe. `raven`, `rdr`, and `llava-video-178k` derive deterministic 95/5 train and
142-
validation slices; `cord-v2` and `medpix` use their published validation splits. Pass a VLM forward step explicitly.
166+
validation slices; `cord-v2` and `medpix` use their published validation splits. The runner selects the registered VLM
167+
forward step from the recipe name; pass `--step-func` only to override it.
143168

144169
For local JSON/JSONL, select `local-vlm` and set
145170
`dataset.source.load_kwargs.data_files.train=/path/to/train.jsonl`. Optional split overrides are
@@ -179,9 +204,9 @@ directory:
179204

180205
## Overrides
181206

182-
Every `ConfigContainer` field can be set with trailing `KEY=VALUE` arguments. Common fields also accept the convenience
183-
flags listed by `run_recipe.py --help`. For example, batch sizes and training duration belong under `train`, not
184-
`model`:
207+
Every selected recipe's `ConfigContainer` fields can be set with trailing `KEY=VALUE` arguments. Common fields also
208+
accept the convenience flags listed by `run_recipe.py --help`. For example, batch sizes and training duration belong
209+
under `train`, not `model`:
185210

186211
```bash
187212
./scripts/training/train.sh \
@@ -199,6 +224,9 @@ Precedence is recipe defaults, the selected dataset configuration, common conven
199224
`ConfigContainer` overrides. A trailing override therefore wins when it targets the same field as a convenience
200225
argument.
201226

227+
Overrides take a benchmark recipe outside its canonical configuration. Use
228+
`scripts/performance/setup_experiment.py` for specialized workflows that the unified launcher has not migrated yet.
229+
202230
## Slurm and containers
203231

204232
Required Slurm arguments are:
@@ -215,10 +243,8 @@ Set `CONTAINER_IMAGE` to avoid repeating `--container-image`. On clusters that a
215243
forwarded implicitly. Export credentials in the launcher environment, then repeat `--env NAME` to forward names without
216244
materializing their values in the generated sbatch script. Repeat `--mount HOST` for the same host and container path, or use
217245
`--mount HOST:CONTAINER` when the paths differ. Mount every dataset, checkpoint, cache, and output path the job needs.
218-
219-
The launcher adds no cluster-specific `srun` flags. Repeat
220-
`--srun-arg=ARG` for every flag required by the target cluster. For example,
221-
a Pyxis/Enroot cluster may use:
246+
The launcher adds no cluster-specific `srun` flags by default. Repeat `--srun-arg=ARG` for every flag required by the
247+
target cluster. For example, a Pyxis/Enroot cluster may use:
222248

223249
```bash
224250
--srun-arg=--mpi=pmix \
@@ -228,8 +254,9 @@ a Pyxis/Enroot cluster may use:
228254

229255
The `=` form is required when `ARG` begins with `-`.
230256

231-
Common NCCL, Transformer Engine, tokenizer, and allocator environment defaults are applied to both library and
232-
performance recipes. Explicitly inherited environment names take precedence over these defaults.
257+
The compact launcher does not add rank-command prefixes or extra sbatch parameters such as `segment`. Configure those
258+
through the target cluster integration, or use `scripts/performance/setup_experiment.py` when its compatibility NUMA
259+
and segment policies are required.
233260

234261
The launcher submits the experiment in detached mode and returns after Slurm accepts the job. Inspect its state and
235262
logs with the cluster's normal `squeue`, `sacct`, and log-file workflow.
@@ -244,6 +271,10 @@ uv run python scripts/training/run_recipe.py \
244271
--dry-run logger.save_config_filepath=/tmp/config.yaml
245272
```
246273

274+
For a benchmark dry run, use the complete flat recipe name and omit `--dataset`. The rank-local dry run discovers the
275+
recipe and validates the final config against the total GPU count encoded in that name without
276+
requiring a live allocation; the submission dry run additionally validates `--nodes` and `--gpus-per-node`.
277+
247278
## Rank-local entry point
248279

249280
`run_recipe.py` remains available for existing distributed environments that already own process launch:
@@ -257,4 +288,5 @@ uv run python -m torch.distributed.run --nproc_per_node=2 \
257288
model.sequence_parallel=true
258289
```
259290

260-
This entry point loads library recipes for functional pretraining, SFT, LoRA, and DoRA.
291+
This entry point loads library recipes for pretraining, SFT, LoRA, and DoRA, and all exact exported
292+
benchmark recipes when selected explicitly.

0 commit comments

Comments
 (0)