pre-commit, English-only PRs — but has its own
test topology, because almost everything meaningful needs GPUs.
Repository layout
miles/backends/fsdp_utils/configs/<family>.py (register with
@register_train_pipeline_config), optionally
miles/backends/fsdp_utils/models/... for a native package or FSDP plan, a launcher in
scripts/, and a page under docs/models/.
Local dev loop
Tests
Four tiers, by what they need:
Run the CPU tier before every push; it is fast and catches most regressions. On a CPU-only box
without sglang’s GPU kernels, install the stubs first the way CI does:
uv pip install tests/ci/cpu_stubs.
CI does not call pytest directly — it goes through the suite runner, which is also the way to
reproduce a CI failure locally:
Registering a test with CI
CI discovers tests by AST-parsing aregister_*_ci(...) call at the top of the file — the
call is a runtime no-op and never executes.
Suites
Labels
A test with a non-emptylabels list runs only when the PR carries run-ci-<label> for one of
them. The canonical registry is tests/ci/labels.py:
Two meta-labels bypass the filter and run everything:
run-ci-all and run-ci-image.
Adding a label means adding an entry to tests/ci/labels.py and creating the matching
run-ci-<key> label in GitHub repo settings. The workflow needs no edit — the stage job filters
at runtime.
E2E metric standards
An e2e test declares the recipe to run, the arguments to run it with, and the metrics to check:script is a Python recipe under scripts/, run with the same interpreter. Because the recipes
are Typer CLIs, CI configures them through args rather than through environment variables —
env still exists for anything the recipe reads from the environment instead.
This is also why launch scripts must stay runnable with no arguments and configurable through
their ScriptArgs dataclass: CI drives them the same way you do.
The recorded series live in tests/ci/fixtures/e2e_standards/. Because these runs use
--deterministic-mode, comparison is strict, bit for bit — which is exactly what makes them
useful, and also why any intentional numeric change requires re-recording the standard via the
record-e2e-standards workflow.
If your PR legitimately changes numerics, say so in the PR body and re-record. Do not loosen a
tolerance to make a test pass.
Style
pre-commit is the enforcement point:
ruff (with --fix), autoflake, isort (black profile), black, plus the standard
YAML / large-file / private-key checks.
- Line length 119 (
blackandisortinpyproject.toml). - Python ≥ 3.12 — modern syntax is fine (
X | None,match, PEP 695 where it reads well). - Type hints on new code.
- Comments explain why, not what. The codebase leans on this heavily: most of the tricky code here exists because of a specific numeric mismatch, and the comment recording which mismatch is the most valuable line in the file.
Docker changes
A PR touchingdocker/Dockerfile or requirements.txt triggers an image build; every GPU suite
then runs inside radixark/miles_diffusion:pr-<num> instead of latest, and a failed build stops
the matrix. The fresh build outranks a ci-image-tag: directive in the PR body. Fork PRs skip
the build and stay on latest. The tag is deleted when the PR closes.
PR conventions
English only — title, body, commit messages, code comments. Conventional commits, first line under ~70 characters:Before requesting review
-
pre-commit run --all-filespasses. -
pytest tests/fast -x -qis green. -
python3 train_diffusion.py --helpstill parses (any argparse change). - A new public flag is documented in CLI Reference.
- A new model family has a page under
docs/models/. - Numeric changes are called out, and e2e standards re-recorded if they moved.
- New behaviour has a test, registered with the right suite and label.
Where to ask
- Design discussion: open a GitHub Issue or Discussion on radixark/miles_diffusion.

