Autonomous ML iteration on a Ray cluster. Generates train.py boilerplate from a model file and runs the autoresearch loop. User provides model.py; the skill handles Ray, DDP, dataset, and metric extraction.
Extends autoresearch with two key additions:
model.py, skill generates train.py (Ray + DDP)See references/ray-cluster.md for full cluster setup and known issues.
model.py ← autoresearch scope (user's model, nn.Module subclass named "Model")
train.py ← generated boilerplate, never modified by autoresearch
autoraysearch-results.tsv ← results log (gitignored)
| Subcommand | Purpose |
|---|---|
/autoraysearch | Run the autonomous loop (sequential) |
/autoraysearch --parallel N | Run N experiments simultaneously per iteration |
/autoraysearch:plan | Interactive wizard: goal → model → train.py → baseline → launch |
/autoraysearch:setup | Generate train.py from a model file (no goal wizard) |
/autoraysearch → run the loop (must already have baseline; if not, run plan first)/autoraysearch:plan → run the planning wizardRead references/plan-workflow.md for full protocol.
Quick summary:
Model class exists.val_acc=X.XXXX as last linereferences/train-template.mdRead references/setup-protocol.md for full details.
If cluster is not running:
# Head node
ray start --head --port=6379 --temp-dir=/tmp/$USER/ray --num-gpus=4
# Worker node
ray start --address=<head-ip>:6379 --num-gpus=4
Read references/parallel-loop-protocol.md for full details.
LOOP:
1. Review: read model.py + git log + results log
2. Ideate: pick next atomic change to model.py
3. Modify: one change to model.py
4. Commit: git commit before verify
5. Verify: python train.py
6. Extract: val_acc from last line of stdout
7. Decide: improved → keep | same/worse → git reset --hard HEAD~1
8. Log: append to autoraysearch-results.tsv
9. Repeat: NEVER STOP, NEVER ASK "should I continue?"
Each iteration generates N candidate changes, applies them to N git branches,
submits N Ray jobs simultaneously, keeps the best. See references/parallel-loop-protocol.md.
Model — train.py imports this exact nameWhat it does NOT tune (those live in train.py config):
# metric_direction: higher_is_better
iteration commit metric delta status description
0 baseline 0.8728 0.0 baseline initial state
1 a1b2c3d 0.8810 +0.008 keep increase conv channels 64->128 in first block
2 - 0.8690 -0.004 discard add extra ResBlock (underfits in 20 epochs)