Skip to content

Conversation

@chang-l
Copy link
Collaborator

@chang-l chang-l commented Oct 28, 2025

This PR fixes an import issue that only occurs when using editable installs with prebuilt wheels. Regular pip install or source builds are unaffected.

The problem lies in the setup.py extraction logic, which skips .py files during editable installs when using prebuilt wheels.
This went unnoticed because:
1. Source builds: submodule init.py files are generated at build time, so they’re always present.
2. Normal pip installs: the wheel is unpacked directly into site-packages, ensuring all .py files exist.
Only the editable install + prebuilt wheel combination triggers the missing imports (e.g. tensorrt_llm.deep_gemm, deep_ep, flashMLA).

To repro (under a clean TensorRT-LLM code dir without build cache, e.g., no ./tensorrt_llm/deep_gemm dir):

pip uninstall -y tensorrt-llm
TRTLLM_PRECOMPILED_LOCATION=https://urm.nvidia.com/artifactory/sw-tensorrt-generic/llm-artifacts/LLM/main/L0_PostMerge/2356/x86_64-linux-gnu/cuda13/tensorrt_llm-1.2.0rc2-cp312-cp312-linux_x86_64.whl pip install -e .["devel"]
python -c 'from tensorrt_llm.deep_gemm import fp8_mqa_logits' or python -c 'from tensorrt_llm.deep_ep import Buffer'
// Error

but with this PR, TRTLLM_PRECOMPILED_LOCATION=... pip install ... should install it properly and have no more import errors.

Summary by CodeRabbit

  • Enhancements

    • Improved packaging and extraction of C++ extension modules within distribution wheels with refined logic for handling extension wrapper files.
  • Tests

    • Added verification tests to ensure C++ extension wrappers are properly available and importable in packaged distributions.

Description

Test Coverage

PR Checklist

Please review the following before submitting your PR:

  • PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.

  • PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.

  • Test cases are provided for new code paths (see test instructions)

  • Any new dependencies have been scanned for license and vulnerabilities

  • CODEOWNERS updated if ownership changes

  • Documentation updated as needed

  • The reviewers assigned automatically/manually are appropriate for the PR.

  • Please check this after reviewing the above items as appropriate for this PR.

GitHub Bot Help

/bot [-h] ['run', 'kill', 'skip', 'reuse-pipeline'] ...

Provide a user friendly way for developers to interact with a Jenkins server.

Run /bot [-h|--help] to print this help message.

See details below for each supported subcommand.

