# Pre-Check Checklists Each item is a concrete check to run against the diff. ✗ = fix before PR. ⚠ = consider fixing. --- ## All PRs: Title Format (check first) PR title must follow the project convention documented in `docs/contributing/README.md`: | Prefix | Applies to | |--------|-----------| | `[Bugfix]` | Bug fixes | | `[CI/Build]` | Build or CI improvements | | `[Doc]` | Documentation changes | | `[Model]` | New/improved models (include model name) | | `[Frontend]` | Frontend changes (API server, OmniLLM class, etc.) | | `[Kernel]` | CUDA/kernel changes | | `[Core]` | Core logic changes (OmniProcessor, OmniARScheduler, etc.) | | `[Hardware][Vendor]` | Hardware-specific (e.g., `[Hardware][Ascend]`) | | `[Misc]` | Other changes (use sparingly) | **Examples:** ``` ✓ [Model] Add MiniCPM-o 4.5 support ✓ [Bugfix] Fix Ovis image text encoder dtype ✓ [Core] Qwen3-Omni performance optimization ✓ [Hardware][Ascend] Fix VoxCPM2 on Ascend ✗ Fix Ovis image text encoder dtype ← missing prefix ✗ [bugfix] Fix Ovis image text encoder ← wrong case ✗ [WIP] Add model ← WIP in title ``` - [ ] **Title has valid prefix** — ✗ if missing prefix, wrong case, or WIP/Draft in title. For `[Model]` PRs, the title MUST also include the model identifier (e.g., `[Model] Add ...`). ⚠ if missing the model name. --- ## All PRs: Code Quality (run on every PR, quick & full) Diff-scoped sweep for five fragility patterns that are pervasive in the existing codebase — **only lines the PR adds count**, not the pre-existing backlog. Detection commands, codebase examples, and full severity rules live in [code-quality.md](code-quality.md). - [ ] **No new `**kwargs` string-lookup plumbing:** the diff adds no `**kwargs` + `kwargs["..."]` / `kwargs.get("...")` / `"..." in kwargs`. ⚠ any new instance; ✗ if a new string key is duplicated across ≥2 files without a shared constant, or unknown keys are silently dropped on a fail-fast path. - [ ] **No new broad exception swallow:** the diff adds no `except Exception:` / bare `except:`. ⚠ any new instance; ✗ for `except: pass` / `except Exception: return None` / `continue` on a fail-fast path (init, config validation, weight loading, request handling). - [ ] **No new `Any` / wrong type hints:** the diff adds no `: Any` / `-> Any` / untyped production signature, and no new `SimpleNamespace` in tests faking an object that already has a real typed stub. ⚠ any new instance; ✗ for a *wrong* (actively misleading) annotation or a `SimpleNamespace` test fake of a typed object. - [ ] **No new hot-path copy:** the diff adds no `.clone()` / `.copy_()` / `copy.deepcopy(...)` inside a per-step loop or per-request path. ⚠ any new instance; ✗ for `.clone()` of a full latent/activations tensor inside an AR or diffusion step loop without a comment, or `deepcopy` of a scheduler / sampling-config on the request path. - [ ] **No new event-loop blocking:** the diff adds no `time.sleep` / blocking HTTP (`requests`, `urllib`) / `await` inside a held lock in `async def` code. ⚠ any new instance; ✗ for blocking sleep or HTTP on the serving path (`engine/`, `entrypoints/`, async `connectors/`), or a lock held across an `await`. Blocking inside a dedicated worker thread is fine. Roll the ⚠/✗ counts into the report as a single **Code quality** dimension row. --- ## All PRs: Examples Policy (run on every PR, quick & full) Inspect Python files introduced under `examples/` using [examples-policy.md](examples-policy.md). This is a diff-scoped ratchet: existing model-specific examples may be edited or removed without triggering the check. - [ ] **No new model-specific Python examples:** the diff adds, copies, or renames no Python file whose path or behavior is specific to one model, checkpoint, vendor, or model family. ✗ for any violation. Route inference through a shared task/protocol entrypoint, model request behavior through `vllm_omni/model_extras`, and commands through task docs or `recipes/`. - [ ] **New generic example code is justified:** any new task-neutral Python file under `examples/` is an actual user-facing entrypoint rather than reusable production logic, a benchmark, an app, a setup tool, or a reproducer. ⚠ when the placement is questionable. Roll the result into the report as a separate **Examples policy** dimension. ### Conventions (eyeball — no grep) Judgment calls that don't grep cleanly — apply them while reading the diff, not as a mechanical check: - **Right log level** — `info` is for end-user-visible events; routine internal events are `debug`; hot paths are `trace` or removed. Logging is not free. - **Structured fields over f-strings** — pass dynamic values as structured fields (`logger.info("msg", extra={...})`), not interpolated strings, so they stay greppable and parseable. - **No reflexive synchronization** — don't add `threading.Lock` / `asyncio.Lock` / `deepcopy` / re-wrap shared state unless there is real concurrent mutation; the GIL covers most Python code. Owners decide their own synchronization — don't pre-lock in a constructor. - **Context managers for cleanup** — use `with` / `contextlib` for files, locks, CUDA streams, and profilers; not raw `open()` + manual `.close()` or ad-hoc `finally`. - **No new dependencies without justification** — prefer the stdlib and existing vllm-omni deps; a new top-level dep needs a reason (check `pyproject.toml` / `requirements*.txt`). - **Naming / interface discipline** — don't rename or change interfaces just for taste in this PR, but do fix names that actively mislead (e.g. `serve` implying a long-running server, `Instance` where multiple instance kinds coexist). --- ## Bug Fix PRs ### Quick - [ ] **PR body has 4 sections:** what broke (error message), repro steps, root cause, fix description - [ ] **Fix is minimal:** diff touches only files directly related to the bug. No unrelated refactors or style changes. - [ ] **Repro is runnable:** the PR body includes a copy-paste command that reproduces the bug - [ ] **Branch is rebased:** `git merge-base HEAD origin/main` is recent, no merge conflicts ### Full (adds) - [ ] **Regression test exists:** `git diff --name-only` includes at least one `tests/` file - [ ] **Regression test reproduces the original error:** the test would fail on main, pass on this branch - [ ] **Fix matches root cause exactly:** no "fix the symptom + something else" — if the root cause is dtype, the fix is dtype, not dtype + reformatting - [ ] **No silent failure risk:** no bare `except: pass`, no `try: ... except: return None`, no empty fallback added. See the broad-except pattern in [code-quality.md](code-quality.md#2-broad-exception-swallow) for the full severity rule (⚠ any new broad catch; ✗ for a swallow on a fail-fast path). - [ ] **Upstream pattern match:** the fix follows the same pattern as existing code for similar cases (grep for analogous `from_pretrained` calls, etc.) - [ ] **Environment documented:** torch/transformers/vllm versions listed if the bug is version-dependent --- ## Performance PRs ### Quick - [ ] **Before/after numbers in PR body:** at minimum, one metric (RTF, RPS, latency, VRAM) with main vs PR values - [ ] **Hardware specified:** GPU model, count, VRAM. "L4" or "H20" is sufficient. "tested on GPU" is not. - [ ] **Concurrency scaling:** if the optimization claims better throughput, numbers at 2+ concurrency levels - [ ] **No unexplained regressions:** if any metric goes down at any concurrency level, explain why - [ ] **Branch is rebased:** `git merge-base HEAD origin/main` is recent, no merge conflicts ### Full (adds) - [ ] **Software versions:** torch, CUDA, vllm, vllm-omni versions in PR body - [ ] **Warmup stated:** "1 warmup + 3 measured" or equivalent - [ ] **Stddev or range:** not just a single best run. "average of 2 rounds" is minimum. - [ ] **VRAM measured:** peak GPU memory before and after - [ ] **Benchmark script checked in:** under `tests/` or `examples/`, runnable by reviewer - [ ] **Exact command line in PR:** not pseudocode, not "run the benchmark" - [ ] **Pytest summary included:** `36 passed, 3 skipped, 17 warnings in 2897.66s` — proves the whole suite passes - [ ] **Config changes documented:** if `max_num_seqs`, `gpu_memory_utilization`, or deploy YAML changed, old and new values stated with reasoning --- ## New Model PRs ### Quick - [ ] **PR body file list matches `git diff --name-only`:** every file path in the description exists in the diff - [ ] **Registry entries match claimed count:** count `_OMNI_MODELS` or `_DIFFUSION_MODELS` entries added vs claimed in body - [ ] **Pipeline config `custom_process_input_func` paths resolve:** each referenced module.function exists - [ ] **`__init__.py` exports match registry:** each registered class appears in `__init__.py` and `__all__` - [ ] **Shell script modes match README:** `run_curl.sh` supports every mode the README documents - [ ] **Branch is rebased:** `git merge-base HEAD origin/main` is recent, no merge conflicts ### Full (adds) - [ ] **Dead code scan (5 patterns):** 1. Dead `forward()` — defined but never called through the pipeline path 2. Dead factory/builder functions — instantiated nowhere 3. Dead wrappers — thin wrappers with no callers 4. Dead branch guards — `if version > X` where X is always satisfied 5. Unused parameters — `__init__` args never accessed - [ ] **Copy-paste detection:** no string constant defined in 3+ files, no cross-module validation duplication, no near-identical shape coercion fns - [ ] **Import hygiene:** no re-export-only imports, no module-level side effects without docs, no `import os` in function body when already at top. Function-body imports are acceptable when the import is only reachable from a closure or factory return value (i.e., `import` would otherwise execute at module load even though the user may never trigger that path). Either lift to top-of-file or annotate with `# noqa: PLC0415`. - [ ] **Accuracy:** at least one test compares output against reference; audio = valid WAV at correct sample rate; determinism verified if seed claimed. ⚠ if missing and not explicitly deferred to a follow-up PR or RFC section; — if explicitly deferred (the deferral target SHOULD be linked in the PR body). - [ ] **Performance:** hardware, software versions, warmup, and metrics (RTF, VRAM, RPS, latency) stated. ⚠ if missing and not explicitly deferred; — if explicitly deferred. - [ ] **Benchmark settings:** model config (TP, PP, max_model_len, enforce_eager, quant), runtime config (batch, input/output spec), environment versions - [ ] **Benchmark script checked in + exact command line + pytest summary** --- ## Diffusion Model PRs Diffusion models live under `vllm_omni/diffusion/`. In addition to the New Model checklist above, verify: - [ ] **Transformer adapter follows contract:** inherits from `nn.Module`, implements `load_weights()`, uses `vllm_omni.diffusion.attention.layer.Attention` - [ ] **Pipeline has both offline and online paths:** `forward()` for batch generation, streaming path for online serving - [ ] **Cache-DiT integration:** at least one acceleration (TeaCache, FBCache, etc.) is wired up. ✗ for new **top-level** pipelines. For **subclass** pipelines that inherit `__call__` from a parent where Cache-DiT is already absent, downgrade to ⚠ and recommend filing a follow-up issue against the parent pipeline family. - [ ] **Parallelism config:** TP/SP/USP/CFG-Parallel options exposed in pipeline config - [ ] **Docs table updated:** model added to `docs/models/supported_models.md` with correct metadata - [ ] **E2E test exists:** at least one test exercises the full generate path --- ## General PRs ### Quick - [ ] **PR body matches diff:** description doesn't claim changes not in the diff - [ ] **Branch is rebased:** `git merge-base HEAD origin/main` is recent, no merge conflicts - [ ] **CI gates passing:** DCO, pre-commit, build — check `gh pr view --json statusCheckRollup` if a PR already exists - [ ] **Local pre-commit gates:** full list in [Linting](../../../../docs/contributing/README.md#linting). Blocking when the diff introduces: stale `vLLM project` SPDX; stdlib `re`/`base64` or pickle in library code; new `torch.cuda` call sites; `tests/**/test_*.py` without level+hardware marks; new `_tts_model_type` branches in `serving_speech.py`; invalid `.buildkite` YAML. macOS/Windows need a native `shellcheck`. ✗ for growing `CHECK_IMPORTS[*].allowed_files`, `ALLOWED_FILES`, or `MAX_MODEL_TYPE_BRANCHES` without review. ### Full (adds) - [ ] **No new dead code in changed files:** scan for unreachable paths, unused imports - [ ] **Test coverage:** if core code changed (`engine/`, `stages/`, `connectors/`), tests are added or existing tests cover the path - [ ] **Import hygiene:** no redundant imports added - [ ] **No unrelated changes:** diff scope matches PR description