Другое

uv pyproject.toml: Блокировка PyTorch на кастомном CUDA индексе

Узнайте, как настроить uv через pyproject.toml для блокировки PyTorch (+cu118) на кастомном индексе и предотвращения конфликтов версий только для CPU во время операций uv run.

Как настроить uv через pyproject.toml для блокировки PyTorch (+cu118) на пользовательском индексе и предотвращения использования uv run версии только для CPU?

Я управляю проектом с использованием uv (v0.9.4), который требует определённую сборку PyTorch с CUDA. Хотя общая установка работает, использование uv run вызывает конфликт пакетов, несмотря на корректную настройку окружения.

Я успешно установил пакет CUDA 11.8 в своё окружение, используя явный URL индекса:

uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

Прямая проверка подтверждает, что версия CUDA установлена и доступна в активированном окружении:

python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available())"
# Вывод: 2.7.1+cu118 11.8 True

Однако, когда я пытаюсь запустить скрипт (test_gpu.py) с помощью uv run, он игнорирует корректно установленный пакет и разрешает/устанавливает сборку только для CPU (2.8.0+cpu), что приводит к ошибке выполнения:

uv run python test_gpu.py
# Фрагмент вывода:
# PyTorch version: 2.8.0+cpu
# CUDA available: False
# AssertionError: Torch not compiled with CUDA enabled

Проблема, по-видимому, заключается в том, что uv run запускает процесс переопределения зависимостей, который находит общую версию для CPU на индексе PyPI по умолчанию и приоритизирует её над пользовательской сборкой CUDA.

Какова надёжная, идиоматичная конфигурация pyproject.toml, чтобы uv учитывал пользовательский индекс для PyTorch и избегал этого конфликта, позволяя мне использовать uv run?

Настройка uv через pyproject.toml для блокировки PyTorch (+cu118) на пользовательском индексе и предотвращения использования версии только для CPU

Чтобы настроить uv через pyproject.toml для блокировки PyTorch (+cu118) на пользовательском индексе и предотвращения использования uv run версии только для CPU, необходимо явно определить источники и индексы PyTorch в вашем файле конфигурации. Ключевой момент — переопределение поведения разрешения зависимостей uv, указав, какой индекс использовать для пакетов PyTorch.


Содержание


Базовый подход к конфигурации

Наиболее надежное решение — определить пользовательские индексы PyTorch и явно указать источник для сборки PyTorch с поддержкой CUDA. Это предотвращает возврат uv к индексу PyPI по умолчанию, где доступны версии только для CPU.

Добавьте эти разделы в ваш pyproject.toml:

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

[[tool.uv.index]]
name = "default"
url = "https://pypi.org/simple"
explicit = true

[tool.uv.sources]
torch = "pytorch-cu118"
torchvision = "pytorch-cu118"
torchaudio = "pytorch-cu118"

Эта конфигурация:

  • Определяет пользовательский индекс PyTorch для сборок с CUDA 11.8
  • Помечает оба индекса как explicit = true для предотвращения автоматического разрешения
  • Явно указывает все пакеты PyTorch на использование CUDA-специфичного индекса

Примечание: Параметр explicit = true является критически важным, так как он сообщает uv использовать только эти индексы при явном запросе, предотвращая возврат к индексу PyPI по умолчанию.


Конфигурация для конкретных платформ

Если вам нужны разные варианты PyTorch для разных платформ, вы можете использовать условные маркеры. Это особенно полезно для проектов, которые должны работать как в Linux (с CUDA), так и в macOS/Windows (с CPU):

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

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

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

Согласно официальной документации uv, этот подход позволяет поддерживать разные варианты PyTorch на разных платформах, гарантируя использование правильной версии в каждой среде.


Метод необязательных зависимостей

Другой подход — использование необязательных зависимостей для переключения между вариантами CPU и CUDA. Это полезно, когда вы хотите явно контролировать, какой вариант использовать:

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

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

[project]
dependencies = [
    "torch-cpu",
    "torchvision-cpu",
    "torchaudio-cpu",
]

[project.optional-dependencies]
cuda = [
    "torch-cu118",
    "torchvision-cu118",
    "torchaudio-cu118",
]

[tool.uv.sources]
torch-cpu = "pytorch-cpu"
torchvision-cpu = "pytorch-cpu"
torchaudio-cpu = "pytorch-cpu"
torch-cu118 = "pytorch-cu118"
torchvision-cu118 = "pytorch-cu118"
torchaudio-cu118 = "pytorch-cu118"

С этой настройкой вы можете установить вариант CUDA с помощью:

bash
uv sync --extra cuda

И запускать скрипты с помощью:

