Skip to content

ci: test GPU workflows against unpinned wheel - #691

Merged
zywind merged 9 commits into
mainfrom
yunfeng/ci-unpinned-gpu-coverage
Aug 4, 2026
Merged

ci: test GPU workflows against unpinned wheel#691
zywind merged 9 commits into
mainfrom
yunfeng/ci-unpinned-gpu-coverage

Conversation

@zywind

@zywind zywind commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • install the built wheel in a clean GPU environment with dependencies resolved from live indexes without uv.lock
  • run GPU-marked unit tests and keep E2E on the prepared unpinned environment
  • discover CUDA wheel indexes from pyproject.toml with a tested stdlib-only helper, require at least three unique matches, and reuse it in CI wheel verification instead of hardcoding the vLLM index

Test plan

  • mise run format-check
  • mise run typecheck
  • uv run --frozen pytest tests/tools -n0
  • Composite-action YAML parsing
  • docker build --check --target wheel-install --file containers/Dockerfile.test_ci .
  • Linux/CUDA dependency-resolution dry run
  • Full GPU workflow

Summary by CodeRabbit

  • Testing

    • Added dedicated GPU unit-test coverage.
    • Added prepared-environment end-to-end testing.
    • Expanded GPU validation and increased GPU test timeouts.
    • GPU end-to-end tests now run against the prepared package environment.
  • Documentation

    • Updated GPU testing guidance for consolidated smoke-test workflows and clean-room wheel installation.
    • Documented commands for running GPU unit tests and prepared end-to-end tests.
    • Clarified GPU test durations and environment setup expectations.

@zywind
zywind requested review from a team as code owners August 3, 2026 17:39
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review 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

Walkthrough

The GPU setup action now builds and installs a wheel in a clean virtual environment. New tasks separate environment preparation from GPU unit and E2E execution. The GPU workflow runs the new lanes and updates its timeout and documentation.

Changes

GPU test pipeline

Layer / File(s) Summary
Wheel-based GPU environment
.github/actions/setup-gpu-test-env/action.yml, .github/workflows/README.md
The action builds and installs one wheel with CUDA, engine, and test dependencies. It validates the environment and disables later synchronization.
Prepared test task execution
.mise/tasks/tests.toml, tests/TESTING.md
GPU unit-test and prepared E2E tasks were added. Default and DP E2E tasks delegate execution with --no-sync.
GPU workflow integration
.github/workflows/gpu-tests.yml, .github/workflows/README.md
The workflow adds GPU unit tests, increases the smoke-test timeout, and runs prepared E2E tests. Documentation describes the staged lanes and updated timeouts.

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

Possibly related PRs

Suggested labels: chore

Suggested reviewers: mckornfield

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly summarizes the main change: updating CI to test GPU workflows with an unpinned wheel.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yunfeng/ci-unpinned-gpu-coverage

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

@coderabbitai coderabbitai Bot added the chore Maintenance not tied to a user-visible change label Aug 3, 2026
@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR changes GPU CI to validate a freshly built wheel against dependencies resolved from live package indexes rather than the lockfile.

  • Builds and installs the wheel into a clean GPU environment using CUDA indexes discovered from pyproject.toml.
  • Adds GPU-marked unit tests before the staged smoke suites.
  • Runs E2E tests against the already prepared wheel environment without bootstrapping dependencies again.
  • Updates GPU workflow timeouts and testing documentation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
.github/actions/setup-gpu-test-env/action.yml Replaces lockfile-based GPU bootstrapping with clean-venv wheel installation, metadata-driven CUDA indexes, package checks, and CUDA validation.
.github/workflows/gpu-tests.yml Adds GPU unit tests, routes E2E through the prepared environment, and expands workflow timeouts.
.mise/tasks/tests.toml Adds selectors for non-slow GPU unit tests and reusable E2E commands that skip dependency synchronization.
.github/workflows/README.md Documents the clean-room GPU environment and updated workflow scope and durations.
tests/TESTING.md Documents the new GPU unit and prepared-environment E2E tasks.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Checkout[Checkout repository] --> Build[Build wheel]
  Build --> Discover[Discover CUDA indexes]
  Discover --> Install[Install wheel and unpinned dependencies in clean venv]
  Install --> Validate[Validate package version and CUDA]
  Validate --> Unit[GPU unit tests]
  Unit --> Smoke[Staged GPU smoke tests]
  Validate --> E2E[Prepared-environment E2E tests]
