pixi cookbook
Conda的前世今生
在介绍pixi之前,有必要先聊聊Conda。实际上Conda最早诞生于2012年,晚于pip和venv,为什么在已经存在pip和venv的情况下,还要推出一个看似重复的包管理工具呢?
将时间倒回2012年,python的包管理面临着一个巨大的问题。彼时,很多科学计算库(如 NumPy, SciPy, Pandas)底层都是用 C、C++ 或 Fortran 编写的,而 pip 主要安装的是源码包(sdist)。这意味着当你执行pip install numpy时,你的电脑必须装有对应的编译器、动态链接库和复杂的数学库(如 MKL 或 OpenBLAS)。如果环境不匹配,安装就会报错。这是一个让人头疼的事情(尤其是那些编程基础本就不扎实的科学家们)。
当时 Anaconda 的创始人 Travis Oliphant 意识到,科学计算的用户(物理学家、生物学家、金融分析师)不应该把时间花在解决 gcc 编译器报错上。因此,Conda出现了,它直接分发预编译好的二进制文件。这就意味着用户不需要在本地编译,直接下载解压就能用。由于不需要处理那些烦人的依赖,这对很多那些科学家来说简直是救命稻草。而将所有这些库以及非python编写的依赖库打包在一起的巨大的库,就是 Anaconda Distribution。如今,它是目前全球最流行的科学计算平台,本质上是将 Python、Conda 包管理器以及一大堆常用的科学计算库打包在一起的软件发行版。
不过在最初,Anaconda Distribution只是一个将所有软件包放在一起的大杂烩,在后续的更新中,人们意识到需要一个类似于 pip 的命令来管理这些依赖库,比如添加、更新和删除依赖,于是,conda命令行诞生了。他们维护的那个软件包仓库,在当时叫做default。
在一段时间以来,他们维护着官方的 defaults ,这是一个经过严格测试的软件包仓库,兼容性极好。但问题也随之而来:科学计算的世界太大了。除了 NumPy、Pandas 这些通用的,还有成千上万个小众领域的库(比如天文学的 Astropy、地理信息的 GDAL、生物信息学的Biopython)。这对于一家商业公司(当时甚至只是个创业公司)来说,根本没有人力去打包、编译、测试全世界所有的科学软件。而且,Conda 包是二进制文件,需要针对 Windows、Linux、macOS 分别编译,工作量是 PyPI 的数倍。
为了解决这个问题,Anaconda开放了 Channel 机制。 他们推出了 Anaconda.org(最初叫 Binstar.org),允许用户创建自己的 Channel。如果你需要的包官方不提供,那么你可以自己打包上传到你的个人频道,别人只要添加你的 URL 就能下载。
将权限下放给用户,解决了官方维护成本的问题,但是随着个人 Channel 的开放,又带来了过于混乱的问题。很快,大家就发现,如果要装 tensorflow,在搜索时可能会发现:
google/tensorflowzhang3/tensorflowalice/tensorflow
如此多的tensorflow,你敢用吗?这些包是基于什么环境编译的?有没有植入恶意代码?彼此兼容吗?一群核心开发者意识到,不能让成千上万个个人频道各自为战。于是他们建立了一个社区驱动的超级频道 —— conda-forge。它引入了自动化的 CI/CD 流水线。任何人都可以在 GitHub 上提交 Recipe,由CI自动构建,并由社区审核。它解决了信任和标准化的问题,成为了现如今的事实标准。
而对于那些生物信息学的软件。很多底层工具是用 Perl、C++ 甚至 Fortran 写的老古董,而且依赖关系极其复杂(不仅仅依赖 Python,还依赖系统级的库)。这些软件对于做金融或做 Web 开发的人来说完全没有用,拖慢搜索速度。而且,生物软件的版本更新逻辑和通用软件完全不同。因此,Bioconda Channel 诞生了。 这是一群生物学家建立的。他们把所有生物相关的软件(超过 7000 个)都放在这个频道里。通过 Channel,不同领域的人可以在自己的圈子里维护自己的生态,互不干扰。
pixi:新时代的包管理方案
既然 Conda 生态已经如此成熟,为什么还需要 pixi?
简单来说,pixi 是一个基于 Rust 编写(底层使用 rattler 库)、强调完全可重现性和极高性能的现代化包管理器。它不仅完全兼容 Conda 庞大的 conda-forge 生态,还通过内置的 uv 库实现了对 PyPI 的“一等公民”级支持。
相比于传统的 Conda 客户端,pixi 的核心优势在于:
- 快到极致:依赖解析速度比传统 conda 快几个数量级。
- 声明式配置:不再依赖一系列手动输入的命令行指令,所有配置都记录在一个
pixi.toml中。 - 强制锁文件:生成
pixi.lock确保跨平台、跨机器的安装结果 100% 一致。 - 无需激活:直接运行
pixi run即可,不再需要繁琐的conda activate。
本文章介绍pixi的基本用法和最佳实践,并不作为百科全书使用,要想了解更多,强烈建议去查看官方文档。
快速上手
对于 Python 项目,pixi 推荐直接使用 pyproject.toml 作为配置文件。这不仅符合 Python 社区的标准,还能让你在同一个文件中管理构建系统、项目元数据以及 pixi 专有的环境配置。
1. 安装 pixi
在 macOS 或 Linux 上,使用官方脚本进行一键安装:
1 | curl -fsSL https://pixi.sh/install.sh | sh |
安装脚本会将 ~/.pixi/bin 添加到 PATH。安装完成后,重启终端以使配置生效。
要更新pixi,可以使用如下命令:
1 | pixi self-update |
2. 初始化项目(pyproject.toml 模式)
进入你的项目目录,使用 --format pyproject 参数初始化:
1 | pixi init test1 --format pyproject |
如图,这将创建一个具有以下结构的项目目录:

其中,pyproject.toml 内容如下:
1 | [project] |
Pixi 中使用 pyproject.toml 作为清单文件。这样用户只需一个文件即可管理所有配置。 pyproject.toml 文件是 Python 项目的标准配置。我们不建议将 pyproject.toml 文件用于 Python 项目以外的任何用途, pixi.toml 更适合其他类型的项目。
我们来看看里面分别添加了什么:
1 | # pixi 入口 |
channels 和 platforms 被添加到 [tool.pixi.workspace] 部分。conda-forge 作为默认的Channel。关键字 platforms 决定了工作区支持哪些平台,如果你希望在macos和linux平台使用,可以改为platforms = ["linux-64", "osx-arm64"]。
1 | # Editable installs |
test1 包本身被添加为 editable 依赖项。这意味着该包以可编辑模式安装,因此你可以对包进行更改并在环境中看到更改的反映,而无需重新安装它。
1 | [build-system] |
pyproject.toml 文件通常包含一个 [build-system] 部分。如果该项目被添加为 PyPI 路径依赖项,Pixi 将使用此部分来构建和安装该项目。pixi init --format pyproject 默认使用 hatchling 作为构建后端,你可以在Choosing a build backend查看更多内容。
pixi 会自动将 requires-python 映射为 Python 依赖,pixi 可以识别该字段,并自动将 Python 版本添加到依赖项中。
3. 添加依赖(Conda 与 PyPI 混合)
我们的项目通常依赖于其他软件包。pixi 遵循 “Conda 优先” 策略:先解析 Conda 依赖,再处理 PyPI 依赖。
1 | pixi add numpy |
该命令会自动添加conda依赖,并写入 [tool.pixi.dependencies]:
1 | [tool.pixi.dependencies] |
有些软件包在 conda-forge 上不可用,但在 PyPI 上却有发布。使用--pypi参数添加 PyPI 依赖:
1 | pixi add black --pypi |
此时的依赖会自动添加到 [project.dependencies]。
1 | [project] |
并且在执行后,pixi 会更新 pyproject.toml 并同步生成 pixi.lock 文件。该锁文件记录了跨平台一致的精确依赖版本。
4.修改cache路径
Pixi 会将所有先前下载的软件包缓存到一个缓存文件夹中。该缓存文件夹在所有 Pixi 工作区和全局安装的工具之间共享。
通常情况下默认的缓存路径如下:
- Linux:
$XDG_CACHE_HOME/rattler或$HOME/.cache/rattler - macOS:
$HOME/Library/Caches/rattler - Windows:
%LOCALAPPDATA%\rattler
可通过设置 PIXI_CACHE_DIR 或 RATTLER_CACHE_DIR 环境变量来配置此位置。比如:
1 | export PIXI_CACHE_DIR=/somewhere/a/b/tmp/pixi_cache |
使用pixi info可以查看到有关缓存位置的信息:
1 | Cache dir: /somewhere/a/b/tmp/pixi_cache |
在实践中,如果
$HOME存储空间有限,建议修改PIXI_CACHE_DIR至大容量存储位置。
5. 安装环境
当别人使用pixi管理项目并向你共享时,你可以通过pixi install来获得相同的依赖包。
运行该命令,工作区根目录会新增一个名为 .pixi 的目录。该环境是一个 Conda 环境,其中已安装了所有 Conda 和 PyPI 依赖项。
环境始终由 pixi.lock 文件生成,而 pixi.lock 文件又由 pyproject.toml 文件生成。该文件包含了跨平台环境中已安装的依赖项的确切版本。
6. 运行代码
在 pixi 中,你不需要手动激活环境。通过 pixi run 执行命令时,pixi 会自动确保环境处于最新状态。
直接运行 Python 命令:
1 | pixi run python -c "import rich; rich.print('[bold magenta]Hello Pixi![/bold magenta]')" |
如果需要交互式 Shell,可以使用:
1 | pixi shell |
5. 查看环境状态
1 | # 列出当前环境的所有包及其来源(Conda 或 PyPI) |
最佳实践
1. 使用 [tool.uv.sources]
因为 pixi 使用 uv 来构建其 pypi-dependencies ,所以可以使用 tool.uv.sources 部分来指定从主 pixi 清单引用的任何 pypi 依赖项的来源。
首先创建一个新的项目:
1 | pixi init example --format pyproject |

