SANSUI'S BLOG

系统外观
分类标签
RSS
Sansui 2025
All rights reserved
人活着就是为了卡卡西

uv 管理 conda 项目依赖

7 月 25 日, 2025

conda 的问题

Python 新项目使用 uv 管理容易,但是总是有一些老项目不用。 conda 包管理一直以来都是 AI 的标配。我用 python 99% 都是在扒别人代码运行。这就导致了我运行了多少个项目,就装了多少份 torch……硬盘再大也经不起十几次折腾。

conda 的问题在于

  1. requirements.txt 全手写!很多人可能忘更新配置,导致扒拉下来缺库运行不了,先解决一个小时的依赖问题再说。
  2. 依赖和安装顺序强相关。比如项目需要更新的 numpy,但你可能要装个别的项目的库,python 发了论文和仓库就跑的项目是很多的。安装一个旧项目导致之前安装 numpy 被卸载,然后整个项目就垮掉。这种情况相当之多,又解决两个小时的依赖问题。
  3. (至少我不愿意看到)电脑里十几个相同版本的 torch 和 cuda。当时的硬盘还只有 256G,多装几个 torch 无法接受,嗯……

直到现在都还是这样的,大家主打一个能跑完实验就行。包的更新是激进的,包管理是落后的。在几年前有人说用 PDM,后面有 poetry。这两是不用再手写 requirements.txt 了,依赖也会自动 resolve 不会覆盖来覆盖去的,但还是会装十几个 torch。直到 uv 开始用硬链接进行包管理。

uv 之于 conda 项目

uv 接管 python 界的依赖管理按理说已经没什么问题。但实际情况是,很多项目还是在用 conda。除非哪天 torch 和 HF 都把 uv 设置为首推,否则就得一直与 conda 存在的问题战斗。

1. 不提供 venv 的项目

用于研究的项目一般都是不提供的打包好的环境的,主要是太大了,每个人设备情况也不一样。所以下载后第一件事是

uv venv
./.venv/Script/activate

如果这个项目不再更新了,或者是打算迁移到 uv,可以直接使用 uv 的方式管理依赖。uv 会自动维护 pyproject.tomluv.lock 文件。

uv add -r requirements.in -c requirements.txt

如果这个项目,他还在更新,你时不时就得去拉一下分支。这时候最好用 uv pip 。至于依赖混乱问题,听天由命吧。跑得起来就得了

uv pip install -r requirement.txt

2. 提供 venv 的项目

提供 venv 的项目通常是给人用的,b 站的整合包一大堆。这种已经配好环境的项目也意味着你最好只用 pip。通常还是非常原始地调用 pip

./.venv/python -m pip install xxx

……等于说又开始了安装十几份 torch 的依赖管理模式。用 uv 是可以重复利用缓存的。这个时候 uv 的问题在于无法接管 python 环境,需要设置一下环境变量:

export UV_PYTHON="./.venv/python"
uv pip list

然后就可以利用 uv 的缓存了。

当然,依赖混乱问题使用 uv pip 是无法避免的。这对于发行版也是一种麻烦。因为发行版的环境全给你配好了,但有的项目设计了插件系统,插件系统又需要装插件的 requirement.txt,安一个许久没更新的插件让主项目废掉的情况也不是不可能……

如果让插件作者指定的兼容版本?只靠规范做不到,必须像MC那样检查版本号,不更新版本号就不放行。这样就算不更新代码了,也得倒逼作者每个版本都进行一次(至少是与主项目的)依赖兼容性测试。

我觉得以当前 python 的运行方式,不 lock 子依赖的版本,这个问题是没法解决的。

uv 管理 torch 下载源

通常而言,在不指定 index 时 uv add torch 是去 pypi 或清华镜像源找 CPU 版本。如果打算每个项目都采用一样的 torch 版本 和 cuda ——

uv 创建的新项目

共用的 uv.toml 指定下载源。

Linux 在 .config/uv/ 下,Windows 在 %APPDATA%/uv/ 下。

[[index]]
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
default = true
[[index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true

项目级别的 pyproject.toml

dependencies = [
  "torch==2.7.1",
  "torchvision==0.22.1",
  "torchaudio==2.7.1",
]

[tool.uv.sources]
torch = [
  { index = "pytorch-cu128"},
]
torchvision = [
  { index = "pytorch-cu128"},
]
torchaudio = [
  { index = "pytorch-cu128"},
]

然后执行 uv sync 安装。

uv pip 管理老项目

直接指定命令行 的 --index-url

uv pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu124

和用 pip 的方式差不多,区别是会硬链接到集中的缓存,不会重复占用十几份 torch。当然。该有的依赖冲突还是会有的。关键是装好后就不要更新了

更新于 2025-07-25 04:12
Waline