bash
uv run --extra cuda python test_gpu.py

Пример полного pyproject.toml

Вот полная конфигурация pyproject.toml, которая решает вашу конкретную проблему:

toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "your-project"
version = "0.1.0"
description = "Проект с PyTorch с поддержкой CUDA"
dependencies = [
    "torch",
    "torchvision", 
    "torchaudio",
]

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

[[tool.uv.index]]
name = "default"
url = "https://pypi.org/simple"
explicit = true

[tool.uv.sources]
torch = "pytorch-cu118"
torchvision = "pytorch-cu118"
torchaudio = "pytorch-cu118"

[tool.uv.dev-dependencies]
dev = [
    "pytest",
    "black",
    "ruff",
]

Чтобы использовать эту конфигурацию:

  1. Сначала синхронизируйте ваши зависимости:
bash
uv sync
  1. Затем запустите ваш скрипт:
bash
uv run python test_gpu.py

Теперь это должно учитывать вашу конфигурацию CUDA и не разрешать версию только для CPU.


Устранение распространенных проблем

Проблема: uv все еще устанавливает версию для CPU, несмотря на конфигурацию

Решение: Убедитесь, что все пакеты, связанные с PyTorch, правильно получены из вашего пользовательского индекса. Проверьте, что вы не пропустили никакие зависимости torch в вашем массиве dependencies.

Проблема: Конфликты между пакетами CPU и CUDA

Решение: Используйте настройку explicit = true для ваших пользовательских индексов и рассмотрите возможность использования разных групп зависимостей для вариантов CPU/CUDA.

Проблема: Проблемы, специфичные для платформы

Решение: Добавьте платформенные маркеры в вашу конфигурацию источников, как показано в разделе выше для конкретных платформ.

Согласно обсуждению на Stack Overflow, основная проблема заключается в том, что uv run запускает повторное разрешение зависимостей, которое может найти общую версию CPU на индексе PyPI по умолчанию. Решение — сделать ваш пользовательский индекс основным источником для пакетов PyTorch.


Советы по продвинутой конфигурации

Для более сложных сценариев рассмотрите эти продвинутые советы:

Несколько версий CUDA

Если вам нужно поддерживать несколько версий CUDA, вы можете определить несколько индексов:

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

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

Переменные окружения

Вы можете использовать переменные окружения для контроля, какой вариант PyTorch использовать:

toml
[tool.uv.sources]
torch = { index = "${PYTORCH_INDEX:-pytorch-cpu}" }

Затем установите переменную окружения перед запуском:

bash
export PYTORCH_INDEX=pytorch-cu118
uv run python test_gpu.py

Виртуальные среды

Рассмотрите использование управления виртуальными средами uv для изоляции сред, специфичных для CUDA:

bash
uv venv --python 3.10 --extra cuda
source .venv/bin/activate
uv run python test_gpu.py

Ключевой вывод заключается в том, что вы должны явно контролировать, где uv ищет пакеты PyTorch. Определяя пользовательские индексы и указывая источники в вашем pyproject.toml, вы предотвращаете возврат uv к индексу PyPI по умолчанию, где версии только для CPU легко доступны. Согласно документации uv, этот подход обеспечивает последовательное поведение в разных командах uv и предотвращает конфликты разрешения зависимостей, с которыми вы сталкиваетесь.


Источники

  1. Использование uv с PyTorch | Документация uv
  2. Как настроить uv через pyproject.toml для блокировки PyTorch - Stack Overflow
  3. Управление версиями CPU/CUDA PyTorch на среду с uv
  4. Настройка проекта для машинного обучения с PyTorch и UV
  5. Учебник по установке torch/pytorch с cuda с использованием uv

Заключение

Чтобы настроить uv через pyproject.toml для блокировки PyTorch (+cu118) на пользовательском индексе и предотвращения конфликтов версий только для CPU:

  1. Определите пользовательские индексы для вашего конкретного варианта PyTorch (cu118) в pyproject.toml
  2. Используйте explicit = true для предотвращения автоматического возврата к индексу PyPI по умолчанию
  3. Укажите источники для всех пакетов PyTorch для использования вашего пользовательского индекса
  4. Рассмотрите платформенные маркеры, если поддерживается несколько платформ
  5. Протестируйте с помощью uv sync и uv run для обеспечения последовательности

Наиболее надежным решением является базовый подход к конфигурации с явными индексами и источниками, который предотвращает разрешение uv версий только для CPU во время выполнения. Это гарантирует, что ваша сборка PyTorch с поддержкой CUDA остается заблокированной на пользовательском индексе во всех операциях uv.

Авторы
Проверено модерацией
Модерация