Skip to content

chore: standardize model feature flags and adopt cargo-nextest as test runner#555

Open
xiaguan wants to merge 3 commits into
mainfrom
chore/feature-flags-and-nextest
Open

chore: standardize model feature flags and adopt cargo-nextest as test runner#555
xiaguan wants to merge 3 commits into
mainfrom
chore/feature-flags-and-nextest

Conversation

@xiaguan

@xiaguan xiaguan commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Three commits that turn two implicit conventions into enforced, documented standards: how model lines are feature-gated, and what the test sweep contract is.

1. fix(glm52): restore cfg(test) imports of Glm52ProjBytes

#550 marked from_host/upload test-only but dropped the imports they need — cargo test -p openinfer-glm52 --lib has been broken on main since.

2. chore(features): one feature name per model line, no crate-internal gates

New standard in docs/conventions/feature-flags.md. Model selection lives in exactly two places: openinfer-server (what the binary serves) and openinfer-kernels (what nvcc compiles). Two crate tiers:

  • Tier A (pure-CUDA kernels) — qwen3, glm52, kimi-k2, deepseek-v2-lite (migrated here): no self-named feature, the crate always compiles whole, openinfer-kernels = { features = ["<model>"] } non-optional. Removes 22 scattered #[cfg] gates, reject-only stubs, and dsv2-lite's optional kernels dep (the only one in the workspace).
  • Tier B (build-time Python toolchains) — qwen35-4b (Triton), deepseek-v4 (TileLang + CuTe DSL): the only allowed gate is a single whole-crate #![cfg]. deepseek-v4's 10 scattered item gates collapse into one, matching qwen35-4b.

Consumers of the removed crate-level features updated: pre-commit kimi clippy hook, scripts/bench_dsv2lite_vllm_matrix.py (4 call sites), living gate docs. Server-level --features kimi-k2 / --features deepseek-v2-lite invocations are unchanged.

Known cost, priced in the convention doc: workspace-wide builds now compile kimi/dsv2-lite kernels (cached after first build), and a bare cargo test --workspace (no --lib) builds their GPU gates — same behavior qwen3/glm52 already had.

3. chore(tests): adopt cargo-nextest as the test runner

The sweep contract moves from convention to config (.config/nextest.toml):

  • Bare cargo nextest run --workspace = lib unit tests, green on any single-GPU box; hardware gates are excluded by default-filter and reported as skipped — selection is explicit, never silent. Gates opt in per package with --ignore-default-filter.
  • retries = 0 (flaky = bug; exact-match gates must not rot under retry).
  • slow-timeout + terminate-after: a wedged NCCL collective goes red instead of hanging the session.
  • gpu-gate (serial) / gpu-lib (max 4) groups: nextest is process-per-test, engines and CUDA contexts must not stack.

nextest also compiles every test target where --lib compiles none, which immediately surfaced two rotted files (fixed here): kv-offload/tests/cpu_roundtrip.rs still used pre-#522 QueryOutcome struct fields; kernels/tests/glm52_indexer_smoke.rs had an unused variable.

Requires nextest >= 0.9.138 (0.9.70 fails to list proc-macro test binaries).

Verification (RTX 5070 Ti, OPENINFER_NCCL_ROOT set)

  • cargo test --release --workspace --lib: green (only pre-existing env failure: gdr_copy_flag_GPU needs GDRCopy hardware)
  • cargo check --release -p openinfer-server × {default, kimi-k2, deepseek-v2-lite, glm52}; -p openinfer-kimi-k2 --features kernel-report --bins --tests; -p openinfer-deepseek-v2-lite --bins --tests
  • Sweep: 725 passed / 12 skipped / ~10s, green (baseline cargo test --lib --no-fail-fast: 4.2s but red on gdr)
  • Gates through documented nextest invocations: qwen3 hf_golden_gate PASS 46.7s; qwen35-4b e2e_scheduler (Tier B --features path) PASS 26.6s
  • fmt, clippy (-D warnings local hooks), pre-commit chain all pass
  • Not verifiable on this box: deepseek-v4 with its feature (no TileLang Python); its feature-on item set is byte-identical to before

🤖 Generated with Claude Code

xiaguan and others added 3 commits July 4, 2026 05:16
PR #550 marked from_host/upload test-only but dropped the imports they
need, breaking cargo test -p openinfer-glm52 --lib on main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… gates

Codify the feature standard in docs/conventions/feature-flags.md: one
feature name per model line, selection lives in openinfer-server and
openinfer-kernels only.

- Tier A (pure-CUDA kernels): model crates carry no self-named feature
  and always compile whole. Migrate deepseek-v2-lite (14 cfg gates,
  optional kernels dep, reject-only stubs) and kimi-k2 (8 cfg gates,
  stub, kernel-report no longer implies a model feature) to the pattern
  #550 established for glm52.
- Tier B (build-time Python toolchains): the only allowed gate is a
  whole-crate #![cfg]. Collapse deepseek-v4's 10 scattered item gates
  into one, matching qwen35-4b.
- Update the pre-commit kimi hook, bench_dsv2lite_vllm_matrix.py, and
  living gate docs that passed the removed crate-level features.

Verified: workspace --lib tests, server check per feature (default,
kimi-k2, deepseek-v2-lite, glm52), model-crate --bins --tests checks,
both local clippy hooks with -D warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sweep contract moves from convention to config: a bare
`cargo nextest run --workspace` runs lib unit tests, excludes hardware
gates via default-filter, and reports every exclusion as skipped —
selection is explicit, never silent. Gates opt in per package with
--ignore-default-filter.

.config/nextest.toml encodes:
- default-filter = lib tests minus the one RDMA-hardware lib test
  (gdr_copy_flag_GPU), so the sweep is green on plain GPU boxes where
  cargo test --lib was red
- retries = 0: flaky = bug; exact-match gates must not rot under retry
- slow-timeout with terminate-after: a wedged NCCL collective goes red
  instead of hanging the session
- gpu-gate (serial) / gpu-lib (max 4) groups: nextest is
  process-per-test, engines and CUDA contexts must not stack

nextest also compiles every test target where --lib compiles none,
which immediately surfaced two rotted files, fixed here:
- kv-offload cpu_roundtrip.rs still used the pre-#522 QueryOutcome
  struct fields
- kernels glm52_indexer_smoke.rs had an unused variable

Measured on the 5070 Ti box: sweep 725 passed / 12 skipped in ~10s
(cargo test --lib --no-fail-fast: 4.2s but red on gdr); qwen3
hf_golden_gate and qwen35-4b e2e_scheduler both pass through the
documented nextest invocations. Requires nextest >= 0.9.138 (0.9.70
fails to list proc-macro test binaries: dynamic libstd).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant