How to Install CUDA PyTorch Wheels Without a GPU
PyTorch publishes CPU, CUDA, and ROCm wheels on separate indexes, and uv’s --torch-backend=auto picks between them by inspecting the local machine for a GPU. On a CI runner or Docker build stage there is no GPU to find, so auto quietly selects CPU wheels and the build succeeds with the wrong artifact.
Two environment variables let you state what the target machine has instead of what the build machine has.
Prerequisites
- uv installed, with
--torch-backendavailable on theuv pipinterface - The CUDA driver version of the machine that will run the code
Confirm the build machine fell back to CPU
Resolve torch on the build machine and read the local version suffix:
$ echo "torch" > requirements.in
$ uv pip compile requirements.in --torch-backend=auto
torch==2.13.0+cpu
The +cpu suffix is the symptom. uv found no driver and fell through to the CPU index.
Declare the driver the target machine runs
Set UV_CUDA_DRIVER_VERSION to the driver version reported by nvidia-smi --query-gpu=driver_version --format=csv,noheader on the target host:
$ UV_CUDA_DRIVER_VERSION=550.144.03 uv pip compile requirements.in --torch-backend=auto
torch==2.13.0+cu129
uv now behaves as though it had detected that driver locally. The same variable works for an install:
$ UV_CUDA_DRIVER_VERSION=550.144.03 uv pip install torch --torch-backend=auto
In a Dockerfile, set it for the build stage that installs dependencies:
ENV UV_CUDA_DRIVER_VERSION=550.144.03
RUN uv pip install --system torch --torch-backend=autoBoth overrides are read before uv probes the hardware, so they win even on a machine that has a GPU. A stale value will quietly override a correct autodetection.
Important
--torch-backend is respected by uv pip install, uv pip compile, uv pip sync, uv tool run, and uv tool install. Project commands ignore it, so uv add, uv sync, and uv lock see no effect from either variable. To pin a backend in a project, route torch through an explicit index as described in How to Install PyTorch with uv.
Name the target platform when resolving from macOS
uv maps drivers to CUDA indexes only for Linux and Windows targets. Resolving from macOS without naming a target platform drops the override and returns a plain PyPI build:
$ UV_CUDA_DRIVER_VERSION=550.144.03 uv pip compile requirements.in --torch-backend=auto
torch==2.13.0
Add --python-platform so the resolution targets the machine that will run the wheels:
$ UV_CUDA_DRIVER_VERSION=550.144.03 uv pip compile requirements.in \
--torch-backend=auto --python-platform linux
torch==2.13.0+cu129
Linux build agents already resolve for Linux, so this step only applies when the resolve runs on macOS.
Pick a driver value
uv compares the driver against a floor for each CUDA version, then takes the highest backend the driver satisfies. Exact values do not matter, only which floor they clear:
| Driver version | Highest CUDA backend selected |
|---|---|
| 580 and above | cu132 |
| 525.60.13 up to 580 | cu129 |
| 450.80.2 up to 525.60.13 | cu118 |
An older driver constrains the torch version too, because recent torch releases stopped publishing CUDA 11.8 wheels:
$ UV_CUDA_DRIVER_VERSION=470.199.02 uv pip compile requirements.in \
--torch-backend=auto --python-platform linux --python-version 3.12
torch==2.7.1+cu118
Name the target Python version alongside the driver. The CUDA 11.8 index carries no build for Python 3.14, so asking for both drops the resolution back to CPU wheels without reporting a conflict:
$ UV_CUDA_DRIVER_VERSION=470.199.02 uv pip compile requirements.in \
--torch-backend=auto --python-platform linux --python-version 3.14
torch==2.13.0+cpu
A +cpu suffix after setting the override means the requested combination of driver, platform, and Python version has no CUDA build, not that the override was ignored.
An unparseable value fails the command rather than falling back to autodetection, so a typo surfaces immediately:
$ UV_CUDA_DRIVER_VERSION=not-a-version uv pip compile requirements.in --torch-backend=auto
error: Failed to parse environment variable `UV_CUDA_DRIVER_VERSION` with invalid value `not-a-version`: expected version to start with a number, but no leading ASCII digits were found
Target an AMD GPU instead
UV_AMD_GPU_ARCHITECTURE does the same job for ROCm. Set it to the architecture of the target card, such as gfx1100 for RDNA 3:
$ UV_AMD_GPU_ARCHITECTURE=gfx1100 uv pip compile requirements.in \
--torch-backend=auto --python-platform linux
torch==2.13.0+rocm7.2
uv checks the CUDA override first, so set only one of the two.
Learn More
- Using uv with PyTorch documents
--torch-backendand the index layout it selects from - Why Installing GPU Python Packages Is So Complicated explains why the wheels are split across indexes at all
- How to Use uv in a Dockerfile covers the surrounding build-stage and caching setup
- What Are Wheel Variants? describes the proposed standard that would make hardware detection part of package metadata
- light-the-torch is the pip wrapper whose driver-to-CUDA mapping uv’s implementation is based on