Skip to content

Using fyn with PyTorch

The PyTorch ecosystem is a popular choice for deep learning research and development. You can use fyn to manage PyTorch projects and PyTorch dependencies across different Python versions and environments, even controlling for the choice of accelerator (e.g., CPU-only vs. CUDA).

Note

Some of the features outlined in this guide require fyn version 0.5.3 or later. We recommend upgrading prior to configuring PyTorch.

Installing PyTorch

From a packaging perspective, PyTorch has a few uncommon characteristics:

  • Many PyTorch wheels are hosted on a dedicated index, rather than the Python Package Index (PyPI). As such, installing PyTorch often requires configuring a project to use the PyTorch index.
  • PyTorch produces distinct builds for each accelerator (e.g., CPU-only, CUDA). Since there's no standardized mechanism for specifying these accelerators when publishing or installing, PyTorch encodes them in the local version specifier. As such, PyTorch versions will often look like 2.5.1+cpu, 2.5.1+cu121, etc.
  • Builds for different accelerators are published to different indexes. For example, the +cpu builds are published on https://download.pytorch.org/whl/cpu, while the +cu121 builds are published on https://download.pytorch.org/whl/cu121.

As such, the necessary packaging configuration will vary depending on both the platforms you need to support and the accelerators you want to enable.

To start, consider the following (default) configuration, which would be generated by running fyn init --python 3.14 followed by fyn add torch torchvision.

In this case, PyTorch would be installed from PyPI, which hosts CPU-only wheels for Windows and macOS, and GPU-accelerated wheels on Linux (targeting CUDA 12.8, as of PyTorch 2.9.1):

