1. Koutaru

    Posted

    Koutaru
Changes in title
+Proxyの影響下のUbuntu 18.04でKeras on TensorFlow with GPU on NVIDIA Docker !!
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,313 @@
+# 前書き
+
+このドキュメントはhttp://geotaru.hatenablog.com/entry/2018/07/06/153208 の改正版です。
+
+20180803現在、Ubuntu 18.04ではCUDA9.1をインストールできますが、下記リンクによるとTensorFlowの最新版はCUDA 9.0に対応しています。Ubuntu18.04にCUDA 9.0を入れるのはなんだかめんどくさそう...
+
+https://www.tensorflow.org/install/install_linux#NVIDIARequirements
+
+TensorFlowのアップデートを待とうと考えていますが、Dockerを使って楽に環境構築する方法を確立したので共有します。Dockerのオーバヘッドが小さいなら、環境が汚れないからこの方法を維持するのがいいのではないでしょうか?
+
+# Keras on TensorFlow with GPUを使えるようにする
+
+## Overview
+手順を簡単に説明すると
+
+* NVIDIA DriverをホストマシンのUbuntu 18.04にインストール
+* Dockerをインストール
+* NVIDIA Dockerをインストール
+* GitHubまたはBitbucketのリポジトリにDockerfileを置く
+* DockerHubと上のリポジトリを連携させる(Automated Build)
+* Dockerfileからイメージをダウンロードして起動
+
+## Pros/Cons
+
+### 利点
+* 安定したバージョンのCUDAを使える
+* 環境を持ち運べる
+* CUDAやcudnnをホストマシンにインストールする手間が省ける
+### 欠点
+* Dockerによるオーバーヘッドの発生
+
+## Requirements
+
+* Docker 18.06.0-ce
+* [NVIDIA Docker](https://github.com/NVIDIA/nvidia-docker)
+* Ubuntu 18.04
+* NVIDIA Driver 390.48, 390.77で動作確認済み
+* ネットワーク環境: Proxyの影響下の環境であればProxyの設定をホストマシンにしてください
+
+NVIDIA DriverはUbuntu 18.04なら
+
+```bash
+
+$ sudo ubuntu-drivers autoinstall
+```
+で簡単にインストールできます
+
+### Dockerグループにユーザを追加
+
+Dockerをsudoなしで使うためのコマンドを実行
+しなくても良いがすると楽。
+
+```bash
+
+$ sudo gpasswd -a $USER docker
+```
+
+## Quick Start
+
+下記のようなシェルスクリプトを書いて実行!
+実行するとJupyter Notebookが動いているインスタンスが生成されます。
+
+```bash
+
+#!/bin/bash
+
+docker run --runtime=nvidia \
+ -e NVIDIA_VISIBLE_DEVICES=0 \
+ --rm \
+ -p 60000:8888 \
+ -v `pwd`:/notebooks \
+ -v /home/geotaru/data/:/notebooks/data \
+ -it \
+ geotaru/keras-notebook
+```
+
+tokenをコピーしてブラウザを開き、
+"GPUサーバのURL":60000/?token="上のコマンドを実行して表示されたtoken"
+にアクセスすれば親の顔より見たJupyter Notebookが!!
+
+## 上のシェルスクリプトの説明
+
+若干の語弊があるかもしれないですが、だいたいコメントのような意味です。
+
+```bash
+
+#!/bin/bash
+
+docker run --runtime=nvidia \ # NVIDIAのドライバを使用する
+ -e NVIDIA_VISIBLE_DEVICES=0 \ # GPUのID "0,1"とやるとGPUを2本使える(GPUが2本あれば)
+ --rm \ # Dockerのインスタンスをstop時に消す
+ -p 60000:8888 \ # ホストの60000ポートとDockerの8888ポートを繋ぐ
+ -v `pwd`:/notebooks \ # カレントディレクトリをDockerの中の/notebooksディレクトリとする
+ -v /home/geotaru/data/:/notebooks/data \ # 上と同様に
+ -it \ # コマンドラインをインタラクティブにする
+ geotaru/keras-notebook # DockerHubのリポジトリ geotaru/keras-notebookのイメージを使用
+```
+
+## Dockerfile
+私のDocker imageを使用してもいいですが、自分でカスタマイズしたくなるでしょう。
+Dockerfileを書き換えればキーバインドをEmacsにしたりすることもできる上に、好きなライブラリを入れることもできます。
+まず、GitHubまたはBitbucketにリポジトリを作成してそこに下記のようなDockerfileを置きます。
+
+```Docker
+FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
+MAINTAINER geotaru
+
+# 一部のライブラリをインストールするときに
+# スクリプトが止まらないように下記の環境変数を設定する
+ENV DEBIAN_FRONTEND=noninteractive
+
+# Pythonをソースからコンパイルするのに必要なライブラリをインストール
+RUN apt-get update -y && apt-get upgrade -y && \
+apt-get install -y git \
+build-essential \
+graphviz \
+make \
+build-essential \
+libssl-dev \
+zlib1g-dev \
+libbz2-dev \
+libreadline-dev \
+libsqlite3-dev \
+wget \
+curl \
+llvm \
+libncurses5-dev \
+libncursesw5-dev \
+xz-utils \
+tk-dev \
+libffi-dev
+
+# Python
+WORKDIR /opt
+RUN wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz && \
+tar xf Python-3.6.6.tgz
+
+WORKDIR /opt/Python-3.6.6
+RUN ./configure && \
+make && \
+make install && \
+rm /opt/Python-3.6.6.tgz
+
+# 欲しいライブラリをインストール
+RUN pip3 install --upgrade pip && \
+pip3 install numpy \
+scipy \
+pandas \
+h5py \
+scikit-learn \
+imbalanced-learn \
+nose \
+xgboost \
+lightgbm \
+tensorflow-gpu \
+keras \
+seaborn \
+matplotlib \
+plotly \
+jupyter \
+tqdm \
+cython \
+jupyter_contrib_nbextensions \
+pydot \
+graphviz \
+pydot3 \
+pydot-ng \
+folium \
+autopep8 \
+line_profiler \
+memory_profiler \
+rise
+
+# Jupyter NotebookのExtensionの設定
+RUN jupyter contrib nbextension install --user && \
+: "Jupyter NotebookのキーバインドをVim風に設定" && \
+mkdir -p $(jupyter --data-dir)/nbextensions && \
+cd $(jupyter --data-dir)/nbextensions && \
+git clone https://github.com/lambdalisue/jupyter-vim-binding vim_binding && \
+jupyter nbextension enable vim_binding/vim_binding && \
+: "Jupyter Notebookでプレゼンをするためのライブラリ" && \
+jupyter-nbextension install rise --py --sys-prefix && \
+jupyter-nbextension enable rise --py --sys-prefix && \
+: "セルごとに実行時間を測定" && \
+jupyter-nbextension enable execute_time/ExecuteTime && \
+jupyter nbextension enable move_selected_cells/main && \
+jupyter nbextension enable toggle_all_line_numbers/main && \
+jupyter nbextension enable code_prettify/code_prettify && \
+jupyter nbextension enable scratchpad/main
+
+WORKDIR /notebooks
+EXPOSE 8888
+ENTRYPOINT ["jupyter", "notebook", "--no-browser", "--ip=0.0.0.0", "--allow-root"]
+```
+
+### このDockerfileの問題点
+* バージョン固定
+ pip install hogeのところは本当はバージョン固定した方がよいとおもいます。面倒なのでここではやっていませんが。
+
+* Dockerイメージが大きいのでビルドにしか使用していないライブラリは削除したい...
+
+
+## DockerHubを利用する
+
+Proxyの影響下の環境ではProxyの設定が必要で面倒なので(コンテナの中からも通信できるように設定する必要がある)、DockerHub上でビルドすると楽でしょう。Proxyの影響下ではなくても、ビルドが楽になるのでおすすめです。
+
+DockerHubのアカウントを作成して、ホーム画面の右上 create -> Create Automated Buildでさっき作成したリポジトリを指定してください。
+
+詳しくは[Docker docs](http://docs.docker.jp/docker-hub/builds.html)を参照してください。
+ビルドには時間がかかります。
+うまく設定できれば、GitHubやGitBucketのリポジトリが更新されるたびに自動でDockerHub上でDocker imageがビルドされるようになります。
+
+DockerHubをどうしても使用したくないなら、家などProxyのない場所でDocker imageをビルドしてハードディスクに入れて持って来るとか、scpで持って来るとかすれば良いでしょう。
+
+### ビルドできたら...
+
+
+```bash
+
+$ docker pull "DockerHubアカウント名"/"リポジトリ名"
+```
+
+で自分が作ったイメージをダウンロードできる。
+
+最初に書いたようなスクリプトを書いて実行してください。
+
+```run.sh
+#!/bin/bash
+
+docker run --runtime=nvidia \
+ -e NVIDIA_VISIBLE_DEVICES=0 \
+ --rm \
+ -p 60000:8888 \
+ -v `pwd`:/notebooks \
+ -v /home/geotaru/data/:/notebooks/data \
+ -it \
+ geotaru/keras-notebook
+```
+
+```bash
+
+geotaru@gpu-server:~/project/interactive$ chmod +x ./run.sh # 実行権限の付与
+geotaru@gpu-server:~/project/interactive$ ./run.sh
+[I 22:24:12.442 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
+[I 22:24:12.568 NotebookApp] [jupyter_nbextensions_configurator] enabled 0.4.0
+[I 22:24:12.568 NotebookApp] Serving notebooks from local directory: /notebooks
+[I 22:24:12.568 NotebookApp] The Jupyter Notebook is running at:
+[I 22:24:12.568 NotebookApp] http://(f11eb68ebfa1 or 127.0.0.1):8888/?token=01bdb4d77d7f893f35423007968035149360374a6d30e48d
+[I 22:24:12.568 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
+[C 22:24:12.568 NotebookApp]
+
+ Copy/paste this URL into your browser when you connect for the first time,
+ to login with a token:
+ http://(f11eb68ebfa1 or 127.0.0.1):8888/?token=01bdb4d77d7f893f35423007912345649362361b6d30e48d
+```
+
+tokenをコピーしてブラウザを開き、
+
+```
+"GPUサーバのURL":60000/?token=01bdb4d77d7f893f35423007912345649362361b6d30e48d
+```
+
+をURL欄に書いてアクセスするとJupyter Notebookの画面がでます!
+
+# まとめ
+
+NVIDIA DockerとDocker Hubを活用して、Proxy環境下であろうと機械学習の環境構築を簡単にできるようにした。
+
+# おまけ
+
+## 稼動中のDockerのインスタンスを止める方法
+
+```
+$ docker ps -a # どんなインスタンスがあるか確認
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+f9bf6bfc6e68 geotaru/keras-notebook "jupyter notebook --…" 10 seconds ago Up 7 seconds 0.0.0.0:60000->8888/tcp ecstatic_meninsky
+```
+
+上記のインスタンスは--rmオプションで実行しているため、stopするだけでDockerインスタンスが停止し削除される。
+
+```bash
+
+$ docker stop ecstatic_meninsky
+ecstatic_meninsky
+$ docker ps -a # インスタンスがなくなったことを確認
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+```
+
+## 既存のDocker imageを削除する方法
+
+```bash
+
+$ docker ps -a
+```
+
+で削除したいイメージのインスタンス確認する。
+使っているものがあったら、
+
+```bash
+
+$ docker stop "インスタンス名"
+$ docker rm "インスタンス名"
+````
+
+とする。
+削除したいイメージのインスタンスがなければ
+
+```bash
+
+$ docker rmi "イメージの名前"
+```
+
+で破棄できる