Summary
The repository documents more than one way to install it, and they do not produce the same environment: following pip install . installs torch 2.14.0 from PyPI, while following uv sync / uv pip install . installs torch 2.11.0+cu128 from download.pytorch.org/whl/cu128; 1 further package(s) differ the same way (cffi). A user who reads the README/Dockerfile expects the CUDA/ROCm build named there, but depending on the installer and index order gets a different variant or major version, which is confusing to debug (GPU silently unused, mismatched CUDA libraries) and means the two paths are not tested against the same dependencies. Because the selection is decided by index visibility and installer semantics rather than by the project, it is also an exposure: whichever index publishes a higher version of these names decides what gets installed.
Description
torch:
pip install . (pyproject/requirements only, PyPI) → torch 2.14.0 from PyPI
uv sync / uv pip install . (pyproject with [tool.uv.sources]) → torch 2.11.0+cu128 from download.pytorch.org/whl/cu128
cffi (transitive):
pip install . (pyproject/requirements only, PyPI) → not installed
uv sync / uv pip install . (pyproject with [tool.uv.sources]) → cffi 2.1.1 from PyPI
Steps to reproduce
Dry-run resolutions (nothing is installed), Python 3.11, Linux x86_64, pip 26.2.1 / uv 0.12.10, index state of 2026-09-07:
# A: `pip install .` (pyproject/requirements only, PyPI)
pip install --dry-run --report a.json "torch" "Pillow" "PyYAML" "fastapi" "gymnasium" "h5py" "imageio" "jinja2" "json_numpy"
# -> `torch 2.14.0` from PyPI; not installed
# B: `uv sync` / `uv pip install .` (pyproject with `[tool.uv.sources]`)
uv lock # in the repo checkout (honours [tool.uv.sources]); or: uv pip compile --emit-index-annotation -o b.txt req.txt --index-strategy unsafe-best-match # req.txt: "torch" "Pillow" "PyYAML" "fastapi" "gymnasium" "h5py" "imageio" "jinja2" "json_numpy"
# -> `torch 2.11.0+cu128` from download.pytorch.org/whl/cu128; `cffi 2.1.1` from PyPI
Expected behavior
Every documented install path selects the same file for the package(s) above (same version, same index, same hash), or the documentation states which build is intended.
Actual behavior
torch: 2.14.0 (PyPI) vs 2.11.0+cu128 (download.pytorch.org/whl/cu128).
cffi is installed by one path and absent from the other.
Consequences
- Users following one path get a different PyTorch build (CUDA/ROCm/CPU variant or major version) than users following the other; GPU code may run on CPU or fail to load CUDA libraries.
- Common packages are pinned to years-old copies from the PyTorch channel under uv (e.g. an outdated CA bundle in
certifi), while pip users get current releases.
- The environment produced by one path is not the one exercised in CI, so bug reports are hard to reproduce.
- The two paths install files with different hashes from different indexes; which build (and whose build) ends up in the environment is decided by index order and installer behaviour rather than by the project's declaration, and the two files were not verified against each other here.
Root cause
- Case 1: pip applies version priority across all indexes it can see (PEP 766): when PyPI is visible next to a
download.pytorch.org channel, the newer PyPI release wins over the +cuXXX build. uv's default first-index strategy does the opposite (first index that has the name). The selected build therefore depends on the installer and on whether the channel is passed as --index-url or --extra-index-url, not on the declaration. [tool.uv.sources] is honoured only by uv; every pip install command in the docs/Dockerfile ignores it and resolves from the indexes on its own command line.
- Case 2: The two paths select different top-level builds whose metadata pulls in different transitive packages (e.g.
nvidia-*-cu12 vs nvidia-*-cu13, triton present or absent). [tool.uv.sources] is honoured only by uv; every pip install command in the docs/Dockerfile ignores it and resolves from the indexes on its own command line.
Where the repo binds these packages to an index
Proposed fix
- Commit a lock (
uv.lock, or pip-compile/pip lock output with hashes) and make the README/Dockerfile/CI install from it, so every documented path resolves identical files.
Environment
- pip 26.2.1, uv 0.12.10, CPython 3.11, Linux x86_64 (Ubuntu 24.04 on WSL2)
- repository at commit
9db0aaf09d9fe5d4f37b168320788258c7012463
- index contents as observed on 2026-09-07; file URLs and sha256 in the table below make the result re-checkable
Selected files
Found by an automated check that resolves the declared dependencies under each documented install path and diffs the selected files. File URLs and sha256 hashes are listed above so the result can be re-checked independently.
Summary
The repository documents more than one way to install it, and they do not produce the same environment: following
pip install .installstorch 2.14.0from PyPI, while followinguv sync/uv pip install .installstorch 2.11.0+cu128from download.pytorch.org/whl/cu128; 1 further package(s) differ the same way (cffi). A user who reads the README/Dockerfile expects the CUDA/ROCm build named there, but depending on the installer and index order gets a different variant or major version, which is confusing to debug (GPU silently unused, mismatched CUDA libraries) and means the two paths are not tested against the same dependencies. Because the selection is decided by index visibility and installer semantics rather than by the project, it is also an exposure: whichever index publishes a higher version of these names decides what gets installed.Description
torch:pip install .(pyproject/requirements only, PyPI) →torch 2.14.0from PyPIuv sync/uv pip install .(pyproject with[tool.uv.sources]) →torch 2.11.0+cu128from download.pytorch.org/whl/cu128cffi(transitive):pip install .(pyproject/requirements only, PyPI) → not installeduv sync/uv pip install .(pyproject with[tool.uv.sources]) →cffi 2.1.1from PyPISteps to reproduce
Dry-run resolutions (nothing is installed), Python 3.11, Linux x86_64, pip 26.2.1 / uv 0.12.10, index state of 2026-09-07:
Expected behavior
Every documented install path selects the same file for the package(s) above (same version, same index, same hash), or the documentation states which build is intended.
Actual behavior
torch: 2.14.0 (PyPI) vs 2.11.0+cu128 (download.pytorch.org/whl/cu128).cffiis installed by one path and absent from the other.Consequences
certifi), while pip users get current releases.Root cause
download.pytorch.orgchannel, the newer PyPI release wins over the+cuXXXbuild. uv's defaultfirst-indexstrategy does the opposite (first index that has the name). The selected build therefore depends on the installer and on whether the channel is passed as--index-urlor--extra-index-url, not on the declaration.[tool.uv.sources]is honoured only by uv; everypip installcommand in the docs/Dockerfile ignores it and resolves from the indexes on its own command line.nvidia-*-cu12vsnvidia-*-cu13,tritonpresent or absent).[tool.uv.sources]is honoured only by uv; everypip installcommand in the docs/Dockerfile ignores it and resolves from the indexes on its own command line.Where the repo binds these packages to an index
pyproject.toml:117 —torch→ https://download.pytorch.org/whl/cu128 (uv binding -> pytorch-cu128)pyproject.toml:107 —torch→ https://download.pytorch.org/whl/cu128 ([[tool.uv.index]] name = "pytorch-cu128" url = "https://download.pytorch.org/whl/cu128" explicit = t)Proposed fix
uv.lock, orpip-compile/pip lockoutput with hashes) and make the README/Dockerfile/CI install from it, so every documented path resolves identical files.Environment
9db0aaf09d9fe5d4f37b168320788258c7012463Selected files
pip install .(pyproject/requirements only, PyPI)torch8d9e232b6376c62fuv sync/uv pip install .(pyproject with[tool.uv.sources])torchc9a7ca4c74fae10apip install .(pyproject/requirements only, PyPI)cffiuv sync/uv pip install .(pyproject with[tool.uv.sources])cffi34e261f78cb6ceaaFound by an automated check that resolves the declared dependencies under each documented install path and diffs the selected files. File URLs and sha256 hashes are listed above so the result can be re-checked independently.