Setting Up Custom PyTorch Indexes for Nightly or Bleeding‑Edge Builds with uv

Configure uv's [tool.uv.sources] and [tool.uv.index] sections in pyproject.toml to declaratively install PyTorch from custom CPU or CUDA package indexes, selecting hardware-specific variants through mutually exclusive optional extras.

Setting up custom PyTorch indexes for nightly or bleeding‑edge builds with uv eliminates manual wheel management and complex pip installation commands. The baonguyen6742/uv-install-torch repository demonstrates a fully declarative approach that uses static configuration to resolve PyTorch wheels from the official custom indexes based on your selected hardware target.

Configuring Custom Indexes in pyproject.toml

The entire workflow centers on pyproject.toml, where project metadata, optional dependencies, and index definitions coalesce. This file replaces traditional installation scripts with a reproducible configuration that uv consumes to resolve and lock dependencies.

Declaring Optional Dependencies for CPU and CUDA

Define two mutually exclusive extras under [project.optional-dependencies] to represent the CPU‑only and CUDA‑enabled variants. Both extras declare identical package versions, but uv routes them to different indexes based on subsequent source mappings.

[project.optional-dependencies]
cpu = ["torch==2.4.1", "torchvision==0.19.1", "torchaudio==2.4.1"]
cu124 = ["torch==2.4.1", "torchvision==0.19.1", "torchaudio==2.4.1"]

Mapping Package Sources to Specific Indexes

The [tool.uv.sources] section creates conditional logic that binds each extra to its corresponding PyTorch index. When uv resolves dependencies, it selects the URL based on which extra is active during synchronization.

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

Defining Index URLs and Conflict Resolution

Declare the actual PyTorch repository URLs under [[tool.uv.index]]. To prevent uv from attempting to install both CPU and CUDA wheels simultaneously—an impossible state since they provide the same package names—explicitly declare them as conflicting using the conflicts array.

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

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

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

Installing PyTorch from Custom Indexes

With the configuration in place, use uv sync with the appropriate --extra flag to install your desired variant. This command resolves the dependency graph against the specified index and generates or updates uv.lock for reproducibility.

Install the CUDA 12.4 build:

uv sync --extra cu124

Install the CPU-only build:

uv sync --extra cpu

Managing Cache and Environment State

When switching between indexes or troubleshooting resolution failures, clear uv's cache to purge stale metadata about available wheels. This forces uv to re-query the custom indexes on the next synchronization.

Clear the PyTorch-specific cache and reinstall:

uv cache clean torch
uv sync --extra cu124

For a complete environment reset—necessary when switching between radically different PyTorch builds or recovering from resolution corruption—remove the virtual environment and lock file before re-syncing:

rm -rf .venv uv.lock
uv sync --extra cu124

Verifying the Installation

The repository includes main.py, a minimal verification script that imports the installed libraries and inspects GPU availability. Execute it using uv run to confirm that the correct wheels are active without manually activating the virtual environment.

uv run main.py

The script calls torch.cuda.is_available() to validate that the CUDA build detects the GPU, or confirms the CPU-only configuration when False.

Summary

  • Declarative configuration in pyproject.toml replaces imperative installation scripts for managing custom PyTorch indexes.
  • Mutually exclusive extras (cpu and cu124) map to distinct PyTorch wheel repositories via [tool.uv.sources].
  • Explicit conflict declaration prevents the resolver from attempting to install incompatible CPU and CUDA variants simultaneously.
  • Index-specific caching via uv cache clean torch resolves metadata conflicts when switching between stable and nightly builds.
  • Environment verification through uv run main.py provides immediate feedback on whether GPU acceleration is active.

Frequently Asked Questions

How do I switch from a CUDA build to a CPU build?

Clear the uv cache to eliminate stale resolution metadata, then synchronize with the CPU extra. The conflicts array in pyproject.toml ensures uv uninstalls the CUDA variant before installing the CPU wheels.

uv cache clean torch
uv sync --extra cpu

Can I configure multiple CUDA versions simultaneously?

While you can define additional extras for other CUDA versions (e.g., cu118) in [project.optional-dependencies], the repository implements strict mutual exclusivity via the conflicts setting. Supporting multiple simultaneous CUDA versions requires separate virtual environments or removing the conflicts constraint and manually managing the resolution graph.

Why does uv require explicit conflict declaration for PyTorch extras?

Without the conflicts = [[{ extra = "cpu" }, { extra = "cu124" }]] configuration, uv's resolver might attempt to satisfy both extras if transitive dependencies request them, creating an impossible resolution state where both CPU and CUDA wheels of the same package version are required. Explicit conflicts enforce a single variant per environment.

How do I install a specific nightly build instead of the stable versions shown?

Update the version pins in [project.optional-dependencies] to reference the specific nightly wheel (e.g., torch==2.5.0.dev20240815+cu124) and change the index URLs in [[tool.uv.index]] to point to the nightly repositories (e.g., https://download.pytorch.org/whl/nightly/cu124). The [tool.uv.sources] mapping logic remains identical regardless of whether the index serves stable or bleeding‑edge releases.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →