You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️Note that this runbook is now outdated and is only kept as reference.
Use the runbook for the current version instead.⚠️
This runbook walks you through an artificial "campaign" on a Slurm login node using Karpathy's autoresearch: start the control plane, POST a plan, watch the ledger stream, confirm the 5-minute training job ran and was judged. Ends with the kill-mid-run exit test, where the 5-minute budget gives plenty of room to interrupt and restart.
This runbook uses two shells (two tmux panes, or two terminals). Shell 1 runs the control plane. Shell 2 prepares the workload and submits the campaign.
This runbook still contains a lot of manual steps that will be automated in the next Faberon versions, when LLMs will start driving the experiments. For now, it just checks that all the mechanical bits work correctly.
Prerequisites
Ensure that there is:
sbatch, sacct, squeue, scancel on your PATH.
A Slurm account you can bill jobs to.
A single-GPU partition (autoresearch targets one NVIDIA GPU, tested on H100).
Create a file campaign.json with this content. Replace /path/to/autoresearch with your checkout path (twice) and optionally campaign_id with a fresh UUID (python -c "import uuid; print(uuid.uuid4())"):
{
"campaign_id": "00000000-3333-6666-9999-000000000001",
"plan": {
"goal": "Beat the measured val_bpb baseline on autoresearch.",
"metric_name": "val_bpb",
"metric_command": "grep val_bpb /path/to/autoresearch/.faberon/run.log",
"baseline": 2.0,
"budget_gpu_hours": 1.0,
"max_concurrency": 1,
"stop_conditions": ["one run"]
},
"command": ["sh", "-c", "cd /path/to/autoresearch && set -o pipefail && uv run train.py 2>&1 | tee .faberon/run.log"],
"poll_interval_seconds": 15.0
}
The baseline of 2.0 is a placeholder so the first run always keeps (any real val_bpb is below 2). For real campaigns, set baseline to a prior run's val_bpb you want to beat.
The response lists the campaign's events in order. The last one is experiment.judged with judgment: keep.
Exit test: kill mid-run, restart, resume
This is the v0.1.0 exit test. The 5-minute training budget gives a wide window to interrupt the control plane while the Slurm job is still running.
In shell 2, start a fresh campaign by changing the campaign_id in campaign.json and updating $CAMP_ID
POST the new campaign and watch squeue until the job is RUNNING:
squeue -u $USER
While the job is RUNNING (anytime in the first ~5 minutes), kill the control plane in shell 1: Ctrl-C the faberon process.
Confirm the Slurm job is still running. The job is independent of the control plane.
In shell 1, restart the control plane:
faberon
DBOS recovers the workflow on launch. It does not resubmit the job (submission is idempotent on the job name). It resumes polling sacct. When the job completes, it parses val_bpb from .faberon/run.log and records experiment.completed and experiment.judged exactly once.
In shell 2, confirm with the SSE stream or GET /v0/campaigns/$CAMP_ID: exactly one experiment.completed and one experiment.judged, no duplicates. The Slurm job ran exactly once (sacct shows one job, not two).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Use the runbook for the current version instead.
This runbook walks you through an artificial "campaign" on a Slurm login node using Karpathy's autoresearch: start the control plane, POST a plan, watch the ledger stream, confirm the 5-minute training job ran and was judged. Ends with the kill-mid-run exit test, where the 5-minute budget gives plenty of room to interrupt and restart.
This runbook uses two shells (two tmux panes, or two terminals). Shell 1 runs the control plane. Shell 2 prepares the workload and submits the campaign.
This runbook still contains a lot of manual steps that will be automated in the next Faberon versions, when LLMs will start driving the experiments. For now, it just checks that all the mechanical bits work correctly.
Prerequisites
Ensure that there is:
sbatch,sacct,squeue,scancelon yourPATH.Shell 1: set up and start the control plane
One-time setup
Clone the Faberon repo and install Postgres:
git clone https://github.com/sevren-ai/faberon cd faberon git checkout v0.1.0 -b v0.1.0 bash scripts/install-postgres-no-sudo.shStart Postgres and create the Faberon DB:
bash scripts/start-postgres.sh bash scripts/create-faberon-db.sh # once, after installInstall the
faberoncommand:Start the server (each session)
Source the Postgres env (sets
FABERON_DATABASE_URLand puts the Postgres binaries onPATH), then set the Slurm account and API token:The server binds to
127.0.0.1:8000. Override withFABERON_HOSTandFABERON_PORTif needed.Shell 2: prepare the workload and submit a campaign
Open a new shell or tmux pane. This is where you clone autoresearch, build the campaign JSON, and submit it.
Prepare the autoresearch checkout (one-time)
Clone autoresearch onto the shared filesystem so the login node and compute nodes see the same tree:
Check Faberon is listening
Check liveness in a quick curl (no token needed):
curl -s http://127.0.0.1:8000/healthz # {"status":"ok"}Submit a campaign
Set the API token to the same value shell 1 printed:
Create a file
campaign.jsonwith this content. Replace/path/to/autoresearchwith your checkout path (twice) and optionallycampaign_idwith a fresh UUID (python -c "import uuid; print(uuid.uuid4())"):{ "campaign_id": "00000000-3333-6666-9999-000000000001", "plan": { "goal": "Beat the measured val_bpb baseline on autoresearch.", "metric_name": "val_bpb", "metric_command": "grep val_bpb /path/to/autoresearch/.faberon/run.log", "baseline": 2.0, "budget_gpu_hours": 1.0, "max_concurrency": 1, "stop_conditions": ["one run"] }, "command": ["sh", "-c", "cd /path/to/autoresearch && set -o pipefail && uv run train.py 2>&1 | tee .faberon/run.log"], "poll_interval_seconds": 15.0 }The
baselineof2.0is a placeholder so the first run always keeps (any realval_bpbis below 2). For real campaigns, setbaselineto a prior run'sval_bpbyou want to beat.Submit it:
A
201response returnscampaign_idandworkflow_id. SetCAMP_IDfor the commands below:Watch the ledger stream
If you keep it open for 5-6 minutes, you'll see the following events getting streamed in:
event: ledgerwith"type":"campaign.created"event: ledgerwith"type":"experiment.completed"(after the 5-minute run finishes)event: ledgerwith"type":"experiment.judged"and"payload":{"judgment":"keep"}The job trained for 5 minutes, printed
val_bpb: <value>(well below 99), so the judge keeps it.Confirm the job ran on Slurm
The job name is
faberon:<campaign_id>. Confirm it in Slurm:sacct -X --name "faberon:$CAMP_ID" -P -o JobID,State,ExitCode,ElapsedExpect one row,
COMPLETED, exit0:0, elapsed near00:05:00.Confirm the metric and judgment
The training output is in
.faberon/run.loginside your autoresearch checkout. Check the metric line:grep val_bpb run.log # val_bpb: 1.234567Confirm the judgment in the ledger:
The response lists the campaign's events in order. The last one is
experiment.judgedwithjudgment: keep.Exit test: kill mid-run, restart, resume
This is the v0.1.0 exit test. The 5-minute training budget gives a wide window to interrupt the control plane while the Slurm job is still running.
In shell 2, start a fresh campaign by changing the
campaign_idincampaign.jsonand updating$CAMP_IDPOST the new campaign and watch
squeueuntil the job isRUNNING:squeue -u $USERWhile the job is
RUNNING(anytime in the first ~5 minutes), kill the control plane in shell 1:Ctrl-Cthefaberonprocess.Confirm the Slurm job is still running. The job is independent of the control plane.
In shell 1, restart the control plane:
DBOS recovers the workflow on launch. It does not resubmit the job (submission is idempotent on the job name). It resumes polling
sacct. When the job completes, it parsesval_bpbfrom.faberon/run.logand recordsexperiment.completedandexperiment.judgedexactly once.In shell 2, confirm with the SSE stream or
GET /v0/campaigns/$CAMP_ID: exactly oneexperiment.completedand oneexperiment.judged, no duplicates. The Slurm job ran exactly once (sacctshows one job, not two).All reactions