Loading

Reviews (9): Last reviewed commit: "test: exclude slow tests from GPU unit l..." | Re-trigger Greptile

@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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5d70fcbf-e47e-40bf-9d8f-828751564c98

📥 Commits

Reviewing files that changed from the base of the PR and between 1e968ec and d137792.

📒 Files selected for processing (5)
  • .github/actions/setup-gpu-test-env/action.yml
  • .github/workflows/README.md
  • .github/workflows/gpu-tests.yml
  • .mise/tasks/tests.toml
  • tests/TESTING.md
📜 Review details
⏰ Context from checks skipped due to timeout. (11)
  • GitHub Check: Unit Tests (3.12)
  • GitHub Check: Unit Tests (3.13)
  • GitHub Check: Unit Tests (3.11)
  • GitHub Check: End-user Wheel Install
  • GitHub Check: Smoke Tests
  • GitHub Check: Greptile Review
  • GitHub Check: Analyze (Python)
  • GitHub Check: Typecheck
  • GitHub Check: Format
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{md,markdown,py}

📄 CodeRabbit inference engine (.cursor/rules/agent-markdown-style.mdc)

**/*.{md,markdown,py}: Avoid decorative bold (**text**) in list items, body text, and docstrings; use structural cues (headers, list markers, colons, backticks) for emphasis instead
Use backticks for code identifiers, paths, and CLI commands in markdown and docstrings

Files:

  • tests/TESTING.md
**/*.{md,markdown}

📄 CodeRabbit inference engine (.cursor/rules/agent-markdown-style.mdc)

**/*.{md,markdown}: Bold is acceptable only in markdown tables where it's the conventional way to mark header-like cells in the body
Use ## headers to segment markdown sections instead of bold text
Use -- (em-dash) instead of - (hyphen) for asides in markdown

Files:

  • tests/TESTING.md
tests/**

📄 CodeRabbit inference engine (.cursor/rules/repo-navigation.mdc)

tests/**: Mirror src/ directory structure in tests/ directory for test organization
Auto-mark tests by directory: tests/e2e/e2e, tests/smoke/smoke, otherwise default to unit

Files:

  • tests/TESTING.md
**/*.md

📄 CodeRabbit inference engine (STYLE_GUIDE.md)

Do not use decorative bold in Markdown body text, list items, or docstrings; use single backticks for code identifiers, paths, and commands.

Files:

  • tests/TESTING.md
**/*

📄 CodeRabbit inference engine (STYLE_GUIDE.md)

**/*: Every source file requires the SPDX copyright and license header appropriate to its file format.
End files with a newline, remove trailing whitespace, use one space between sentences, and keep code, comments, and docstrings within 120 characters.

**/*: All contributions must use verified Git commits and DCO sign-off; unsigned or unsigned-off commits cannot be merged.
Branches other than main must follow <author>/<description>, optionally including an issue ID or type; branch names must use lowercase alphanumeric characters and hyphens.
Commits merged to main must follow Conventional Commits, using a valid lowercase type and a description of at most 100 characters.

Files:

  • tests/TESTING.md

⚙️ CodeRabbit configuration file

**/*: Review as a senior maintainer for NeMo Safe Synthesizer. Prioritize issues that can change behavior, break user workflows, weaken privacy guarantees, hide failures, make tests unreliable, or create maintenance risk. Avoid generic style commentary unless it points to a concrete project convention that automated tools will not catch.
Comment only when the finding is actionable and tied to changed code. For each finding, state the impact, the condition that triggers it, and the smallest practical fix. Prefer one precise comment over broad advice. Do not ask for refactors outside the PR scope unless the changed code creates the problem.
Review type guidance: - Potential issue: use for correctness bugs, data loss, privacy leaks,
security risks, broken public APIs, invalid config behavior, missing
validation, hidden failures, nondeterministic tests, or CI breakage.

  • Refactor suggestion: use for local maintainability problems introduced
    by the diff when they have clear future cost, such as duplicated setup,
    unclear boundaries, over-mocking, avoidable complexity, or opaque test
    helpers.
  • Nitpick: avoid in chill mode. Do not emit formatting, import-order,
    wording, or style-only comments unless automated tools cannot catch the
    issue and it affects maintainability.

