Skip to main content
miles-diffusion is the diffusion-model sibling of miles. It shares miles’ conventions — conventional commits, pre-commit, English-only PRs — but has its own test topology, because almost everything meaningful needs GPUs.

Repository layout

If you are adding a model family, you will touch: 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:
Stage A (CPU) gates every GPU stage: a broken import should not burn GPU runner slots.

Registering a test with CI

CI discovers tests by AST-parsing a register_*_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-empty labels 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:
Hooks: ruff (with --fix), autoflake, isort (black profile), black, plus the standard YAML / large-file / private-key checks.
  • Line length 119 (black and isort in pyproject.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 touching docker/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:
The body explains why; the diff already shows what.

Before requesting review

  • pre-commit run --all-files passes.
  • pytest tests/fast -x -q is green.
  • python3 train_diffusion.py --help still 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