/nemo-mbridge-multi-node-slurm
Convert single-node scripts to multi-node Slurm sbatch jobs and debug common multi-node failures. Covers srun-native vs uv run torch.distributed approaches, container setup, NCCL timeouts, OOM sizing for MoE models, and interactive allocation.
$ npx -y skills add NVIDIA/skills --skill nemo-mbridge-multi-node-slurm --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/nemo-mbridge-multi-node-slurm
Context preview
The summary Claude sees to decide when to auto-load this skill.
Convert single-node scripts to multi-node Slurm sbatch jobs and debug common multi-node failures. Covers srun-native vs uv run torch.distributed approaches, container setup, NCCL timeouts, OOM sizing for MoE models, and interactive allocation.
SKILL.md
nemo-mbridge-multi-node-slurm.SKILL.mdname: nemo-mbridge-multi-node-slurm
description: Convert single-node scripts to multi-node Slurm sbatch jobs and debug common multi-node failures. Covers srun-native vs uv run torch.distributed approaches, container setup, NCCL timeouts, OOM sizing for MoE models, and interactive allocation.
license: Apache-2.0
when_to_use: Writing or converting Slurm sbatch scripts, scaling to multiple nodes, debugging NCCL/launch failures, or investigating a commit that caused multi-node training failures; 'run on multiple nodes', 'sbatch script', 'NCCL timeout', 'multi-node OOM'.
Multi-Node Slurm
Convert single-node `uv run python -m torch.distributed.run` commands into multi-node Slurm sbatch scripts with Enroot container support, and debug common multi-node failures.
First Answer Checklist
When converting or debugging Bridge multi-node jobs, answer in this order:
1. Prefer the **srun-native** launch shape for Bridge scripts that reach `initialize.py`: `#SBATCH --ntasks-per-node=8` and a direct `srun ... uv run python <script> ...` launch. Do not wrap these jobs in `python -m torch.distributed.run`. 2. State that Bridge derives `RANK`, `WORLD_SIZE`, `LOCAL_RANK`, `MASTER_ADDR`, and `MASTER_PORT` from SLURM variables during `initialize.py` distributed init. 3. Require shared paths and matching container mounts for the repo, data, logs, `HF_HOME`, `UV_CACHE_DIR`, and `NEMO_HOME`. 4. For NCCL timeout reports, do these first-log checks before speculating:
- grep for real errors while filtering warning/frame noise
- inspect `Failures:` to find the first failed rank and node
- grep for `ncclUniqueId`, `timeout`, or `crash on rank 0`
Two Approaches: srun-native vs uv run torch.distributed
| Approach | `ntasks-per-node` | Process spawning | Best for | |---|---|---|---| | **srun-native** (preferred) | 8 | Slurm spawns 8 tasks/node | Conversion, inference, Bridge scripts | | **uv run torch.distributed** (legacy) | 1 | `uv run python -m torch.distributed.run` spawns 8 procs/node | MLM pretrain_gpt.py |
**Prefer srun-native** — simpler, avoids shell escaping issues with TRAIN_CMD. Megatron Bridge auto-derives `RANK`, `WORLD_SIZE`, `LOCAL_RANK`, `MASTER_ADDR`, `MASTER_PORT` from SLURM env vars (`SLURM_PROCID`, `SLURM_NTASKS`, `SLURM_LOCALID`, `SLURM_NODELIST`) via `common_utils.py` helpers called during `initialize.py` distributed init, so you never need to set them manually.
Cluster Environment
Use a shared filesystem for the repository, data, logs, `HF_HOME`, `UV_CACHE_DIR`, and `NEMO_HOME`. `NEMO_HOME` must not use the container-local default (`/root/.cache/nemo`) for multi-node SFT/PEFT jobs, because packed-sequence data prepared on node 0 must be visible to the other nodes.
Keep credentials out of sbatch templates and logs. Provide `HF_TOKEN`, `GH_TOKEN`, and `WANDB_API_KEY` through the scheduler environment or a restricted secrets file, and never hardcode token values in the script body. For copy-paste environment and sbatch templates, read `references/templates.md`.
Log Directory
<SHARED_FS>/logs/<job_name>_<suffix>
srun-native Approach (Preferred)
Slurm spawns all processes directly. No `torch.distributed.run`, no TRAIN_CMD escaping.
SBATCH Headers
#SBATCH --job-name=<model>-<task>
#SBATCH --nodes=<NNODES>
#SBATCH --ntasks-per-node=8 # Slurm spawns 8 tasks per node
#SBATCH --gpus-per-node=8
#SBATCH --time=00:30:00
#SBATCH --account=<YOUR_ACCOUNT>
#SBATCH --partition=batch
#SBATCH --output=<SHARED_FS>/logs/<job_name>_%j.log
#SBATCH --exclusive
Build and Launch
Use a two-phase `srun` pattern: first run a single-process `uv sync` to populate the shared cache, then launch the full multi-node job. The full copy-paste version lives in `references/templates.md`.
srun-native Key Points
- Phase 1 runs `uv sync` once on a single node/process, building all wheels into the shared cache on Lustre
- Phase 2's `uv sync` is a fast no-op (everything is cached) — safe to run on all ranks without sleep guards
- `initialize.py` + `common_utils.py` auto-set `RANK`, `WORLD_SIZE`, `LOCAL_RANK`, `MASTER_ADDR`, `MASTER_PORT` from SLURM env vars
- Env vars like `HF_TOKEN`, `HF_HOME`, `UV_CACHE_DIR` exported at sbatch level are inherited by srun tasks
- Reference: `examples/models/glm/glm_45v/slurm_sft.sh`, `examples/models/minimax/minimax_m2/slurm_conversion.sh`
---
uv run torch.distributed Approach (Legacy)
Use when the script requires `torch.distributed.run` (e.g., MLM pretrain_gpt.py) or when Bridge's `initialize.py` is not in the call path.
1. Add SBATCH Headers
#SBATCH --job-name=<model>-<framework>
#SBATCH --nodes=<NNODES>
#SBATCH --ntasks-per-node=1 # ALWAYS 1 — torchrun handles per-node spawning
#SBATCH --gpus-per-node=8
#SBATCH --time=00:30:00
#SBATCH --account=<YOUR_ACCOUNT>
#SBATCH --partition=batch
#SBATCH --output=<SHARED_FS>/logs/<job_name>_%j.log
#SBATCH --exclusive
**Critical**: `--ntasks-per-node=1`, NOT 8. `uv run python -m torch.distributed.run --nproc_per_node=8` spawns 8 processes per node. Using `ntasks-per-node=8` causes EADDRINUSE port collisions (8 tasks x 8 procs = 64 per node).
2. Convert to Multi-Node
Replace single-node:
uv run python -m torch.distributed.run --nproc_per_node=8 \
<script> <args>
With multi-node (inside `TRAIN_CMD` string):
uv run python -m torch.distributed.run \
--nproc_per_node=8 \
--nnodes=\${SLURM_JOB_NUM_NODES} \
--node_rank=\${SLURM_NODEID} \
<script> <args>`MASTER_ADDR` and `MASTER_PORT` are auto-derived from SLURM env vars by `initialize.py` / `common_utils.py` — no need to set them.
3. Wrap in TRAIN_CMD + two-phase srun
Use the same two-phase pattern: first a single-process srun to warm the uv cache, then the full run.
Set runtime variables inside the container, but do not inject token values into a long `bash -c` string. Export credentials through the scheduler or source a r
Read more
name: nemo-mbridge-multi-node-slurm description: Convert single-node scripts to multi-node Slurm sbatch jobs and debug common multi-node failures. Covers srun-native vs uv run torch.distributed approaches, container setup, NCCL timeouts, OOM sizing for MoE models, and interactive allocation. license: Apache-2.0 when_to_use: Writing or converting Slurm sbatch scripts, scaling to multiple nodes, debugging NCCL/launch failures, or investigating a commit that caused multi-node training failures; 'run on multiple nodes', 'sbatch script', 'NCCL timeout', 'multi-node OOM'.
Multi-Node Slurm
Convert single-node `uv run python -m torch.distributed.run` commands into multi-node Slurm sbatch scripts with Enroot container support, and debug common multi-node failures.
First Answer Checklist
When converting or debugging Bridge multi-node jobs, answer in this order:
1. Prefer the **srun-native** launch shape for Bridge scripts that reach `initialize.py`: `#SBATCH --ntasks-per-node=8` and a direct `srun ... uv run python <script> ...` launch. Do not wrap these jobs in `python -m torch.distributed.run`. 2. State that Bridge derives `RANK`, `WORLD_SIZE`, `LOCAL_RANK`, `MASTER_ADDR`, and `MASTER_PORT` from SLURM variables during `initialize.py` distributed init. 3. Require shared paths and matching container mounts for the repo, data, logs, `HF_HOME`, `UV_CACHE_DIR`, and `NEMO_HOME`. 4. For NCCL timeout reports, do these first-log checks before speculating:
- grep for real errors while filtering warning/frame noise
- inspect `Failures:` to find the first failed rank and node
- grep for `ncclUniqueId`, `timeout`, or `crash on rank 0`
Two Approaches: srun-native vs uv run torch.distributed
| Approach | `ntasks-per-node` | Process spawning | Best for | |---|---|---|---| | **srun-native** (preferred) | 8 | Slurm spawns 8 tasks/node | Conversion, inference, Bridge scripts | | **uv run torch.distributed** (legacy) | 1 | `uv run python -m torch.distributed.run` spawns 8 procs/node | MLM pretrain_gpt.py |
**Prefer srun-native** — simpler, avoids shell escaping issues with TRAIN_CMD. Megatron Bridge auto-derives `RANK`, `WORLD_SIZE`, `LOCAL_RANK`, `MASTER_ADDR`, `MASTER_PORT` from SLURM env vars (`SLURM_PROCID`, `SLURM_NTASKS`, `SLURM_LOCALID`, `SLURM_NODELIST`) via `common_utils.py` helpers called during `initialize.py` distributed init, so you never need to set them manually.
Cluster Environment
Use a shared filesystem for the repository, data, logs, `HF_HOME`, `UV_CACHE_DIR`, and `NEMO_HOME`. `NEMO_HOME` must not use the container-local default (`/root/.cache/nemo`) for multi-node SFT/PEFT jobs, because packed-sequence data prepared on node 0 must be visible to the other nodes.
Keep credentials out of sbatch templates and logs. Provide `HF_TOKEN`, `GH_TOKEN`, and `WANDB_API_KEY` through the scheduler environment or a restricted secrets file, and never hardcode token values in the script body. For copy-paste environment and sbatch templates, read `references/templates.md`.
Log Directory
<SHARED_FS>/logs/<job_name>_<suffix>
srun-native Approach (Preferred)
Slurm spawns all processes directly. No `torch.distributed.run`, no TRAIN_CMD escaping.
SBATCH Headers
#SBATCH --job-name=<model>-<task> #SBATCH --nodes=<NNODES> #SBATCH --ntasks-per-node=8 # Slurm spawns 8 tasks per node #SBATCH --gpus-per-node=8 #SBATCH --time=00:30:00 #SBATCH --account=<YOUR_ACCOUNT> #SBATCH --partition=batch #SBATCH --output=<SHARED_FS>/logs/<job_name>_%j.log #SBATCH --exclusive
Build and Launch
Use a two-phase `srun` pattern: first run a single-process `uv sync` to populate the shared cache, then launch the full multi-node job. The full copy-paste version lives in `references/templates.md`.
srun-native Key Points
- Phase 1 runs `uv sync` once on a single node/process, building all wheels into the shared cache on Lustre
- Phase 2's `uv sync` is a fast no-op (everything is cached) — safe to run on all ranks without sleep guards
- `initialize.py` + `common_utils.py` auto-set `RANK`, `WORLD_SIZE`, `LOCAL_RANK`, `MASTER_ADDR`, `MASTER_PORT` from SLURM env vars
- Env vars like `HF_TOKEN`, `HF_HOME`, `UV_CACHE_DIR` exported at sbatch level are inherited by srun tasks
- Reference: `examples/models/glm/glm_45v/slurm_sft.sh`, `examples/models/minimax/minimax_m2/slurm_conversion.sh`
---
uv run torch.distributed Approach (Legacy)
Use when the script requires `torch.distributed.run` (e.g., MLM pretrain_gpt.py) or when Bridge's `initialize.py` is not in the call path.
1. Add SBATCH Headers
#SBATCH --job-name=<model>-<framework> #SBATCH --nodes=<NNODES> #SBATCH --ntasks-per-node=1 # ALWAYS 1 — torchrun handles per-node spawning #SBATCH --gpus-per-node=8 #SBATCH --time=00:30:00 #SBATCH --account=<YOUR_ACCOUNT> #SBATCH --partition=batch #SBATCH --output=<SHARED_FS>/logs/<job_name>_%j.log #SBATCH --exclusive
**Critical**: `--ntasks-per-node=1`, NOT 8. `uv run python -m torch.distributed.run --nproc_per_node=8` spawns 8 processes per node. Using `ntasks-per-node=8` causes EADDRINUSE port collisions (8 tasks x 8 procs = 64 per node).
2. Convert to Multi-Node
Replace single-node:
uv run python -m torch.distributed.run --nproc_per_node=8 \ <script> <args>
With multi-node (inside `TRAIN_CMD` string):
uv run python -m torch.distributed.run \
--nproc_per_node=8 \
--nnodes=\${SLURM_JOB_NUM_NODES} \
--node_rank=\${SLURM_NODEID} \
<script> <args>`MASTER_ADDR` and `MASTER_PORT` are auto-derived from SLURM env vars by `initialize.py` / `common_utils.py` — no need to set them.
3. Wrap in TRAIN_CMD + two-phase srun
Use the same two-phase pattern: first a single-process srun to warm the uv cache, then the full run.
Set runtime variables inside the container, but do not inject token values into a long `bash -c` string. Export credentials through the scheduler or source a r
Official, NVIDIA-verified Agent Skills for Claude Code, Codex, and other coding agents.
Other skills on nvidia-skills.
- /nvidia-skill-finder
Use for NVIDIA-related requests where an NVIDIA skill might help, even if the user did not ask for a skill. Trigger on NVIDIA products, hardware, software, SDKs, GPUs, Jetson/JetPack/L4T/BSP/SDK Manager/driver/flashing/setup, CUDA, NIM, NeMo, Omniverse/OpenUSD/SimReady,
Open skill - /accelerated-computing-cudf
Official NVIDIA-authored guidance for NVIDIA cuDF GPU DataFrames, pandas acceleration, dask-cuDF, ETL, joins, groupby, CSV/Parquet I/O, nullable semantics, and multi-GPU DataFrame workloads.
Open skill - /aiq-deploy
Use when asked to install, deploy, run, validate, troubleshoot, or stop NVIDIA AI-Q Blueprint infrastructure.
Open skill - /aiq-research
Use when asked to run deep research or AI-Q research through a reachable NVIDIA AI-Q Blueprint backend.
Open skill - /amc-run-sample-calibration
Run end-to-end calibration on the shipped sample dataset (sdg_08_2_sample_data_010926.zip) against a running AMC microservice. Use when user says 'test sample dataset', 'run sample calibration', 'verify AMC install', or 'launch and test'.
Open skill - /amc-run-video-calibration
Calibrate a new dataset from pre-recorded video files via the AutoMagicCalib REST API. Use when user has local MP4s and says 'calibrate my videos', 'run AMC on these videos', or similar. For RTSP/live streams, use amc-run-rtsp-calibration instead.
Open skill