[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = [
  "torch>=2.9.1",
  "torchvision>=0.24.1",
]

This is a valid configuration for projects that want to use CPU builds on Windows and macOS, and CUDA-enabled builds on Linux. However, if you need to support different platforms or accelerators, you'll need to configure the project accordingly.

Using a PyTorch index

In some cases, you may want to use a specific PyTorch variant across all platforms. For example, you may want to use the CPU-only builds on Linux too.

In such cases, the first step is to add the relevant PyTorch index to your pyproject.toml:

[[tool.fyn.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
[[tool.fyn.index]]
name = "pytorch-cu118"
url = "https://download.pytorch.org/whl/cu118"
explicit = true
[[tool.fyn.index]]
name = "pytorch-cu126"
url = "https://download.pytorch.org/whl/cu126"
explicit = true
[[tool.fyn.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true
[[tool.fyn.index]]
name = "pytorch-cu130"
url = "https://download.pytorch.org/whl/cu130"
explicit = true
[[tool.fyn.index]]
name = "pytorch-rocm"
url = "https://download.pytorch.org/whl/rocm6.4"
explicit = true
[[tool.fyn.index]]
name = "pytorch-xpu"
url = "https://download.pytorch.org/whl/xpu"
explicit = true

We recommend the use of explicit = true to ensure that the index is only used for torch, torchvision, and other PyTorch-related packages, as opposed to generic dependencies like jinja2, which should continue to be sourced from the default index (PyPI).

Next, update the pyproject.toml to point torch and torchvision to the desired index:

[tool.fyn.sources]
torch = [
  { index = "pytorch-cpu" },
]
torchvision = [
  { index = "pytorch-cpu" },
]

PyTorch doesn't publish CUDA builds for macOS. As such, we gate on sys_platform to instruct fyn to use the PyTorch index on Linux and Windows, but fall back to PyPI on macOS:

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

PyTorch doesn't publish CUDA builds for macOS. As such, we gate on sys_platform to instruct fyn to limit the PyTorch index to Linux and Windows, falling back to PyPI on macOS:

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

PyTorch doesn't publish CUDA builds for macOS. As such, we gate on sys_platform to instruct fyn to limit the PyTorch index to Linux and Windows, falling back to PyPI on macOS:

[tool.fyn.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'" },
]

PyTorch doesn't publish CUDA builds for macOS. As such, we gate on sys_platform to instruct fyn to limit the PyTorch index to Linux and Windows, falling back to PyPI on macOS:

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

PyTorch doesn't publish ROCm6 builds for macOS or Windows. As such, we gate on sys_platform to instruct fyn to limit the PyTorch index to Linux, falling back to PyPI on macOS and Windows:

[tool.fyn.sources]
torch = [
  { index = "pytorch-rocm", marker = "sys_platform == 'linux'" },
]
torchvision = [
  { index = "pytorch-rocm", marker = "sys_platform == 'linux'" },
]
# ROCm6 support relies on `pytorch-triton-rocm`, which should also be installed from the PyTorch index
# (and included in `project.dependencies`).
pytorch-triton-rocm = [
  { index = "pytorch-rocm", marker = "sys_platform == 'linux'" },
]

PyTorch doesn't publish Intel GPU builds for macOS. As such, we gate on sys_platform to instruct fyn to limit the PyTorch index to Linux and Windows, falling back to PyPI on macOS:

[tool.fyn.sources]
torch = [
  { index = "pytorch-xpu", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
torchvision = [
  { index = "pytorch-xpu", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
# Intel GPU support relies on `pytorch-triton-xpu`, which should also be installed from the PyTorch index
# (and included in `project.dependencies`).
pytorch-triton-xpu = [
  { index = "pytorch-xpu", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]

As a complete example, the following project would use PyTorch's CPU-only builds on all platforms:

[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.14.0"
dependencies = [
  "torch>=2.9.1",
  "torchvision>=0.24.1",
]

[tool.fyn.sources]
torch = [
    { index = "pytorch-cpu" },
]
torchvision = [
    { index = "pytorch-cpu" },
]

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

Configuring accelerators with environment markers

In some cases, you may want to use CPU-only builds in one environment (e.g., macOS and Windows), and CUDA-enabled builds in another (e.g., Linux).

With tool.fyn.sources, you can use environment markers to specify the desired index for each platform. For example, the following configuration would use PyTorch's CUDA-enabled builds on Linux, and CPU-only builds on all other platforms (e.g., macOS and Windows):

[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.14.0"
dependencies = [
  "torch>=2.9.1",
  "torchvision>=0.24.1",
]

[tool.fyn.sources]
torch = [
  { index = "pytorch-cpu", marker = "sys_platform != 'linux'" },
  { index = "pytorch-cu128", marker = "sys_platform == 'linux'" },
]
torchvision = [
  { index = "pytorch-cpu", marker = "sys_platform != 'linux'" },
  { index = "pytorch-cu128", marker = "sys_platform == 'linux'" },
]

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

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

Similarly, the following configuration would use PyTorch's AMD GPU builds on Linux, and CPU-only builds on Windows and macOS (by way of falling back to PyPI):

[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.14.0"
dependencies = [
  "torch>=2.9.1",
  "torchvision>=0.24.1",
  "pytorch-triton-rocm>=3.5.1 ; sys_platform == 'linux'",
]

[tool.fyn.sources]
torch = [
  { index = "pytorch-rocm", marker = "sys_platform == 'linux'" },
]
torchvision = [
  { index = "pytorch-rocm", marker = "sys_platform == 'linux'" },
]
pytorch-triton-rocm = [
  { index = "pytorch-rocm", marker = "sys_platform == 'linux'" },
]

[[tool.fyn.index]]
name = "pytorch-rocm"
url = "https://download.pytorch.org/whl/rocm6.4"
explicit = true

Or, for Intel GPU builds:

[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.14.0"
dependencies = [
  "torch>=2.9.1",
  "torchvision>=0.24.1",
  "pytorch-triton-xpu>=3.5.0 ; sys_platform == 'win32' or sys_platform == 'linux'",
]

[tool.fyn.sources]
torch = [
  { index = "pytorch-xpu", marker = "sys_platform == 'win32' or sys_platform == 'linux'" },
]
torchvision = [
  { index = "pytorch-xpu", marker = "sys_platform == 'win32' or sys_platform == 'linux'" },
]
pytorch-triton-xpu = [
  { index = "pytorch-xpu", marker = "sys_platform == 'win32' or sys_platform == 'linux'" },
]

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

Configuring accelerators with optional dependencies

In some cases, you may want to use CPU-only builds in some cases, but CUDA-enabled builds in others, with the choice toggled by a user-provided extra (e.g., fyn sync --extra cpu vs. fyn sync --extra cu128).

With tool.fyn.sources, you can use extra markers to specify the desired index for each enabled extra. For example, the following configuration would use PyTorch's CPU-only for fyn sync --extra cpu and CUDA-enabled builds for fyn sync --extra cu128:

[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.14.0"
dependencies = []

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

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

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

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

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

Note

Since GPU-accelerated builds aren't available on macOS, the above configuration will fail to install on macOS when the cu128 extra is enabled.

The fyn pip interface

While the above examples are focused on fyn's project interface (fyn lock, fyn sync, fyn run, etc.), PyTorch can also be installed via the fyn pip interface.

PyTorch itself offers a dedicated interface to determine the appropriate pip command to run for a given target configuration. For example, you can install stable, CPU-only PyTorch on Linux with:

$ pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

To use the same workflow with fyn, replace pip3 with fyn pip:

$ fyn pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

If you switch between machines or GPU families, use fyn torch doctor to inspect the current machine and print the recommended --torch-backend value without modifying pyproject.toml:

$ fyn torch doctor
PyTorch doctor
environment: /workspace/.venv
python: /workspace/.venv/bin/python3 (3.12.8)
platform: manylinux_2_28_x86_64
accelerator: CUDA 570.86.15
recommended backend: cu130
reason: Detected NVIDIA driver 570.86.15; selected the highest compatible CUDA backend for manylinux_2_28_x86_64.

installed packages:
torch: not installed
torchvision: not installed
torchaudio: not installed

next command:
  fyn pip install torch torchvision torchaudio --torch-backend=cu130

notes:
- `fyn torch doctor` only reports the recommended backend.
- Recreate the environment when switching GPU or backend families.

If PyTorch is already installed, fyn torch doctor also reports the installed torch, torchvision, and torchaudio versions, including any backend suffixes such as +cu128. Use --json to consume the same report in scripts or editor tooling.

Automatic backend selection

fyn supports automatic selection of the appropriate PyTorch index via the --torch-backend=auto command-line argument (or the UV_TORCH_BACKEND=auto environment variable), as in:

$ # With a command-line argument.
$ fyn pip install torch --torch-backend=auto

$ # With an environment variable.
$ UV_TORCH_BACKEND=auto fyn pip install torch

When enabled, fyn will query for the installed CUDA driver, AMD GPU versions, and Intel GPU presence, then use the most-compatible PyTorch index for all relevant packages (e.g., torch, torchvision, etc.). If no such GPU is found, fyn will fall back to the CPU-only index. fyn will continue to respect existing index configuration for any packages outside the PyTorch ecosystem.

You can also select a specific backend (e.g., CUDA 12.8) with --torch-backend=cu126 (or UV_TORCH_BACKEND=cu126):

$ # With a command-line argument.
$ fyn pip install torch torchvision --torch-backend=cu126

$ # With an environment variable.
$ UV_TORCH_BACKEND=cu128 fyn pip install torch torchvision

At present, --torch-backend is only available in the fyn pip interface.