Ubuntu 14.04 に Chainer, TensorFlow, DMTK をインストールする (GPU 有効)

# はじめに

※この記事は [word2vec の各種実装の速度比較](http://aial.shiroyagi.co.jp/2015/12/word2vec/) の環境構築部分を抜き出したものですが、単体でも読める内容となっています。

機械学習のフレームワークである Chainer, TensorFlow, DMTK (Microsoft Distributed Machine Learning Toolkit) を Ubuntu にインストールします ([Mac にインストールする手順](http://qiita.com/knzm/items/5667680be8e975a89377) はこちら)。動作環境は NVIDIA 製の GPU が載った Ubuntu マシンで、特に AWS の GPU インスタンスで動かすことを念頭に置いています。

なお、記事中で説明した手順を実行するスクリプトを含むリポジトリはここにあります: https://bitbucket.org/knzm/wordembedding-experiments

(CUDA のインストール周りは [gist](https://gist.github.com/knzm/91f88e1703360a3904c7) を参照)

# パッケージのインストール

最初に必要なパッケージをインストールします。

```
$ sudo apt-get install git subversion unzip
$ sudo apt-get install build-essential gfortran
$ sudo apt-get install python-virtualenv python-dev
$ sudo apt-get install libatlas-base-dev swig
```

# CUDA 7.0 と cuDNN 6.5 v2 をインストールする

この部分はなかなか面倒ですが、以下の手順でインストールできるはずです。

```bash:install.sh
#!/bin/sh -e

### cuda

CUDA_VERSION=7.0
CUDA_PKG_VERSION=7-0
CUDA_REPO_VERSION=7.0-28
CUDA_DOWNLOAD_SUM=7570ef4b5cb5dd861b6e01732e20a0da3241c69f164bcb3348cfecba04230e85

curl -fsSL http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_${CUDA_REPO_VERSION}_amd64.deb -O
echo "${CUDA_DOWNLOAD_SUM} cuda-repo-ubuntu1404_7.0-28_amd64.deb" | sha256sum -c --strict -
dpkg -i cuda-repo-ubuntu1404_${CUDA_REPO_VERSION}_amd64.deb
apt-get update

apt-get install -y build-essential

apt-get install -y \
  cuda-core-${CUDA_PKG_VERSION} \
  cuda-license-${CUDA_PKG_VERSION} \
  cuda-misc-headers-${CUDA_PKG_VERSION}

apt-get install -y \
  cuda-nvrtc-${CUDA_PKG_VERSION} \
  cuda-cusolver-${CUDA_PKG_VERSION} \
  cuda-cublas-${CUDA_PKG_VERSION} \
  cuda-cufft-${CUDA_PKG_VERSION} \
  cuda-curand-${CUDA_PKG_VERSION} \
  cuda-cusparse-${CUDA_PKG_VERSION} \
  cuda-npp-${CUDA_PKG_VERSION} \
  cuda-cudart-${CUDA_PKG_VERSION}

apt-get install -y \
  cuda-driver-dev-${CUDA_PKG_VERSION} \
  cuda-nvrtc-dev-${CUDA_PKG_VERSION} \
  cuda-cusolver-dev-${CUDA_PKG_VERSION} \
  cuda-cublas-dev-${CUDA_PKG_VERSION} \
  cuda-cufft-dev-${CUDA_PKG_VERSION} \
  cuda-curand-dev-${CUDA_PKG_VERSION} \
  cuda-cusparse-dev-${CUDA_PKG_VERSION} \
  cuda-npp-dev-${CUDA_PKG_VERSION} \
  cuda-cudart-dev-${CUDA_PKG_VERSION}

apt-get install -y \
  cuda-drivers \
  cuda-command-line-tools-${CUDA_PKG_VERSION} \
  nvidia-modprobe

ln -s cuda-${CUDA_VERSION} /usr/local/cuda
echo "/usr/local/cuda/lib" >> /etc/ld.so.conf.d/cuda.conf
echo "/usr/local/cuda/lib64" >> /etc/ld.so.conf.d/cuda.conf
ldconfig

cp cuda.env /etc/profile.d/cuda.sh
. /etc/profile.d/cuda.sh

### cuDNN

CUDNN_VERSION=6.5
CUDNN_PKG_VERSION=${CUDNN_VERSION}-linux-x64-v2
CUDNN_DOWNLOAD_SUM=4b02cb6bf9dfa57f63bfff33e532f53e2c5a12f9f1a1b46e980e626a55f380aa

curl -fsSL http://developer.download.nvidia.com/compute/redist/cudnn/v2/cudnn-${CUDNN_PKG_VERSION}.tgz -O
echo "${CUDNN_DOWNLOAD_SUM} cudnn-${CUDNN_PKG_VERSION}.tgz" | sha256sum -c --strict -
tar -xzf cudnn-${CUDNN_PKG_VERSION}.tgz
cp -a cudnn-${CUDNN_PKG_VERSION} /usr/local/cudnn-${CUDNN_VERSION}
ln -s cudnn-${CUDNN_VERSION} /usr/local/cudnn
ln -s /usr/local/cudnn/cudnn.h /usr/local/cuda/include/
ln -s /usr/local/cudnn/libcudnn* /usr/local/cuda/lib64/
ldconfig
```

```bash:cuda.env
CUDA_PATH=/usr/local/cuda
PATH=${CUDA_PATH}/bin:${PATH}
LD_LIBRARY_PATH=${CUDA_PATH}/lib64:${LD_LIBRARY_PATH}
export CUDA_PATH
```

同じ内容のファイルが [gist](https://gist.github.com/knzm/91f88e1703360a3904c7) にもあるので、以下のようにして一発でインストールすることも可能です。

```
$ git clone https://gist.github.com/knzm/91f88e1703360a3904c7
$ cd 91f88e1703360a3904c7
$ chmod a+x install.sh
$ sudo ./install.sh
```

# Chainer をインストールする

公式ドキュメント: http://docs.chainer.org/en/stable/install.html

先に HDF5 ライブラリをインストールしておきます。

```
$ sudo apt-get install libhdf5-dev
```

virtualenv を作成して、

```
$ virtualenv ~/virtualenvs/chainer
$ source ~/virtualenvs/chainer/bin/activate
```

setuptools / pip のバージョンが古いとインストールに失敗するので最新に上げて、

```
$ pip install -U setuptools pip
```

pip でインストール

```
$ pip install chainer
```

または開発版をインストールします。

```
$ git clone https://github.com/pfnet/chainer.git
$ cd chainer
$ pip intall h5py
$ python setup.py develop
```

# TensorFlow をインストールする

公式ドキュメント: https://www.tensorflow.org/versions/master/get_started/os_setup.html

virtualenv を作成して、

```
$ virtualenv ~/virtualenvs/tensorflow-gpu --system-site-packages
$ source ~/virtualenvs/tensorflow-gpu/bin/activate
```

公式に提供されている wheel ファイルをインストールします。

```
$ pip install https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
```

ただし EC2 のように TensorFlow が公式に対応してない GPU を使用している場合は、以下のような手順でビルドが必要になります。

JDK のインストール:

```
$ sudo apt-get install default-jdk
```

bazel のビルド:

```
$ git clone https://github.com/bazelbuild/bazel.git
$ cd bazel
$ git checkout tags/0.1.0
$ ./compile.sh
$ cd ..
```

tensorflow のビルド

```
$ git clone https://github.com/tensorflow/tensorflow
$ cd tensorflow
$ git checkout tags/0.6.0
$ git submodule update --init
$ TF_UNOFFICIAL_SETTING=1 ./configure
$ ../bazel/output/bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
$ bazel-bin/tensorflow/tools/pip_package/build_pip_package $PWD/dist
$ cd ..
```

configure の途中で Cuda compute capabilities を聞かれるので、 使用している GPU に対応した値を入力してください。 AWS の g2 インスタンス (GRID K520) の場合は 3.0 です。市販されている GPU に関しては NVIDIA のサイトに [一覧表](https://developer.nvidia.com/cuda-gpus) があります。

できた wheel ファイルをインストールします。

```
$ pip install tensorflow/dist/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
```

# DMTK をインストールする

Ubuntu 14.04 では 標準の GCC のバージョンは 4.8 なので、 DMTK をビルドするために必要な GCC 4.8 はすでにインストールされています。

```
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

もしインストールされていなければ以下のようにしてインストールします。

```
$ sudo apt-get install gcc-4.8 g++-4.8
```

フレームワーク (multiverso) のビルド:

```
$ git clone https://github.com/Microsoft/multiverso.git
$ cd multiverso
$ vi Makefile
```

以下のように Makefile を修正して、

```diff
--- Makefile
+++ Makefile
@@ -18,7 +18,7 @@
 
 INC_FLAGS = -I$(HEADERS_DIR)
 INC_FLAGS += -I$(THIRD_PARTY_INC)
-LD_FLAGS = -L$(THIRD_PARTY_LIB) -lzmq -lmpich -lmpl
+LD_FLAGS = -L$(THIRD_PARTY_LIB) -Wl,-Bstatic -lzmq -lmpich -lmpl -Wl,-Bdynamic -lpthread -lrt
 
 LIB_SRC_DIR = $(PROJECT)/src/multiverso
 SERVER_SRC_DIR = $(PROJECT)/src/multiverso_server
```

ビルドします。

```
$ cd third_party
$ ./install.sh
$ cd ..
$ make
$ cd ..
```

次に個別のプロジェクトをビルドします。ここでは distributed_word_embedding を対象としますが、 lightlda, distributed_skipgram_mixture もほぼ同様の手順でビルドできます。

```
$ git clone https://github.com/Microsoft/distributed_word_embedding.git
$ cd distributed_word_embedding
$ ln -s ../multiverso
$ vi Makefile
```

以下のように Makefile を修正して、

```diff
--- Makefile
+++ Makefile
@@ -14,7 +14,7 @@
 
 INC_FLAGS = -I$(MULTIVERSO_INC)
 LD_FLAGS  = -L$(MULTIVERSO_LIB) -lmultiverso
-LD_FLAGS += -L$(THIRD_PARTY_LIB) -lzmq -lmpich -lmpl
+LD_FLAGS += -L$(THIRD_PARTY_LIB) -Wl,-Bstatic -lzmq -lmpich -lmpl dw
 LD_FLAGS += -lpthread
   	  	
 WORD_EMBEDDING_HEADERS = $(shell find $(PROJECT)/src -type f -name "*.h")
```

ビルドします。

```
$ make
```

ビルドが終わると bin ディレクトリの下に実行ファイルが作られています。