我们希望example作为主项目,引用a的依赖项,而a引用b的依赖项,我们希望引用结构如下所示:
1 | . |
具体来说,这在 example 的 pyproject.toml 文件中看起来是这样的:
1 | [tool.pixi.pypi-dependencies] |
那么此时a中的 pyproject.toml 应该包含一个 [tool.uv.sources] 部分:
1 | [project] |
让我们检查一下:
1 | cd example |
需要注意的是,截至目前为止,主 pixi.toml 或 pyproject.toml 文件由 pixi 直接解析,而非由 uv 处理。这意味着你无法在主 pixi.toml 或 pyproject.toml 文件中使用 [tool.uv.sources] 部分。
想了解更多关于[tool.uv.sources]的内容,请参考uv文档。
2. System Requirements
System Requirements用于告知 Pixi 安装和运行你的环境所需的系统规格。它们确保依赖项与你机器的操作系统和硬件相匹配。
这用于定义你的环境可以在哪些“类型的机器”上运行。比如:
1 | [system-requirements] |
这样就形成了一个可以在以下平台上运行的环境:
- Linux 内核版本 4.18
- GNU C 库 (glibc) 版本 2.28
- CUDA 版本 12
- macOS 版本 13.0
在依赖求解时,Pixi 会结合使用:
platforms的默认要求- 通过
[system-requirements]添加的任何自定义要求
System Requirements以虚拟包的形式添加。虚拟包是特殊的包(例如 __linux 、 __cuda 、 __glibc ),它们不包含任何文件。它们仅声明系统上可用的功能,求解器使用它们来过滤掉不兼容的包。
System Requirements并未指定最高或最低版本,而是指定了主机系统上可以安装的版本。依赖求解器会根据可用版本来判断系统是否满足要求。例如:
- 一个软件包可能需要
__cuda >= 12,而系统可以有12.1或任何12.6版本。 - 一个软件包可能需要
__cuda <= 12,而系统可以有12.0.0或任何11的版本。
大多数情况下,软件包会指定其所需的最低版本( >= )。因此,我们常说 system-requirements 定义了系统规范的最低版本。
2.1 使用cuda
要在环境中使用 CUDA,你必须在系统需求表中指定所需的 CUDA 版本。这可以确保 CUDA 被识别,并在必要时将其正确锁定到pixi.lock中。
1 | [system-requirements] |
system-requirements 这样写,是否等于强制指定 CUDA 运行时版本? 答案是不能。 system-requirements 字段用于根据主机的 NVIDIA 驱动程序 API 指定支持的 CUDA 版本。添加此字段可确保正确解析依赖于 __cuda >= {version} 的软件包。因此,这是在告诉 Pixi:CUDA 版本 12 可用,并且可以在解析过程中使用。
3. 安装Pytorch
我们大致有两种方式来安装pytorch。下面的toml清单均以pyproject.toml为例。
3.1 从Conda-forge安装
可以使用 conda-forge 安装 PyTorch。这些是由 conda-forge 社区维护的 PyTorch 构建版本。你可以直接使用 Nvidia 提供的软件包,以确保这些软件包能够协同工作。
1 | [project] |
这样默认安装的是符合要求的、且与环境中cuda版本相同的torch:
1 | pixi list | grep cuda |

