uv 与 conda 详解:Python 环境管理的两条路线

前言

Python 的环境管理一直是开发者的痛点。你大概率经历过这些事:用 pip install 装依赖等了五分钟、conda create 卡在 "Solving environment" 转了十分钟、不同项目的依赖互相打架、换台电脑环境就搭不起来。 目前 Python 生态中主流的两条路线是 condauv。conda 是数据科学和 AI领域的老牌选手,统治了十多年;uv 是 2024 年崛起的挑战者,用 Rust 重写,号称快 10~100 倍,已被 OpenAI收购。理解这两个工具的设计哲学和适用场景,是每个 Python 开发者的基本功。

一、它们各自解决什么问题

pip + venv:最基础的组合

Python 自带 pip,它只做一件事------从 PyPI 下载并安装 Python 包。但 pip 不管环境隔离:你在系统 Python 里装了一堆包,所有项目共享同一个环境,版本冲突在所难免。

为了解决隔离问题,Python 提供了 venv(虚拟环境),它在项目目录下创建一套独立的 Python 解释器和 site-packages,让不同项目的依赖互不影响。

这个组合的问题在于:pip 的依赖解析很慢,不支持 lockfile,不管理 Python 版本,大型项目中经常遇到"装不上""装错了""装太慢"三连。

conda:一站式环境 + 包管理

conda 从一开始就走了不同的路。它不仅管理 Python 包,还能管理 C/C++ 库、CUDA 工具链、R 语言包等非 Python 依赖。conda 的环境隔离不是基于 venv 的复制,而是创建独立的目录树------每个环境有自己的 Python 解释器、共享库和包。

这在科学计算领域很重要:装一个 numpy 可能需要特定版本的 BLAS/LAPACK,装 pytorch 需要匹配 CUDA 版本。pip 处理不了这些底层依赖,conda 可以。

uv:用 Rust 重写一切

uv 由 Astral 公司(也是 ruff 的开发者)用 Rust 编写,目标是用一个工具替代 pip + pip-tools + virtualenv + pyenv + pipx + poetry 这整条工具链。它的核心卖点是速度------安装 100 个依赖,pip 要 8 分钟,uv 只要 15 秒。

二、uv 深度解析

2.1 为什么这么快

uv 的速度优势不是靠简单优化,而是从底层架构上就不同

Rust 实现:零成本抽象 + 内存安全,没有 Python GIL 的限制,可以充分利用多核 CPU 并行处理依赖解析和下载。

并行下载与安装:pip 是串行下载包、串行安装。uv 同时下载所有依赖,同时解压和安装,I/O 和 CPU 不闲着。

全局缓存 + 硬链接 :uv 维护一个全局缓存目录(~/.cache/uv)。第一次下载某个包后,后续项目再需要同一个版本时,uv 不会重新下载,而是通过硬链接直接指向缓存中的文件。这意味着多个项目共享同一份包文件,既省磁盘又省时间。

解析器优化:uv 使用移植自 Dart 的 PubGrub 算法(而非 pip 的回溯算法),并针对 Python 生态做了深度定制------提前终止无效分支、缓存中间解析结果、按约束严格程度智能排序。

实测数据:安装 100 个依赖,uv 比 pip 快 10~100 倍;创建虚拟环境,uv 比 virtualenv 快 30 倍;Docker 构建时间缩短 60%~80%。

2.2 核心功能全景

uv 不只是"更快的 pip",它是一个统一的 Python 工具链

功能 uv 命令 替代的传统工具
安装包 uv pip install <pkg> pip install
创建虚拟环境 uv venv python -m venv / virtualenv
锁定依赖 uv pip compile pip-compile (pip-tools)
同步依赖 uv pip sync pip-sync (pip-tools)
安装 Python uv python install 3.12 pyenv install
运行脚本 uv run script.py python script.py(自动激活环境)
运行 CLI 工具 uvx ruff check . pipx run ruff check .
项目管理 uv init / uv add / uv lock poetry init / poetry add

