Edited at

Chainer 1.5のインストールがうまくいかない人への非公式なTips

More than 3 years have passed since last update.

Chainer 1.6以降で、この記事の問題の大部分は解消しました

Chainer 1.5で、外部の依存状況が大きく変わりました。その結果、幾つかの要因でインストールが難しくなりました。この記事では、その対策を書きます。


主な原因


  1. Cythonを使うようになりました。ソースの一部は.pyxファイルになり、.cppを生成して.soにビルドしています(1.5.1でcythonize済みの.cppファイルを同梱しています)

  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が必要になります。これらがない環境ではビルドができません。

v1.5.1からCython済みの.cppファイルを同梱しているため、Chainer自体はCythonに依存しなくなりました。一方で、h5pyがCythonを要求するため、依然としてCythonが必要です。


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を入れて下さい。

特に、

...h5py/h5py/api_compat.h:27:18: fatal error: hdf5.h: No such file or directory

#include "hdf5.h"

こういうエラーメッセージがでたら、これはlibhdf5-devがない証拠です(h5pyのインストールに失敗しています)。

CUDAも予めインストールして、nvccをPATHに通してください。cuDNNも、適当なディレクトリに展開して、CPATHにcudnn.hがあるディレクトリを、LIBRARY_PATHとLD_LIBRARY_PATHにcudnn.soがあるディレクトリをそれぞれ追加します。ちなみに、cuDNN v2は解凍すると無造作に.hと.soが入っており、cuDNN v3はそれぞれcuda/includeとcuda/lib64というディレクトリに展開されます。


pipを最新にする

完全に原因を特定していませんが、pipが古いとh5pyのインストールに失敗することが有ります。

pip install -upgrade pip

してください。これは、h5pyのバージョンが上がると解消されるかもしれません。


setuptoolsを最新にする

同様にsetuptoolsが古いと失敗することが有ります。これもh5pyのバージョンが上がると解消されるかもしれません。

pip install -U setuptools


Cythonを先にインストールする

Cythonを使ったライブラリのインストールは、全体的に(?)失敗しやすくなっているようです。Cythonは利用時はもとより、インストール に必要になります。.pyxファイルを.cppに変換する必要があるからです。

h5pyのsetup.pyに問題がある(?)ようで、masterブランチでは直っていますが、2.5.0ではsetup_requireにCythonがありません。そのせいで、ビルド時にCythonを見つけられずに失敗することが有ります(何らかの要因でCythonの方が先に入って、成功することも有ります)。

先に、



pip install cython



すると解消される可能性があります。


メモリが足りなくなる [未解決]

Cythonのsetup.py中で無限ループが発生して、メモリがなくなることが原因と考えられています。Cythonを直接インストールするとこの問題が発生しないことが知られているので、直接入れると解決する可能性があります。

pip install -U cython

この発生原因は、まだ完全にはわかっていません。Chainerのsetup.pyがCythonに依存していると、先にCythonをアップグレードするためにCythonのソースを落としてきて、その中のsetup.pyを実行しようとしますが、setuptoolsはこのときにevalメソッドを使って実行するようです。そのために、一度importしたモジュールを開放してからsetup.pyの中身をevalしているようですが、そこで問題が発生しているように見えます。直接の原因は、同名のモジュールとクラスが混在した状態になって(reloadするまえのオブジェクトが、reload後のclassとisinstance関係ではなくなってしまうのと同じような状況)、unpickleできなくなって無限ループが発生する現象を確認しています。


sudoに気をつける

sudoは環境変数を引き継ぎません。そのため、一生懸命上記の環境変数をセットしたつもりが、sudoの中では無視されます。envコマンドを駆使するか、rootになって作業して下さい。

しかし、そもそも論として個人的にはpyenvなどでユーザー固有のPython環境を構築するか、--userオプションを付けてローカルにインストールすることをおすすめします(これはChainerに限った話ではないですが)。研究室などで勝手にアップデートすると、締め切り直前の先輩に怒られますよ。

一般的になぜこの問題がおこらないかというと、普通は ./configure は一般ユーザーで行って必要な情報をファイルに書きだして、 make だけ sudo するからです。pipではそのようなプロセスがありません。

masterでは指定がなければ /usr/local/cuda を直接参照するようにしています。


Chainerがたくさんいる

Chainerが沢山インストールされている事があります。アンインストール時は、pip uninstall chainerを、警告が出なくなるまで繰り返してください。


何かゴミが残っている

site-packageディレクトリにChainerの残骸が残っている事があります。pip uninstallしても消えません。私はドキドキしながら手動で消したりしています。正しい対応方法などはよくわかりません。


キャッシュに嵌らないようにする

キャッシュを見てしまってインストールが失敗する現象が散見されます

pip install chainer --no-cacheを試して下さい。


pycudaはもういらない

pycudaにはもう依存していません。インストールの必要はありません。


chainer-cuda-depsはもういらない

chainer-cuda-depsは以前のバージョンでpycudaなどの、CUDA動作に必要な依存ライブラリをインストールするためのものでした。もういりません。


環境変数あれこれ


  • 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公式の環境変数ではない気がする。