要指定安装特定版本的 cuda 软件包,可以添加一条cuda-version依赖,其他软件包会在依赖解析过程中根据该依赖关系进行配置。cuda cuda-version 会限制 __cuda 虚拟软件包和 cudatoolkit 软件包的版本。这确保了正确安装 cudatoolkit 软件包版本,并正确解析依赖关系树。
1 | [tool.pixi.dependencies] |
1 | pixi list | grep cuda |

3.2 从 PyPI 安装
由于 pixi 与 uv 集成,我们还可以从 PyPI 安装 PyTorch。但是有以下注意事项:
如果使用这种方法安装 torch 包,还应该从 PyPI 安装 torch 的依赖包。因此,如果 Conda 包依赖于 PyPI 包,则不要将 PyPI 包与 Conda 包混用。 原因在于pixi解析过程分为两步:首先解析 Conda 包,然后解析 PyPI 包。因此,如果我们要求某个 Conda 包依赖于某个 PyPI 包,则解析过程无法成功。
PyTorch 包通过自定义索引(index-url)提供,类似于 Conda Channel,由 PyTorch 团队维护。要从 PyTorch 索引安装 PyTorch,需要将索引添加到清单文件中。最好为每个依赖项都添加此操作,以强制使用该索引。
1 | [tool.pixi.pypi-dependencies] |
1 | pixi list | grep cuda |

3.3 从 PyTorch 频道安装(不推荐)
由于 PyTorch 官方已停止运营其官方Channel,因此该方法不会更新到更高版本。
1 | [project] |
3.4 注意事项
- 同时使用
conda-forge和旧版pytorchChannel可能会导致冲突。请选择一个Channel并坚持使用它,以避免环境问题。对于新项目而言,建议使用conda-forge。 - 如果从 PyPI 安装 PyTorch,所有依赖于 PyTorch 的软件包也必须来自 PyPI。在同一依赖链中混用 Conda 和 PyPI 软件包会导致冲突。
- 检查 Pixi 在你的机器上检测到的 CUDA 版本,请运行:
pixi info,其中可以查看到:如果缺少1
2
3Virtual packages: __unix=0=0
: __glibc=2.35=0
: __cuda=12.9=0__cuda,可以使用 NVIDIA 工具验证系统的 CUDA 版本:1
nvidia-smi
- 检查环境中安装的 CUDA 工具包版本:
1
pixi run nvcc --version
4. Environment(环境)和 Multi Environment (多环境)
4.1 环境
Environment(环境)其实就是一组安装在特定位置的文件,它在某种程度上模拟了全局系统安装。但它有两个非常关键的特点,区别于 Conda 或 venv,pixi环境默认存放在当前项目的 .pixi/envs 目录下。这意味着环境完全属于这个项目(Workspace)。如果查看 .pixi/envs 目录,你会看到每个环境都有一个目录, default 是通常默认使用的环境,如果你指定自定义环境,则会使用你指定的名称。

