Skip to content

[OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests - #2851

Open
shengliangxu wants to merge 6 commits into
mainfrom
shengliangx/ci-7-example-tests
Open

shengliangxu wants to merge 6 commits into
mainfrom
shengliangx/ci-7-example-tests

Conversation

@shengliangxu

@shengliangxu shengliangxu commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Type of change: CI (test runtime, tests only)

Five cuts to the example lanes, each with its reasoning:

  • test_lm_eval_hf evaluates one MMLU subtask. It ran --tasks mmlu --limit 0.1: the 57-subtask group, about 5.6k loglikelihood requests, on a tiny Qwen3 whose max_position_embeddings is 32, so its runtime is dominated by loading one HF dataset config per subtask (over 331 CI runs: min 198.9 s, median 212.5 s). It runs mmlu_abstract_algebra (100 test documents, 5-shot) through the same lm_eval_hf.py path and the same accuracy gate (exactly one task, lower bound 0.1 unchanged; the label distribution of that split is 22/26/31/21, so even a model that always predicts one letter scores at least 0.21).
  • The llm_qat QAT and QAD tests quantize once per module. test_qwen3_qat_nvfp4 (3 backends), test_qwen3_qad_nvfp4 (2) and test_qwen3_qlora_nvfp4 ran 6 quantize.py and 12 cold tokenized-dataset builds per module (104-121 s each, qlora 169 s). A module-scoped fixture runs quantize.py once (guarded by assert_unmodified_tree, like the other shared tiny-model fixtures) and all quantize and train calls share one dataset cache; the qlora test keeps its own PTQ because it passes --compress True.
  • The 1-GPU EAGLE3 compile smoke test skips the Triton GEMM autotune (TORCHINDUCTOR_MAX_AUTOTUNE_GEMM_BACKENDS=ATEN, the mechanism test_diffusers.py already uses). test_llama_eagle3[1-False] takes 175.5 s against 40.6 s for [1-True] (the same flow without compile), about 135 s of it torch.compile benchmarking Triton GEMM templates for a draft model that is one tiny decoder layer. The mode stays max-autotune, and the shortcut applies only when the run has one GPU: [2-False] and any run on more GPUs (the nightly) keep the full autotune.
  • The duplicate tiny-llama offline EAGLE3 training test is dropped (test_offline_eagle3_training[tinyllama], 34.9 s per job, almost all launcher start-up). test_offline_eagle_training already runs that mode on the same model with hidden states from compute_hidden_states_hf.py, and the FakeBaseModel case keeps the synthetic path. The one thing the dropped case covered that stage 2 did not, the collator truncating dumps, moves there (training_seq_len=16, so 28-token dumps are truncated), and the collator is also unit tested on CPU.
  • megatron_bridge tests that use no GPU skip the Megatron state reset. The conftest resets Megatron's global state around every test (destroy_model_parallel, gc.collect(), empty_cache), about 1.3 s per test; 77 tests in the directory are pure Python (the mlflow wiring and checkpoint-path tests) and leave nothing to reset (the 82 tests that took under 3 s each add up to 118 s in the series' runs before this PR and to 0.3 s after it). The reset now runs only for tests that request num_gpus; the environment restore stays for every test. The job runs at 68-75 minutes against its 75-minute nightly limit.

Time improvement (measured in CI)

Example lanes, pytest time of the changed tests and of the lane; before = #2846 (plus #2848 where its runner was as fast), after = #2851, #2854 and #2855 (median). #2849 and #2850 ran on runners 1.3-1.5x slower for every test and are left out of the before column.

