使用 Conda + Poetry 有意义吗?
Does it make sense to use Conda + Poetry?
将 Conda + Poetry 用于机器学习项目是否有意义?分享一下我(菜鸟)的理解,请指正或赐教:
据我了解,Conda 和 Poetry 有不同的目的,但在很大程度上是多余的:
- Conda 主要是一个环境管理器(实际上不一定Python),但它也可以管理包和依赖项。
- Poetry 主要是一个 Python 包管理器(比如 pip 的升级版),但它也可以创建和管理 Python 环境(比如, Pyenv).
的升级版
我的想法是同时使用两者并划分它们的角色:让 Conda 成为环境管理者,让 Poetry 成为包管理者。我的理由是(听起来)Conda 最适合管理环境,可用于编译和安装非 python 包,尤其是 CUDA 驱动程序(用于 GPU 功能),而 Poetry 比 Conda 更强大Python 包管理器。
通过在 Conda 环境中使用 Poetry,我设法相当轻松地完成了这项工作。诀窍是不使用 Poetry 来管理 Python 环境:我没有使用像 poetry shell
或 poetry run
这样的命令,只使用 poetry init
、poetry install
等(激活 Conda 环境后)。
为了全面披露,我的 environment.yml 文件(针对 Conda)如下所示:
name: N
channels:
- defaults
- conda-forge
dependencies:
- python=3.9
- cudatoolkit
- cudnn
我的 poetry.toml 文件看起来像这样:
[tool.poetry]
name = "N"
authors = ["B"]
[tool.poetry.dependencies]
python = "3.9"
torch = "^1.10.1"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
老实说,我这样做的原因之一是我在没有 Conda 的情况下努力安装 CUDA(用于 GPU 支持)。
您觉得这个项目设计合理吗?
我有使用 Conda + Poetry 设置的经验,并且运行良好。我的大部分依赖项都在 pyproject.toml
中指定,但是当 PyPI 中没有某些东西时,或者使用 Conda 安装它更容易时,我将它添加到 environment.yml
中。而且,Conda作为虚拟环境管理器,与Poetry配合得很好:不需要使用poetry run
或poetry shell
,激活正确的Conda环境就够了。
创建可重现环境的技巧
- 添加 Poetry,可能带有版本号(如果需要),作为
environment.yml
中的依赖项,以便在 运行 conda create
时安装 Poetry,以及 Python 和其他 non-PyPI 依赖项。
- 添加
conda-lock
,它可以为 Conda 依赖项提供锁定文件,就像您为 Poetry 依赖项提供 poetry.lock
一样。
- 考虑使用
mamba
,它通常与 conda
兼容,但更擅长解决冲突,而且速度也更快。另一个好处是您设置的所有用户都将使用相同的包解析器,独立于 locally-installed 版本的 Conda。
- 默认情况下,使用 Poetry 添加 Python 依赖项。如果有理由通过 Conda 安装软件包(例如为了获得 CUDA-enabled 版本)。在这种情况下,最好在
environment.yml
中指定包的确切版本,并在安装后,在 Poetry 的 pyproject.toml
中添加具有相同版本说明的条目(没有 ^
或~
版本号前)。这将让 Poetry 知道包在那里,不应该升级。
- 如果您使用提供相同包的不同渠道,则可能不清楚从哪个渠道下载特定包。一种解决方案是使用 :: 符号指定程序包的通道(请参阅下面的
pytorch
条目),另一种解决方案是启用 strict channel priority。不幸的是,在 Conda 4.x 中无法通过 environment.yml
. 启用此选项
- 请注意 Python 添加 user site-packages to
sys.path
, which may cause lack of reproducibility if the user has installed Python packages outside Conda environments. One possible solution is to make sure that the PYTHONNOUSERSITE
环境变量设置为 True
(或任何其他 non-empty 值)。
例子
environment.yml
:
name: my_project_env
channels:
- pytorch
- conda-forge
# We want to have a reproducible setup, so we don't want default channels,
# which may be different for different users. All required channels should
# be listed explicitly here.
- nodefaults
dependencies:
- python=3.10.* # or don't specify the version and use the latest stable Python
- mamba
- pip # pip must be mentioned explicitly, or conda-lock will fail
- poetry=1.* # or 1.1.*, or no version at all -- as you want
- tensorflow=2.8.0
- pytorch::pytorch=1.11.0
- pytorch::torchaudio=0.11.0
- pytorch::torchvision=0.12.0
# Non-standard section listing target platforms for conda-lock:
platforms:
- linux-64
virtual-packages.yml
(可以使用,例如,当我们希望 conda-lock
生成 CUDA-enabled 锁定文件,即使在没有 CUDA 的平台上):
subdirs:
linux-64:
packages:
__cuda: 11.5
First-time 设置
如果您已经在目标环境之外安装了 conda-lock
、mamba
和 poetry
,则可以避免使用 bootstrap 环境并简化下面的示例。
# Create a bootstrap env
conda create -p /tmp/bootstrap -c conda-forge mamba conda-lock poetry='1.*'
conda activate /tmp/bootstrap
# Create Conda lock file(s) from environment.yml
conda-lock -k explicit --conda mamba
# Set up Poetry
poetry init --python=~3.10 # version spec should match the one from environment.yml
# Fix package versions installed by Conda to prevent upgrades
poetry add --lock tensorflow=2.8.0 torch=1.11.0 torchaudio=0.11.0 torchvision=0.12.0
# Add conda-lock (and other packages, as needed) to pyproject.toml and poetry.lock
poetry add --lock conda-lock
# Remove the bootstrap env
conda deactivate
rm -rf /tmp/bootstrap
# Add Conda spec and lock files
git add environment.yml virtual-packages.yml conda-linux-64.lock
# Add Poetry spec and lock files
git add pyproject.toml poetry.lock
git commit
用法
上面的设置可能看起来很复杂,但它可以以相当简单的方式使用。
创造环境
conda create --name my_project_env --file conda-linux-64.lock
poetry install
激活环境
conda activate my_project_env
正在更新环境
# Re-generate Conda lock file(s) based on environment.yml
conda-lock -k explicit --conda mamba
# Update Conda packages based on re-generated lock file
mamba update --file conda-linux-64.lock
# Update Poetry packages and re-generate poetry.lock
poetry update
将 Conda + Poetry 用于机器学习项目是否有意义?分享一下我(菜鸟)的理解,请指正或赐教:
据我了解,Conda 和 Poetry 有不同的目的,但在很大程度上是多余的:
- Conda 主要是一个环境管理器(实际上不一定Python),但它也可以管理包和依赖项。
- Poetry 主要是一个 Python 包管理器(比如 pip 的升级版),但它也可以创建和管理 Python 环境(比如, Pyenv). 的升级版
我的想法是同时使用两者并划分它们的角色:让 Conda 成为环境管理者,让 Poetry 成为包管理者。我的理由是(听起来)Conda 最适合管理环境,可用于编译和安装非 python 包,尤其是 CUDA 驱动程序(用于 GPU 功能),而 Poetry 比 Conda 更强大Python 包管理器。
通过在 Conda 环境中使用 Poetry,我设法相当轻松地完成了这项工作。诀窍是不使用 Poetry 来管理 Python 环境:我没有使用像 poetry shell
或 poetry run
这样的命令,只使用 poetry init
、poetry install
等(激活 Conda 环境后)。
为了全面披露,我的 environment.yml 文件(针对 Conda)如下所示:
name: N
channels:
- defaults
- conda-forge
dependencies:
- python=3.9
- cudatoolkit
- cudnn
我的 poetry.toml 文件看起来像这样:
[tool.poetry]
name = "N"
authors = ["B"]
[tool.poetry.dependencies]
python = "3.9"
torch = "^1.10.1"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
老实说,我这样做的原因之一是我在没有 Conda 的情况下努力安装 CUDA(用于 GPU 支持)。
您觉得这个项目设计合理吗?
我有使用 Conda + Poetry 设置的经验,并且运行良好。我的大部分依赖项都在 pyproject.toml
中指定,但是当 PyPI 中没有某些东西时,或者使用 Conda 安装它更容易时,我将它添加到 environment.yml
中。而且,Conda作为虚拟环境管理器,与Poetry配合得很好:不需要使用poetry run
或poetry shell
,激活正确的Conda环境就够了。
创建可重现环境的技巧
- 添加 Poetry,可能带有版本号(如果需要),作为
environment.yml
中的依赖项,以便在 运行conda create
时安装 Poetry,以及 Python 和其他 non-PyPI 依赖项。 - 添加
conda-lock
,它可以为 Conda 依赖项提供锁定文件,就像您为 Poetry 依赖项提供poetry.lock
一样。 - 考虑使用
mamba
,它通常与conda
兼容,但更擅长解决冲突,而且速度也更快。另一个好处是您设置的所有用户都将使用相同的包解析器,独立于 locally-installed 版本的 Conda。 - 默认情况下,使用 Poetry 添加 Python 依赖项。如果有理由通过 Conda 安装软件包(例如为了获得 CUDA-enabled 版本)。在这种情况下,最好在
environment.yml
中指定包的确切版本,并在安装后,在 Poetry 的pyproject.toml
中添加具有相同版本说明的条目(没有^
或~
版本号前)。这将让 Poetry 知道包在那里,不应该升级。 - 如果您使用提供相同包的不同渠道,则可能不清楚从哪个渠道下载特定包。一种解决方案是使用 :: 符号指定程序包的通道(请参阅下面的
pytorch
条目),另一种解决方案是启用 strict channel priority。不幸的是,在 Conda 4.x 中无法通过environment.yml
. 启用此选项
- 请注意 Python 添加 user site-packages to
sys.path
, which may cause lack of reproducibility if the user has installed Python packages outside Conda environments. One possible solution is to make sure that thePYTHONNOUSERSITE
环境变量设置为True
(或任何其他 non-empty 值)。
例子
environment.yml
:
name: my_project_env
channels:
- pytorch
- conda-forge
# We want to have a reproducible setup, so we don't want default channels,
# which may be different for different users. All required channels should
# be listed explicitly here.
- nodefaults
dependencies:
- python=3.10.* # or don't specify the version and use the latest stable Python
- mamba
- pip # pip must be mentioned explicitly, or conda-lock will fail
- poetry=1.* # or 1.1.*, or no version at all -- as you want
- tensorflow=2.8.0
- pytorch::pytorch=1.11.0
- pytorch::torchaudio=0.11.0
- pytorch::torchvision=0.12.0
# Non-standard section listing target platforms for conda-lock:
platforms:
- linux-64
virtual-packages.yml
(可以使用,例如,当我们希望 conda-lock
生成 CUDA-enabled 锁定文件,即使在没有 CUDA 的平台上):
subdirs:
linux-64:
packages:
__cuda: 11.5
First-time 设置
如果您已经在目标环境之外安装了 conda-lock
、mamba
和 poetry
,则可以避免使用 bootstrap 环境并简化下面的示例。
# Create a bootstrap env
conda create -p /tmp/bootstrap -c conda-forge mamba conda-lock poetry='1.*'
conda activate /tmp/bootstrap
# Create Conda lock file(s) from environment.yml
conda-lock -k explicit --conda mamba
# Set up Poetry
poetry init --python=~3.10 # version spec should match the one from environment.yml
# Fix package versions installed by Conda to prevent upgrades
poetry add --lock tensorflow=2.8.0 torch=1.11.0 torchaudio=0.11.0 torchvision=0.12.0
# Add conda-lock (and other packages, as needed) to pyproject.toml and poetry.lock
poetry add --lock conda-lock
# Remove the bootstrap env
conda deactivate
rm -rf /tmp/bootstrap
# Add Conda spec and lock files
git add environment.yml virtual-packages.yml conda-linux-64.lock
# Add Poetry spec and lock files
git add pyproject.toml poetry.lock
git commit
用法
上面的设置可能看起来很复杂,但它可以以相当简单的方式使用。
创造环境
conda create --name my_project_env --file conda-linux-64.lock
poetry install
激活环境
conda activate my_project_env
正在更新环境
# Re-generate Conda lock file(s) based on environment.yml
conda-lock -k explicit --conda mamba
# Update Conda packages based on re-generated lock file
mamba update --file conda-linux-64.lock
# Update Poetry packages and re-generate poetry.lock
poetry update