在 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 导出依赖
在现有 venv 中,导出已安装的依赖列表。这一步使用 uv 的 pip 兼容命令,避免直接用 pip freeze 时的一些问题。
- 激活 venv:在 Windows 上,运行
.\venv\Scripts\activate。 - 导出依赖:运行
uv pip freeze > requirements.txt。这会生成一个 requirements.txt 文件,列出所有包及其版本,例如torch==2.7+cu128。

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

现在,检查 requirements.txt,确保没有多余的本地路径或 editable 安装(如 -e .)。如果有,手动移除或编辑。
步骤二:初始化 pyproject.toml
uv 使用 pyproject.toml 作为项目配置文件,取代 requirements.txt。
- 在项目根目录运行
uv init --bare。这会创建一个基本的 pyproject.toml 文件。

- 编辑 pyproject.toml,添加基本信息:
ini
[project]
name = "your-project-name"
version = "0.1.0"
requires-python = "==3.10.*" # 根据你的 Python 版本调整,最好固定,uv有自己的python版本寻找规则,找出来的默认版本和实际系统默认版本可能不一样
[project.dependencies]
# 这里稍后添加依赖
[project.optional-dependencies]
dev = [] # 如果有开发依赖
- 将依赖导入:运行
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就更新好了

这一步可能会报错,提示有版本冲突等,如果你确定项目可正常运行,此时你可以修改 命令,添加--frozen选项,
uv add --active --no-sync --frozen --python 3.10 -r requirements.txt
如果有 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 版本:
ini
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true
添加 CPU 索引作为 回退:
ini
[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
2. 配置来源路由:在 [tool.uv.sources] 部分,使用环境标记(markers)指定平台:
ini
[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。
- 更新依赖:在 [project.dependencies] 中指定:
ini
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。
没有意外的话,就能很快很顺利的安装了

注意事项和常见问题
- 版本冲突 :如果 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++的桌面套件。