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

Ubuntu 19.04 Disco Dingo はUbuntu標準のレポジトリにNVIDIAの新しいドライバとCUDA 10.0が入っているから、tensorflow 1.13.1を使うために必要な作業が少なくて済む。Ubuntuがアホだから、19.04リリース時にCUDA 10.1をバンドルしやがったので以下の話は使えません！

# GPUと関係ない作業

1. [http://cdimage.ubuntu.com/ubuntu-server/daily/current/](http://cdimage.ubuntu.com/ubuntu-server/daily/current/) からダウンロードする。
2. インストーラーの一番最初の言語選択肢では「English」を選ぶ。そのあと「F6」を押して「Other Options」を選び、「Expert mode」にチェックを入れるとともに、ブートローダーのオプションの`ubuntu-server.seed`を`ubuntu-server-minimal.seed`に変更する（これは好みなのでそうしなくてもよい） ![インストーラー初期画面](https://www.server-world.info/Ubuntu_18.04/install/img/1.png)
3. なぜか上記の画面が出なくて通常のgrubの画面が出ることがあるので、その場合カーソルを「Install Ubuntu Server」に合わせてから `e` を押して起動オプションを編集する。`ubuntu-server.seed`を`ubuntu-server-minimal.seed`に変更するとともに`priority=low` を追加してexpert modeにする。編集を終えたらF10を押してインストーラーを起動する。
4. インストーラーのLinuxが起動するともう一度言語を聞かれるが今度は「日本語」を選んで問題ない。そのあと適切にインストールする。入れるパッケージを最小化したい場合インストーラーが追加のコンポーネントを入れないようにする。
5. インストールしたUbuntuが起動したら最初に `/etc/apt/apt.conf.d/01norecommends` に`APT::Install-Recommends 0;` を書いて余計なパッケージが入らないようにする（これも好み）
6. `dpkg-reconfigure debconf` を実行し、パッケージインストール時にどの程度細かい質問を無視するか再設定する
7. 追加パッケージを入れる
 * `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` など
 * `emacs-nox` (必要なら)
 * `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` する（上記でインストーラーで　`ubuntu-server-minimal.seed` を選ぶとこういう要らないアプリが入らない）
5. `/etc/fstab` についてネットワーク経由でアクセスするNFSやCIFSには`fstab` のオプションとして `_netdev` を付ける。起動時にマウントしない場合は `noauto` を付け、一般ユーザーのマウントを許可するときは `user` を付ける。マウント出来なくても問題なく起動出来るマウントポイントには`nofail`を付ける。マウントにタイムアウトを設定したいときは`x-systemd.mount-timeout=何秒`を付ける。

# GPUそのものを使うための作業
1. （`add-apt-repository ppa:graphics-drivers/ppa` はUbuntu 19.04 Disco Dingoの標準レポジトリに新しいGPUドライバが入っているから不要（2019年3月現在））
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 pip`

## CUDAバージョンについて
Ubuntu 19.04に付属するCUDAは10.0である。

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

## Tensorflow 1.13.1
Ubuntu 19.04レポジトリに標準で入っているCUDAは10.0でtensorflow 1.13バイナリが期待するバージョンであるから、普通にCUDAライブラリをインストールすればよい。
1. `apt-get install libaccinj64-10.0 libcublas10.0 libcudart10.0 libcufft10.0 libcufftw10.0 libcuinj64-10.0 libcupti10.0 libcurand10.0 libcusolver10.0 libcusparse10.0 libnppc10.0 libnppial10.0 libnppicc10.0 libnppicom10.0 libnppidei10.0 libnppif10.0 libnppig10.0 libnppim10.0 libnppist10.0 libnppisu10.0 libnppitc10.0 libnpps10.0 libnvblas10.0 libnvgraph10.0 libnvjpeg10.0 libnvrtc10.0 libnvtoolsext1 libnvvm3`
2. [http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/](http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/) からCUDA10.0で使える `libcudnn7` と `libnccl2` の一番新しいバージョンを持ってきて、 `.deb` ファイルを `dpkg -X` で展開し、その中に入っている `.so` ファイルを`/usr/lib/x86_64-linux-gnu/` に`mv`する
3. `ldconfig` を実行する。
4. `pip3 install -U matplotlib tensorflow-gpu; apt-get install libgomp1`
5. `python3 -c "import tensorflow as tf; tf.enable_eager_execution(); print(tf.reduce_sum(tf.random_normal([1000, 1000])))"` で動作確認する

## Chainer
1. 上記のtensorflowのための共有ライブラリの用意を行う（ただしlibncclとlibcudnn7はcupyに含まれているから不要）
2. `pip3 install -U cupy-cuda100 chainer`

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

## pytorch
[https://pytorch.org/get-started/locally/](https://pytorch.org/get-started/locally/) に行くとインストールするためのコマンドを教えてくれる