Intro
データ解析業務なんかでPythonに色々なライブラリを入れて使うとき、環境分離ができるとなにかと助かる。
pipenvはPython界隈で(おそらく)一番使われている構成管理・環境分離のためのツール。私もLinuxPC上での開発や、実環境へのデプロイで大変お世話になっている。
ところで、先日、NVIDIAの出している組み込み向けAIコンピューティングデバイス Jetson TX2で色々開発する機会があった。
GPUを搭載し深層学習に最適化されたパワフルなマシンらしいのだが…GPUはTegra。そしてCPUはARM製。nvidia-smi
すら叩けない、ちょっと特殊なハードウェア。(代わりにtegrastats
というコマンドが用意されている)
このマシンにpipenvを入れたところ、インストールは成功するも開発時に何かとハマったので、解決方法を書いてみた。
(Jetpack 4.2で作業。執筆時点での最新版が4.2.2なので、細かな差異があるかもしれません)
pipenvを入れるまで
pipenvのインストール自体は、そこまで難しくない。
まずはpip(pip3)
が入っていなかったのでインストールする。
# aptでpython3-pipは入れない
# 依存関係が壊れ、筆者環境ではpipコマンドがエラーを吐くようになってしまった(その場合Pythonを再インストール)
sudo apt install curl
curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python3
pip3 -V
pipenvと一緒に使うpyenvをインストールする。
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
環境変数設定とpyenvのinitializeが、シェル起動時に行われるようにする。
筆者の場合zshを使っているので、~/.zshrc
に以下を追記する。
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$HOME/.local/bin:$PATH"
eval "$(pyenv init -)"
続いてpipでpipenvをインストールする
sudo pip3 install pipenv
pipenv
コマンドを叩いて、以下のUsageが表示されたらインストール完了。
Usage: pipenv [OPTIONS] COMMAND [ARGS]...
(省略)
インストール作業自体は普通のUbuntu等とかわらない。
普通のpipenvの使い方
pipenvの使い方は なりとさんのブログで非常にわかりやすく説明されています。
また公式ドキュメントにより高度な使い方が説明されています。
多くの場合、下のようなPipfile
を作成した後、pipenv install
で仮想環境を作成。
pipenv shell
やpipenv run
で仮想環境でコマンドを実行…というのがよくある使い方ではないでしょうか。
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
[dev-packages]
[packages]
requests = "*"
[requires]
python_version = "3.6"
OpenCVを使いたい(システムのパッケージを使いたい)
ここからがJetson TX2らしい(?)使い方。
Jetpack(JetsonのOSとソフトをまとめたソフトウェア群)にははじめから、OpenCVがインストールされている。
手動でOpenCVを入れなくとも、python3
でデフォルトのPythonを起動し、
import cv2
でimportできる。
未確認だが、最初から入っているOpenCVならgstreamerやTegraへの対応がされていて、Jetsonのハード性能を引き出せそう(そうであってほしい)。
つまり極力デフォルトのOpenCVを使いたいのだが、仮想環境を構築してしまうとそのOpenCVは参照できなくなる。
そこで環境の分離度は下がるものの、システムのpythonパッケージを継承しその上に仮想環境を構築してみる。
試しにopencv
(デフォルト)とrequests
(仮想環境が提供)が入った環境を用意してみる。
# 適当なデモ用ディレクトリを掘る
mkdir opencv_install
cd opencv_install/
# OpenCVがインストールされたPython実行ファイルの場所を調べる
which python3 # -> /usr/bin/python3
# バージョンを調べる。
/usr/bin/python3 -V # -> 3.6.7
次のPipfileを用意。requests
パッケージだけで、openCV
はどこにも書かれていないことに留意。
仮想環境のpython_version
は念の為、上記で調べたpythonのバージョンに合わせておく。
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
requests = "*"
[requires]
python_version = "3.6.7"
Pipfile
を用意したら仮想環境を作成するのだが、ここでちょっと工夫をする。
# --python <path> でpythonの実行ファイルを指定
# --site-packages でそのpythonのsite-packagesを継承する
# なお install を省略すると、空の仮想環境を作ることもできる
pipenv --python /usr/bin/python3 --site-packages install
--site-packages
がここのポイント。システムのPythonのライブラリが仮想環境内で参照できるようになる。--python
で、どのPythonのライブラリを参照するか明示的に指定する。
仮想環境が作成されたら、 OpenCV
とrequests
が使えるか実際にみてみる。
pipenv shell
python #インタプリタ起動
import cv2 # 仮想環境の外から。読み込めてる
import requests # 仮想環境から読み込めてる
Tensorflowを使いたい(NVIDIAのリポからインストール)
そもそも、JetsonにTensorflowを入れるには?
(Jetpack4.2.1以降?では、最初からTensorflowがインストール済みであるよう。)
せっかくGPUを搭載したマシンなので、tensorflow-gpu
を入れたいところだが、pip install tensorflow-gpu
では入らない。(こんな環境のパッケージなんぞ配布してない、と怒られる。)
NVIDIAがJetson向けにビルド済みのTensorflowを配布しているので、ここからインストールする。公式ドキュメントに方法が記載されているのでこれに倣ってすすめる。
# 必要なパッケージのインストール
sudo apt-get install libhdf5-serial-dev hdf5-tools libhdf5-dev zlib1g-dev zip libjpeg8-dev
# tensorflowをdeveloper.download.nvidia.comからインストールする
sudo pip3 install --pre --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v42 tensorflow-gpu
なおバージョンを指定したインストールもできる。配布されているバージョンはこのサイトで確認できる。
pipenvでインストールするには
上記のように、デフォルトのpypiリポジトリ外からのインストールもpipenv
は対応できる。
次のようにPipfile
を書いておけばよい。
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[[source]]
name = "nvidia_repo"
url = "https://developer.download.nvidia.com/compute/redist/jp/v42"
verify_ssl = true
[packages]
tensorflow-gpu = {version="*", index='nvidia_repo'}
[requires]
python_version = "3.6"
[[source]]
でリポジトリを宣言後、[packages]
の項でどのリポジトリからインストールするか指定する。(未指定の場合はpypiが自動的に使われる?)
Jetsonでpipenv使ってみた感想
基本的にはJetsonでもpipenvつかえるのすごい便利!
なのだが、いくつか難点が。
- scipy, tensorflow-gpu等のインストールにかかる時間がいちいち長い(例えば上記tensorfowの場合15分ほど。CPUがやや弱い?)
- Jetsonの内蔵ストレージは小さい(32GB)…大きなパッケージをあちこちの環境でインストールするとストレージがパンパンに。(
pipenv --rm
ですぐ消せるけれど。) - 結局OpenCVみたいにシステムに入っているパッケージを参照したい場合が多い
とはいえpipenv
にはバージョンを固定できたり、環境構築作業を手順化できたりと他のメリットも多い。
用法用量を守って使っていきます。