# PyTorch CPU-Only Installation Without CUDA Extras Using uv

> Install PyTorch CPU-only without CUDA extras using uv. Configure optional dependencies in pyproject.toml and run uv sync --extra cpu for efficient, GPU-free installs.

- Repository: [Th3Unknovvn/uv-install-torch](https://github.com/baonguyen6742/uv-install-torch)
- Tags: tutorial
- Published: 2026-02-26

---

**Configure uv's optional dependencies in [`pyproject.toml`](https://github.com/baonguyen6742/uv-install-torch/blob/main/pyproject.toml) to install PyTorch CPU wheels from the official PyTorch index while excluding CUDA packages, then run `uv sync --extra cpu` to resolve dependencies without GPU libraries.**

This guide demonstrates how to configure **uv** (the ultra-fast Python package manager) for a **PyTorch CPU-only installation without CUDA extras** using the `baonguyen6742/uv-install-torch` repository methodology. By leveraging uv's conditional extras and explicit index management, you can isolate CPU-only wheels and avoid bloating your environment with unnecessary CUDA dependencies.

## Project Architecture Overview

The solution centers on three files in the repository root: [`pyproject.toml`](https://github.com/baonguyen6742/uv-install-torch/blob/main/pyproject.toml) (dependency declaration and index configuration), [`main.py`](https://github.com/baonguyen6742/uv-install-torch/blob/main/main.py) (runtime validation), and [`README.md`](https://github.com/baonguyen6742/uv-install-torch/blob/main/README.md) (setup instructions). The [`pyproject.toml`](https://github.com/baonguyen6742/uv-install-torch/blob/main/pyproject.toml) file implements a dual-extra strategy where the `cpu` extra pins CPU-specific wheels and the `cu124` extra pins CUDA-enabled wheels, with uv enforcing mutual exclusivity between them.

### Declaring Optional Dependencies

In [`pyproject.toml`](https://github.com/baonguyen6742/uv-install-torch/blob/main/pyproject.toml), the `[project.optional-dependencies]` section defines two conflicting extras:

- **The `cpu` extra**: Pins `torch==2.4.1`, `torchvision==0.19.1`, and `torchaudio==2.4.1` for CPU-only execution
- **The `cu124` extra**: Pins identical version numbers but resolves them from the CUDA 12.4 wheel index

Regular dependencies (non-PyTorch libraries) are listed in the main `dependencies` array, while the PyTorch stack is deliberately omitted from this section to prevent automatic installation of GPU-enabled defaults.

### Configuring uv Package Indexes

The `[tool.uv.sources]` section maps each extra to a specific PyTorch wheel index:

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

```

Two explicit indexes are defined under `[tool.uv]`:
- `pytorch-cpu`: `https://download.pytorch.org/whl/cpu`
- `pytorch-cu124`: `https://download.pytorch.org/whl/cu124`

When you activate the `cpu` extra, uv resolves PyTorch packages exclusively from the CPU index, ensuring no CUDA libraries enter your environment.

### Preventing Conflicting Extras

The configuration includes a `conflicts` declaration that prevents simultaneous activation of both extras:

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

```

This guardrail prevents uv from attempting to resolve an unsolvable dependency graph where both CPU and CUDA wheels are requested simultaneously.

## Installation Workflow

### Installing the CPU-Only Stack

Run the following command to install all dependencies with the CPU-only PyTorch wheels:

```bash
uv sync --extra cpu

```

This command resolves regular dependencies from PyPI and pulls PyTorch, torchvision, and torchaudio from the `pytorch-cpu` index. The resulting environment contains no CUDA runtime libraries, reducing installation size and avoiding DLL conflicts on machines without NVIDIA hardware.

### Verifying the Installation with main.py

Validate your setup by executing the repository's test script:

```bash
uv run main.py

```

The [`main.py`](https://github.com/baonguyen6742/uv-install-torch/blob/main/main.py) script performs three critical checks:
1. Imports `torch`, `torchvision`, and `torchaudio` without errors
2. Prints `torch.cuda.is_available()` (should return `False` for CPU-only installs)
3. Executes a minimal tensor calculation to confirm functional PyTorch operations

Expected output includes version numbers (2.4.1 for torch), a `False` CUDA availability status, and numerical results from the `basic_calculation` function.

### Switching to CUDA (Optional)

If you later acquire GPU hardware, migrate to CUDA-enabled wheels without modifying configuration files:

```bash
uv sync --extra cu124
uv run main.py

```

The script will now display `torch.cuda.is_available(): True` along with device property details, confirming the switch to GPU acceleration.

## Troubleshooting Cache Issues

When switching between CPU and CUDA builds or troubleshooting version mismatches, clear uv's cache to prevent stale wheel resolution:

```bash
uv cache clean torch
uv cache prune
uv sync --extra cpu

```

The `uv cache clean torch` command removes all cached torch-related artifacts, while `uv cache prune` eliminates unreachable cache entries. Subsequent sync operations download fresh wheels from the appropriate index.

## Summary

- **Use optional extras** in [`pyproject.toml`](https://github.com/baonguyen6742/uv-install-torch/blob/main/pyproject.toml) to separate CPU and CUDA dependency resolution paths
- **Configure explicit indexes** under `[tool.uv.sources]` to point uv to `download.pytorch.org/whl/cpu`
- **Enforce conflicts** to prevent accidental simultaneous installation of CPU and CUDA wheels
- **Validate with [`main.py`](https://github.com/baonguyen6742/uv-install-torch/blob/main/main.py)** by checking that `torch.cuda.is_available()` returns `False`
- **Clear caches** with `uv cache clean torch` when switching between hardware configurations

## Frequently Asked Questions

### How does the configuration ensure CUDA dependencies are completely excluded?

The [`pyproject.toml`](https://github.com/baonguyen6742/uv-install-torch/blob/main/pyproject.toml) omits PyTorch from the base `dependencies` array and instead defines it exclusively within the `[project.optional-dependencies]` section. By activating only the `cpu` extra during `uv sync`, uv resolves torch packages from the `pytorch-cpu` index rather than the default GPU-enabled PyPI distribution, ensuring no NVIDIA runtime libraries (cuDNN, CUDA Toolkit) enter the environment.

### Can I switch from CPU-only to CUDA later without reinstalling uv?

Yes. Simply run `uv sync --extra cu124` to replace the CPU wheels with CUDA 12.4 variants. The configuration uses identical version pins for both extras (2.4.1 for torch), allowing seamless switching without dependency conflicts. Run `uv cache clean torch` first if you encounter resolution errors during the transition.

### What PyTorch versions does this configuration support?

The repository pins `torch==2.4.1`, `torchvision==0.19.1`, and `torchaudio==2.4.1`. You can update these versions in both the `cpu` and `cu124` extra definitions to match your requirements, provided the versions exist on both the CPU and CUDA wheel indexes at `download.pytorch.org`.

### Why is explicit index configuration necessary for PyTorch?

PyTorch's default PyPI distribution includes CUDA dependencies that significantly increase installation size and fail on machines without GPU drivers. By explicitly configuring the `pytorch-cpu` index in `[tool.uv.sources]`, you override uv's default resolution behavior and force installation of the lean CPU-only wheels (approximately 100MB versus 2GB+ for CUDA variants).