2.3 项目管理模式

uv 原生支持 pyproject.toml 作为项目配置文件,并提供 lockfile 机制

bash 复制代码
# 初始化新项目
uv init my-project
cd my-project

# 添加依赖(自动更新 pyproject.toml 和 uv.lock)
uv add requests flask

# 锁定依赖版本(生成 uv.lock)
uv lock

# 安装所有依赖(严格按 lockfile)
uv sync

uv.lock 文件记录了每个依赖的精确版本和哈希值,确保团队所有成员和 CI 环境安装的包完全一致------这是 pip 原生做不到的。

2.4 单文件脚本依赖

uv 支持在单个 Python 文件中内嵌依赖声明

python 复制代码
# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "rich",
# ]
# ///

import requests
from rich import print

resp = requests.get("https://api.github.com")
print(resp.json())

运行 uv run script.py,uv 会自动创建临时环境、安装依赖、执行脚本。这意味着你可以把一个完整的可运行程序打包成一个 .py 文件,分享给别人时无需附带 requirements.txt。

三、conda 深度解析

3.1 conda 的设计哲学

conda 的核心定位是跨语言的包管理和环境管理工具。它不只面向 Python------在生物信息学、地球科学等领域,conda 被用来管理 R、Julia、C/C++ 等各种语言的依赖。

conda 的包格式是 .tar.bz2.conda,里面装的是预编译的二进制文件,而不是 PyPI 上的源码包(sdist/wheel)。这意味着 conda 在安装时不需要编译,直接解压就能用------省去了编译环境和编译时间的麻烦。

3.2 环境隔离机制

conda 的环境隔离比 venv 更彻底。venv 本质上是复制一份 Python 解释器的引用 ,共享系统的部分库;conda 环境是一个完全独立的目录树

复制代码
~/miniconda3/envs/myenv/
├── bin/
│   ├── python          # 独立的 Python 解释器
│   ├── pip
│   └── ...
├── lib/
│   ├── python3.11/
│   │   └── site-packages/   # 独立的包目录
│   ├── libmkl_intel_lp64.so  # 独立的 BLAS 库
│   └── libcuda.so            # CUDA 运行时库
└── include/
    └── ...

每个 conda 环境自带完整的依赖栈,包括底层 C/C++ 库。这就是为什么 conda 在安装 pytorch 时可以自动处理 CUDA 依赖------它把 CUDA toolkit 也当作一个"包"来管理。

3.3 Channel 机制

conda 的包来源于 Channel(频道),这是一种分层的包仓库:

  • defaults:Anaconda 公司维护的默认频道,商业使用需要许可证
  • conda-forge:社区维护的开源频道,包的数量和质量最高
  • 自定义频道:企业内部可以搭建私有频道
bash 复制代码
# 配置 conda-forge 为优先频道
conda config --add channels conda-forge
conda config --set channel_priority strict

conda 在安装包时会从所有已配置的 Channel 中搜索,按优先级选择。这和 pip 从 PyPI 单一源安装不同。

3.4 依赖解析:SAT Solver

conda 的依赖解析使用 SAT 求解器------把依赖关系转化成一个布尔可满足性问题(Satisfiability),用数学方法找出是否存在一个满足所有约束的安装方案。

这个过程在理论上很严谨,但实际体验是。原因包括:

  • Channel 中的元数据量巨大(conda-forge 有上万个包,每个包有多个版本和构建变体)
  • 约束条件复杂(不仅要匹配 Python 版本,还要匹配 CUDA 版本、操作系统、CPU 架构)
  • SAT 求解器的搜索空间随包数量指数增长

这就是为什么 conda install 经常卡在 "Solving environment..." 上。社区为此开发了 Mamba------一个用 C++ 重写的 conda 替代品,专门优化了解析速度,效果提升明显。

3.5 常用命令

bash 复制代码
# 环境管理
conda create -n myenv python=3.11        # 创建环境
conda activate myenv                      # 激活环境
conda deactivate                          # 退出环境
conda env list                            # 列出所有环境
conda env export > environment.yml        # 导出环境
conda env create -f environment.yml       # 从文件创建环境

# 包管理
conda install numpy pytorch               # 安装包
conda install -c conda-forge scipy        # 从指定频道安装
conda update --all                        # 更新所有包
conda list                                # 列出已安装包
conda search pytorch                      # 搜索可用包

# 清理
conda clean --all                         # 清理缓存和未使用的包

四、uv 与 conda 的全面对比

维度 uv conda
实现语言 Rust Python
包来源 PyPI(纯 Python 生态) conda channels(跨语言)
包格式 wheel / sdist 预编译二进制(.tar.bz2 / .conda)
环境隔离 基于 venv(轻量) 独立目录树(重量)
Python 版本管理 支持(uv python install 支持(conda install python=3.11
非 Python 依赖 不支持 支持(CUDA、C/C++ 库等)
依赖解析算法 PubGrub(快) SAT Solver(慢但严谨)
Lockfile 原生支持(uv.lock 通过 environment.yml 导出
安装速度 极快(10~100x pip) 慢("Solving environment...")
工具体积 ~10MB ~400MB(Miniconda)
CUDA 管理 不直接管理 可以自动安装 CUDA toolkit

关键差异解读

速度差异的本质:uv 的快不只是"Rust 比 Python 快"。它的全局缓存 + 硬链接机制意味着同一个包只需下载和存储一次,后续所有项目直接复用。而 conda 每次创建新环境都可能重新下载和安装。

包来源的差异:uv 从 PyPI 拿包,PyPI 上绝大多数是 wheel 格式(预编译),但也有 sdist(源码包)需要本地编译。conda 的包全是预编译二进制,不会出现"编译失败"的问题,但也意味着包的更新速度比 PyPI 慢(conda-forge 需要社区构建和审核)。

非 Python 依赖是分水岭:如果你需要安装的包依赖 CUDA、MKL、HDF5 等底层库,conda 是目前最省心的选择。uv 在这方面无能为力------它只能处理 PyPI 上的纯 Python 包和 wheel。

五、怎么选:场景决策框架

选 uv 的场景:

  • 纯 Python 项目(Web 开发、脚本工具、API 服务)
  • 追求速度和开发体验(CI/CD 构建时间敏感)
  • 需要 lockfile 保证环境可重现
  • 团队协作,需要统一依赖版本
  • 单文件脚本分享(内嵌依赖声明)

选 conda 的场景:

  • 深度学习 / 科学计算,需要管理 CUDA、cuDNN、MKL 等底层依赖
  • 跨语言项目(Python + R、Python + C/C++)
  • 生物信息学等领域(conda-forge 有大量专业工具)
  • 需要在没有系统级安装权限的机器上独立管理完整的运行环境

混合使用的方案:

很多 AI 团队采用"conda 管底层,uv/pip 管上层"的策略:用 conda 安装 Python 解释器和 CUDA 工具链,然后用 uv pip install 安装 PyPI 上的 Python 包。这样既利用了 conda 管理非 Python 依赖的能力,又享受了 uv 的安装速度。

bash 复制代码
# 混合方案示例
conda create -n myenv python=3.11 cudatoolkit=12.1
conda activate myenv
uv pip install torch torchvision    # 用 uv 快速安装 PyTorch
uv pip install -r requirements.txt  # 用 uv 安装其余依赖

六、常见坑与排查

坑1:conda 的 defaults 频道商业许可问题

Anaconda 的 defaults 频道从 2020 年起对商业用户收费(200 人以上的企业)。如果你在公司环境使用 conda,应该配置 conda-forge 作为唯一频道,或使用 Miniforge(默认只用 conda-forge)。

bash 复制代码
conda config --remove channels defaults    # 移除默认频道
conda config --add channels conda-forge     # 添加社区频道

坑2:uv 和 conda 环境混用导致的问题

如果你在 conda 环境中使用 uv pip install,uv 会把包装到 conda 环境的 site-packages 中。这通常没问题,但如果 conda 和 uv 安装了同一个包的不同版本,可能会导致冲突。建议明确分工:要么全用 conda,要么 conda 只管底层 + uv 管 Python 包。

坑3:conda "Solving environment" 卡死

这是 conda 最被诟病的问题。解决方案:

  • 使用 Mamba 替代 conda(conda install mamba -n base -c conda-forge,之后用 mamba install 代替 conda install
  • 配置 conda config --set solver libmamba,启用新的高速求解器(conda 23.10+ 已内置)
  • 减少 channel 数量,缩小搜索空间

坑4:uv 不支持需要源码编译的包

少数 Python 包没有预编译的 wheel(特别是一些小众的科学计算包),需要从源码编译安装。uv 对这种情况的支持不如 pip 成熟。遇到时可以回退到 pip install 单独处理。

坑5:团队环境不一致

不管用 uv 还是 conda,都要提交 lockfile / environment.yml 到版本控制。没有锁定文件,"在我机器上能跑"的问题永远不会消失。

七、命令对照速查表

操作 uv conda pip + venv
创建环境 uv venv conda create -n env python -m venv env
激活环境 source .venv/bin/activate conda activate env source env/bin/activate
安装包 uv pip install pkg conda install pkg pip install pkg
导出依赖 uv pip freeze conda env export pip freeze
从文件安装 uv pip sync conda env create -f pip install -r
管理 Python 版本 uv python install 3.12 conda install python=3.12 不支持
运行 CLI 工具 uvx ruff conda run ruff pipx run ruff
清理缓存 uv cache clean conda clean --all pip cache purge

八、总结

conda 和 uv 代表了 Python 环境管理的两种哲学。conda 走的是"大而全"路线------用一个工具管理所有语言的依赖,代价是速度和体积。uv 走的是"快而精"路线------专注 Python 生态,用 Rust 把每个环节做到极致速度,但对非 Python 依赖无能为力。

对于 AI Infra 方向的工程师来说,选择逻辑很清晰:需要 CUDA 等非 Python 依赖时用 conda(搭配 libmamba solver 或 Mamba 提速),纯 Python 项目用 uv。在 AI 团队中,两者混合使用(conda 管底层 + uv 管上层)是目前最常见的实践。

不管用哪个工具,最关键的习惯是锁定依赖版本 ------用 uv.lockenvironment.yml 确保环境可重现。"在我机器上能跑"这个问题,本质上都是因为没有做好依赖锁定。

参考资料

相关推荐
min(a,b)2 小时前
学习第 6 天:类型注解、装饰器与高级特性
python·学习
码云骑士2 小时前
80-指令微调Instruction-Tuning-指令数据构造-多任务训练-过拟合检测
python
爱昏羔3 小时前
上篇:从PDF到向量库 — 物流行业RAG系统的知识库构建全解析
python·langchain·pdf·agent·rag
麻雀飞吧3 小时前
最新量化实现难点,规则和流程要先有形状
人工智能·python
用户0332126663673 小时前
使用 Python 在 Word 文档中添加或删除文本框
python
激动的兔子3 小时前
关于Anaconda的使用心得pkgs.trash清理
conda
LadenKiller3 小时前
近期AI量化辅助,工具重点要跟学习阶段变化
人工智能·python
phltxy4 小时前
LangChain_Agent中间件实战
人工智能·python·深度学习·语言模型·中间件·langchain
axinawang4 小时前
第14课:查找、统计、分割字符串
python
倒流时光三十年4 小时前
第一阶段 02 · Mapping 与数据类型(text vs keyword 是重点)
后端·python·django