用 uv 替代 conda,速度飙升(从 0 到 1 开始使用 uv)

1 阅读12分钟

在很多 Python 团队里,conda 长期承担了环境管理、依赖安装、Python 版本切换等多项职责。它功能完整,但也有一个非常现实的问题:。创建环境要等待,解析依赖要等待,安装几个常用包也要等待。久而久之,很多开发者把这种等待视为理所当然。

但如果你的项目本质上是一个以 PyPI 为中心的 Python 应用,而不是一个重度依赖底层二进制生态的科研运行时,那么现在有一个更值得优先考虑的选择: uv

uv 是 Astral 推出的现代 Python 包与项目管理工具,使用 Rust 编写,核心目标非常明确: 以更快的速度、更统一的工作流管理 Python 项目。uv 官方文档在常见 pip 工作流中给出 10-100x 的速度提升表述。

Conda与uv工具对比.png

本文会说明,什么场景适合用 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

  1. 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
    
  2. 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
  1. 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

这一步的意义非常大。传统流程里,很多团队会把 pyenvvirtualenvpippip-toolsconda 混合使用;而在 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 版本和依赖管理放进了统一结构。

  1. main.pyREADME.md.git:基本项目文件,不做过多赘叙
  2. .python-version:Python 版本锁定文件,明确指定当前项目使用的 Python 版本
  3. .venv:虚拟环境目录,存放项目专属的虚拟环境文件
  4. pyproject.toml:项目核心配置文件,存储项目的基础信息(如项目名称、版本)和依赖配置,后续通过 uv add 安装的包、导入的依赖,都会同步更新到这个文件中,是 uv sync 命令同步环境的核心依据,也是团队协作时统一依赖的关键。
  5. 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 添加依赖

例如安装 FastAPIuvicorn:

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 包。

简单区分两个易混淆的概念,就能看懂两者的差异:

  1. 系统级 CUDA 管理:安装 NVIDIA 驱动、CUDA Toolkit、nvcc 编译器、系统库、头文件 → conda 更擅长
  2. 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 环境规范

这时可以把职责拆开:

  1. conda:安装 / 管理 NVIDIA 驱动、CUDA Toolkit 等系统级组件
  2. uv:安装 / 锁定 Python 项目依赖,执行训练、测试命令

具体实现:

conda activate mycuda
uv run python your_script.py