{ "id": "miles-101", "title": "Miles 101", "subtitle": "Reinforcement learning on language models with Miles, from one GPU to a run you can trust", "summary": "How to run GRPO with Miles on one GPU, choose a model that fits, and check that the run is correct. Every measured line comes from recorded runs on a DGX Spark.", "plate": { "figure": "plate-miles-loop", "title": "One GRPO step on one GB10", "caption": "The SGLang engine and the FSDP trainer take turns on the Blackwell GPU. The one that waits stays parked in the same 128 GB pool. Medians of 48 steps on one GB10, from a run made before we added the heat guard." }, "audience": "You can serve a model and you know what a reward is. You want to train a model with reinforcement learning, and you want to know which settings matter before you rent a cluster.", "edition": "2026.10", "status": "ready", "pin": { "subject": "Miles", "version": "radixark/miles:latest, Miles main of 2026-10-15", "source": "https://github.com/radixark/miles", "commit": "08752a1283", "date": "2026-10-15", "verified": "2026-10-22" }, "outcomes": [ "Run GRPO on one GPU with the radixark/miles image and read the first ten steps.", "Stop a run that keeps going after its rollout engine died.", "Pick a model size that fits training and rollout on one GPU.", "Check that a run is correct, and not only that it runs.", "Find the cause of a failed run from its first symptom." ], "palette": [ { "hue": "blue", "meaning": "the trainer: the FSDP actor, its weights, and its optimizer" }, { "hue": "violet", "meaning": "the rollout engine: the SGLang server that generates samples" }, { "hue": "green", "meaning": "data and rewards: prompts, samples, groups, and scores" }, { "hue": "amber", "meaning": "lifecycle: steps, phases, and weight versions" }, { "hue": "teal", "meaning": "durable state: checkpoints, logs, and the summary files" }, { "hue": "rose", "meaning": "failure: a dead engine, an out-of-memory kill, a crash" }, { "hue": "grey", "meaning": "outside Miles: the host, Docker, and Ray" } ], "sources": [ { "name": "Miles source in the image", "path": "radixark/miles:latest, Miles main 08752a12", "usedFor": "every flag and every default that a page names" }, { "name": "Recorded runs", "path": "capture/gpu/", "usedFor": "every listing and every number marked as measured" }, { "name": "Miles issues and pull requests", "path": "github.com/radixark/miles", "usedFor": "the incidents in the troubleshooting part" }, { "name": "Miles documentation and release notes", "path": "github.com/radixark/miles/tree/main/docs", "usedFor": "documented behaviour, checked against the code" } ], "quoteSources": { "issue": null, "docs": null }, "capture": { "run": [ "python3", "capture/run.py" ], "check": [ "python3", "capture/run.py", "--check" ], "timeoutSeconds": 300 }, "front": "front.md", "parts": [ { "number": 1, "title": "Start", "thesis": "One GRPO step on your own GPU, a watchdog that stops a dead run, and the ten steps that tell you the run is healthy.", "summary": "Install, run, guard, and read a first run.", "accent": "blue", "sections": [ { "id": "1.1", "file": "sections/1-1-run-grpo-on-one-gpu.md" }, { "id": "1.2", "file": "sections/1-2-add-a-watchdog.md" }, { "id": "1.3", "file": "sections/1-3-read-your-first-ten-steps.md" } ] }, { "number": 2, "title": "Size it", "thesis": "Training and rollout share one GPU, so the model you can train is the model whose two copies fit together.", "summary": "Model size, offload choices, Ray on unified memory, and the cost of a weight update.", "accent": "violet", "sections": [ { "id": "2.1", "file": "sections/2-1-pick-a-model-size.md" }, { "id": "2.2", "file": "sections/2-2-choose-what-to-offload.md" }, { "id": "2.3", "file": "sections/2-3-stop-ray-killing-the-job.md" }, { "id": "2.4", "file": "sections/2-4-size-the-weight-update.md" } ] }, { "number": 3, "title": "Recipes", "thesis": "Each recipe gives the flags to set, the flags to leave alone, and the metric that proves the run works.", "summary": "Math, DAPO, agents, MoE, and custom rewards.", "accent": "green", "sections": [ { "id": "3.1", "file": "sections/3-1-train-math-on-gsm8k.md" }, { "id": "3.2", "file": "sections/3-2-train-with-the-dapo-filter.md" }, { "id": "3.3", "file": "sections/3-3-train-an-agent.md" }, { "id": "3.4", "file": "sections/3-4-train-a-moe-model.md" }, { "id": "3.5", "file": "sections/3-5-write-a-custom-reward.md" } ] }, { "number": 4, "title": "Speed and stability", "thesis": "Every speed or stability feature has a cost, and each page says when the cost is worth it.", "summary": "Async, partial rollout, FP8 rollout, replay, determinism, and true on-policy.", "accent": "plum", "sections": [ { "id": "4.1", "file": "sections/4-1-run-rollout-and-training-at-once.md" }, { "id": "4.2", "file": "sections/4-2-handle-long-responses.md" }, { "id": "4.3", "file": "sections/4-3-roll-out-in-fp8.md" }, { "id": "4.4", "file": "sections/4-4-lower-the-logprob-gap.md" }, { "id": "4.5", "file": "sections/4-5-use-deterministic-inference.md" }, { "id": "4.6", "file": "sections/4-6-know-the-true-on-policy-limits.md" } ] }, { "number": 5, "title": "Check your run", "thesis": "A run can finish every step and still train the wrong thing, so check the signals before you trust the reward.", "summary": "The signals, the step-0 checks, and seed spread.", "accent": "amber", "sections": [ { "id": "5.1", "file": "sections/5-1-read-the-run.md" }, { "id": "5.2", "file": "sections/5-2-check-the-first-step.md" }, { "id": "5.3", "file": "sections/5-3-repeat-a-run.md" } ] }, { "number": 6, "title": "Scale out", "thesis": "Miles is built for many GPUs, and this part says which choices you make there and which we could not measure on one GPU.", "summary": "Placement, evaluation, failures, and images.", "accent": "indigo", "sections": [ { "id": "6.1", "file": "sections/6-1-split-rollout-and-training.md" }, { "id": "6.2", "file": "sections/6-2-run-a-separate-eval-fleet.md" }, { "id": "6.3", "file": "sections/6-3-survive-failures.md" }, { "id": "6.4", "file": "sections/6-4-pick-an-image.md" } ] }, { "number": 7, "title": "Debug", "thesis": "Start from the symptom you see, and each entry gives the cause, the check, and the fix.", "summary": "Troubleshooting by symptom, and records that make runs comparable.", "accent": "rose", "sections": [ { "id": "7.1", "file": "sections/7-1-troubleshoot-by-symptom.md" }, { "id": "7.2", "file": "sections/7-2-keep-runs-comparable.md" } ] }, { "number": 8, "title": "How Miles works", "thesis": "This optional part explains why Miles is built the way it is, for readers who want the reasons behind the settings.", "summary": "Mismatch, correction methods, memory, plugins, routing, and history.", "accent": "teal", "sections": [ { "id": "8.1", "file": "sections/8-1-why-rl-owns-an-engine.md" }, { "id": "8.2", "file": "sections/8-2-the-correction-methods.md" }, { "id": "8.3", "file": "sections/8-3-why-true-on-policy-is-a-contract.md" }, { "id": "8.4", "file": "sections/8-4-memory-on-unified-memory.md" }, { "id": "8.5", "file": "sections/8-5-how-rollout-functions-plug-in.md" }, { "id": "8.6", "file": "sections/8-6-which-router-to-use.md" }, { "id": "8.7", "file": "sections/8-7-where-miles-came-from.md" } ] } ], "reference": { "title": "Reference", "thesis": "The flags, metrics, lab notes, and sources this manual uses, in one place.", "accent": "grey", "sections": [ { "id": "R.1", "file": "sections/r-1-flags-by-job.md" }, { "id": "R.2", "file": "sections/r-2-metrics.md" }, { "id": "R.3", "file": "sections/r-3-lab-notes.md" }, { "id": "R.4", "file": "sections/r-4-sources.md" }, { "id": "R.5", "file": "sections/r-5-figure-index.md" } ] }, "related": [ "phases/09-reinforcement-learning/06-policy-gradients-reinforce", "phases/09-reinforcement-learning/08-ppo", "phases/09-reinforcement-learning/09-reward-modeling-rlhf", "phases/10-llms-from-scratch/07-rlhf" ] }