Severity guidance: - Critical: security/privacy leaks, data loss, training/test/holdout
contamination, or broken release/package/core pipeline execution.

  • Major: incorrect generation/training/evaluation behavior, broken
    CLI/SDK public API, invalid config defaults or validators, or GPU/vLLM
    cleanup and process-isolation bugs likely to fail CI or production
    runs.
  • Minor: localized bugs, missing focused tests for changed behavior, or
    bad test patterns that weaken regression coverage.
  • Trivial: small cleanup with no behavior impact. Usually suppress in
    chill mode.
  • Info: context only. Avoid unless it helps reviewers understand risk.
    Safe-Synthesizer-specific review focus: - Data ...

Files:

  • tests/TESTING.md
**/*.{py,sh,yaml,yml,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

All Python, shell, YAML, YML, and Markdown source files require SPDX copyright headers.

Files:

  • tests/TESTING.md
**/*.{py,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use the repository's documented Python and Markdown style conventions and validate changes with the pinned mise formatting and checking tasks.

Files:

  • tests/TESTING.md
.github/workflows/*.yml

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Changes to GitHub Actions workflows must preserve the documented CI, release, signing, and deployment requirements.

Files:

  • .github/workflows/gpu-tests.yml
.github/**

⚙️ CodeRabbit configuration file

Review GitHub configuration for branch protection expectations, CODEOWNERS alignment, least privilege permissions, pinned actions where practical, and consistency with CONTRIBUTING.md.

Files:

  • .github/workflows/gpu-tests.yml
  • .github/actions/setup-gpu-test-env/action.yml
  • .github/workflows/README.md
.mise/tasks/**/*.toml

📄 CodeRabbit inference engine (STYLE_GUIDE.md)

Keep declarative Mise tasks under .mise/tasks/, provide descriptions for public tasks, and add usage metadata where arguments need validation or help.

Files:

  • .mise/tasks/tests.toml
.mise/tasks/*

📄 CodeRabbit inference engine (STYLE_GUIDE.md)

Keep shared shell helpers in .mise/tasks/_lib.sh and make that file non-executable.

Files:

  • .mise/tasks/tests.toml
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: NVIDIA-NeMo/Safe-Synthesizer

Timestamp: 2026-08-03T17:39:40.076Z
Learning: Use the documented mise and pytest commands for the appropriate test scope; run individual tests with `uv run --frozen pytest tests/path/test_file.py::test_name -vvs -n0`.
🪛 LanguageTool
.github/workflows/README.md

[uncategorized] ~154-~154: The official name of this software platform is spelled with a capital “H”.
Context: ... workflow/action changes. GPU jobs use .github/actions/setup-gpu-test-env for shared ...

(GITHUB)

🔇 Additional comments (6)
.github/actions/setup-gpu-test-env/action.yml (1)

16-16: LGTM!

Also applies to: 28-28, 42-42, 50-94

.mise/tasks/tests.toml (2)

89-115: LGTM!


13-16: 🩺 Stability & Availability

No process-isolation change is needed.

The only matching test is tests/benchmarks/test_generation_structured_methods.py. Each benchmark invokes the vLLM CLI through subprocess.run, so each generation runs in a separate process.

			> Likely an incorrect or invalid review comment.
tests/TESTING.md (1)

22-22: LGTM!

Also applies to: 32-32

.github/workflows/gpu-tests.yml (1)

88-88: LGTM!

Also applies to: 165-165

.github/workflows/README.md (1)

154-154: LGTM!

Comment thread .github/workflows/README.md Outdated
@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
@binaryaaron binaryaaron self-assigned this Aug 3, 2026
@zywind
zywind force-pushed the yunfeng/ci-unpinned-gpu-coverage branch from d137792 to a66b092 Compare August 3, 2026 17:57
zywind added 4 commits August 3, 2026 14:07
Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
@github-actions github-actions Bot added area:dev-ex Affects build or dev experience area:build-dist labels Aug 3, 2026
zywind added 3 commits August 3, 2026 20:23
Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
This reverts commit b5a3979.

Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
This reverts commit 1d6bc52.

Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
Comment thread .mise/tasks/tests.toml Outdated
@binaryaaron

Copy link
Copy Markdown
Collaborator

our test semantics could use a little update in a followup pr

@zywind

zywind commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

our test semantics could use a little update in a followup pr

Agree.
There's also a lot of repeated code that tries to resolve the right pip indexes. I plan to tackle that later.

Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>

@binaryaaron binaryaaron 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.

approved; up to you if you want to address this in this pr or a followup. thanks!

Comment thread .github/actions/setup-gpu-test-env/action.yml
@zywind
zywind enabled auto-merge August 4, 2026 16:28
@zywind
zywind removed the request for review from mckornfield August 4, 2026 16:45
@zywind
zywind disabled auto-merge August 4, 2026 16:49
@zywind
zywind added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit 5008564 Aug 4, 2026
22 checks passed
@zywind
zywind deleted the yunfeng/ci-unpinned-gpu-coverage branch August 4, 2026 16:52
andrewwhitecdw pushed a commit to andrewwhitecdw/Safe-Synthesizer that referenced this pull request Aug 13, 2026
…NeMo#705)

# Summary

Fixes GPU smoke + e2e failing on `main` with:

```
× No solution found when resolving dependencies:
╰─▶ Because there is no version of flashinfer-cubin{sys_platform == 'linux'}==0.6.14 ...
    conclude that your requirements are unsatisfiable.
```

## Root cause

`setup-gpu-test-env` infers which indexes to pass to `uv` by matching
the CUDA extra
against each index's name or URL:

```python
if index["name"].endswith(f"-{cuda_extra}") or f"/{cuda_extra}" in index["url"]
```

When that inference landed (NVIDIA-NeMo#691, Aug 4 16:50 UTC) every index encoded
its variant one
of those two ways, so the rule held. NVIDIA-NeMo#664 landed 27 minutes later (17:17
UTC) and added
the first index that doesn't: `flashinfer-cubin`, which serves a single
variant-agnostic `https://flashinfer.ai/whl/` and is bound to packages
only through
`[tool.uv.sources]`.

It matches neither branch of the rule, so it was silently dropped — and
since the
install also passes `--no-sources`, the sources table couldn't reach it
either. Both
PRs were green on their own base; the breakage exists only in the merge.

That index is the only place `flashinfer-cubin==0.6.14` exists:

| Index | max `flashinfer-cubin` |
| ----- | ---------------------- |
| `https://flashinfer.ai/whl/` | 0.6.16.post1 (has 0.6.14) |
| PyPI | 0.6.13 |
| `https://flashinfer.ai/whl/cu129` | does not serve the package |
| `https://wheels.vllm.ai/0.26.0/cu129` | 0.6.13 |

## Fix

Also collect indexes referenced by `[tool.uv.sources]` for the target
extra.

Before / after, run against `pyproject.toml` at `cu129`:

```
  https://download.pytorch.org/whl/cu129
  https://flashinfer.ai/whl/cu129
+ https://flashinfer.ai/whl/
  https://wheels.vllm.ai/0.26.0/cu129
```

This matches the index set in the documented manual install command,
which is why
installing by hand works today while CI does not.

## Verification

Resolution flips with exactly that one index, reproducing CI's error
before and
succeeding after:

```
$ uv pip install --dry-run --no-deps --default-index https://pypi.org/simple \
    --index .../cu129 (x3) --index-strategy unsafe-best-match flashinfer-cubin==0.6.14
  × No solution found ... there is no version of flashinfer-cubin==0.6.14

$ # same, plus --index https://flashinfer.ai/whl/
  Resolved 1 package
   + flashinfer-cubin==0.6.14
```

`mise run format-check` passes. No dependency versions change.

## Pre-Review Checklist

- [x] `mise run format && mise run check`
- [x] GPU CI status check passes -- this PR is the fix for it

## Other Notes

CI-only change; no source or dependency changes. Worth noting the
`index_count < 3` guard did not catch this — the count stayed at exactly
3
while the wrong index was dropped.

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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved GPU test environment setup to reliably discover all CUDA
package indexes configured for the selected extra.
* Added support for indexes declared through source configuration,
alongside existing name- and URL-based matching.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Yunfeng Zhang <yunzhang@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:build-dist area:ci area:dev-ex Affects build or dev experience area:tests chore Maintenance not tied to a user-visible change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants