Docker上でTensorflowを動かす

# 目的
松尾研が公開しているDeep Learning実践開発講座（DL4US）公開用リポジトリで深層学習の勉強をするため、Dockerでその環境構築を行う。
（面倒な人はGoogle Colaboratoryを使えばいい）

# 環境
- Intel Core i5 9400F
- NVIDIA GTX1660Ti
- Ubuntu 18.04
- セキュアブート無効済み（有効でもインストールできたが、念のため）

# Nvidia-driverのインストール
以下のコマンドでインストールする方法もあるが、私の環境では正常にインストールできなかったため、nvidia公式から直でインストールする。

```bash
sudo ubuntu-drivers autoinstall
```

[こちら](https://qiita.com/ohta6/items/684b9ecd4d67a52e5a7f)を参考にインストール
gccとmakeが必要
1. Nvidia公式からドライバをダウンロード
2. nouveauを無効化
3. ランレベルを3にする
4. ドライバインストール

## Nvidia公式からドライバをダウンロード
https://www.nvidia.co.jp/Download/index.aspx?lang=jp から落とす
私が落としたのはNVIDIA-Linux-x86_64-430.14.runだった

## nouveauを無効化
```bash
sudo su -
cd /etc/modprobe.d/
touch blacklist-nvidia-nouveau.conf
```
```blacklist-nvidia-nouveau.conf
options nouveau modeset=0
```
```bash
update-initramfs -u
reboot
```
```bash
lsmod | grep -i nouveau
```
で何も出力されなければnouveauが無効化されている。

## ランレベルを3にする
```bash
sudo telinit 3
```
Ctrl+Alt+F1でtty1に移動し、先程ダウンロードしたドライバのディレクトリに移動する

## ドライバインストール
```
sudo bash NVIDIA-Linux-x86_64-430.14.run
```
nvidiaドライバの対話的なインストールが始まる。
基本的にデフォルトの選択肢を選んでインストールすればよい．
私の場合、はじめにPre-installが失敗しました的な表示がされたが無視してインストールしたところ、正常にインストールされてしまった
また、gccのバージョンがnvidiaドライバのそれと異なると怒られたが、これも特に問題はなかった

## ドライバ正常インストールの確認
```bash
puri@Dorothy:~/docker/dl4us$ nvidia-smi
Sun Jun  2 20:54:40 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 430.14       Driver Version: 430.14       CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| 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 GTX 166...  Off  | 00000000:01:00.0  On |                  N/A |
| 41%   35C    P8    15W / 120W |   1124MiB /  5941MiB |     14%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1658      G   /usr/lib/xorg/Xorg                            40MiB |
|    0      1701      G   /usr/bin/gnome-shell                          48MiB |
|    0      4080      G   /usr/lib/xorg/Xorg                           667MiB |
|    0      4210      G   /usr/bin/gnome-shell                         254MiB |
|    0     17646      G   ...uest-channel-token=10238543940149882084   111MiB |
+-----------------------------------------------------------------------------+
```
こんな感じでGPUが見えればok.

## よくあるトラブル
- 再起動したらNVIDIAドライバが壊れる
    - 上記手順の「ランレベル3変更」のステップから，インストールを実行する~~（は？？？）~~

# Docker
1. nvidia-docker2導入
2. イメージ作成
3. jupyter notebook起動

## Dockerインストール
[公式](http://docs.docker.jp/engine/installation/linux/docker-ce/ubuntu.html)を参考にインストール

## nvidia-docker インストール
[公式github](https://github.com/NVIDIA/nvidia-docker)のQuickstartを参考にする

## イメージ作成
ベースイメージはtensorflow:latest-gpu-py3-jupyterを使用した
まずはDockerfileを作成
途中の`RUN ln -s /usr/lib/x86_64-linux-gnu/libcudnn.so.7.4.1 /usr/lib/x86_64-linux-gnu/libcudnn.so`は、cuDNN 7.4の内部でライブラリが正しく参照されないバグが存在するため、それに対するworkaroundである。

```Dockerfile
FROM tensorflow/tensorflow:latest-gpu-py3-jupyter
RUN apt-get update && apt-get install -y git graphviz build-essential cmake vim
COPY ${PWD}/mount/requirements.txt /tf
COPY ${PWD}/mount/jupyter_notebook_config.py /root/.jupyter/
RUN pip install -r requirements.txt
RUN ln -s /usr/lib/x86_64-linux-gnu/libcudnn.so.7.4.1 /usr/lib/x86_64-linux-gnu/libcudnn.so
RUN git clone https://github.com/matsuolab-edu/dl4us.git
```

ビルドする

```bash
docker build . -t dl4us
```

コンテナを作成・起動

```bash
docker run -it -p 8888:8888 -v ${PWD}/mount:/mnt/host --name "laala" dl4us bash
```

ホスト側のブラウザでlocalhost:8888にアクセスするとjupyter notebookの画面が見られるはず
あとはお勉強するだけ