技術研究所のYKです。 今回、新たにGPU環境を構築する必要が生じたので、そのついでにPython3でのCaffe環境構築を試してみました。 以前もCaffeの環境構築を行いましたが、その時には、情報がより多く出回っているという理由からPython2.7を使用して環境構築を行いました。
しかし、普段の業務やプライベートではPython3系を使っている為、どうせならPython3系を使ってやってみよう!と思い立ったのがキッカケです。 Python2.7での環境構築では手間取らなかったようなところで手間取ったので、(私自身の備忘の為にも)試行錯誤した結果をメモしておきます。
- 環境: AWS EC2上にGPUインスタンスを立てました。
- インスタンスタイプ: g2.8xlarge
- これまではg2.2xlargeのインスタンスを使っていましたが、今回はかなりスペックを上げてみました。 下記表は、 https://aws.amazon.com/jp/ec2/instance-types/ より引用しています。
モデル GPU vCPU メモリ(GiB) SSDストレージ (GB) g2.2xlarge 1 8 15 1 x 60 g2.8xlarge 4 32 60 2 x 120
- これまではg2.2xlargeのインスタンスを使っていましたが、今回はかなりスペックを上げてみました。 下記表は、 https://aws.amazon.com/jp/ec2/instance-types/ より引用しています。
- インスタンスタイプ: g2.8xlarge
- CUDA 8.0
- cuDNN 5.1
- Python
- 今後TensorFlowやChainer等を導入することが見込まれる為、pyenvを利用してAnacondaの導入を行いました。
- Anacondaのバージョン: Python 3.6.0 :: Anaconda 4.3.1
- pyenv
- Pythonのバージョン管理システム 複数のバージョンのPythonを共存させたり、用途に応じて利用するPythonのバージョンを切替えたりできる
pyenv GitHub
- Pythonのバージョン管理システム 複数のバージョンのPythonを共存させたり、用途に応じて利用するPythonのバージョンを切替えたりできる
- Continuum Analyticsが提供している、Pythonと科学計算向けのライブラリが同梱されたPythonのパッケージ
Linux版、macOS版、Windows版が提供されており、それぞれPython2.7、Python3.6向けが提供されている
手間取った箇所のログと、その対策を記載しておきます。
In file included from /usr/include/boost/python/detail/prefix.hpp:13:0, |
from /usr/include/boost/python/args.hpp:8, |
from /usr/include/boost/python.hpp:11, |
from src/caffe/layer_factory.cpp:4: |
/usr/include/boost/python/detail/wrap_python.hpp:50:23: fatal error: pyconfig.h: No such file or directory |
- 原因
- 導入したAnacondaのパスをMakefile.configに設定していなかったことに因ります。
- 対策
- Makefile.configを以下のように修正しました。
# 72行目: コメントアウトを外す & パスの書換え |
## 変更前 |
# ANACONDA_HOME := $(HOME)/anaconda |
## 変更後</code> <code>ANACONDA_HOME := $(HOME)/.pyenv/versions/anaconda3-4.3.1/ |
/usr/bin/ld: warning: libpython3.6m.so.1.0, needed by .build_release/lib/libcaffe.so, not found (try using -rpath or -rpath-link) |
- 原因
- Makefile.config内のANACONDA_INCLUDEに、libcaffe.soが格納されているディレクトリのパスが記載されていなかったことに因ります。
- Makefile.configを以下のように修正しました。
# 79 ~ 80行目: コメントアウトを外す & パスの書換え・追加 |
# 併せて、導入したPythonのバージョンに合わせる修正も実施 |
## 変更前 |
# PYTHON_INCLUDE := /usr/include/python3.5m \ |
# /usr/lib/python3.5/dist-packages/numpy/core/include |
## 変更後 |
PYTHON_INCLUDE := $(ANACONDA_HOME)/include \ |
$(ANACONDA_HOME)/lib \ |
$(ANACONDA_HOME)/include/python3.6m \ |
$(ANACONDA_HOME)/lib/python3.6/site-packages/numpy/core/include |
ここまでで、一旦make all -> make test -> make runtest -> make pycaffeが全て通るようになりました。
makeが全て通ったのでPythonインタプリタ上で import caffe を叩いてみましたが、まだまだエラーが出ました。
import caffe |
Traceback (most recent call last): |
File "", line 1, in |
File "$HOME/caffe/python/caffe/__init__.py", line 1, in |
from .pycaffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, RMSPropSolver, AdaDeltaSolver, AdamSolver, NCCL, Timer |
File "$HOME/caffe/python/caffe/pycaffe.py", line 13, in |
from ._caffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, \ |
ImportError: $HOME/.pyenv/versions/anaconda3-4.3.1/bin/../lib/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by $HOME/caffe/python/caffe/_caffe.so) |
- 原因
- libstdc++に含まれるGLIBCのバージョンが適切でないことによるエラーであり、 $HOME/.pyenv/versions/anaconda3-4.3.1/bin/../lib/libstdc++.so.6に、GLIBCXX_3.4.21が含まれていないことに起因するものでした。
- GLIBC: C言語の標準ライブラリ
weblio辞書_OSS用語集_Glibc
- ※ 合致するバージョンを含むlibstdc++やlibgompが見つからなかった場合はcondaコマンド等を利用して更新する必要がありますが、今回は割愛致します。
- 以下の手順で対策を行いました。
strings $HOME/.pyenv/versions/anaconda3-4.3.1/bin/../lib/libstdc++.so.6 | grep GLIBCXX |
# 確かに、GLIBCXX_3.4.21が無い |
GLIBCXX_3.4 |
... |
GLIBCXX_3.4.18 |
GLIBCXX_3.4.19 |
GLIBCXX_FORCE_NEW |
GLIBCXX_DEBUG_MESSAGE_LENGTH |
ls -al $HOME/.pyenv/versions/anaconda3-4.3.1/bin/../lib/libstdc++.so.6 |
# 実体はlibstdc++.so.6.0.19 |
lrwxrwxrwx 1 caffe-user caffe-user 19 May 8 18:45 libstdc++.so.6 - libstdc++.so.6.0.19 |
sudo find / -name "libstdc+*" |
$HOME/.pyenv/versions/anaconda3-4.3.1/pkgs/libgcc-4.8.5-2/lib/libstdc++.so.6 |
... |
$HOME/.pyenv/versions/anaconda3-4.3.1/lib/libstdc++.so.6 |
$HOME/.pyenv/versions/anaconda3-4.3.1/lib/libstdc++.so |
$HOME/.pyenv/versions/anaconda3-4.3.1/lib/libstdc++.so.6.0.19 |
/usr/lib/x86_64-linux-gnu/libstdc++.so.6 # ここら辺使えそう |
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 # |
- (1) と同様の手順で、内包しているランタイムのバージョンを確認します。
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX |
GLIBCXX_3.4 |
... |
GLIBCXX_3.4.19 |
GLIBCXX_3.4.20 |
GLIBCXX_3.4.21 # あった! |
GLIBCXX_DEBUG_MESSAGE_LENGTH |
- 見つけたlibstdc++がシンボリックリンクか否か確認します。
ls -al /usr/lib/x86_64-linux-gnu/libstdc++.so.6 |
# シンボリックリンクかファイルの実体かを確認 |
lrwxrwxrwx 1 root root 19 Nov 3 2016 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 - libstdc++.so.6.0.21 |
- 念の為、元のlibstdc++.so.*をバックアップした上で行いました。
ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 $HOME/.pyenv/versions/anaconda3-4.3.1/bin/../lib/libstdc++.so.6 |
ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 $HOME/.pyenv/versions/anaconda3-4.3.1/bin/../lib/libstdc++.so.6.0.21 |
- 再度Pythonインタプリタを起動し、import caffeを実行してみました。
- 当方の環境では、今度はlibgomp.so.1が存在しないというエラーが出ましたが、 (1) ~ (4)の対象をlibgomp.so.1に読み替えて対応し、解消しました。
import caffe |
Traceback (most recent call last): |
File "", line 1, in |
File "$HOME/caffe/python/caffe/__init__.py", line 1, in |
from .pycaffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, RMSPropSolver, AdaDeltaSolver, AdamSolver, NCCL, Timer |
File "$HOME/caffe/python/caffe/pycaffe.py", line 13, in |
from ._caffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, \ |
ImportError: $HOME/caffe/python/caffe/_caffe.so: undefined symbol: _ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE |
- 原因
- boost.pythonに起因するエラーであり、Makefile.configにて指定したバージョンのboost.pythonが存在しないことが原因でした。
- 参考
- 以下の手順で対策を行いました。
- Makefile.config内の以下の部分で、boost.python等のバージョン指定を行っている為、 当該行のコメントアウトを外します。
# 78行目 |
## 変更前 |
# PYTHON_LIBRARIES := boost_python3 python3.5m |
## 変更後 |
PYTHON_LIBRARIES := boost_python3 python3.5m |
sudo find / -name "libboost_python*" |
/usr/lib/x86_64-linux-gnu/libboost_python-py27.a |
/usr/lib/x86_64-linux-gnu/libboost_python.a |
/usr/lib/x86_64-linux-gnu/libboost_python-py35.a |
/usr/lib/x86_64-linux-gnu/libboost_python-py35.so |
... |
/usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0 |
sudo find / -name "libpython3*" |
$HOME/.pyenv/versions/anaconda3-4.3.1/pkgs/python-3.6.0-0/lib/libpython3.so |
... |
/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu/libpython3.5m.so |
/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu/libpython3.5.so |
/usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 |
/usr/lib/x86_64-linux-gnu/libpython3.5m.so.1 |
上記の出力から、libpython3.5とlibboost_python-py35.soが存在することが確認できます。
- 対策: Makefile.configの修正
- PYTHON_LIBRARIESにてライブラリの名称が指定されており、また、PYTHON_LIBRARIESはLIBRARY_DIRSを参照していると考えられる為、LIBRARY_DIRSに対して両ファイルが格納されているディレクトリのパス(/usr/lib/x86_64-linux-gnu)を追加しました。
# 95行目 |
## 変更前 |
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib |
## 変更後 |
# 最後のパスはhdf5を利用する為の指定であり、今回の問題への対策とは無関係 |
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/hdf5/serial |
ln -s /usr/lib/x86_64-linux-gnu/libboost_python-py35.so /usr/lib/x86_64-linux-gnu/libboost_python3.so |
ln -s /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 /usr/lib/x86_64-linux-gnu/libpython3.5m.so |
ls -al /usr/lib/x86_64-linux-gnu/ | grep -E "libboost_python*|libpython*" |
lrwxrwxrwx 1 root root 23 May 9 11:18 libboost_python3.so --- libboost_python-py35.so |
... |
lrwxrwxrwx 1 root root 46 May 9 11:22 libpython3.5m.so --- /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 |
lrwxrwxrwx 1 root root 20 Nov 18 04:23 libpython3.5m.so.1 ---libpython3.5m.so.1.0 |
-rw-r--r-- 1 root root 4547880 Nov 18 04:23 libpython3.5m.so.1.0 |
import caffe |
Traceback (most recent call last): |
File "", line 1, in |
File "$HOME/caffe/python/caffe/__init__.py", line 1, in |
from .pycaffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, RMSPropSolver, AdaDeltaSolver, AdamSolver, NCCL, Timer |
File "$HOME/caffe/python/caffe/pycaffe.py", line 15, in |
import caffe.io |
... |
import matplotlib.dates as File "$HOME/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/matplotlib/dates.py", line 125, in |
from dateutil.rrule import (rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY, |
File "$HOME/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/dateutil/rrule.py", line 55 |
raise ValueError, "Can't create weekday with n == 0" |
^ |
SyntaxError: invalid syntax |
- 原因
- Anacondaに含まれるmatplotlibライブラリに起因する問題
- Caffeがmatplotlibに依存しており、また、そのmatplotlibがimportしているdateutilのバージョンが古い為に発生していると見られます。
- Anacondaに含まれるmatplotlibライブラリに起因する問題
- 下記の通り、dateutilを更新することで解消しました。
pip install python-dateutil --upgrade |
- makeを叩く際には以下のように呼び出すのがおすすめです。
make all -B -j8 |
# オプションの説明 |
# -B: 丸々リビルドし直す(事前にmake cleanしておけば特に指定する必要はなし) |
# -j8: 8並列でmakeの処理を実行する(任意の数を指定可能、CPUのコア数に合わせるように指定すると処理が速い) |
- 細かなところで手こずりましたが、何とかPython3.6からCaffeを呼び出せるようになりました。 g2.2xlargeインスタンスと比べ、どれほど学習が速くなるかを検証してみようと思います。