Ubuntu Server 18.04をGPU深層学習計算サーバーにするための最小限の設定

~~今やるなら「[Ubuntu Server 19.04 disco をGPU深層学習計算サーバーにするための最小限の設定](https://qiita.com/kakinaguru_zo/items/779ece2bd7235112076b)」を見たほうがいいと思います~~

# GPUと関係ない作業

1. インストーラーではopensshサーバー以外を入れない。現時点では英語でインストールしないとインストーラーがうまく動かないらしい。スワップパーティションとホームパーティションを独立させておけば別バージョンのUbuntuなどでそれらを再利用出来る。alternative installer (debian installer)で最初にF6を押すとエキスパートモードを選ぶことができる。またそこでブートコマンドラインの`ubuntu-server.seed`を`ubuntu-server-minimal.seed`に変えればインストールされるパッケージをより少なくできる。
2. 追加パッケージを入れる
 * `intel-microcode` または `amd-microcode`
 * `build-essential`
 * `language-pack-ja-base` で `ja_JP.UTF-8` ロケールが入り、一部のメッセージの日本語版も入る。システムのデフォルト言語は英語のまま
 * `mdns` (ドメイン名が `.local` で終わるもの) を使いたい場合は `avahi-daemon` をインストールする
 * `exim4-daemon-light` などのメール配送ソフトを使いたい場合は入れておく
 * `/etc/aliases` を書き換えて `newaliases` を実行する
 * `pam-auth-update` を実行して必要なモジュールを入れる（例えばログイン時のホームディレクトリ作成など）
 * `/etc/update-motd.d/` に必要なメッセージを置く。詳細は`man update-motd`
 * `smartmontools` をインストールし`/etc/update-motd.d/`のスクリプトに`if ! smartctl -l xselftest,selftest -l xerror,error -T conservative -q silent /dev/sda; then echo "smartctlが異常なので大至急管理者を読んで下さい"; fi` を追加する。 `/etc/smartd.conf` を適切に設定する、例えば `/dev/sda -a -o on -S on -s (S/../.././02|L/../../6/03) -m root` など
 * `acpi` をインストールし、`/etc/update-motd.d/`のスクリプトに `acpi -t` を追加する
 * `/lib/systemd/set-cpufreq` を書き換えて `/sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference` を好きなモードに設定する
 * `emacs25` (必要なら)
 * `nis` (必要なら), `/etc/nsswitch.conf`, `/etc/yp.conf` の設定をする。わからなければ`man`を見る。`nis`を入れてNISクライアントとして用いるときは`unscd`もインストールしないとログイン時に25秒固まるようになる。
 * `systemd-run --user`を使うなら`dbus-user-session`を入れる必要がある。
3. `crontab -u root -e` で実行すること
 *  renice -n 19 -p \`pgrep '^python3|^caffe'\` (ディープラーニングのプロセスの優先度を下げる)
4. `systemctl --state=running list-units` を実行して不要なパッケージ見つけて、削除する。例えば `apt-get --purge remove open-iscsi lvm2 lxcfs snapd` そのあとに `apt-get --purge autoremove` する
5. `/etc/fstab` についてネットワーク経由でアクセスするNFSやCIFSには`fstab` のオプションとして `_netdev` を付ける。起動時にマウントしない場合は `noauto` を付け、一般ユーザーのマウントを許可するときは `user` を付ける。マウント出来なくても問題なく起動出来るマウントポイントには`nofail`を付ける。マウントにタイムアウトを設定したいときは`x-systemd.mount-timeout=何秒`を付ける。

# GPUそのものを使うための作業
1. `add-apt-repository ppa:graphics-drivers/ppa`
2. `apt-get update`
3. `apt-get install ubuntu-drivers-common`
4. `ubuntu-drivers devices` を実行してインストールドライバ候補が妥当なら`ubuntu-drivers autoinstall`でインストールする。余計なものをなるべく入れたくない場合は `apt-get --no-install-recommends install` を用いる
5. `nvidia-smi --ecc-config=1` を用いてGPUメモリー誤り訂正機能を有効にする(QuadoroとTeslaのみ)

# 深層学習フレームワークのインストール
## Python関係共通
1. `apt-get install jupyter-notebook python3-pip python3-ipywidgets  python3-setuptools python3-wheel; pip3 install -U setuptools wheel`

## CUDAバージョンについて
Ubuntu 18.04に付属するCUDAは9.1であり、`caffe-cuda`, `python3-theano`, `python3-pycuda`などがそのCUDA 9.1に依存している。一方tensorflow-gpuやTensorRTはCUDA9.0を推奨していているし、最近のNVIDIAのレポジトリを見るとCUDA9.0とCUDA9.2に対するバイナリだけ置いてあってCUDA9.1は棄てられるように見える。NVIDIA TensorRTは2018年5月末の時点ではCUDA9.0でしか使えない。

## Caffe
1. `apt-get install caffe-cuda` これで依存関係によりCUDA9.1の一部もインストールされる

## Tensorflow 1.8
Ubuntuレポジトリに標準で入っているCUDAは9.1でtensorflow 1.8バイナリが期待するバージョンではない。そこで、CUDA 9.0の共有ライブラリ(`.so`を含むファイル)だけ抜き出してインストールすることにする
1. `wget https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda-repo-ubuntu1704-9-0-local_9.0.176-1_amd64-deb` でCUDA 9.0の`.deb` ファイルをNVIDIAから持ってくる
2. `dpkg -X 上でダウンロードしたファイル /tmp` として/tmpに.debファイルを展開する
3. /tmpに展開されたファイルから `.so` を含むファイルをすべて `/usr/lib/x86_64-linux-gnu` に `mv` する。シンボリックリンクをシンボリックリンクとして移動するように注意する。それ以外のファイルは無視する。
4. CuDNNやNCCLをインストールするために `https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/` から関連する`.deb`ファイルを持ってきて、上記の手順で必要な`.so`を含むファイルだけを`/usr/lib/x86_64-linux-gnu` に `mv` する。
5. `ldconfig`を実行する
6. `pip3 install -U matplotlib tensorflow-gpu; apt-get install libgomp1`

## Chainer
1. 上記のtensorflowのための共有ライブラリの用意を行う
2. `pip3 install cupy-cuda90 chainer`

## Keras 2.1.6以降
1. `apt-get install graphviz libgts-bin python3-pil python3-h5py`
2. `pip3 install -U pydot graphviz keras`