Arrays#
An array runs one worker template many times, each copy with its own index. Use it for embarrassingly parallel work: a hyper-parameter sweep, one shard of a dataset per worker, a batch of evaluations. The copies are independent — none waits for another, and one failing does not stop the rest — and you can cap how many run at once so the array does not take every GPU of the workspace.
It is Astraeus' form of a Slurm job array.
How an array runs#
array.sizeworkers are created, named<run>-0…<run>-<size−1>.- Each worker has the template's whole ask: with
gpu_requests.count: 1, every copy gets one GPU. Nothing is split. - Worker
igetsASTRAEUS_ARRAY_TASK_ID=i(from 0) andASTRAEUS_ARRAY_SIZE=<size>.RANKandASTRAEUS_REPLICA_INDEXhold the same index, andWORLD_SIZEthe size. - Copies are placed independently, as room appears, and several may share a machine.
array.max_parallelcaps how many hold machines at once. The next waiting copy saysArray runs at most 10 workers at once.- Each copy restarts on its own under its
restart_policy; the run isCompletedwhen every copy completed, andFailedif any failed for good (3 of 100 workers failed; the first: Worker sweep-17 failed on gpu-02: Exited with code 1).
Run a parameter sweep#
100 learning-rate and batch-size combinations, one GPU each, at most 8 at a time, each with a one-hour limit.
import itertools, os
lrs = [1e-4, 3e-4, 1e-3, 3e-3, 1e-2]
batches = [16, 32, 64, 128]
seeds = range(5)
grid = list(itertools.product(lrs, batches, seeds)) # 100 combinations
i = int(os.environ["ASTRAEUS_ARRAY_TASK_ID"])
lr, batch, seed = grid[i]
train(lr=lr, batch=batch, seed=seed, out=f"/results/{i:03d}.json")
- New run: Name
sweep, Imagenvcr.io/nvidia/pytorch:24.08-py3, Commandpython, Arguments/data/code/sweep.py. - GPUs
1, CPU cores8, Memory32Gi(with an array, CPU and memory are per worker). - Drives:
datasets:/data,results:/results. - More options: Array size
100, At most in parallel8, Time limit1h. - Start run. Start is forced to independent for an array.
astra astraeus run has no array flag; use Slurm's:
#!/bin/bash
#SBATCH --array=0-99%8
#SBATCH --gres=gpu:1
#SBATCH --cpus-per-task=8
#SBATCH --mem=32G
#SBATCH --time=1:00:00
#SBATCH --container-image=registry.example.com/ml/sweep:1
python /opt/sweep/sweep.py
The script runs in the image, so the code must be in it (/opt/sweep here). Inside, read ASTRAEUS_ARRAY_TASK_ID: SLURM_ARRAY_TASK_ID is not set. astra cannot mount drives: for the results drive, use the API.
{
"metadata": { "name": "sweep" },
"spec": {
"array": { "size": 100, "max_parallel": 8 },
"task_template": {
"image": "nvcr.io/nvidia/pytorch:24.08-py3",
"command": "python",
"args": ["/data/code/sweep.py"],
"time_limit_seconds": 3600,
"datavolume_refs": [
{ "name": "datasets", "mount_path": "/data", "mode": "ReadOnly" },
{ "name": "results", "mount_path": "/results", "mode": "ReadWrite" }
],
"requested_resources": {
"cpu_cores": 8,
"memory_bytes": 34359738368,
"gpu_requests": { "count": 1 }
}
}
}
}
Give each copy a time limit: a run whose workers all state one can backfill, which on a busy cluster often starts copies sooner.
Follow an array#
The run's Workers tab lists every copy with its state, machine, GPUs and exit code; the readout says how many run (Workers 8 running of 100). Select Log on a row for that copy's output.
Limits#
| Limit | Value |
|---|---|
array.size |
1 to 10 000 |
array.max_parallel |
0 (no cap) to size |
| Start policy | Independent only: start: Gang or policy: Gang with an array is refused (An array's workers are independent: use policy Independent). |
| Worker groups | Not with task_groups. |
| Lifetime | Not with lifetime: Service. |
| Model engine | Not with model.engine. |
| Indices | Always 0 to size − 1, in steps of 1. |
Troubleshooting#
| Symptom | Cause | Fix |
|---|---|---|
| Every copy computes the same thing | The script reads SLURM_ARRAY_TASK_ID, which is not set. |
Read ASTRAEUS_ARRAY_TASK_ID. |
| Only a few copies run though GPUs are free | max_parallel, or the workspace's quota. |
Check the waiting copy's reason. |
The run is Failed though most copies completed |
One copy failed for good. | Its row on Workers has the exit code and log; run only the missing indices in a new array, mapping its index onto them. |