UbuntuにGPU対応の機械学習環境を入れた時のメモ

KaggleのKernelを手元で動かそうとした時に色々とハマったので最終的に辿り着いた環境へ至るまでのメモです。

最終的にどうすれば良いのかだけ読みたい人は[こちら](#まとめ)からどうぞ

## 開始時の環境

Ubuntu 18.04 LTS
Python3.7(Anacondaからインストール)
CUDA10
GeForce RTX 2080

## TensorflowがCUDA10で動かない

最初はAnacondaを入れて必要なライブラリを適宜インストールしたりしていました。
全部pip installとかconda installとかでなんとかなるだろうと思っていたのですが、gpu対応のtensorflowをインストールしようとした段階で、ローカルにインストールされているCUDAのバージョン（10）と　tensorflowが必要としているCUDAのバージョン(9)が違うことが原因で上手くインストールできませんでした。
この問題はこちらを参考にして手動でビルド＆インストールを行い解決しました。
https://www.pytorials.com/how-to-install-tensorflow-gpu-with-cuda-10-0-for-python-on-ubuntu/
この時Python3.7だとビルドが通らなかったので3.6.6にダウングレードしました。

## fbprophetが動かない
たぶんこのあたりのissue( https://github.com/facebook/prophet/issues/775 )と同じようなエラーで、こちらでは0.3.post2にダウングレードすることで解決したとか、キャッシュなしで全部インストールし直せば解決するとか書いていましたが全然解決せず、このあたりで素直にnvidia-docker2を使うかーとを考え始めました。


## 良い感じのDockerfileを探す
最初はDockerhubに公開されているGPU対応のtensorflowのイメージを使ってみたのですが、これもホスト側のCUDAを使うからなのか何なのか原因は分かりませんでしたが動きませんでした。
https://hub.docker.com/r/tensorflow/tensorflow

そこで、nvidia/cuda ( https://hub.docker.com/r/nvidia/cuda/ )をベースにして、CUDAやCuDNNのバージョンを指定し、そこから色々インストールすれば良いのでは？と思ったのですが、自分でDockerfileを書くのがめんどくさかったので、必要なものが一通り入っていてとりあえず動かせるものを探しました。

そこで発見したのがこちらなのですが、GPU対応のtensorflowは動いたものの、追加でインストールしてみたfbprophetは相変わらず動きませんでした。
https://qiita.com/Koutaru/items/1ad3c321aa04d21f485d

## Kaggleの公式イメージを発見する

発生した問題で都度ググっていたらKaggleの公式githubリポジトリに辿り着きました。
https://github.com/Kaggle/docker-python
このリポジトリのDockerfileとかDockerfile.gpu読んでみると必要なものが全部入ってそうなのでもうこれでいいじゃないかと思いとりあえずビルドしてみました。
fbprophetの挙動を確認したところ問題なく動き、一息ついたのも束の間、今度はtensorflow実行時にgpu周りでエラーが出てきました。
nvidia-smiコマンドを実行したところCUDAのバージョン番号のところにエラーとか出てるし何かおかしいと思いissueを漁っていたらこちらのissueに辿り着き、LD_LIBRARY_PATHを書き換えて無事すべてが解決しました。
https://github.com/Kaggle/docker-python/issues/361#issuecomment-448093930

##　まとめ

最初からnvidia-docker2+Kaggleの公式Dockerイメージを使うべきだった。

最終的に利用しているDockerfileとdocker-compose.ymlを置いておきます。
kaggle/python-gpu-buildに関してはKaggleのリポジトリからcloneして自分でビルドしてください。

```Dockerfile:Dockerfile
FROM kaggle/python-gpu-build

# TensorBoard
EXPOSE 6006
# IPython
EXPOSE 8888
WORKDIR "/notebooks"
ENV LD_LIBRARY_PATH="/usr/local/cuda/lib64"
CMD jupyter notebook --no-browser --ip="0.0.0.0" --notebook-dir=/notebooks --allow-root
```

```yaml:docker-compose.yml
version: '2.3'
services:
  app:
    build: .
    volumes:
      - .:/notebooks
      - /path/to/your/input:/input
    runtime: nvidia
    ports:
      - "8888:8888"
      - "6006:6006"
```


---- 

追記：ホスト側にCUDA10が入っているせいなのか何なのかPytorchでRuntimeError: CUDNN_STATUS_EXECUTION_FAILEDが出たので
conda install pytorch torchvision cuda100 -c pytorch
を実行しとりあえず解決しました。
ちなみにコンテナ側でnvcc -Vするとこんな感じで

```
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Tue_Jun_12_23:07:04_CDT_2018
Cuda compilation tools, release 9.2, V9.2.148
```
nvidia-smiするとこんな感じでした。

```
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.79       Driver Version: 410.79       CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce RTX 2080    Off  | 00000000:01:00.0  On |                  N/A |
| 35%   35C    P2   191W / 245W |   2348MiB /  7949MiB |     21%      Default |
+-------------------------------+----------------------+----------------------+
```