1. unnonouno

    Posted

    unnonouno
Changes in title
+Chainer 1.5のインストールがうまくいかない人への非公式なTips
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,63 @@
+
+Chainer 1.5で、外部の依存状況が大きく変わりました。その結果、幾つかの要因でインストールが難しくなりました。この記事では、その対策を書きます。
+
+*この内容には間違いが含まれている可能性があります。気付き次第更新します*
+
+# ハマリポイント
+
+1. Cythonを使うようになりました。ソースの一部は.pyxファイルになり、.cppを生成して.soにビルドしています。
+2. CUDAやcuDNNなどの共有ライブラリ(.soファイル)もCythonから使うようになりました。今までは、ctypesを使っていました。
+3. h5pyなど、共有ライブラリを必要とするパッケージを利用するようになりました。
+
+順に、何が問題になるのか説明します。
+
+## Cythonの利用
+
+Cythonは.pyxで記述したファイルを、.cppに変換(コンパイル)してから、.soファイルを作り、それを呼び出すことによって高速化するツールです。CuPyの速度が遅い理由の1つが、Pythonインタプリタが遅すぎることだったので、Cythonによる高速化が求められました。
+まず、Cythonが必要になります。これはpipで勝手にインストールします。.cppができるということは、それをビルドするC++コンパイラが必要になります。これは、gcc(g++)や、WindowsならMSVCが必要になります。これらがない環境ではビルドができません。
+
+## ctypesからCythonへ
+
+外部の共有ライブラリを使うには、これらにアクセスする必要があります。今まではctypesというライブラリを使っていましたが、ctypesは動作が遅く、ここもまたボトルネックの一つになっていました。
+ctypesは.so中のシンボルに直接アクセスします。つまり、.hファイル相当の情報がChainerの.pyソース中に暗に記述されていました。Cythonの場合は、.cppにして静的にビルドするため公式の.hファイルをインクルードして使う、ある意味正しい使い方になりました。一方で、v1.5では.hファイルの場所や.soファイルの場所が、 **インストール時** に指定する必要があります。そのため、インストール時にnvccにパスが通っていたり(そこからCUDAのディレクトリを逆算します)、cudnn.hやcudnn.soの場所がCPATHやLIBRARY_PATHで指定されている必要があります(cuDNNには公式のインストール先やインストーラがありません)。
+また、CuPyのインストール後にCUDAやcuDNNを入れただければ動きません(ctypesの場合は、soファイルさえ見つけられればよかった)。そのため、これらの場所が変わったり、バージョンが上がってバイナリ互換性が崩れた場合は、再インストールの必要があります。
+
+## h5pyへの依存
+
+シリアライズに使っているHDF5は、h5pyから使っています。このh5pyはlibhdf5.soを使っているため、このライブラリがインストールされている必要があります。こうした制約は、pillowからjpegファイルを使う時と同様です(一度libjpegがない状況でpip pillowしてみると状況がわかります)。
+ライブラリは通常pipでは管理されていませんから、Ubuntuならlibhdf5-devなどを予めインストールしておかないとh5pyのインストールに失敗します。・・・といっても、この制約はChainerではなくてh5pyの制約です。
+
+# 対処法
+
+## 依存ツール・ライブラリ群を予めインストールする
+
+アップグレード前に、依存ツール・ライブラリをインストールします。Ubuntuならg++やlibhdf5-devを入れて下さい。
+CUDAも予めインストールして、nvccをPATHに通してください。cuDNNも、適当なディレクトリに展開して、CPATHにcudnn.hがあるディレクトリを、LIBRARY_PATHとLD_LIBRARY_PATHにcudnn.soがあるディレクトリをそれぞれ追加します。ちなみに、cuDNN v2は解凍すると無造作に.hと.soが入っており、cuDNN v3はそれぞれcuda/includeとcuda/lib64というディレクトリに展開されます。
+
+## Chainerがたくさんいる
+
+Chainerが沢山インストールされている事があります。アンインストール時は、`pip uninstall chainer`を、警告が出なくなるまで繰り返してください。
+
+## 何かゴミが残っている
+
+`site-package`ディレクトリにChainerの残骸が残っている事があります。`pip uninstall`しても消えません。私はドキドキしながら手動で消したりしています。正しい対応方法などはよくわかりません。
+
+## キャッシュに嵌らないようにする
+
+キャッシュを見てしまってインストールが失敗する現象が散見されます
+`pip install chainer --no-cache`を試して下さい。
+
+## sudoに気をつける
+
+sudoは環境変数を引き継ぎません。そのため、一生懸命上記の環境変数をセットしたつもりが、sudoの中では無視されます。envコマンドを駆使するか、rootになって作業して下さい。
+しかし、そもそも論として個人的にはpyenvなどでユーザー固有のPython環境を構築することをおすすめします。研究室などで勝手にアップデートすると、締め切り直前の先輩に刺されますよ。
+
+# 環境変数あれこれ
+
+- CPATH: gccがインクルードファイルを探す先。ビルド時に必要。
+- LIBRARY_PATH: gccがライブラリファイルを探す先。ビルド時に必要。
+- LD_LIBRARY_PATH: dlopenがライブラリファイルを探す先。実行時に必要(な場合がある)。
+- DYLD_LIBRARY_PATH: Mac(BSD系?)でdlopenがライブラリファイルを探す先。実行時に必要(な場合がある)。
+- CUDA_PATH: Windows版CUDAをインストールすると、インストール先として勝手にセットされる。
+- CUDA_ROOT: PyCUDAで使われているが、別にnVidia公式の環境変数ではない気がする。
+- CUDA_HOME: TensorFlowで使われているが、別にnVidia公式の環境変数ではない気がする。