Skip to main content

How it works

mill schedule generates a job matrix (models × tasks × n_shots), filters out already-completed jobs from the output cache, then submits a SLURM array job. Each array worker evaluates one (model, task, n_shot) combination and writes results to the shared output_dir.

Cluster configuration

On first run, Mill copies its bundled clusters.yaml to ~/.cache/mill/clusters.yaml. Edit it to match your cluster:
There’s no walltime field — the SLURM time limit is computed automatically from the number of evals per job. Override the per-eval budget with --minutes_per_eval (raise it for heavy generative tasks like mmlu_pro):
Use --cache_dir to point Mill at a different location:

Basic usage

Arguments are positional: schedule <models> <tasks>. Passing the mmlu benchmark expands to its 57 subject tasks, so this sweep is 57 tasks × 2 n-shot values = 114 jobs.

Selecting the cluster

Dry run — preview without submitting

Prints the full job table so you can verify the sweep before committing GPU hours.

Local sequential run

Skip SLURM and run all jobs in the current process — useful for debugging:

Virtual environments in SLURM jobs

The SLURM worker activates this venv before running mill eval.

Custom task paths in SLURM workers

If your tasks live outside the Mill package, pass extra directories so the worker can discover them:

Checking completion

After the job array finishes:
The --check flag (default on) lists any missing (model, task, n_shot) combinations so you can resubmit stragglers.