lane before after change
llm_eval test_lm_eval_hf 130 s 19 s -111 s
llm_eval lane 332 s 212 s -120 s (-36%)
llm_qat six QAT, QAD and QLoRA tests (call time) 563 s 428 s -135 s (the shared quantize adds 20 s to the first test's setup)
llm_qat lane 591 s 475 s -116 s (-20%)
speculative_decoding test_llama_eagle3[1-False] 131 s 87 s -44 s
speculative_decoding dropped test_offline_eagle3_training[tinyllama] 20 s - -20 s
speculative_decoding lane 407 s 341 s -66 s (-16%)
megatron the 82 megatron_bridge tests that use no GPU (the state reset) 118 s 0.3 s -118 s
megatron lane 583 s 460 s -123 s (-21%)
  • A mmlu_limit=1 change for test_qwen3_eval_fp8 was dropped from this PR. The runs above are of its earlier head, which had it: the test took 175-246 s in all 7 runs, before and after (187 s against 176 s on comparable runners), so the CI history it was based on (mean 723.7 s, 2026-09-25 to 10-09) is not reproduced by the current lane and the change saved nothing measurable. The llm_eval lane figure above is test_lm_eval_hf's.
  • That is 425 s of lane time per PR run. The Example workflow ends with its slowest lane, torch_onnx (18.1-18.8 min of job time) until [OMNIML-6180] [9/11] Trim the torch_onnx example lane #2853, so the gain reaches the workflow's wall time only with that PR.

Method: every PR of the series has its own CI run, so "before" is the run of the PR(s) below that lack the change and "after" the runs that carry it. Times come from the job logs (--durations, or the gap between consecutive result lines). Where runner speed matters, the tests that no PR of the series touches scale each run, and the raw and the scaled medians are both shown. One test varies by 15-30% from run to run on its own, so smaller differences are not evidence.

Usage

Nothing user-facing.

Testing

  • llm_eval: ran the test's command on CPU with the tiny Qwen3 it builds: old configuration 223.4 s, mmlu/acc 0.2343; new 22.4-24.0 s, mmlu_abstract_algebra/acc 0.27, gate passes.
  • llm_qat: with run_example_command faked, quantize.py runs 6 -> 2 times and cold dataset builds go 12 -> 2; real quantize.py and train.py (QAT, then QAD from the checkpoint) ran on CPU with the int4 and fp8 recipes (NVFP4 needs CUDA) and left the checkpoint unmodified.
  • EAGLE: stage 1 and 2 of the offline flow ran on CPU with training_seq_len 64 and 16 (the collator pads 28 -> 64 and truncates 28 -> 16); with run_example_command faked, only [1-False] on one GPU gets the autotune variable (that case on 2 GPUs and every other case keep the full autotune) and the only removed test id is test_offline_eagle3_training[tinyllama].
  • megatron_bridge: a throwaway pytest module (not in this PR) against the patched conftest counts the resets: plain tests trigger none, tests that request num_gpus trigger one before and one after; it fails against the old conftest.
  • Not run: the example lanes themselves (they need GPUs, TRT-LLM and model downloads), so the accuracy with CUDA bf16 numerics, the savings and the autotune variable are checked by this PR's example jobs. Pre-commit passes.
  • trust_remote_code=True in test_offline_eagle3_training is not new: it is the line on main (the Kimi and MiniMax repos it loads need remote code), and this PR only renames its variable after dropping the tinyllama case.

Before your PR is "Ready for review"

Make sure you read and follow Contributor guidelines and your commits are signed (git commit -s -S).

Make sure you read and follow the Security Best Practices (e.g. avoiding hardcoded trust_remote_code=True, torch.load(..., weights_only=False), pickle, etc.).

  • Is this change backward compatible?: N/A (CI and tests)
  • If you copied code from any other sources or added a new PIP dependency, did you follow guidance in CONTRIBUTING.md: no new dependency
  • Did you write any new necessary tests?: N/A (existing tests made cheaper; one duplicate test dropped, see the description)
  • Did you update Changelog?: N/A (CI and tests)
  • Did you get Claude approval on this PR?: N/A (optional, not run)

Additional Information

Slice 7 of 11 of the GPU-CI speed-up work, split out of the reference draft #2730 (not for merge; it holds the whole series with its measurements). Slices 1, 2, 5, 8, 9 and 10 (#2845, #2846, #2849, #2852, #2853, #2854) have merged. The remaining slices (#2847, #2848, #2850, #2851, #2855) are independent PRs on main: each applies to main on its own, and merging all of them onto main in different orders gives the same tree. The times above are from the series' CI runs before 2026-10-21, when all slices formed one linear stack; a PR number in a method note names that PR's run from then.

  1. [OMNIML-6178] [1/11] Run the unit tests in parallel with pytest-xdist #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with pytest-xdist (merged)
  2. [OMNIML-6178] [2/11] Use the sysmon coverage core in CI #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI (merged)
  3. [OMNIML-6179] [3/11] Run manual-marked tests on nightly and on-demand GPU runs #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and on-demand GPU runs
  4. [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more time #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more time
  5. [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones to the unit lane, small models #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones to the unit lane, small models (merged)
  6. [OMNIML-6179] [6/11] Use local tokenizers and calibration text in GPU tests, shrink puzzletron data #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text in GPU tests, shrink puzzletron data
  7. [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests (this PR)
  8. [OMNIML-6180] [8/11] Trim the DFlash regression test #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test (merged)
  9. [OMNIML-6180] [9/11] Trim the torch_onnx example lane #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane (merged)
  10. [OMNIML-6181] [10/11] Make the distributed worker pool fail fast when a worker dies #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail fast when a worker dies (merged)
  11. [OMNIML-6181] [11/11] Share one Megatron worker pool across the gpu_megatron modules #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across the gpu_megatron modules

Summary by CodeRabbit

  • Tests
    • Focused language-model evaluation coverage on the abstract algebra task while retaining five-shot evaluation.
    • Streamlined quantization-aware training scenarios by reusing cached datasets and checkpoints, reducing repeated setup.
    • Improved Megatron test isolation by applying state cleanup only where needed.
    • Refined EAGLE test configurations for single-GPU runs, remote model coverage, and offline training with shorter sequence lengths.

@copy-pr-bot

copy-pr-bot Bot commented Oct 17, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/Model-Optimizer/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 5ba1a897-b7a8-40da-918b-02f3a52718e3
📥 Commits

Reviewing files that changed from the base of the PR and between 5529023 and 9bcfae8.

📒 Files selected for processing: 2
  • tests/examples/llm_qat/test_llm_qat.py
  • tests/examples/speculative_decoding/test_eagle.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 5 remain after this review.

📝 Walkthrough

The pull request updates tests for LLM evaluation, QAT workflows, Megatron state isolation, and EAGLE speculative decoding. It changes fixture reuse, task selection, conditional state resets, environment handling, and offline-training inputs.

Changes: LLM evaluation and workflow fixtures

Layer / File(s) Summary
Update evaluation and LLM workflow fixtures
tests/examples/llm_eval/test_llm_eval.py, tests/examples/llm_qat/test_llm_qat.py
The evaluation test selects mmlu_abstract_algebra without a limit. Module-scoped fixtures provide a shared dataset cache and protected NVFP4 PTQ checkpoint. QAT and QAD use the checkpoint, while QAT, QAD, and QLoRA use the cache.

Megatron test state isolation

Layer / File(s) Summary
Conditionally reset Megatron state
tests/examples/megatron_bridge/conftest.py
The fixture resets Megatron state only for tests that use num_gpus. Environment variables remain restored around every test.

EAGLE speculative decoding tests

Layer / File(s) Summary
Adjust EAGLE runtime configuration
tests/examples/speculative_decoding/test_eagle.py
The single-GPU case without mixed hidden states sets the TorchInductor GEMM autotuning backend to ATEN.
Update EAGLE offline-training inputs
tests/examples/speculative_decoding/test_eagle.py, tests/examples/speculative_decoding/test_eagle_offline_ptq.py
The offline-training test removes the tiny-Llama case and uses model_source directly. The offline PTQ test sets training.training_seq_len to 16.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Other

Suggested reviewers: realasma, kevalmorabia97

Merge Risk: ⚪ Minimal · up to 9bcfa

The test-only changes preserve the inspected contracts and are suitable to merge.

Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

Failed Failed checks: 1 error · 1 warning

Check name Status Explanation Resolution
Security Anti-Patterns Error CRITICAL: The PR adds AutoConfig.from_pretrained(model_source, trust_remote_code=True) in tests/examples/speculative_decoding/test_eagle.py:261. SECURITY.md prohibits hardcoded `trust_remote_cod… Add a trust_remote_code parameter with default False to the test or its model-loading path. Pass that parameter to AutoConfig.from_pretrained and use it for the training override. Set it to True only for explicitly trusted model sou…
Docstring Coverage Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: reducing runtime for the llm_eval, llm_qat, EAGLE, and megatron_bridge example tests.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Full details: Security Anti-Patterns

Explanation

CRITICAL: The PR adds AutoConfig.from_pretrained(model_source, trust_remote_code=True) in tests/examples/speculative_decoding/test_eagle.py:261. SECURITY.md prohibits hardcoded trust_remote_code=True because it can execute code from an untrusted model source. The function has no caller-configurable trust_remote_code parameter, and the training override also remains hardcoded as model.trust_remote_code=true at line 274.

Resolution

Add a trust_remote_code parameter with default False to the test or its model-loading path. Pass that parameter to AutoConfig.from_pretrained and use it for the training override. Set it to True only for explicitly trusted model sources, with the opt-in documented. The current diff shows no new dependency or other prohibited security pattern that changes this result.

✨ Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.10%. Comparing base (6d76b59) to head (5b4b6ea).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2851      +/-   ##
==========================================
- Coverage   70.16%   70.10%   -0.07%     
==========================================
  Files         659      659              
  Lines       74081    74081              
==========================================
- Hits        51978    51931      -47     
- Misses      22103    22150      +47     
Flag Coverage Δ
examples-gpt-oss 13.51% <ø> (-0.01%) ⬇️
examples-hf_ptq 23.19% <ø> (-0.04%) ⬇️
examples-llm_distill 13.59% <ø> (-0.01%) ⬇️
examples-llm_eval 17.24% <ø> (+<0.01%) ⬆️
examples-llm_qat 17.48% <ø> (-0.01%) ⬇️
examples-llm_sparsity 15.76% <ø> (-0.01%) ⬇️
examples-megatron_bridge 26.43% <ø> (-0.13%) ⬇️
examples-specdec_bench 13.29% <ø> (-0.01%) ⬇️
examples-speculative_decoding 17.47% <ø> (-0.01%) ⬇️
unit 60.59% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@shengliangxu

Copy link
Copy Markdown
Collaborator Author

/ok to test 2519292

@shengliangxu shengliangxu changed the title [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests [7/12] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests Oct 17, 2026
@shengliangxu
shengliangxu removed this pull request from stack #2856 October 17, 2026 06:58
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch from 2519292 to f8fa147 Compare October 17, 2026 07:02
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-6-local-data-tests branch from 2d82a59 to 7383ca1 Compare October 17, 2026 07:02
@shengliangxu
shengliangxu added this pull request to stack #2859 October 17, 2026 07:02
@shengliangxu shengliangxu changed the title [7/12] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests Oct 17, 2026
@shengliangxu

Copy link
Copy Markdown
Collaborator Author

/ok to test f8fa147

@shengliangxu shengliangxu changed the title [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and megatron_bridge example tests Oct 18, 2026
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-6-local-data-tests branch from 7383ca1 to 5f3497e Compare October 18, 2026 23:15
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch from f8fa147 to 0a781bd Compare October 18, 2026 23:15
@shengliangxu
shengliangxu marked this pull request as ready for review October 19, 2026 03:45
@shengliangxu
shengliangxu requested a review from a team as a code owner October 19, 2026 03:45
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch 2 times, most recently from 5529023 to 5366b9c Compare October 20, 2026 19:05
shengliangxu added a commit that referenced this pull request Oct 20, 2026
…#2845)

### What does this PR do?

Type of change: CI (unit-test runtime)

The unit `linux` job gates every GPU and example workflow (their pr-gate
jobs wait for it), and its tests are CPU-bound but run serially. This
runs them under pytest-xdist on the runner's four vCPUs. The `linux` job
and the multi-version matrix get `PYTEST_ADDOPTS=-n 4 --dist loadfile`
and `OMP_NUM_THREADS=1`: one worker per vCPU (`-n auto` counts physical
cores), whole files per worker, and one thread per worker, because with
torch's default threads the runner is oversubscribed and slower than
serial (1,481 s and 41 failures in my local runs).

What else changes so the suite passes under xdist:

- `noxfile.py`: the second pytest process that runs the `manual` tests
clears `PYTEST_ADDOPTS`, so it stays serial. Those tests leak global
state into each other, and a worker would run them in some order.
- `tests/_test_utils/torch/quantization/onnx_export.py`: `TEST_MODELS`
was a set of classes, whose iteration order differs between processes,
so workers collected different test ids. It is a tuple now.
- `test_hf_dflash2.py::test_overfits_a_single_batch` takes about 30 s on
one thread on main (53 s before #2836 halved its loop to 30 steps; that
version hit the 60 s default call timeout in the nightly on main on
2026-10-20). Its tiny model is built in bf16, and a CPU without native
bf16 support emulates bf16 matmuls (about 0.9 s per step, 0.1 s in
float32). The model is float32 now, which takes the test to about 4 s on
one thread, so it needs no timeout override; the loop and both
assertions are unchanged.
- `test_full_algorithms_vision.py::test_search_constraints` assigned
`ConstraintsFunc._get_true_latency` and never restored it. Serial runs
never noticed, because `test_evaluate_constraints.py` sorts first. Under
xdist a worker can get the files in the other order, and the Python 3.10
and 3.14 legs failed two tests after it. It uses `monkeypatch` now.
- `tests/conftest.py`: the unit per-test cap is 120 s on every platform.
`test_dist.py::test_data_parallel` takes 8-15 s serial and 25-35 s with
four workers sharing four vCPUs, and went over 60 s on the slowest
runner. A hung test is still reported, after 2 min instead of 1.

Why: on current main the `linux` job has a median of 12.9 min (27 runs
of other PRs since #2823 merged), and a pull request's GPU run waits a
median 14.5 min for it (125 runs of 33 PRs).

### Time improvement (measured in CI)

Unit `linux` job: serial on current main (27 runs of other PRs since
#2823 merged) against the runs of this series with `-n 4`.

| | before (serial) | with this PR |
|---|---|---|
| pytest | 630 s median (355-709 s) | 479 s in this PR's own run; 294 s
median over the 11 runs of the series (166-479 s) |
| whole job | 12.9 min median (8.8-14.8) | 10.9 min in this PR's own
run; 7.0 min median over the 11 runs (5.0-10.9) |
| unit workflow: `linux`, then the multi-version and Windows legs | 24.1
min median (12 runs) | 17.2 min median (the 7 runs that ran every leg) |

- The runs of #2846 and above also carry the sysmon core of #2846 (about
22% off the unit suite on its own, measured locally), so the 294 s
median is xdist plus sysmon; this PR's own run is the xdist-only number.
It was the slowest of the 11 (166-479 s for nearly the same tests:
runner variance), so it understates the gain. Locally on 4 CPUs with
coverage as in CI, the base took 825 s serial and 332-344 s with this
configuration (3 runs).
- The GPU, Example and Regression workflows hold their jobs until the
unit `linux` check is done (`pr-gate / wait-checks`, at least 5 min).
That wait is a median 14.5 min (IQR 12.9-15.8) on 125 GPU runs of 33 PRs
since #2823; in this PR's own GPU run it was 9.7 min (its `linux` job
took 10.9 min). With a 7 min `linux` job instead of 12.9 min, a GPU run
requested right after a push starts about 6 min earlier. That figure is
derived from the job times: the later runs of the series were requested
after their unit check had finished (the wait sat at its 5.2 min floor
in 7 of the 9 GPU runs), so they cannot show it.

Method: every PR of the series has its own CI run, so "before" is the
run of the PR(s) below that lack the change and "after" the runs that
carry it. Times come from the job logs (`--durations`, or the gap
between consecutive result lines). Where runner speed matters, the tests
that no PR of the series touches scale each run, and the raw and the
scaled medians are both shown. One test varies by 15-30% from run to run
on its own, so smaller differences are not evidence.

### Usage

Nothing user-facing. Locally: `OMP_NUM_THREADS=1 pytest tests/unit -n 4
--dist loadfile`.

### Testing

- Full `tests/unit` on 4 CPUs with coverage as in CI, on the base before
#2823: serial 825 s, this configuration 332-344 s in three repeated runs
(4,724 passed, 0 failed).
- This PR's own CI run: the `linux` job took 10.9 min (479 s of pytest)
against the 12.9 min serial median; see the time section above for the
later runs of the series.
- `tests/unit` without `puzzletron` (it needs `hydra`, absent from my
local environment) in reversed and in shuffled file order shows no other
order dependence; `test_search_constraints` followed by
`test_evaluate_constraints.py` in one process failed before the fix and
passes after it.
- `test_hf_dflash2.py` (33 tests) on one CPU thread: 13.5 s, of which
`test_overfits_a_single_batch` takes about 4 s (30 s with the bf16 model
on main; the next slowest test takes about 1.3 s).
- Pre-commit (all hooks) passes.

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: N/A (CI and tests)
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: no new
dependency (`pytest-xdist` is already in the `dev-test` extra on main)
- Did you write any new necessary tests?: N/A (two existing tests fixed
or sped up so they pass under xdist)
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A (CI and tests)
- Did you get Claude approval on this PR?: N/A (optional, not run)

### Additional Information

Slice 1 of 11 of the GPU-CI speed-up work, split out of the reference
draft #2730 (not for merge; it holds the whole series with its
measurements). Merge in order; each PR stands on its own and passes CI
without the later ones.

1. #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with
pytest-xdist **(this PR)**
2. #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI
3. #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and
on-demand GPU runs
4. #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more
time
5. #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones
to the unit lane, small models
6. #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text
in GPU tests, shrink puzzletron data
7. #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and
megatron_bridge example tests
8. #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test
9. #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane
10. #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail
fast when a worker dies
11. #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across
the gpu_megatron modules


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Improved consistency and performance of automated test runs across
platforms and Python configurations through controlled parallel
execution.
* Preserved predictable model-check ordering and isolated temporary test
changes.
* Increased unit-test time limits to better support process-spawning and
slower runs.
* Improved test reliability by explicitly controlling numeric precision
and ensuring serial execution for manual CPU tests.
  * No end-user functionality or product behavior changed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch from 9c4d11c to 9bcfae8 Compare October 20, 2026 19:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-merge checks failed. Please resolve the failing checks before merging.

@shengliangxu
shengliangxu removed this pull request from stack #2859 October 21, 2026 07:05
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch from 9bcfae8 to 349db95 Compare October 21, 2026 07:06
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-6-local-data-tests branch from bd0525c to 126279b Compare October 21, 2026 07:06
@shengliangxu
shengliangxu added this pull request to stack #2907 October 21, 2026 07:06
shengliangxu added a commit that referenced this pull request Oct 21, 2026
### What does this PR do?

Type of change: CI (test runtime)

Sets `COVERAGE_CORE=sysmon` on the unit `linux` job, `gpu_tests.yml` and
`regression_tests.yml`. Python 3.12 defaults to coverage's C tracer,
which slows every line of Python run under it, and every lane starts
coverage in each spawned worker and subprocess through
`COVERAGE_PROCESS_START`, so import-heavy start-ups pay for it (the 76 s
Megatron pool start, the 22 s hf_ptq processes of the unified-export
tests, the puzzletron spawns, the vLLM engine core). sysmon records the
same lines through `sys.monitoring`. The example runner is left to
#2727, which makes the same change there. On a Python older than 3.12
coverage warns and keeps its default core, so a lane that turned out to
run an older Python would be slower, not broken (the gpu and
gpu_megatron logs show 3.12).

### Time improvement (measured in CI)

pytest time of each lane in the run of #2845 (the base of this PR) and
in this PR's run, one run each:

| lane | #2845 | this PR | change |
|---|---|---|---|
| gpu | 2,093 s | 1,289 s | -38% |
| gpu_megatron | 2,240 s | 1,212 s | -46% |
| gpu_vllm v0.20.0 | 204 s | 170 s | -17% |
| gpu_vllm v0.30.0 | 426 s | 328 s | -23% |
| regression | 366 s | 268 s | -27% |
| unit `linux` (xdist) | 479 s | 305 s | -36% |

Workflow wall time: GPU tests 59.2 -> 39.6 min, Regression 21.3 -> 15.2
min.

- **How much of that is this PR.** Two single runs of the same code
differ by 15-30% on their own: the eight example lanes that run over 100
s, which this PR does not touch, moved by -4% to -31% (llm_sparsity
+38%) between the same two runs. The deterministic part is the Megatron
worker-pool start, the setup of the first test of each gpu_megatron
module: 75-77 s in each of 14 modules before (all setups of 12 s or more
add up to 1,365 s) and 22-27 s after (575 s), which is 790 s of the
lane's 1,028 s. Locally the unit suite takes 825 s with the C tracer,
640 s with sysmon and 572 s without coverage (4 CPUs, serial).
- **A `coverage.xml`-only report change was dropped from this PR.** The
runs above are of its earlier head, which also had it. It showed no CI
effect: the pytest summary line came 1-4 s after the last test in the
#2845 runs, which still wrote the html report, and 0-3 s in this PR's
runs (median 1.1 s over the 82 lane runs of the series), so the table is
the sysmon core's. It would only have saved developers' local runs
(about 25 s per pytest session).

Method: every PR of the series has its own CI run, so "before" is the
run of the PR(s) below that lack the change and "after" the runs that
carry it. Times come from the job logs (`--durations`, or the gap
between consecutive result lines). Where runner speed matters, the tests
that no PR of the series touches scale each run, and the raw and the
scaled medians are both shown. One test varies by 15-30% from run to run
on its own, so smaller differences are not evidence.

### Usage

Nothing user-facing.

### Testing

Measured on this tree (tests/unit on 4 CPUs serial: 572 s without
coverage, 825 s with the C tracer, 640 s with sysmon; `import
modelopt.torch.quantization.extensions`: 17.1 s native, 23.6 s with the
C tracer, 18.3 s with sysmon, with the same 362 files and 13,821
executed lines in the spawned child's data file; one TinyLlama fp8 plus
TRT-LLM deploy test: 64.8 s without coverage, 103.3 s with the C tracer,
70.5 s with sysmon, identical covered lines). Pre-commit and actionlint
pass. The CI runs of the series are the check on real runners (time
section above).

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: N/A (CI and tests)
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: no new
dependency
- Did you write any new necessary tests?: N/A (CI configuration)
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A (CI and tests)
- Did you get Claude approval on this PR?: N/A (optional, not run)

### Additional Information

Slice 2 of 11 of the GPU-CI speed-up work, split out of the reference
draft #2730 (not for merge; it holds the whole series with its
measurements). Slices 5, 8 and 10 (#2849, #2852, #2854) target main and
merge independently; the other open slices form a stack and merge
bottom-up. Each PR stands on its own and passes CI without the later
ones.

1. #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with
pytest-xdist (merged)
2. #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI **(this
PR)**
3. #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and
on-demand GPU runs
4. #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more
time
5. #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones
to the unit lane, small models (targets main)
6. #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text
in GPU tests, shrink puzzletron data
7. #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and
megatron_bridge example tests
8. #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test (targets
main)
9. #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane
10. #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail
fast when a worker dies (targets main)
11. #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across
the gpu_megatron modules


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Updated coverage collection for GPU, regression, and Linux unit-test
runs to use Python’s monitoring-based coverage core on supported Python
3.12+ environments.
* This configuration reduces overhead during coverage-enabled test
execution, particularly for import-heavy worker processes.
* No changes to application functionality or public interfaces are
included.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch from 349db95 to d09436a Compare October 21, 2026 07:57
shengliangxu added a commit that referenced this pull request Oct 21, 2026
### What does this PR do?

Type of change: CI (test runtime, tests only)

**The DFlash regression trains 500 steps and resumes for 20.**
`test_dflash_training` trained 3 epochs (1,500 steps) and
`test_dflash_resume` then a fourth epoch (500 more). On the 1-GPU PR
runner the recorded durations solve to about 33 s of start-up plus 55-73
ms per step, so the two tests spend roughly 115-140 s and 60-70 s. The
loss assertion only needs a final loss below 3.0, and the L40 baseline
is already 1.78 at step 500. The resume still goes through the whole
restore-and-train path, and it now reads `trainer_state.json` and checks
that `global_step` is 520 and that a log entry follows step 500 (it had
no assertion besides the exit status). The step count is fixed with
`max_steps` rather than `num_train_epochs`, because the regression job
runs on 2 GPUs off pull requests, where `accelerate launch` starts one
process per visible GPU and an epoch is 250 steps. Measured: 81 s per PR
regression job. Risk: the 1.78 baseline comes from a 1,500-step run, and
with `max_steps=500` the linear schedule decays to zero at step 500, so
the final loss can differ from it; the bound leaves 1.2 of margin.

### Time improvement (measured in CI)

| lane | | before | after | change |
|---|---|---|---|---|
| regression | `test_dflash_training` | 118 s | 62 s | -56 s |
| regression | `test_dflash_resume` | 56 s | 31 s | -25 s |
| regression | **lane pytest** | 268 s | 170 s | **-98 s (-37%)** |

DFlash: before = #2846, #2848 and #2850 (#2849 ran on a slower runner),
after = #2852, #2854 and #2855 (median; the lane took 168 and 170 s on
the normal-speed runners and 243 s on the slow one).

On its own, on main (2026-10-21): this PR's regression job against
#2854's, which has the same base and lacks this change. The unchanged
DFlash tests took the same time within about 3% (equally fast runners).
`test_dflash_training` takes 144 s before and 83 s after,
`test_dflash_resume` 73 s and 47 s, and the lane's pytest time goes from
374 s to 291 s (-83 s). The lane passes (5 passed), so the loss stays
below 3.0 after 500 steps and the resume ends at `global_step` 520.

A vLLM change that sized the KV pool of the Qwen3-MoE and DeepSeek
engines down was dropped from this PR. The runs above are of its earlier
head, which had it: the engines it touched booted 5-6 s per vLLM version
faster than the ones it left alone, in line with the 1-3 s per boot
expected and below the boot-to-boot noise (the unchanged Llama engine
took 84-99 s on v0.30.0), so it saved nothing measurable.

Method: every PR of the series has its own CI run, so "before" is the
run of the PR(s) below that lack the change and "after" the runs that
carry it. Times come from the job logs (`--durations`, or the gap
between consecutive result lines). Where runner speed matters, the tests
that no PR of the series touches scale each run, and the raw and the
scaled medians are both shown. One test varies by 15-30% from run to run
on its own, so smaller differences are not evidence.

### Usage

Nothing user-facing.

### Testing

I read the transformers 4.57.1 sources (`max_steps` overrides
`num_train_epochs`; with the steps save strategy a checkpoint is saved
at step 500 and again at the end) and the accelerate 1.10.0 launcher
defaults. Not run on a GPU here: this PR's regression job is the check,
in particular that the final DFlash loss stays below 3.0 after 500 steps
and that the resume ends at `global_step` 520. Pre-commit passes.

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: N/A (CI and tests)
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: no new
dependency
- Did you write any new necessary tests?: N/A (existing tests made
cheaper; the DFlash resume test now also asserts on its result)
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A (CI and tests)
- Did you get Claude approval on this PR?: N/A (optional, not run)

### Additional Information

Slice 8 of 11 of the GPU-CI speed-up work, split out of the reference
draft #2730 (not for merge; it holds the whole series with its
measurements). Slices 5, 8 and 10 (#2849, #2852, #2854) target main and
merge independently; the other open slices form a stack and merge
bottom-up. Each PR stands on its own and passes CI without the later
ones. The times above are from the series' CI runs before 2026-10-21,
when all slices formed one linear stack; a PR number in a method note
names that PR's run from then.

1. #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with
pytest-xdist (merged)
2. #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI
3. #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and
on-demand GPU runs
4. #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more
time
5. #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones
to the unit lane, small models (targets main)
6. #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text
in GPU tests, shrink puzzletron data
7. #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and
megatron_bridge example tests
8. #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test (targets
main) **(this PR)**
9. #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane
10. #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail
fast when a worker dies (targets main)
11. #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across
the gpu_megatron modules


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Updated regression coverage to use fixed training limits of 500 steps,
with resumed runs extending to step 520.
* Improved checkpoint and resume validation to confirm the final
training step and expected post-resume progress logs.
* Updated loss expectations to reflect the result at the 500-step
training milestone.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
shengliangxu added a commit that referenced this pull request Oct 21, 2026
… a worker dies (#2854)

### What does this PR do?

Type of change: CI (test reliability); changes `tests/_test_utils` only

A worker that exits without reporting (an illegal memory access aborts
the process, or an OOM kill) was only noticed when the result timeout
ran out: 600 s for a job, 120 s for the start. Until then the parent
waits on a queue nobody writes to, and the other workers wait in the
job, typically in a collective, for their dead peer. A start that fails,
for example on a bad backend, also waited out the whole ready timeout
and left the workers it had spawned behind.

`DistributedWorkerPool` now checks the workers' liveness once a second
while it waits. A dead worker is noticed within a second and fails the
run, or the start, naming its rank and exit code (about 4 s after the
death, which includes the 3 s the pool already waits for the other
workers' stack dumps). If another rank had already reported an
exception, its traceback is kept in that error. The pool is marked
`broken` and the other workers are killed with their stacks printed, the
way a hung job or a failed rank already ends in main (`get_live_pool`
then hands out a new pool). A start that fails kills the workers it had
spawned. `ready_timeout` is a constructor argument (120 s by default, as
before), so a test can reach the start timeout without waiting for it.

This builds on the hang handling of #2832 (`broken`, `get_live_pool`,
the stack dump) and does not change it.

### Time improvement (measured locally, not in CI)

No lane time changes in a passing run, and no worker died in this
series' CI runs, so CI cannot show it. What changes is how long a dead
worker costs. CPU, gloo, two ranks, the pool test's own job (rank 0
exits with code 13, rank 1 keeps waiting), seconds from `pool.run(...)`
(or the constructor) to the exception, on main and on this PR:

| scenario | before | after |
|---|---|---|
| a rank dies mid-job, its peer is stuck in a wait, `job_timeout` 30 s
(as in the test) | 33.1 s, `queue.Empty` | 4.0 s, `Worker process(es)
died (rank, exit code): [(0, 13)]` |
| the same with the default `job_timeout` of 600 s | 603.1 s,
`queue.Empty` | 4.0 s |
| the same, the peer waits in `dist.barrier()` | 33.3 s (the 30 s
`failure_grace`) | 4.3 s |
| the start fails (`backend="not-a-backend"`), default `ready_timeout`
of 120 s | 120.1 s, `queue.Empty` | 5.0 s |
| rank 0 dies at the start, rank 1 hangs in the rendezvous | 120.0 s,
one live worker left behind | 5.0 s, no worker left |

The after time is the 1 s liveness poll plus the 3 s the pool waits for
the other workers' stack dumps before it kills them. At the production
timeouts (120 s for the start, 600 s for a job) a dead worker therefore
costs 4-5 s instead of 2-10 minutes of a CI job: the test fails at once
and the next one gets a fresh pool from `get_live_pool`, instead of
waiting for a queue nobody writes to.

Cost: the four new cases add about 27 s to the `gpu` lane: the pool test
module takes 43 s in this PR's run and 17 s in #2849's run, which has
the same base (main) and lacks them (both from the job logs).

Method: a small script (not part of this PR) builds the pool the way the
repo's test does and times each scenario with `time.monotonic()` around
the call, once per commit, on a CPU host.

### Usage

```python
pool = DistributedWorkerPool(world_size=2, backend="nccl", ready_timeout=300)  # new argument, default 120
```

### Testing

`tests/gpu/torch/utils/test_distributed_worker_pool.py` runs the pool
with gloo on CPU (it extends main's three tests; the new cases take 24 s
together):

- a rank that exits with code 13 while its peer waits fails the run in
about 5 s and kills the peer. The test sets `job_timeout = 30`, so a
regression fails there with `queue.Empty` instead of at the test's own
cap. With the liveness check disabled it fails exactly that way.
- the same test with a second job: rank 0 raises an exception and rank 1
exits with code 13 two seconds later, after rank 0 has reported. The
error carries the exit code and rank 0's traceback. Without the change
it carries only the exit code, and the case fails.
- a start that fails raises and leaves no worker, both when every worker
dies (a bad backend) and when the wait times out while they are still
starting (`ready_timeout=0.01`). With `_abort()` removed from the
failed-start path, the second case fails ("workers left behind"); the
first passes either way, since all its workers die on their own, so it
covers the liveness wiring only.

Main's three tests (as reworked by #2836) still pass, and the three new
cases fail against main's unmodified pool. Pre-commit passes. This PR is
rebased onto #2836, which also edited the pool (reporting a failed rank
before its teardown, retiring a pool after any failed job); the changes
are in different places. The default start timeout stays 120 s here;
#2848 raises it to 300 s, so whichever of the two merges second resolves
that one line.

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: N/A (CI and tests)
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: no new
dependency
- Did you write any new necessary tests?: ✅ 2 test functions (4 cases)
in `tests/gpu/torch/utils/test_distributed_worker_pool.py`, run on CPU
with gloo; each fails without its fix
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A (CI and tests)
- Did you get Claude approval on this PR?: N/A (optional, not run)

### Additional Information

Slice 10 of 11 of the GPU-CI speed-up work, split out of the reference
draft #2730 (not for merge; it holds the whole series with its
measurements). Slices 5, 8 and 10 (#2849, #2852, #2854) target main and
merge independently; the other open slices form a stack and merge
bottom-up. Each PR stands on its own and passes CI without the later
ones. The times above are from the series' CI runs before 2026-10-21,
when all slices formed one linear stack; a PR number in a method note
names that PR's run from then.

1. #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with
pytest-xdist (merged)
2. #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI
3. #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and
on-demand GPU runs
4. #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more
time
5. #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones
to the unit lane, small models (targets main)
6. #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text
in GPU tests, shrink puzzletron data
7. #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and
megatron_bridge example tests
8. #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test (targets
main)
9. #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane
10. #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail
fast when a worker dies (targets main) **(this PR)**
11. #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across
the gpu_megatron modules


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Distributed worker pools now detect workers that exit during startup
or job execution and report failures instead of waiting for the full job
timeout.
* Worker startup supports a configurable readiness timeout with prompt
timeout handling.
* Failed or timed-out initialization now cleans up spawned worker
processes, preventing orphaned processes and leaving the pool in a
consistent state.
  * Job result retrieval now responds promptly when a worker fails.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
shengliangxu added a commit that referenced this pull request Oct 21, 2026
…e unit lane, small models (#2849)

### What does this PR do?

Type of change: CI (test runtime, tests only)

Four changes to the ONNX tests of the `gpu` job:

- **Three CPU-only files move to the unit lane**
(`tests/gpu/onnx/quantization/` to `tests/unit/onnx/quantization/`,
content unchanged): `test_dla_qdq_rules.py`,
`test_dla_scalar_constants.py` and
`test_quantization_initializer_names.py` (added with #2678, 68 cases).
They quantize with `calibration_eps=["cpu"]` and run the result on the
CPUExecutionProvider, so they need no GPU, but they cost 26.8 s per
`gpu` job (1.5 + 5.3 + 20.0 s in the CI logs); the unit job runs them in
a few seconds on its xdist workers.
- **`test_concat_elim` calibrates a 32-channel 16x16 model on the CPU**
instead of the (1, 128, 240, 64) three-conv model on `[cpu, cuda:0,
trt]`: the two tests took about 22 s each on the base (15 s together in
the series' CI runs with the sysmon core of #2846), and their assertions
only look at where the pass places Q/DQ nodes. The convs stay above the
16-channel limit of `graph_selection.py`, and both modes produce the
same 8 Q and 8 DQ nodes as with the default size.
`build_conv_concat_model` takes optional `channels`, `height` and
`width` (defaults: the old values; with a seeded RNG the default model
serializes to the same bytes).
- **The autotune benchmark tests build a 1x32x32x32 model** instead of
the 64x32x224x224 one (103 M random floats and about 1.2 GB copied per
iteration; the five tests took 31 s, and none looks at the latency
beyond "a positive float"). The two trtexec tests also pass
`--duration=0`, because trtexec measures for at least 3 s whatever the
iteration count. `_create_simple_conv_onnx_model` takes optional
`batch_size` and `spatial_size` with the old defaults, so the unit
autotuner tests that share it build the same model (their 161 tests
pass).
- **The autotune workflow test passes `--duration=0` to trtexec**:
`test_export_quantized_model[True]` took 44 s, mostly inside trtexec's 3
s minimum measurement per scheme. It still runs the 100 requested
iterations per measurement; the model and `timing_runs` keep their size,
because the test asserts the best scheme carries Q/DQ nodes.

### Time improvement (measured in CI)

gpu lane, time per file from the per-test timestamps; before = the runs
of #2846-#2848, after = this PR's run and the 4 runs above it (median):

| | before | after | change |
|---|---|---|---|
| three CPU-only files (68 cases), moved to the unit lane | 7.4 s | 0 |
-7.4 s |
| `test_concat_elim.py` | 15.2 s | 1.2 s | -14.0 s |
| `autotune/test_benchmark.py` (36 cases) | 37.1 s | 21.0 s | -16.0 s |
| `autotune/test_workflow.py` | 44.4 s | 28.5 s | -15.9 s |
| **sum** | 104 s | 51 s | **-53 s per gpu job** (-59 s after speed
scaling) |

The whole `tests/gpu/onnx` directory takes 110-120 s before and 58 s in
the three later runs on normal-speed runners (81 s and 74 s in #2849 and
#2850, which ran on 1.3x slower runners). The 68 moved cases cost the
unit job 7-13 s of CPU, spread over four xdist workers (below the unit
job's run-to-run spread). My first estimate of the gpu saving (97-107 s)
came from base runs without sysmon, where these files were slower.

On its own, on main as of 07:06 UTC on 2026-10-21 (before #2846 added
the sysmon core): the `gpu` lane's `tests/gpu/onnx` directory takes 145
s in #2854's run, which has the same base and lacks this change, and 66
s in this PR's run (-79 s). The runners were equally fast (median ratio
0.99 over the 17 untouched files above 20 s). `test_concat_elim.py` goes
from 35 s to 2.7 s, `autotune/test_benchmark.py` from 39 s to 24 s and
`autotune/test_workflow.py` from 46 s to 28 s, and the three moved files
cost 14 s there. Times are the gaps between consecutive result lines in
the job logs.

Method: every PR of the series has its own CI run, so "before" is the
run of the PR(s) below that lack the change and "after" the runs that
carry it. Times come from the job logs (`--durations`, or the gap
between consecutive result lines). Where runner speed matters, the tests
that no PR of the series touches scale each run, and the raw and the
scaled medians are both shown. One test varies by 15-30% from run to run
on its own, so smaller differences are not evidence.

### Usage

Nothing user-facing.

### Testing

- The three moved files: 68 passed in 7.1 s at the old location and in
13.3 s from the new one (this includes the unit conftest's session
setup) on Python 3.12 with onnx 1.21.0 and onnxruntime 1.24.4, and 68
passed in 15.3 s on Python 3.10.19 with onnxruntime 1.22.0, the oldest
runtime `pyproject` allows. The whole `tests/unit/onnx` directory passes
(756 passed, 12 xfailed).
- `test_concat_elim`: the two tests pass in 1.3 s on CPU; quantizing the
default and the small model in both modes gives Q=8, DQ=8.
- The shared helper changes: the unit autotune tests (161) pass.
- Not run: the TensorRT tests, because there is no TensorRT here; this
PR's `gpu` job is the check. Pre-commit passes.

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: N/A (CI and tests)
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: no new
dependency
- Did you write any new necessary tests?: N/A (existing tests moved or
made smaller; the 68 moved cases are unchanged)
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A (CI and tests)
- Did you get Claude approval on this PR?: N/A (optional, not run)

### Additional Information

Slice 5 of 11 of the GPU-CI speed-up work, split out of the reference
draft #2730 (not for merge; it holds the whole series with its
measurements). Slices 1, 2, 8 and 10 (#2845, #2846, #2852, #2854) have
merged. Slice 5 (#2849) targets main and merges independently; the other
open slices form a stack and merge bottom-up. Each PR stands on its own
and passes CI without the later ones. The times above are from the
series' CI runs before 2026-10-21, when all slices formed one linear
stack; a PR number in a method note names that PR's run from then.

1. #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with
pytest-xdist (merged)
2. #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI
(merged)
3. #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and
on-demand GPU runs
4. #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more
time
5. #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones
to the unit lane, small models (targets main) **(this PR)**
6. #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text
in GPU tests, shrink puzzletron data
7. #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and
megatron_bridge example tests
8. #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test (merged)
9. #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane
10. #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail
fast when a worker dies (merged)
11. #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across
the gpu_megatron modules


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

* **Tests**
* Added configurable dimensions to ONNX test models and smaller inputs
for selected scenarios.
* Streamlined GPU benchmark timing while retaining configured
measurement runs.
* Updated INT8 and FP8 concat-elimination coverage to use CPU
calibration and smaller model shapes.
* Reorganized DLA and quantization checks as unit tests instead of GPU
tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
test_lm_eval_hf ran `--tasks mmlu --limit 0.1`: the 57-subtask group, about
5.6k loglikelihood requests, on a tiny Qwen3 whose max_position_embeddings is
32, so every context is truncated to 32 tokens. Its runtime is dominated by
loading one HF dataset config per subtask and does not depend on the host
(over 331 CI runs: min 198.9 s, median 212.5 s, mean 221.0 s).

Run `mmlu_abstract_algebra` (100 test documents, 5-shot) instead. It goes
through the same lm_eval_hf.py code path and the same accuracy gate (which
requires exactly one task and reads results[task]['acc,none']); only the
number of datasets and documents changes. The gate's lower bound of 0.1 is
unchanged. The label distribution of that split is 22/26/31/21, so even a
model that always predicts one letter scores at least 0.21.

Testing: ran the test's command on CPU (CUDA hidden) with the tiny Qwen3 the
test builds. Old configuration: 223.4 s wall, mmlu/acc 0.2343, gate PASS. New
configuration: 22.4 to 24.0 s wall, mmlu_abstract_algebra/acc 0.27, gate PASS.
Also ran ruff check, ruff format --check and pytest --collect-only on the file.
A GPU CI run is still needed to confirm the accuracy with CUDA bf16 numerics.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
test_qwen3_qat_nvfp4 (fsdp2, deepspeed, ddp) and test_qwen3_qad_nvfp4 (fsdp2,
deepspeed) each ran quantize.py on the same tiny Qwen3 with the same recipe,
and every quantize.py and train.py call built its own tokenized dataset cache
(the cache key contains max_length, 8192 in quantize.py and 128 in train.py,
so even the two steps of one test could not share it). With
test_qwen3_qlora_nvfp4 that is 6 quantize.py runs and 12 cold dataset builds
per module. These tests take 104 to 121 s each on CI (qlora 169 s).

Run quantize.py once in a module-scoped fixture and let the five tests read
the checkpoint, guarded by assert_unmodified_tree like the shared tiny-model
fixtures. qat_nvfp4.yaml and qad_nvfp4.yaml give quantize.py identical
arguments (distill and teacher_model are not quantize arguments), so one
checkpoint serves both. test_qwen3_qlora_nvfp4 keeps its own PTQ because it
passes --compress True. All quantize.py and train.py calls now share one
dataset cache directory, so the 8192 and 128 variants are each built once;
calibration keeps its 8192 tokens. test_dataset_utils_pretokenize keeps its
own cache directory so it still checks that the CLI writes one.

Fixture time is outside pytest-timeout (timeout_func_only = true), as for the
other shared fixtures in tests/examples.

Testing: node IDs are unchanged. With run_example_command faked, quantize.py
runs 6 -> 2 times and cold dataset builds go 12 -> 2 (plus the pretokenize
test's own); a train.py that writes into the shared checkpoint is reported by
the fixture teardown. Real quantize.py and train.py (QAT, then QAD from the
checkpoint made with the QAT config) ran on CPU with the int4 and fp8
recipes, since NVFP4 dynamic-block quantization needs CUDA: train.py left the
checkpoint unmodified and the QAD run reused the dataset cache the QAT run
built. The saving, about 3 minutes of the 21.7 minute lane, is an estimate
from the CI timings; a GPU CI run is needed to measure it.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
test_llama_eagle3[1-False] is the one compiled EAGLE3 training run on the
1-GPU PR lane: hf_eagle.py compiles _eagle_forward with mode="max-autotune".
It takes 175.5 s per job against 40.6 s for [1-True], the same flow without
compile (call time 158.5 s vs 34.7 s on PRs, 147.8 s vs 34.4 s nightly), so
about 135 s is torch.compile. That includes benchmarking Triton GEMM
templates for a draft model that is one tiny decoder layer.

Launch it with TORCHINDUCTOR_MAX_AUTOTUNE_GEMM_BACKENDS=ATEN, the mechanism
test_diffusers.py already uses for its compile tests. The mode stays
max-autotune, so cudagraphs, coordinate-descent tuning, Dynamo tracing and
Inductor lowering still run; only the Triton GEMM template search is dropped.
There is no conv variable here because the draft has no convolutions.
[2-False] (2 GPUs, nightly) keeps the full autotune.

Testing: with run_example_command faked, only [1-False] gets the variable
(on top of the full os.environ) and the other parametrizations pass no env.
On torch 2.14 torch._inductor.config.max_autotune_gemm_backends reads the
variable and the max-autotune mode options do not override it. CPU cannot
reproduce the Triton autotune, so the saving is not measured; a GPU CI run
is needed to see how much of the 135 s it removes.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
test_offline_eagle3_training[tinyllama] trains one step (num_train_epochs=0.1)
of offline EAGLE3 on the tiny llama with its real base model. It takes 34.9 s
per job, almost all launcher start-up. test_eagle_offline_ptq.py's
test_offline_eagle_training (35.2 s) already runs that mode on the same model
(use_fake_base_for_offline defaults to false) with hidden states dumped by
compute_hidden_states_hf.py, and the FakeBaseModel case keeps the synthetic
dump path.

The only thing the dropped case covered that stage 2 did not is the offline
collator truncating dumps: its 128-token dumps were cut to training_seq_len=64,
while stage 2's dumps are 28 tokens against 64, so they were only padded. Set
stage 2 to training_seq_len=16 so the collator truncates there. The collator
is also unit tested on CPU (test_collator_truncates, test_collator_pads).
Stage 3 (hf_ptq.py --specdec_offline_dataset) takes its collator length from
--calib_seq and does not read the tokenizer saved with the checkpoint, which
now records model_max_length 16.

Testing: ran stage 1 (compute_hidden_states_hf.py, two 28-token dumps) and
stage 2 (main.py, offline EAGLE3 on the tiny llama) on CPU with
training_seq_len=64 and 16 (use_cpu, bf16 and tf32 off are the only changes
from the test): both train and write the checkpoint, and the collator pads
28 -> 64 and truncates 28 -> 16. With run_example_command faked, the launch
commands of the remaining parametrizations are unchanged and the only removed
test ID is test_offline_eagle3_training[tinyllama]; nothing else reads its
eagle-tinyllama-offline output. The ~30 s saving per job is not measured.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
The megatron_bridge conftest resets Megatron's global state before and after every test:
destroy_model_parallel, destroy_rerun_state_machine, then gc.collect() and
torch.cuda.empty_cache(). With torch, Megatron and modelopt imported the collection
walks a large heap and costs about 1.3 s per test in the recorded durations. 77 tests in
this directory are pure Python (the mlflow wiring tests and the checkpoint-path tests),
never run an example step and leave nothing to reset, so the lane pays about 100 s per
job for nothing. The megatron_bridge job runs at 68-75 minutes against its 75-minute
nightly limit.

Reset the Megatron state only for tests that request `num_gpus`, which is how every test
that runs an example step reaches a GPU in this directory. The environment restore stays
for every test: it is cheap, and the NVTE_* leak it guards against does not depend on a
GPU. Tests that run steps keep both resets, and run_example_in_process and
run_torchrun_in_process already reset at the start of each step.

A future test that runs a step without taking `num_gpus` would lose the reset around
it, though its steps would still reset at their start.

Testing: ruff check and ruff format with the pinned ruff 0.15.20, and py_compile. Ran a
throwaway pytest module (not part of this change) on CPU against the patched conftest
with the real fixture, counting calls to reset_megatron_global_state: plain tests trigger
none, tests that request `num_gpus` directly or through another fixture trigger one
before and one after, and the environment is restored in both cases. The same module
fails against the old conftest. Not run: the megatron_bridge suite itself, because
megatron.bridge and the GPUs are not available on this machine. The next GPU CI run
should show the setup and teardown time of the mlflow tests drop to near zero.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
Review feedback on this PR: `cp_size == 1` does not mean one GPU. launch_train.sh starts one
accelerate process per visible GPU, so on the 2-GPU nightly runner `[1-False]` runs with two
processes and still got TORCHINDUCTOR_MAX_AUTOTUNE_GEMM_BACKENDS=ATEN, although the comment
says the nightly keeps the full autotune. Key the shortcut on the GPU count instead.

Testing: pre-commit passes. Calling test_llama_eagle3 on a CPU host with run_example_command
captured: only cp_size=1, mix_hidden_states=False and num_gpus=1 gets the ATEN variable;
that case with 2 GPUs, and every other case, keep the full autotune; cp_size=2 on one GPU is
still skipped. Not run: the example job itself, which needs GPUs.

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
@shengliangxu
shengliangxu removed this pull request from stack #2907 October 21, 2026 16:59
@shengliangxu
shengliangxu changed the base branch from shengliangx/ci-6-local-data-tests to main October 21, 2026 16:59
@shengliangxu
shengliangxu requested a review from a team as a code owner October 21, 2026 16:59
@shengliangxu
shengliangxu force-pushed the shengliangx/ci-7-example-tests branch from d09436a to 5b4b6ea Compare October 21, 2026 17:00

@cjluo-nv cjluo-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bot review (gpt-6.1-sol) — DM the bot to share feedback.

LGTM: the test reductions are justified and preserve the relevant smoke paths; modifying and removing existing tests requires human sign-off.

Needs action:

  • Confirm human sign-off on the narrowed MMLU smoke and duplicate EAGLE removal; offline real-model training and collator truncation remain covered.

No action needed:

  • Shared QAT/QAD PTQ setup uses the existing immutability guard; QLoRA retains separate compressed PTQ.
  • Current Megatron example runners request num_gpus; pure-Python tests retain environment restoration.
  • Tests were inspected, not executed locally.

shengliangxu added a commit that referenced this pull request Oct 21, 2026
### What does this PR do?

Type of change: CI (test runtime); the only non-test file is
`examples/torch_onnx/torch_quant_to_onnx.py`

Three cuts to the torch_onnx example lane:

- **No DataLoader workers in the calibration loaders.**
`load_calibration_data` builds its DataLoaders over lists of tensors
that are already on the GPU, so the four workers load nothing, and since
the script forced the `spawn` start method (CUDA cannot be used in
forked workers), every loader pass spawned four processes that
re-imported torch, timm and modelopt and received the dataset over CUDA
IPC: about 14 s per pass and about 300 s per torch_onnx CI job. Both
loaders use `num_workers=0`, and the module-level
`mp.set_start_method("spawn", force=True)` is dropped, which also stops
importing the script from changing the start method of the importing
process (two tests import it inside the pytest process). Nothing else in
the script uses multiprocessing. The `--evaluate` path keeps the
CPU-only DataLoader workers of `examples/onnx_ptq/evaluation.py`, now
under the default start method, exactly as in the `onnx_ptq` example
that calls the same function.
- **swinv2 int8, mxfp8 and auto are skipped on pull requests.**
`swinv2_tiny` runs all five formats on top of `swin_tiny`, which already
covers every format through the same exporter and TensorRT path; swinv2
only adds its cosine attention and post-norm blocks. On PRs
(`GITHUB_REF` under `refs/heads/pull-request/`) fp8 and nvfp4 still run
and exercise those blocks; scheduled and local runs keep every
combination, and test ids are unchanged. `swinv2_tiny[auto]` alone
averages 121 s over 304 CI runs; the three skipped cases cost about 110
s of every PR run.
- **`build_trt_engine` runs trtexec for one iteration.** It let trtexec
run its default benchmark after the build (200 ms warm-up, then at least
3 s and 10 iterations) and discarded the output. `--warmUp=0
--duration=0 --iterations=1` still executes the engine once and removes
about 3 s per engine, roughly 40 s per lane run. `--trt_build` users see
no difference besides it returning sooner.

### Time improvement (measured in CI)

torch_onnx lane; before = #2846, #2848 and #2850 (875-880 s; #2849 ran
on a slower runner: 1,060 s), after = #2853, #2854 and #2855 (452-463
s).

| | before | after | change |
|---|---|---|---|
| **lane pytest** | 877 s | 458 s | **-419 s (-48%)** |
| of which: the three swinv2 cases skipped on PRs | 143 s | 0 | -143 s |
| of which: the cases that still run (no DataLoader workers, trtexec
runs once) | | | -277 s |
| whole job | 18.6 min | 12.2 min | -6.4 min |

This lane repeats to within 1% (875-880 s before, 452-463 s after), so
it is the cleanest measurement of the series. For example `swin_tiny`
with auto quantization goes from 66 s to 24 s and `vit_tiny` with auto
from 60 s to 17 s.

Method: every PR of the series has its own CI run, so "before" is the
run of the PR(s) below that lack the change and "after" the runs that
carry it. Times come from the job logs (`--durations`, or the gap
between consecutive result lines). Where runner speed matters, the tests
that no PR of the series touches scale each run, and the raw and the
scaled medians are both shown. One test varies by 15-30% from run to run
on its own, so smaller differences are not evidence.

### Usage

No API change. The skip is keyed on `GITHUB_REF`, so a local run keeps
every combination.

### Testing

`py_compile`, ruff 0.15.20 and `pytest --collect-only` on CPU (24 tests,
ids unchanged). With the example command stubbed,
`GITHUB_REF=refs/heads/pull-request/123` skips exactly swinv2 int8,
mxfp8 and auto, and any other ref skips none; the two in-process mapping
tests that import the script pass on CPU, and `build_trt_engine` passes
the three flags to a fake trtexec. Not run: the lane itself (it needs a
GPU, TensorRT and model downloads) and the flags against a real trtexec,
so this PR's torch_onnx job is the check. Pre-commit passes. #2685
(open) also edits this example; the changes touch different lines.

### Before your PR is "*Ready for review*"

Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).

Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).

- Is this change backward compatible?: N/A (CI and tests)
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: no new
dependency
- Did you write any new necessary tests?: N/A (existing tests; the
PR-only skip keeps test ids)
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A (CI and tests)
- Did you get Claude approval on this PR?: N/A (optional, not run)

### Additional Information

Slice 9 of 11 of the GPU-CI speed-up work, split out of the reference
draft #2730 (not for merge; it holds the whole series with its
measurements). Slices 1, 2, 5, 8 and 10 (#2845, #2846, #2849, #2852,
#2854) have merged. The remaining slices (#2847, #2848, #2850, #2851,
#2853, #2855) are independent PRs on main: each applies to main on its
own, and merging all six onto main in different orders gives the same
tree. The times above are from the series' CI runs before 2026-10-21,
when all slices formed one linear stack; a PR number in a method note
names that PR's run from then.

1. #2845 [OMNIML-6178] [1/11] Run the unit tests in parallel with
pytest-xdist (merged)
2. #2846 [OMNIML-6178] [2/11] Use the sysmon coverage core in CI
(merged)
3. #2847 [OMNIML-6179] [3/11] Run manual-marked tests on nightly and
on-demand GPU runs
4. #2848 [OMNIML-6181] [4/11] Give gpu_megatron's slow cold starts more
time
5. #2849 [OMNIML-6179] [5/11] Make the ONNX tests cheaper: CPU-only ones
to the unit lane, small models (merged)
6. #2850 [OMNIML-6179] [6/11] Use local tokenizers and calibration text
in GPU tests, shrink puzzletron data
7. #2851 [OMNIML-6180] [7/11] Trim the llm_eval, llm_qat, EAGLE and
megatron_bridge example tests
8. #2852 [OMNIML-6180] [8/11] Trim the DFlash regression test (merged)
9. #2853 [OMNIML-6180] [9/11] Trim the torch_onnx example lane **(this
PR)**
10. #2854 [OMNIML-6181] [10/11] Make the distributed worker pool fail
fast when a worker dies (merged)
11. #2855 [OMNIML-6181] [11/11] Share one Megatron worker pool across
the gpu_megatron modules


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Updates**
* Quantization examples now use zero-worker calibration loading with
device-resident samples.
* TensorRT example builds perform a single inference iteration without
warmup or timing.
* **Tests**
* Pull-request validation skips selected SwinV2 Tiny formats, while
scheduled validation continues to cover them.
* Pull-request detection uses the repository’s CI reference environment.
* **Impact**
* These changes affect example workflows and validation coverage only;
no application user-facing functionality is changed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
@shengliangxu

Copy link
Copy Markdown
Collaborator Author

The flagged line is not new: AutoConfig.from_pretrained(model_path, trust_remote_code=True) is on main (test_eagle.py:253), next to the model.trust_remote_code=true override. This PR drops the duplicate tinyllama case and only renames model_path to model_source. The remaining cases (Kimi-K2.5, Kimi-K2-Thinking, MiniMax-M2.5) ship their config classes as repo code (auto_map → AutoConfig), so AutoConfig.from_pretrained fails without trust_remote_code=True; a default-False parameter would be True in every case. SECURITY.md's rule targets library code that silently opts users in; this test names the repos itself, and 20 other test lines on main use the same call. The docstring-coverage warning is optional and the PR only edits existing test functions. No code change; please ignore the pre-merge check.

This branch has not been deployed

No deployments
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.

3 participants