Declare the torch version in release wheels - #23311
Open
shoumikhin wants to merge 2 commits into
Open
shoumikhin wants to merge 2 commits into
shoumikhin wants to merge 2 commits into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/23311
Note: Links to docs will display an error until the docs builds have been completed. ⏳ No Failures, 1 PendingAs of commit 511909b with merge base fdd5140 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Release metadata generation fails under standard isolated PEP 517 builds because PyTorch is unavailable to the build backend.
Review effort: Balanced
Findings: 1
What changed in this PR
Adds PyTorch minor-version constraints to release wheels to prevent ABI-incompatible installations.
Changes:
- Derives release-wheel PyTorch bounds from the build environment.
- Adds unit and wheel smoke-test coverage.
- Updates installation and packaging documentation.
| File | Description |
|---|---|
setup.py |
Adds release-only PyTorch dependency metadata. |
install_utils.py |
Derives the compatible PyTorch range. |
docs/source/getting-started.md |
Documents release and nightly behavior. |
.ci/scripts/wheel/test_shared_libraries.py |
Updates dependency commentary. |
.ci/scripts/wheel/test_cuda_linux.py |
Checks CUDA release metadata. |
.ci/scripts/wheel/test_clean_install.py |
Validates the declared PyTorch range. |
.ci/scripts/wheel/cuda_arch_list.sh |
Clarifies PyTorch build selection. |
.ci/scripts/tests/test_release_torch_requirement.py |
Tests dependency generation and wheel scope. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| public = (build_version or "").strip().split("+", 1)[0] | ||
| if not re.fullmatch(r"\d+(\.\d+)*", public): | ||
| return None | ||
| torch_version = importlib.metadata.version("torch").split("+", 1)[0] |
shoumikhin
force-pushed
the
release-wheels-declare-torch
branch
from
October 1, 2026 15:49
7424449 to
33eab4f
Compare
| major, minor = (int(part) for part in torch_version.split(".")[:2]) | ||
| snapshot = re.fullmatch(rf"{major}\.{minor}\.0\.dev\d+", torch_version) | ||
| floor = snapshot.group(0) if snapshot else f"{major}.{minor}.0a0" | ||
| return f"torch>={floor},<{major}.{minor + 1}" |
The ExecuTorch wheel only works with a PyTorch (`torch`) version close to the one it was built with. But since 1.5, nothing tells pip which version that is. So pip can install any torch next to it, and the problem only shows up later, at runtime: ``` pip install executorch==1.5.1 torch==2.12.0 # installs fine # then running a model fails: RuntimeError: tensor does not have a device # 1.5.1 was built on torch 2.14 ``` Releases 0.2 to 1.4 declared torch, because each release branch added the requirement by hand. For 1.5 it was not added. This change makes a release declare its torch version automatically, so pip picks a torch that works: ``` Requires-Dist: torch<2.15,>=2.14.0a0 ``` How it works: - The version comes from the torch the wheel is built against, so nobody has to type it in. - The upper limit (`<2.15`) matters as much as the lower one. Without it, a later torch can break a release that already shipped, as `executorch==1.3.1` with torch 2.14.1 does today. - The `a0` in the lower limit lets a torch built from source (version `2.14.0a0+git...`) count as 2.14. A build on a nightly torch snapshot (version `2.14.0.dev...`) uses that snapshot as the lower limit, because it sorts below `a0`. - It does not choose between the CPU and CUDA builds of torch. The package index you install from still does that. Only releases declare it. Nightly builds, local builds, and the small export-only wheel still declare no torch. The release workflows mark a build as a release by setting `BUILD_VERSION` to a plain version like `1.6.0+cu132`. The wheel tests now also check that a release declares torch and that the installed torch fits the range. Nightly wheels skip this, so on `main` the new unit tests cover the rule instead. Test plan: - New unit tests. Each fails if a part of the rule is removed, including the line in `setup.py` that adds it. - Built the package metadata from the real `setup.py` for release, nightly, local, and export-only builds, and checked the torch line in each. - Checked what pip does with the new range. A fresh install gets torch 2.14.1. An installed 2.14.1 CUDA build or source build is kept, and 2.13 or 2.15 is replaced. - The new wheel test fails on the published 1.5.1 wheel, which shipped without the requirement.
shoumikhin
force-pushed
the
release-wheels-declare-torch
branch
from
October 2, 2026 00:03
72ee216 to
74646aa
Compare
| # carry it are declared here. A CPU wheel adds nothing. | ||
| setup_kwargs["install_requires"] = _base_dependencies() + _cuda_dependencies() | ||
| setup_kwargs["install_requires"] = ( | ||
| _base_dependencies() + _cuda_dependencies() + _torch_dependencies() |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

The ExecuTorch wheel only works with a PyTorch (
torch) version close to the one it was built with. But since 1.5, nothing tells pip which version that is. So pip can install any torch next to it, and the problem only shows up later, at runtime:Releases 0.2 to 1.4 declared torch, because each release branch added the requirement by hand. For 1.5 it was not added.
This change makes a release declare its torch version automatically, so pip picks a torch that works:
How it works:
<2.15) matters as much as the lower one. Without it, a later torch can break a release that already shipped, asexecutorch==1.3.1with torch 2.14.1 does today.a0in the lower limit lets a torch built from source (version2.14.0a0+git...) count as 2.14. A build on a nightly torch snapshot (version2.14.0.dev...) uses that snapshot as the lower limit, because it sorts belowa0.Only releases declare it. Nightly builds, local builds, and the small export-only wheel still declare no torch. The release workflows mark a build as a release by setting
BUILD_VERSIONto a plain version like1.6.0+cu132.The wheel tests now also check that a release declares torch and that the installed torch fits the range. Nightly wheels skip this, so on
mainthe new unit tests cover the rule instead.Test plan:
setup.pythat adds it.setup.pyfor release, nightly, local, and export-only builds, and checked the torch line in each.