这些目录是 conda 环境,你可以像使用 conda 环境一样使用它们,但不能手动编辑,所有操作都必须通过 pixi.toml 或 pyproject.toml 文件进行。pixi 会始终确保环境与 pixi.lock 文件保持同步。如果环境不一致,所有使用该环境的命令都会自动更新,例如 pixi run 和 pixi shell等命令。
在创建环境时,pixi 会添加一个包含一些元数据的小文件。该文件名为 pixi ,位于环境的 conda-meta 文件夹中。
如图所示:

该文件包含以下信息:
manifest_path:用于描述创建此环境的工作区的清单文件的路径environment_name:环境的名称pixi_version:用于创建此环境的 pixi 版本environment_lock_file_hash:用于创建此环境的pixi.lock文件的哈希值
environment_lock_file_hash 用于检查环境是否与 pixi.lock 文件同步。如果 pixi.lock 文件的哈希值与 pixi 文件中的哈希值不同,pixi 将更新环境。但是在通常情况下,哈希值比较无法检测到损坏的环境,但重新验证会重新安装该环境。默认情况下,所有修改锁定文件的命令以及 pixi install 命令都会触发重新验证。因此要触发完整的重新验证和安装,可以使用 pixi install 或 pixi reinstall 命令。
4.2 清理环境
要清理环境,只需删除 .pixi/envs 目录,pixi 会在需要时重新创建环境。
1 | rm -rf .pixi/envs |
4.3 多环境
Multi Environment(多环境)的应用场景十分广泛,比如:
- 一个workspace内有多个系统需求,例如
cuda环境和cpu环境 - 需要测试和pre-commit不需要安装在发布版本中,例如
release和dev环境 - 测试多个软件包版本 ,例如
py39和py310或polars 0.12和0.13版本 - …
4.3.1 feature
feature定义了环境的一部分,但如果不作为环境的一部分则毫无用处。你可以在一个工作区中定义多个feature。feature可以包含 tasks 、 dependencies 、 platforms 、 channels 等等 。你可以组合多个feature来创建一个环境。feature通过在清单文件中的表格中添加 [feature.
在默认情况下,用户无需指定 [feature.<name>.dependencies](对于pyproject就是[tool.pixi.feature.<name>.dependencies],下同) ,可以直接填写 [dependencies] 。这些顶级表会被添加到default feature中,除非用户明确选择不添加,否则该feature会添加到每个环境中。
4.3.2 创建一个多环境的项目
创建一个新的项目,在default环境里安装numpy:
1 | pixi init multi_env --format pyproject |
在项目的 .pixi/envs/default 目录下,default环境就存储在这里。
4.3.3 添加feature
下面开始向工作区添加一个简单的 test feature。我们可以通过命令行或编辑 pyproject.toml 文件来完成此操作。这里我们将使用命令行,并将 pytest 依赖项添加到工作区的 test feature中。
1 | pixi add --feature test pytest |
此时查看pyproject.toml会发现自动添加了这几行:
1 | [tool.pixi.feature.test.dependencies] |
这与普通 dependencies 表完全相同,但仅当 test feature 是环境的一部分时才会被使用。
由于环境不仅仅包含 dependencies ,因此可以通过包含以下字段来描述 feature 字段:
dependencies:conda 包依赖项pypi-dependencies:pypi 包依赖项system-requirements:环境的系统需求activation:环境的激活信息platforms:该环境可以运行的平台channels:用于创建环境的Channel。向Channel添加priority字段,以允许Channel连接而不是覆盖tasks:特定功能的task,一个环境中的任务被选为该环境的默认task
4.3.4 添加另一个环境
接下来向工作区添加 test 环境,以便添加一些测试工具。我们可以通过命令行或编辑 pyproject.toml 文件来完成此操作。这里我们将使用命令行:
1 | pixi workspace environment add test --feature test |
此时查看pyproject.toml会发现自动添加了这几行:
1 | [tool.pixi.environments] |
4.3.5 在新环境中运行任务
现在我们可以在新环境中运行任务了。
1 | pixi run --environment test pytest --version |
这条命令创建了测试环境,并在其中运行 pytest --version 命令。可以看到该环境将被添加到 .pixi/envs 目录中。

如果要查看环境,可以使用 pixi list 命令。
1 | pixi list --environment default | grep pytest |
只有后者可以看到pytest软件包。
4.3.6 添加dev环境
在实践中,我们可能还需要一个dev feature:
1 | pixi add --feature dev jupyterlab ruff |
添加dev环境,我们希望使用与default相同的依赖求解,因此使用--solve-group:
1 | pixi workspace environment add dev --feature dev --solve-group default --force |

使用pixi list -x -e <env_name>查看,可以发现不同的环境具有完全相同的依赖项版本:

4.3.7 关于dependency-groups
实际上这二者都是同一个概念,只是在不同工具中的说法不同罢了,pixi使用的是后者。如果你的pyproject.toml中包含dependency-groups,比如:
1 | [dependency-groups] |
pixi 会将自动将其解释为同名的 feature, 并关联到 pypi-dependencies,因此,这就相当于:
1 | [tool.pixi.feature.docs.pypi-dependencies] |
你可以通过以下命令验证:
1 | pixi list -x -e dev |

4.3.8 关于optional-dependencies
与dependency-groups几乎相同,假设pyproject.toml中这么写:
1 | [project.optional-dependencies] |
pixi 会将自动将其解释为同名的 feature, 并关联到 pypi-dependencies,因此,这就相当于:
1 | [tool.pixi.feature.dev.pypi-dependencies] |
你可以通过以下命令验证:
1 | pixi list -x -e dev |

4.3.9 激活并使用对应环境
可以通过命令行或配置手动激活所需的环境。这种方法保证了环境无冲突,一次只允许激活一个功能集。
使用default环境:
1 | pixi run python |
使用test环境:
1 | pixi run -e test pytest |
在环境中运行任何命令:
1 | pixi run -e test any_command |
5. Config配置
pixi的配置文件一般名为config.toml,如果在多个位置均有该文件,则配置按以下优先级加载:
- 命令行参数如
--change-ps1=false、--tls-no-verify等 your_project/.pixi/config.toml:项目根目录下的配置$PIXI_HOME/config.toml:PIXI_HOME中的全局配置$HOME/.pixi/config.toml:用户HOME目录中的全局配置$HOME/.config/pixi/config.toml:用户指定配置/etc/pixi/config.toml:系统级配置
如果在优先级较高的位置找到配置文件,则从优先级较低的位置读取的配置值将被覆盖。
你可以通过运行 pixi info -vvv 来查看当前pixi在哪里寻找配置。
下面介绍一下我们平时主要用到的配置。
5.1 default-channels
1 | default-channels = ["conda-forge"] |
运行 pixi init 或 pixi global install 时默认选择的Channel。默认仅选择 conda-forge。
5.2 mirrors
使用mirrors可以配置Channel镜像。镜像的优先级根据列表顺序排列。pixi 会尝试从列表中的第一个镜像获取 conda 的repodata(最重要的文件)。repodata 包含所有软件包的 SHA256 哈希值,因此务必从可信来源获取此文件。
你可以替换某个镜像源,比如所有发送到 anaconda.org 上Channel的请求转发到 prefix.dev:
1 | [mirrors] |
以下是南科大的conda镜像源,你可以将其写入配置文件中:
1 | [mirrors] |
5.3 proxy-config
pixi 会优先考虑 https_proxy 等代理环境。也可以在 pixi 配置的 proxy-config 中设置代理,这将影响 pixi 的所有网络操作,例如解析、自动更新、下载等。目前 proxy-config 支持以下选项:
1 | [proxy-config] |
5.4 pypi-config
顾名思义这是PyPI的配置。
1 | [pypi-config] |
5.5 常用的config配置示例
可以配置到$HOME/.pixi/config.toml:
1 | default-channels = ["conda-forge", "bioconda"] |