SingularityでPyenv&Poetry環境構築
SingularityでPoetryが使いたい
これまでSingualrity上のPythonパッケージ管理はpipで行っていました.
最近,以下の記事をきっかけにPoetryの存在を知り,調べていくうちに虜になりました.
Python環境構築[Pyenv+Poetry]|研究のためのPython開発環境
今後,開発したプログラムの公開も見据え,環境の再現性を担保するためにもPoetryを導入したいと思います.
また副次的な産物として,Singularityでpipを使う場合,新しいパッケージの追加はdefファイルを再記述してbuildし直す必要がありましたが,Poetryではイメージ内から新たなパッケージの追加が可能です.もちろん,pyproject.tomlに追加したパッケージは自動で記録されるので,後の環境再現も問題ありません.
Definition File
先程の記事に従い,Singularityイメージを作成するDefinition Fileを以下の通り記述しました.
Bootstrap: docker
From: nvidia/cuda:11.3.1-cudnn8-devel-ubuntu20.04
%environment
export TZ=Asia/Tokyo
export CUDA_PATH=/usr/local/cuda
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
export PYENV_ROOT="/opt/pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export POETRY_HOME=/opt/poetry
export PATH=$POETRY_HOME/bin:$PATH
# PyenvのPythonを利用
export PATH=$PYENV_ROOT/shims:$PATH
%post
perl -p -i.bak -e 's%(deb(?:-src|)\s+)https?://(?!archive\.canonical\.com|security\.ubuntu\.com)[^\s]+%$1http://ftp.riken.jp/Linux/ubuntu/%' /etc/apt/sources.list
export DEBIAN_FRONTEND=noninteractive
export TZ=Asia/Tokyo
export PYENV_ROOT="/opt/pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export PYTHON_VERSION=3.11
export POETRY_ROOT="/opt/poetry"
apt-get -y update
apt-get -y dist-upgrade
apt-get -y install \
build-essential \
curl \
git \
libbz2-dev \
libffi-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
liblzma-dev \
llvm \
make \
tk-dev \
wget \
xz-utils \
zlib1g-dev
# Install pyenv
git clone https://github.com/pyenv/pyenv.git $PYENV_ROOT
eval "$(pyenv init --path)"
pyenv install $PYTHON_VERSION
pyenv local $PYTHON_VERSION
# Install poetry
curl -sSL https://install.python-poetry.org | POETRY_HOME=$POETRY_ROOT python -
%labels
Author msn
Version v1.0.1
今後,GPUの活用(PyTorchの導入)を視野に入れているため,ベースにDockerで配布されているcudaイメージを使用していますが,シンプルなUbuntu環境でも問題ないと思います.
注意点として,Build時に%post
セクションのカレントディレクトリは/root
となり,各インストール先に影響します.
そこで,今回は/opt
以下に明示的にインストールしています.また,インストール先へのパス開通を%environment
セクションで行い,shell実行時に反映されるようにしています.
検証
以下のコマンドでBuildしました.
私の環境では,--fakeroot
権限のみが許可されているため,以下のようなコマンドでBuildしています.
singularity build --fakeroot pyenvpoetry.sif pyenvpoetry.def
Build完了後にコンテナ内に入り,パスの開通と,Python, Poetryの動作確認を行いました.
イメージ化した後でもパッケージの追加インストールが可能なことを確認しました.
Pyenvによる追加のバージョンインストールは,Pyenvのインストール先である/opt/pyenv
が一般ユーザで書き込み不能なため,失敗しました.
複数のPythonバージョンを使用する場合は,予めdefファイルによるインストールが必要だと考えられます.
which pyenv
# /opt/pyenv/bin/pyenv
which poetry
# /opt/poetry/bin/poetry
### poetryの動作チェック ###
poetry init
# (出力省略)すべてreturnを押して進める
poetry shell
which python
# /{USERHOME}/.cache/pypoetry/virtualenvs/hoge-h8c379Fr-py3.11/bin/python
# ndjsonがインストールされていないことを確認
python
# Python 3.11.2 (main, Mar 16 2023, 16:36:22) [GCC 9.4.0] on linux
# Type "help", "copyright", "credits" or "license" for more information.
>>> import ndjson
## Traceback (most recent call last):
## File "<stdin>", line 1, in <module>
## ModuleNotFoundError: No module named 'ndjson'
>>> exit()
# ndjsonをインストールして追加を確認
poetry add ndjson
## Using version ^0.3.1 for ndjson
##
## Updating dependencies
## Resolving dependencies... (0.1s)
##
## Writing lock file
##
## Package operations: 1 install, 0 updates, 0 removals
##
## • Installing ndjson (0.3.1)
python
# Python 3.11.2 (main, Mar 16 2023, 16:36:22) [GCC 9.4.0] on linux
# Type "help", "copyright", "credits" or "license" for more information.
>>> import ndjson
# Errorが出ず成功
exit # poetry shellからの退出
cd ../
mkdir foo
cd foo
### pyenvの追加バージョンインストール -> 失敗 ###
pyenv install 3.9
# perl: warning: Setting locale failed.
# perl: warning: Please check that your locale settings:
# LANGUAGE = (unset),
# LC_ALL = (unset),
# LC_TERMINAL = "iTerm2",
# LANG = "en_US.UTF-8"
# are supported and installed on your system.
# perl: warning: Falling back to the standard locale ("C").
# Downloading Python-3.9.16.tar.xz...
# -> https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tar.xz
# Installing Python-3.9.16...
#
# BUILD FAILED (Ubuntu 20.04 using python-build 2.3.15-1-g4ef81b5c)
#
# Inspect or clean up the working tree at /tmp/python-build.20230317101532.1581633
# Results logged to /tmp/python-build.20230317101532.1581633.log
#
# Last 10 log lines:
# changing mode of build/scripts-3.9/idle3 from 644 to 755
# changing mode of build/scripts-3.9/2to3 from 644 to 755
# renaming build/scripts-3.9/pydoc3 to build/scripts-3.9/pydoc3.9
# renaming build/scripts-3.9/idle3 to build/scripts-3.9/idle3.9
# renaming build/scripts-3.9/2to3 to build/scripts-3.9/2to3-3.9
# Creating directory /opt/pyenv/versions/3.9.16/bin
# /usr/bin/install: cannot create directory '/opt/pyenv/versions/3.9.16': Read-only file system
# Creating directory /opt/pyenv/versions/3.9.16/lib
# /usr/bin/install: cannot create directory '/opt/pyenv/versions/3.9.16': Read-only file system
# make: *** [Makefile:1313: altbininstall] Error 1
むすび
SingularityでPyenvとPoetryによるPython環境構築を行いました.
Poetryによって環境再現性が高く,Singularityの利点の一つである再現性をより高めることができます.
また従来のpipではイメージ化してからパッケージの追加が不可能でした.一方,PoetryのaddコマンドはBuild後でも追加ができることから,パッケージ追加のためにdefファイルの修正・再Buildが不要だとわかり,開発の効率化が期待されます.
ただし,Pyenvによって複数のPythonバージョンをBuild後にインストールすることはできませんでした.予めdefファイルで必要なバージョンをインストールしておくか,Pyenvのインストール先を一般ユーザが書込み可能な領域を選択する(Singularityでは不可能?)必要があり,さらなる検証が必要です.
今後は今回の環境にPyTorchの導入を試みます.
Discussion