Multi-Node Ray on Slurm
Multi-Node Ray on Slurm
Multi-Node Ray on Slurm
SlurmRayClient is a drop-in replacement for RayClient that bootstraps a multi-node Ray cluster under SLURM. The head node starts ray start --head, writes the assigned GCS port to a shared file, and waits for workers to join. Worker nodes block on the port file and call ray start --block. Only the head returns from start(), so your pipeline code runs on the head while workers stay attached to the cluster.
For details on container environments and SLURM-specific environment variables, refer to Container Environments. For the image-curation specific Slurm workflow, refer to Deploy Image Curation on Slurm.
Use SlurmRayClient when:
sbatch and want to span more than one node.For single-node SLURM jobs, the regular RayClient is sufficient.
uv script.Replace RayClient with SlurmRayClient. No other changes are required:
The head/worker split is determined automatically from SLURM_NODEID. Workers stay inside SlurmRayClient.start() for the duration of the job; the head runs your pipeline.
The repository ships two reference submit scripts at tutorials/slurm/:
submit_container.sh — launches the NGC NeMo Curator container via Pyxis on each allocated node. Recommended for production because the container ships a known-good environment.
Submit:
Both scripts default RAY_PORT_BROADCAST_DIR to ${CURATOR_DIR}/logs. Change this to a shared filesystem path (NFS, Lustre, GPFS) if your cluster’s /tmp is node-local — workers cannot read the head’s port file otherwise.
End-to-end tested on H100 nodes using the nvcr.io/nvidia/nemo-curator:26.02 container at the time SlurmRayClient was introduced. The reference workload is a word-count + GPU-tagging pipeline shipped in the tutorials/slurm/ directory; it works unchanged on subsequent container versions, including {{ container_version }}.
Sample output from the 2-node, 8-GPU run:
Check job status:
View logs (the bundled scripts write to logs/slurm_demo_<jobid>.log):
The first line of each node’s log identifies its role:
--time=00:10:00 for the demo; raise it to match your real workload.