在很多 Python 团队里,conda 长期承担了环境管理、依赖安装、Python 版本切换等多项职责。它功能完整,但也有一个非常现实的问题:慢。创建环境要等待,解析依赖要等待,安装几个常用包也要等待。久而久之,很多开发者把这种等待视为理所当然。
但如果你的项目本质上是一个以 PyPI 为中心的 Python 应用,而不是一个重度依赖底层二进制生态的科研运行时,那么现在有一个更值得优先考虑的选择: uv。
uv 是 Astral 推出的现代 Python 包与项目管理工具,使用 Rust 编写,核心目标非常明确: 以更快的速度、更统一的工作流管理 Python 项目。uv 官方文档在常见 pip 工作流中给出 10-100x 的速度提升表述。
本文会说明,什么场景适合用 uv 取代 conda;如何安装并初始化 uv 工作流;帮助你快速了解并上手。
文章最后还说了 conda 和 uv 混用的场景方案,有兴趣可以看看。
一、conda 与 uv 对比适用场景
conda 的慢,不完全是实现问题,更大程度上是定位问题。
conda 官方长期把自己定义为“包、依赖和环境管理器”,不仅管理 Python 包,还管理非 Python 语言包、系统级库与二进制依赖。这意味着它在解算依赖时,需要处理更多维度的兼容关系,包括渠道、构建产物、底层动态库以及 Python 自身版本。
这也是 conda 的价值所在:它不是只服务 Python 应用开发,而是在试图管理一个更复杂的运行时分发体系。
uv 则不同,重点放在现代 Python 开发流程上,不试图替代整个二进制分发生态,而是专注解决“Python 项目开发到底怎样才能更快、更统一”。
速度优势并不只是“Rust 写的所以更快”这么简单。真正决定体验的是工具链设计,主要来自以下几个方面:
- 更高效的实现语言与底层执行模型
- 更积极的全局缓存策略,全局缓存的复用机制更高效,减少重复下载
- 围绕 PyPI 工作流做了针对性优化
- 统一了环境、锁定、同步与执行过程
- 减少了手工切换环境与重复解析依赖的次数
很多团队误以为“安装慢”只是网络问题,实际上并不完全如此。大量时间浪费发生在依赖解析、环境切换、重复安装和工具链分裂上。uv 的价值,恰恰是把这些环节做了整体压缩。
也正因为目标更聚焦,它在以下几个方面通常比 conda 更有体感优势:
- 依赖解析速度显著更快
- 包的下载与安装效率大幅提升
- 项目默认工作流更统一,降低团队协作成本
- 新环境初始化门槛低、耗时短
结合实际开发场景,区分 uv 与 conda 的适用场景:
flowchart TD
subgraph BB[" "]
direction LR
B("优先选择uv场景")
B --> B1["Web后端<br>(FastAPI、Django、Flask等)"]
B --> B2["自动化脚本<br>命令行工具开发"]
B --> B3["普通数据处理<br>(如pandas数据分析)"]
B --> B4["CI流水线中<br>对依赖安装速度敏感的场景"]
B --> B5["团队希望统一<br>pyproject.toml配置<br>依赖锁文件<br>及虚拟环境工作流的场景"]
B --> B6["项目主要依赖<br>PyPI生态常见Python包<br>(FastAPI、Django等)<br>契合现代Python工程实践"]
end
subgraph CC[" "]
direction LR
C("不建议抛弃conda场景")
C --> C1["强依赖conda-forge二进制包生态<br>需特定构建软件包"]
C --> C2["需统一管理<br>CUDAToolkit、MKL、OpenBLAS<br>等底层系统库"]
C --> C3["项目依赖大量<br>非Python组件<br>(如R、Perl语言、系统级共享库)"]
C --> C4["项目历史深度绑定<br>environment.yml配置<br>及特定conda渠道策略"]
end
这里必须明确指出一个常见但不合理的说法,“uv 可以全面替代 conda。”这句话并不严谨。更准确的表述应该是:uv 可以替代大量原本没有必要交给 conda 管理的 Python 项目工作流。
如果你的项目主要是标准 Python 应用开发,那么 uv 往往能提供更快的安装速度、更统一的工程结构和更低的维护成本。
但如果你的项目深度依赖复杂二进制生态,那么 conda 依然是更稳妥的基础设施,不应为了追求速度而强行替换。
二、开始安装 uv
2.1 安装 UV
-
Windows 安装方式
在 PowerShell 中执行:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"如果你更习惯包管理器,也可以使用
winget:winget install --id=astral-sh.uv -e或者使用
scoop:scoop install main/uv -
macOS 和 Linux 安装方式
官方安装脚本:
curl -LsSf https://astral.sh/uv/install.sh | sh如果系统没有
curl,也可以使用:wget -qO- https://astral.sh/uv/install.sh | sh在 macOS 上,如果你已经使用 Homebrew,也可以直接安装:
brew install uv
验证安装结果,执行:
uv --version
如果终端能输出版本号,说明 uv 已经安装成功。
2.2 配置 UV
复制以下内容到配置文件:
# 全局缓存目录(你可以改成自己的路径)
cache-dir = "你希望存储缓存的目录"
# 清华 PyPI 镜像
[[index]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
default = true
0. Windows 配置方式
ni $env:APPDATA\uv\uv.toml -Force;
notepad $env:APPDATA\uv\uv.toml
-
Linux 配置方式
mkdir -p ~/.config/uv nano ~/.config/uv/uv.toml
不想用配置文件方式,可以用环境变量
UV_CACHE_DIR="你希望存储缓存的目录"
2.4 安装或接管 Python 版本
uv 不只是包管理工具,也可以管理 Python 本身。官方文档明确说明,即使系统没有预装 Python,也可以直接通过 uv 下载并安装。
安装最新 Python 版本:
uv python install
如果需要指定版本,例如 Python 3.12:
uv python install 3.12
这一步的意义非常大。传统流程里,很多团队会把 pyenv、virtualenv、pip、pip-tools、conda 混合使用;而在 uv 体系里,这些职责可以被明显收敛。
查看当前项目用的 Python 版本:
uv python list
三、使用 uv 创建项目
3.1 初始化项目
执行项目初始化:
uv init hello-uv --python 3.12
cd hello-uv
这会创建一个基础项目目录,通常包括:
.
├── .git
├── .gitignore
├── .python-version
├── .venv
├── pyproject.toml
├── uv.lock
├── README.md
└── main.py
与传统“手工建虚拟环境、再手工装包”的流程不同,uv 从一开始就把项目元信息、Python 版本和依赖管理放进了统一结构。
- main.py、README.md、 .git:基本项目文件,不做过多赘叙
- .python-version:Python 版本锁定文件,明确指定当前项目使用的 Python 版本
- .venv:虚拟环境目录,存放项目专属的虚拟环境文件
- pyproject.toml:项目核心配置文件,存储项目的基础信息(如项目名称、版本)和依赖配置,后续通过
uv add安装的包、导入的依赖,都会同步更新到这个文件中,是uv sync命令同步环境的核心依据,也是团队协作时统一依赖的关键。 - uv.lock:依赖锁文件,记录所有依赖包的精确版本(如安装的第三方库版本、依赖关系),确保无论在本地、测试环境还是生产环境,都能复现完全一致的依赖环境,从根源上解决 “本地能跑、线上报错” 的问题。
后续想改python版本可以输入以下指令:
uv python pin 3.10
3.2 运行项目
执行:
uv run main.py
# Using CPython 3.12.13
# Creating virtual environment at: .venv
# Hello from hello-uv!
第一次运行时,uv 会自动完成锁定与环境同步,并按需创建项目级虚拟环境,通常位于 .venv 目录。
这也是 uv 非常适合团队协作的一个原因: 你不再需要先记住“激活哪个环境”,而是直接通过 uv run 在项目上下文中执行命令。
3.3 添加依赖
例如安装 FastAPI 与 uvicorn:
uv add fastapi uvicorn
安装测试依赖:
uv add --dev pytest ruff
完成后,依赖会被写入 pyproject.toml,锁定结果会写入 uv.lock。这比“一个 requirements.txt 加一堆口头约定”的方式更适合工程化协作。
3.4 执行项目命令
运行 Python:
uv run python
运行测试:
uv run pytest
运行格式化或检查工具:
uv run ruff check .
uv run 的核心价值是: 让命令始终在正确的项目环境中执行,同时自动确保依赖处于同步状态。
四、从 conda 项目迁移到 uv
迁移前需先做简单评估:查看项目的 environment.yml 文件,若其中大部分依赖为 Python 包,且这些包在 PyPI 仓库中可正常获取,那么迁移可行性极高;若包含大量特定渠道(如 conda-forge)的二进制依赖,则需谨慎评估,不要追求安装速度而破坏项目环境的稳定性。
4.1 初始化迁移目录
首先进入原 conda 项目的根目录,执行以下命令初始化 uv 项目结构:
uv init
注意,若项目目录中已存在 pyproject.toml 文件(如原有 Python 项目配置),无需重复执行uv init,只需根据现有文件结构整理依赖,避免配置冲突即可。
若项目中已存在 requirements.txt(conda 环境导出或手动维护的依赖清单),可直接通过以下命令逐步导入依赖:
uv add -r requirements.txt
如果你同时有更严格的版本约束文件,也可以按官方迁移思路使用约束导入方式,先保留现有版本边界,再逐步清理历史包袱。
4.2 生成并同步锁文件
此时只更新了 pyproject.toml,没有自动创建虚拟环境、安装依赖,所以需要手动执行 uv sync,来完成这 3 件事:
uv sync
这一步是 uv 环境构建的核心,主要完成3件关键工作:一是自动创建项目专属的虚拟环境(等同于uv venv的作用);二是根据 pyproject.toml 中的依赖配置,自动安装所有所需包;三是生成 uv.lock 锁文件(即项目环境的“快照”)。
4.3 用 uv 代替原有激活式工作流
传统 conda 流程往往是:
conda activate myenv # 激活conda环境
python app.py # 运行项目
pytest # 执行测试
迁移到 uv 后,更推荐改成:
uv run python app.py # 直接运行项目(自动使用uv虚拟环境)
uv run pytest # 直接执行测试(无需激活环境)
这种方式的优点是显式、稳定、可复制,尤其适合 CI、脚本化执行和多人协作。
五、CUDA 场景
5.1 conda 安装 cudatoolkit 相对方便
conda 在 CUDA 场景中的核心优势,并非速度更快,而是它能作为完整的环境分发工具,帮你省心管理整套 GPU 依赖。
Anaconda 仓库长期维护 cudatoolkit 官方包,绝大多数依赖 GPU 的 Python 项目,都能通过 conda 直接配齐所有运行组件,无需手动配置底层依赖。
更关键的是,NVIDIA 官方已将 conda 纳入 CUDA Toolkit 正式安装渠道,Windows 等系统的官方安装指南中,直接推荐命令:
conda install cuda -c nvidia
同时,conda 内置宿主机 CUDA 驱动检测机制,通过 cuda 虚拟包识别系统可用的 CUDA 版本,在解析依赖时自动匹配本机 GPU 环境,兼容性更稳定。
如果你的需求是以下场景,conda 会更省心:
- 在独立虚拟环境中统一安装 CUDA 运行时、工具包组件
- 让二进制底层依赖和 Python 包统一由环境管理器维护
- 搭建需要严格对齐 CUDA 版本的科研、模型训练环境
5.2 uv 对 CUDA 的支持
uv 对 CUDA 的支持不负责管理底层驱动,核心聚焦于 Python 包的 GPU 适配,定位和 conda 完全不同。
它的工作逻辑很清晰:自动检测本机 GPU 环境 → 匹配最优的 Python 包索引 → 安装对应 CUDA 版本的 wheel 包。
简单区分两个易混淆的概念,就能看懂两者的差异:
- 系统级 CUDA 管理:安装 NVIDIA 驱动、CUDA Toolkit、nvcc 编译器、系统库、头文件 → conda 更擅长
- Python 包 CUDA 适配:安装带 GPU 支持的 PyTorch、TorchVision 等 Python 库 → uv 更擅长
conda 能同时管理系统 CUDA 和 Python 依赖;uv 只专注现代 Python 包分发,是更轻量的前端调度器。
若使用 uv,则不能将底层驱动纳入环境管理,只能通过系统级安装来使用。
5.3 使用 uv 安装支持 CUDA 的 PyTorch
如果你的目标是“快速装好可用的 GPU 版 PyTorch”,uv 已经提供了很直接的做法。
方法一:自动选择后端
目标是快速部署可用的 GPU PyTorch,uv 提供三种极简方案,按需选择即可:
方法一:自动检测后端
uv 支持自动识别 CUDA、AMD、Intel GPU,无合适 GPU 则自动回退到 CPU 版本,无需手动查询版本:
uv pip install torch torchvision torchaudio --torch-backend=auto
环境变量写法(适配脚本自动化):
UV_TORCH_BACKEND=auto uv pip install torch torchvision torchaudio
方法二:显式指定 CUDA 后端
已知本机 CUDA 版本时,直接指定更稳定,适合团队统一版本、CI 部署、问题排查:
# 示例:安装 CUDA 12.6 对应的 PyTorch
uv pip install torch torchvision torchaudio --torch-backend=cu126
注意,--torch-backend 目前只在 uv pip 接口中可用,而不是通用于所有 uv add 工作流。
方法三:显式指定 PyTorch CUDA 索引
PyTorch 官方安装页面长期提供 CUDA 对应的 wheel 索引,例如:
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
如果你不希望每次都在命令行带索引,可以在项目的 pyproject.toml 中固定下来。例如:
[project]
dependencies = ["torch", "torchvision", "torchaudio"]
[tool.uv.sources]
torch = { index = "pytorch-cu128" }
torchvision = { index = "pytorch-cu128" }
torchaudio = { index = "pytorch-cu128" }
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true
这种方式更适合正式项目,因为它把“这个项目必须从哪个 CUDA 索引安装 PyTorch”写进了配置,而不是依赖口头约定。
5.4 使用 uv 后如何验证 CUDA 是否真的可用
安装完成后,不要只看安装命令是否成功,更要验证运行态。
在项目环境中执行:
uv run python -c "import torch; print(torch.__version__); print(torch.version.cuda); print(torch.cuda.is_available())"
如果最后输出 True,且 torch.version.cuda 显示的是你期望的 CUDA 版本,那么说明当前 PyTorch 已经具备对应的 CUDA 支持。
若包安装成功但验证失败,可能是因为 GPU 驱动不匹配、宿主机库缺失、显卡权限或容器透传问题而不可用。
5.5 混合方案
如果你符合以下任一情况,混合方案通常比“纯 uv”更稳妥:
- 需要编译自定义 CUDA 扩展(依赖 nvcc)
- 需要完整 CUDA Toolkit,不只是深度学习包
- 需管理大量 CUDA 底层系统库
- 团队已有成熟的 CUDA 环境规范
这时可以把职责拆开:
- conda:安装 / 管理 NVIDIA 驱动、CUDA Toolkit 等系统级组件
- uv:安装 / 锁定 Python 项目依赖,执行训练、测试命令
具体实现:
conda activate mycuda
uv run python your_script.py