# How to Install PyTorch with uv


PyTorch publishes different [wheel](https://pydevtools.com/handbook/reference/wheel.md) builds for CPU, CUDA, ROCm, and XPU on separate package indexes (see [Why Installing GPU Python Packages Is So Complicated](https://pydevtools.com/handbook/explanation/installing-cuda-python-packages.md) for background). Getting the right build requires telling [uv](https://pydevtools.com/handbook/reference/uv.md) which index to use.

For llama.cpp models, follow [Install llama-cpp-python](https://pydevtools.com/handbook/how-to/how-to-install-llama-cpp-python.md); its backend indexes and GPU requirements differ from PyTorch's.

## Default behavior without configuration

Running `uv add torch torchvision` with no extra configuration installs from PyPI. PyPI carries CPU-only wheels for Windows and macOS, and CUDA 13.0 wheels for Linux. The CUDA version depends on the resolved PyTorch release; configure an explicit index when a specific CUDA build is required. For projects that only need CPU support on Windows/macOS and GPU support on Linux, this default works without any additional setup.

## Configure a CUDA backend in your project

To install a specific CUDA build across platforms, define a PyTorch index in `pyproject.toml` and route packages to it with `tool.uv.sources`. This example configures CUDA 12.8 on Linux and Windows while letting macOS fall back to PyPI (since CUDA builds are not available for macOS):

```toml
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true

[tool.uv.sources]
torch = [
  { index = "pytorch-cu128", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
torchvision = [
  { index = "pytorch-cu128", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
```

Setting `explicit = true` prevents uv from searching this index for unrelated packages. Every PyTorch-related package that needs a GPU build must be listed in `[tool.uv.sources]`. If `torchvision` or `torchaudio` is omitted, those packages will resolve from PyPI instead of the CUDA index.

Available backends follow the URL pattern `https://download.pytorch.org/whl/{backend}`, where `{backend}` is one of: `cpu`, `cu118`, `cu126`, `cu128`, `cu130`, `rocm6.4`, `xpu`.

## Support multiple backends with extras

Projects that need to work across different hardware can use optional dependency groups to let users choose their backend at install time:

```toml
[project.optional-dependencies]
cpu = ["torch>=2.9.1", "torchvision>=0.24.1"]
cu128 = ["torch>=2.9.1", "torchvision>=0.24.1"]

[tool.uv]
conflicts = [[{ extra = "cpu" }, { extra = "cu128" }]]

[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true

[tool.uv.sources]
torch = [
  { index = "pytorch-cpu", extra = "cpu" },
  { index = "pytorch-cu128", extra = "cu128" },
]
torchvision = [
  { index = "pytorch-cpu", extra = "cpu" },
  { index = "pytorch-cu128", extra = "cu128" },
]
```

Users then install with the extra that matches their hardware:

```sh
uv sync --extra cpu
# or
uv sync --extra cu128
```

The `conflicts` table tells uv these extras are mutually exclusive, so it will not attempt to resolve both at once.

## Quick installs with `uv pip` and `--torch-backend`

The `uv pip` interface offers a `--torch-backend` flag that selects the correct PyTorch index without any `pyproject.toml` configuration:

```sh
uv pip install torch --torch-backend=cu128
```

Setting `--torch-backend=auto` makes uv detect the available GPU hardware (CUDA driver version, AMD GPU, or Intel GPU) and pick the appropriate backend. If no GPU is detected, it falls back to CPU.

```sh
uv pip install torch --torch-backend=auto
```

The `UV_TORCH_BACKEND` environment variable works the same way:

```sh
UV_TORCH_BACKEND=auto uv pip install torch
```

Valid values include `auto`, `cpu`, `cu118`, `cu126`, `cu128`, `cu130`, `rocm6.4`, and `xpu`. Pass an invalid one and uv prints the full list, which is the quickest way to see what the installed version supports.

Running `auto` on a machine with no GPU selects CPU wheels, which is the usual reason a Docker build produces a CPU-only image. [How to Install CUDA PyTorch Wheels Without a GPU](https://pydevtools.com/handbook/how-to/how-to-install-cuda-pytorch-wheels-without-a-gpu.md) covers naming the target hardware instead.

> [!IMPORTANT]
> `--torch-backend` works with `uv pip install`, `uv pip compile`, `uv pip sync`, `uv tool run`, and `uv tool install`. It does not work with `uv add`, `uv lock`, `uv sync`, or `uv run`. For project-level workflows, use the `pyproject.toml` configuration described above.

## Manage PyTorch updates

Each PyTorch release supports a specific set of CUDA versions, so upgrading torch can require a newer CUDA toolkit and NVIDIA driver. Declare a loose constraint in `pyproject.toml` (`torch>=2.6`) and let uv's [lockfile](https://pydevtools.com/handbook/how-to/how-to-use-a-uv-lockfile-for-reproducible-python-environments.md) hold the exact version.

Upgrade when you choose to, then test against the target CUDA environment:

```console
$ uv lock --upgrade-package torch
```

Deferring those upgrades without also silencing PyTorch security advisories takes [a Dependabot ignore rule scoped to version updates](https://pydevtools.com/handbook/how-to/how-to-ignore-a-dependency-in-dependabot-without-blocking-security-updates.md).
