在 Python 开发中,传统上一直习惯使用 venv + pip 来管理虚拟环境和依赖项。这种方式 python 安装后自带,简单方便,但随着项目复杂化,尤其是涉及像 PyTorch 这样的库时,可能会遇到版本锁定不严谨、跨平台兼容性差、各种三方包版本冲突等问题,令人头疼不已。

本文将介绍如何从一个现有的基于 Python + venv 的项目迁移到 uv,特别是针对 torch + cuda 的特殊处理。

项目原本在 Windows 上运行良好,现在需要确保导出的依赖能在 macOS 上正常安装。整个过程强调跨平台兼容性,例如在 Windows 上使用 CUDA 加速的 torch,而在 macOS(尤其是 Apple Silicon)上使用 CPU 版本。

为什么迁移到 uv?uv 比 pip 快得多,支持并行下载,且 uv.lock 文件是平台无关的,能在不同操作系统上复现相同的环境。这对于部署非常有用。整个迁移过程大约需要 30 分钟,适合有基本命令行经验的开发者。

准备工作

首先,确保系统已安装 uv。如果没有,从 uv 官网 ( docs.astral.sh/uv/getting-… )下载安装器。项目应该有一个激活的 venv 环境,其中已安装所有依赖,包括 torch + cuda 版本(如 torch==2.7+cu128)。

步骤一:从 venv 导出依赖

在现有 venv 中,导出已安装的依赖列表。这一步使用 uv 的 pip 兼容命令,避免直接用 pip freeze 时的一些问题。

  1. 激活 venv:在 Windows 上,运行 .venvScriptsactivate
  2. 导出依赖:运行 uv pip freeze > requirements.txt。这会生成一个 requirements.txt 文件,列出所有包及其版本,例如 torch==2.7+cu128

image.png

注意: 对于 torch + cu128,不要直接导入带有 +cu128 的版本。编辑 requirements.txt,将 torch==2.7+cu128 改为 torch>=2.7.0,去掉后缀。同样处理 torchvision/torchaudio 等相关包。这允许 uv 在不同平台上灵活选择版本。

image.png

现在,检查 requirements.txt,确保没有多余的本地路径或 editable 安装(如 -e .)。如果有,手动移除或编辑。

步骤二:初始化 pyproject.toml

uv 使用 pyproject.toml 作为项目配置文件,取代 requirements.txt

  1. 在项目根目录运行 uv init --bare。这会创建一个基本的 pyproject.toml 文件。

image.png

  1. 编辑 pyproject.toml,添加基本信息:
[project]
name = "your-project-name"
version = "0.1.0"
requires-python = "==3.10.*"  # 根据你的 Python 版本调整,最好固定,uv有自己的python版本寻找规则,找出来的默认版本和实际系统默认版本可能不一样

[project.dependencies]
# 这里稍后添加依赖

[project.optional-dependencies]
dev = []  # 如果有开发依赖

3. 将依赖导入:运行 uv add --active --no-sync --python 3.10 -r requirements.txt。这会自动将 requirements.txt 中的包添加到 [project.dependencies] 部分,并触发初步锁定。

  • --active: 选项告诉uv使用当前激活的环境
  • --no-sync: 告诉uv不要安装依赖,仅更新 pyproject.toml
  • --python 3.10 : 是我虚拟环境中使用的python版本

经过一段时间等待,pyproject.toml就更新好了

image.png

这一步可能会报错,提示有版本冲突等,如果你确定项目可正常运行,此时你可以修改 命令,添加--frozen选项,

如果有 dev 依赖:uv add --dev -r requirements-dev.txt

步骤三:特殊处理 torch + cuda

torch 是迁移中的难点,因为 CUDA 版本(如 cu128)是平台特定的:在 Windows 或 Linux 上可用,但 macOS(Apple Silicon)不支持 CUDA,只能用 CPU 或 Metal 后端。我们需要配置 pyproject.toml 来实现条件安装。

1. 添加专用索引:在 pyproject.toml 中添加 [tool.uv.index] 部分,指定 PyTorch 官方的 CUDA 索引,这里我使用的是 cuda12.8 版本:

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

添加 CPU 索引作为 回退:

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

2. 配置来源路由:在 [tool.uv.sources] 部分,使用环境标记(markers)指定平台:

[tool.uv.sources]
torch = [
    { index = "pytorch-cu128", marker = "sys_platform == 'win32' or sys_platform == 'linux'" },
    { index = "pytorch-cpu", marker = "sys_platform == 'darwin'" },  # darwin 为 macOS
]
torchaudio = [ 
    { index = "pytorch-cu128", marker = "sys_platform == 'win32' or sys_platform == 'linux'" },
    { index = "pytorch-cpu", marker = "sys_platform == 'darwin'" },
]
torchvision = [
    { index = "pytorch-cu128", marker = "sys_platform == 'win32' or sys_platform == 'linux'" },
    { index = "pytorch-cpu", marker = "sys_platform == 'darwin'" },
]

这确保:在 Windows/Linux 上安装 CUDA 版本,在 macOS 上安装 CPU 版本。markers 使用 Python 的环境变量,如 sys_platform。

  1. 更新依赖:在 [project.dependencies] 中指定:
dependencies = [
    "torch>=2.7.0",
    "torchaudio>=2.7.0",
    "torchvision>=0.22.0",  # 调整版本
]

运行 uv lock 生成 uv.lock 文件。uv 会根据当前平台解析依赖,并记录精确版本(包括 +cu128)。uv.lock 是跨平台的,它包含元数据支持多环境。

步骤四:分享 pyproject.toml 和 uv.lock

  • 将 pyproject.toml 和 uv.lock 一起分享给他人
  • 确保他们在项目根目录(包含这两个文件的目录)运行命令 uv sync

没有意外的话,就能很快很顺利的安装了

image.png

注意事项和常见问题

  • 版本冲突:如果 uv lock 报错,检查依赖兼容性。使用 uv lock --verbose 查看细节。
  • 性能:uv sync 比 pip install 快 10 倍以上。
  • 回滚:如果迁移失败,删除 pyproject.toml 和 uv.lock,回到 venv。
  • 最佳实践:以后添加依赖用 uv add package,移除用 uv remove package。定期运行 uv lock --upgrade 更新版本。
  • 限制:如果项目有非常特殊的 C 扩展依赖,跨平台可能需额外构建工具,例如windows上安装 Visual Studio后下载基于c++的桌面套件
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]