The scripts are in the repository, not in the installed package. Clone it,
then
cd recipes/04-train/hosted-loop before running the commands below. Browse this recipe on GitHub.wai.train returns and how to wait on it, what
wai.serve gives you back, and how to call the served adapter. The rows
are deliberately small; this is the wiring check, not a result. You need
WHILEAI_API_KEY (or whileai login); no model key, since the rows
come from the template writer and a scripted agent.
What each step does
One run of
python run.py with the defaults (--seed 1 --budget 96,
SFT on Qwen/Qwen3-4B, one epoch): 24 train rows over 7 tasks, and a
72-row holdout because the splitter seeds the held-out side by failure
signature first (see below). The loss numbers are one run’s; the
platform trainer is not seeded, so yours will differ:
scripted_agent and judge with
yours, or point data at rows you already graded.
What to know before you run it
- Only two bases serve.
Qwen/Qwen3-4Bandmicrosoft/phi-4. The trainer’s defaults (Qwen2.5-0.5B for SFT, 1.5B for GRPO and DPO) train faster but cannot be hosted;wai.trainwarns andwai.serverefuses. SFT runs on an A10G and takes about a minute here; GRPO and DPO run on an L40S (--method grpo --steps 10took 137 s on Qwen3-4B). - Cold starts. The serving GPU scales to zero. The first call after
idle can take a few minutes;
callwaits up to fifteen. - Thinking mode. Qwen3 reasons before it answers unless told not to.
callsendschat_template_kwargs: {"enable_thinking": false}so the reply is the answer, not the reasoning. - Cost. SFT here is about a minute of A10G, GRPO a few minutes of L40S. Serving bills while the GPU is awake; the endpoint idles back to zero on its own.
- Holdout.
split_pseudo_productionmoves whole tasks and seeds the held-out side with one task per failure signature first, so on a tiny set (7 tasks here) the holdout ends up larger than the fraction asks. That is fine for a wiring check; a real set has hundreds of tasks.
Where it shows up
run.url is the loss curve and the before/after on the platform.
wai.models() lists what the account hosts, wai.get_run(run_id) returns
the points, and the dataset cards link to the run. Docs:
https://docs.withwhile.com/api/training