run [--reuse-test (optional)pipeline-id --disable-fail-fast --skip-test --stage-list "A10-PyTorch-1, xxx" --gpu-type "A30, H100_PCIe" --test-backend "pytorch, cpp" --add-multi-gpu-test --only-multi-gpu-test --disable-multi-gpu-test --post-merge --extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx" --detailed-log --debug(experimental)]

Launch build/test pipelines. All previously running jobs will be killed.

--reuse-test (optional)pipeline-id (OPTIONAL) : Allow the new pipeline to reuse build artifacts and skip successful test stages from a specified pipeline or the last pipeline if no pipeline-id is indicated. If the Git commit ID has changed, this option will be always ignored. The DEFAULT behavior of the bot is to reuse build artifacts and successful test results from the last pipeline.

--disable-reuse-test (OPTIONAL) : Explicitly prevent the pipeline from reusing build artifacts and skipping successful test stages from a previous pipeline. Ensure that all builds and tests are run regardless of previous successes.

--disable-fail-fast (OPTIONAL) : Disable fail fast on build/tests/infra failures.

--skip-test (OPTIONAL) : Skip all test stages, but still run build stages, package stages and sanity check stages. Note: Does NOT update GitHub check status.

--stage-list "A10-PyTorch-1, xxx" (OPTIONAL) : Only run the specified test stages. Examples: "A10-PyTorch-1, xxx". Note: Does NOT update GitHub check status.

--gpu-type "A30, H100_PCIe" (OPTIONAL) : Only run the test stages on the specified GPU types. Examples: "A30, H100_PCIe". Note: Does NOT update GitHub check status.

--test-backend "pytorch, cpp" (OPTIONAL) : Skip test stages which don't match the specified backends. Only support [pytorch, cpp, tensorrt, triton]. Examples: "pytorch, cpp" (does not run test stages with tensorrt or triton backend). Note: Does NOT update GitHub pipeline status.

--only-multi-gpu-test (OPTIONAL) : Only run the multi-GPU tests. Note: Does NOT update GitHub check status.

--disable-multi-gpu-test (OPTIONAL) : Disable the multi-GPU tests. Note: Does NOT update GitHub check status.

--add-multi-gpu-test (OPTIONAL) : Force run the multi-GPU tests in addition to running L0 pre-merge pipeline.

--post-merge (OPTIONAL) : Run the L0 post-merge pipeline instead of the ordinary L0 pre-merge pipeline.

--extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx" (OPTIONAL) : Run the ordinary L0 pre-merge pipeline and specified test stages. Examples: --extra-stage "H100_PCIe-TensorRT-Post-Merge-1, xxx".

--detailed-log (OPTIONAL) : Enable flushing out all logs to the Jenkins console. This will significantly increase the log volume and may slow down the job.

--debug (OPTIONAL) : Experimental feature. Enable access to the CI container for debugging purpose. Note: Specify exactly one stage in the stage-list parameter to access the appropriate container environment. Note: Does NOT update GitHub check status.

For guidance on mapping tests to stage names, see docs/source/reference/ci-overview.md
and the scripts/test_to_stage_mapping.py helper.

kill

kill

Kill all running builds associated with pull request.

skip

skip --comment COMMENT

Skip testing for latest commit on pull request. --comment "Reason for skipping build/test" is required. IMPORTANT NOTE: This is dangerous since lack of user care and validation can cause top of tree to break.

reuse-pipeline

reuse-pipeline

Reuse a previous pipeline to validate current commit. This action will also kill all currently running builds associated with the pull request. IMPORTANT NOTE: This is dangerous since lack of user care and validation can cause top of tree to break.

Signed-off-by: Chang Liu (Enterprise Products) <[email protected]>
@chang-l chang-l requested a review from a team as a code owner October 28, 2025 20:24
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

📝 Walkthrough

Walkthrough

Extends build packaging to include generated Python files from extension pipelines (deep_ep, deep_gemm, flash_mla) and C++ wrapper extensions. Updates precompiled wheel extraction to skip YAML files and restrict Python files to allowed directories. Adds tests verifying C++ extension wrapper files exist and are importable.

Changes

Cohort / File(s) Summary
Build configuration and wheel extraction
setup.py
Extends packaging data to include Python files from generated extension pipelines and C++ extension wrappers. Updates precompiled wheel extraction logic to skip YAML files and selectively include Python files only from allowed directories (tensorrt_llm/deep_gemm/, tensorrt_llm/deep_ep/, tensorrt_llm/flash_mla/).
C++ extension wrapper tests
tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py
New test module with two tests: test_cpp_extension_wrapper_files_exist() verifies wrapper files exist for deep_gemm, deep_ep, and flash_mla extensions; test_cpp_extensions_importable() verifies the extensions are importable and expose expected attributes. Includes __main__ guard for direct execution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • setup.py: Requires careful review of packaging configuration changes, inclusion patterns, and wheel extraction logic to ensure all necessary files are included and unwanted files are excluded
  • test_prebuilt_whl_cpp_extensions.py: New test logic should be verified for correctness, but changes are relatively straightforward test assertions

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR author provided substantive technical content explaining the import issue with editable installs and prebuilt wheels, including root cause analysis and reproduction steps. However, the description does not properly follow the required template structure. Most critically, the "Test Coverage" section is completely empty despite being a required template section that asks authors to "list clearly what are the relevant test(s) that can safeguard the changes in the PR." While the raw summary indicates a new test file tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py was added and the checklist indicates test cases are provided, these tests are not documented in the Test Coverage section as the template requires. The Description section header also appears unfilled, with substantive content placed above the template instead of within the designated section. The PR description must be updated to properly complete the required template sections. The author should move or duplicate their technical explanation into the "Description" section and fill out the "Test Coverage" section by explicitly documenting the new test file added (tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py) and what test cases it contains, particularly test_cpp_extension_wrapper_files_exist() and test_cpp_extensions_importable() which verify the fix for the extension import issue.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "[https://nvbugs/5617275][fix] Extract py files from prebuilt wheel for editable installs" directly corresponds to the main changes in the pull request. The raw_summary confirms that the primary modifications involve updating wheel packaging to selectively extract Python files from specific generated extension directories (deep_gemm, deep_ep, flash_mla) for prebuilt wheels, and adding tests to verify this behavior. The title follows the required format with a valid NVBugs ticket reference, proper type indicator [fix], and a clear, descriptive summary that accurately reflects the changeset's core objective.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py (1)

44-51: Prefer importlib.import_module over __import__.

The coding guidelines recommend avoiding reflection when a simpler, explicit approach suffices. Using importlib.import_module is more idiomatic and explicit than __import__.

Apply this diff:

+    import importlib
+
     failed_imports = []
     for module_name, attr_name in import_tests:
         try:
-            module = __import__(module_name, fromlist=[attr_name])
+            module = importlib.import_module(module_name)
             if not hasattr(module, attr_name):
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ee71d9 and 35371f9.

📒 Files selected for processing (2)
  • setup.py (2 hunks)
  • tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{h,hpp,hh,hxx,cpp,cxx,cc,cu,cuh,py}

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

Use only spaces, no tabs; indent with 4 spaces.

Files:

  • tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py
  • setup.py
**/*.py

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

**/*.py: Python code must target Python 3.8+.
Indent Python code with 4 spaces; do not use tabs.
Maintain module namespace when importing; prefer 'from package.subpackage import foo' then 'foo.SomeClass()' instead of importing the class directly.
Python filenames should be snake_case (e.g., some_file.py).
Python classes use PascalCase names.
Functions and methods use snake_case names.
Local variables use snake_case; prefix 'k' for variables that start with a number (e.g., k_99th_percentile).
Global variables use upper SNAKE_CASE prefixed with 'G' (e.g., G_MY_GLOBAL).
Constants use upper SNAKE_CASE (e.g., MY_CONSTANT).
Avoid shadowing variables from an outer scope.
Initialize all externally visible members of a class in the constructor.
Prefer docstrings for interfaces that may be used outside a file; comments for in-function or file-local interfaces.
Use Google-style docstrings for classes and functions (Sphinx-parsable).
Document attributes and variables inline so they render under the class/function docstring.
Avoid reflection when a simpler, explicit approach suffices (e.g., avoid dict(**locals()) patterns).
In try/except, catch the most specific exceptions possible.
For duck-typing try/except, keep the try body minimal and use else for the main logic.

Files:

  • tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py
  • setup.py
**/*.{cpp,cxx,cc,h,hpp,hh,hxx,cu,cuh,py}

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

Prepend the NVIDIA Apache-2.0 copyright header with current year to the top of all source files (e.g., .cpp, .h, .cu, .py).

Files:

  • tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py
  • setup.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Pre-commit Check
🔇 Additional comments (2)
setup.py (1)

121-126: LGTM! Package data patterns correctly extended.

The addition of Python files and LICENSE files for the generated C++ extension wrappers (deep_ep, deep_gemm, flash_mla) aligns with the PR objective to support editable installs from prebuilt wheels.

tests/unittest/utils/test_prebuilt_whl_cpp_extensions.py (1)

8-56: Well-structured test coverage for C++ extension wrappers.

The tests effectively verify:

  • Presence of required Python wrapper files for each extension
  • Importability and attribute exposure of the wrappers
  • Clear, actionable error messages with diagnostic guidance

This aligns well with the PR objective to ensure prebuilt wheel extraction includes generated Python files for editable installs.

@chang-l
Copy link
Collaborator Author

chang-l commented Oct 29, 2025

/bot run

@tensorrt-cicd
Copy link
Collaborator

PR_Github #22823 [ run ] triggered by Bot. Commit: 35371f9

@tensorrt-cicd
Copy link
Collaborator

PR_Github #22823 [ run ] completed with state SUCCESS. Commit: 35371f9
/LLM/main/L0_MergeRequest_PR pipeline #17215 completed with status: 'SUCCESS'
Pipeline passed with automatic retried tests. Check the rerun report for details.

@chang-l chang-l enabled auto-merge (squash) October 31, 2025 04:15
@chang-l chang-l merged commit 3a79d03 into NVIDIA:main Oct 31, 2025
11 checks passed
fredricz-20070104 pushed a commit to fredricz-20070104/TensorRT-LLM that referenced this pull request Nov 5, 2025
…r editable installs (NVIDIA#8738)

Signed-off-by: Chang Liu (Enterprise Products) <[email protected]>
Signed-off-by: FredricZ-2007 <[email protected]>
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.

4 participants