こんにちは、chlochanです。Ubuntu 18.04 + CUDA10 に移行したのですが、RStudio で Keras を実行する場合、CUDA9.0 の環境が必要なため、nvidia-docker2 を使って Ubuntu16.04 + CUDA9.0 の環境を作りその上で RStudio を実行する事にします。
docker をインストールする
まず docker をインストールします。
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
インストール出来たか確認してみます。
$ sudo docker container run hello-world
$ sudo docker image
$ sudo docker ps -a
問題なければ コンテナとdockerイメージを削除します。
$ sudo docker rm $(sudo docker ps -aq)
$ sudo docker rmi hello-world
nvidia-docker2 をインストールする
現在、GPUを使うディープラーニング用のツール類は、CUDAのバージョンに依存しています。たとえば TensorFlow Ver1.12 の コンパイル済みバイナリーイメージ は、CUDA9.0 のライブラリが無いと実行時にエラーとなります。この状況は、TensorFlow Ver2 が出るとまた変化すると思われます。また RStudio で Keras を実行する場合も、CUDA9.0 のライブラリが必要です。よって、使いたいツールが要求するバージョンの CUDA Toolkit をインストールする必要があります。nvidia-docker2 は、Docker のコンテナランタイムで、これを使うと、ホストOS の CUDA Driver を最新のものにしておけば、コンテナ毎に異なるバージョン の CUDA Toolkit を使う事ができる様になり、ディープラーニング用のツール類の運用が非常に楽になります。
以下の Quickstart に従ってインストールします。
https://github.com/NVIDIA/nvidia-docker
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
$ sudo apt-get update
$ sudo apt-get install -y nvidia-docker2
$ sudo pkill -SIGHUP dockerd
以下をみたところ、9.0-cudnn7-devel が CUDA9.0 のすべてをインストールするイメージなので、それで動作確認してみます。
https://hub.docker.com/r/nvidia/cuda/
$ sudo docker container run --runtime=nvidia --rm nvidia/cuda:9.0-cudnn7-devel nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176
V9.0.176 になっている事を確認します。
問題なければ コンテナとdockerイメージを削除します。
$ sudo docker rm $(sudo docker ps -aq)
$ sudo docker rmi nvidia/cuda:9.0-cudnn7-devel
##Rocker Project の Dockerfile を調べて作成方針を決める
nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04 をベースにライブラリやアプリを追加したイメージを作ります。
ネットで検索したところ、R/RStudio の docker イメージ として、
[Rocker Project] (https://hub.docker.com/u/rocker/)
というのがありましたのでこれを流用します。githubからソースを持ってきます。
$ git clone https://github.com/rocker-org/rocker-versioned.git
$ git clone https://github.com/rocker-org/shiny.git
ここで用意されているイメージの docker file のFROM行を調べたところ、以下の様になっていました。
FROM debian:stretch
FROM rocker/r-ver:devel
FROM rocker/rstudio:devel
FROM rocker/tidyverse:devel
FROM rocker/r-ver:devel
上記より、イメージの階層は下記の様になっています。
debian:stretch ⇒ r-ver ⇒ rstudio ⇒ tidyverse ⇒ verse
debian:stretch ⇒ r-ver ⇒ shiny
rocker リポジトリでは r-ver が最下層で、debian:stretch をベースイメージとしています。
この最下層の r-ver のベースとなるイメージの debian:stretch を nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04 に入れ替えたバージョンをつくり、最終的に、rocker/verse と同等となる docker イメージを作ります。階層は以下の様に、shinyを間に入れる事にします。
cuda:9.0-cudnn7-devel-ubuntu16.04 ⇒ r-ver ⇒ shiny ⇒ rstudio ⇒ tidyverse ⇒ verse
##Dockerfile を作成する
方針が決まったので、Dockerfile を作成していきます。まず、rocker/r-ver の FROM 行を以下の様に入れ替えたバージョンを作ります。リポジトリの名称は、c9rocker としてみました。
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
... 以下は rocker/r-ver と基本的に同じなので略 (書き換え必要なライブラリが3個あり) ...
ディストリビューションを debian:stretch から ubuntu16.04 に変更するにあたり、以下の書き換えが必要でした。
libicu57 ⇒ libicu55
libjpeg62-turbo ⇒ libjpeg62
libreadline7 ⇒ libreadline6
Dockerfileの該当の3箇所を書き換えます。上位の階層も同様に作っていきます。shiny の変更箇所は FROM行だけです。
FROM c9rocker/r-ver:latest
... 以下は rocker/shiny と全く同じなので略 ...
rstudio の変更箇所は、FROM行の変更の他に、libssl1.0.0.deb のダウンロード元の変更と、Keras の実行に必要なRUNコマンドの追加があります。
FROM c9rocker/shiny:latest
... libssl1.0.0.deb に関係する部分までは rocker/rstudio と全く同じなので略 ...
&& wget -O libssl1.0.0.deb http://security.ubuntu.com/ubuntu/pool/main/o/openssl/\
libssl1.0.0_1.0.2g-1ubuntu4.14_amd64.deb \
... RUNコマンドを追加します ...
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get install python-pip
RUN apt-get install python-virtualenv
... 以下は rocker/rstudio と全く同じなので略 ...
上記の様に、ディストリビューションを debian:stretch から ubuntu16.04 に変更したことから、rstudio の Dockerfile 中で、libssl1.0.0.deb の入力先とファイル名を以下の様に変更しました。変更しないとエラーになります。
http://ftp.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u8_amd64.deb
↓
http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu4.14_amd64.deb
tidyverse と verse の変更箇所は FROM行だけです。
FROM c9rocker/rstudio:latest
... 以下は rocker/tidyverse と全く同じなので略 ...
FROM c9rocker/tidyverse:latest
... 以下は rocker/tidyverse と全く同じなので略 ...
dockerイメージをビルドする時にコピーされるファイルを用意する
GitHubからクローンした rocker-versioned/rstudio の中の sh ファイルを ./rstudio ディレクトリに持ってきて実行属性を追加します。また、disable_auth_rserver.conf ファイルも持ってきます。下記コマンドの前提条件として、一個上のディレクトリに rocker-versioned をクローンしてあるものとします。また rstudio の Dockerfile は ./rstudio にあるものとします。
$ cp ../rocker-versioned/rstudio/disable_auth_rserver.conf ./rstudio
$ cp ../rocker-versioned/rstudio/*.sh ./rstudio
$ chmod +x ./rstudio/*sh
同様に、GitHubからクローンした rocker/shiny の中の shiny-server.sh ファイルを ./shiny ディレクトリに持ってきて実行属性を追加します。
$ cp ../shiny/shiny-server.sh ./shiny
$ chmod +x ./shiny/*sh
dockerイメージをビルドする
dockerイメージを下層から順番にビルドします。ディレクトリ c9rocker でイメージをビルドします。tidyverse はかなり時間がかかります。
$ sudo docker image build -t c9rocker/r-ver:latest ./r-ver
$ sudo docker image build -t c9rocker/shiny:latest ./shiny
$ sudo docker image build -t c9rocker/rstudio:latest ./rstudio
$ sudo docker image build -t c9rocker/tidyverse:latest ./tidyverse
$ sudo docker image build -t c9rocker/verse:latest ./verse
dockerイメージが出来ていることを確認します。
$ sudo docker image ls
Dockerfile 中の文法ミスなどでイメージ作成の失敗を繰り返すと、中途半端なコンテナが沢山出来てしまっている事があります。よってコンテナを一旦全部削除します。
$ sudo docker rm $(sudo docker ps -aq)
コンテナを起動する
c9rocker/verse:latest を起動します。なお、起動時のコマンドで RStudio にログインする時のパスワードを設定します。<YOUR_PASS>
の部分を自分の好きなパスワードに置き換えて実行します。なお、'rstudio' 以外のパスワードにする必要があります。
$ chmod 777 ~/Downloads
$ sudo docker run --runtime=nvidia -v ~/Downloads:/home/rstudio/Downloads \
-e PASSWORD=<YOUR_PASS> -d -p 3838:3838 -p 8787:8787 c9rocker/verse:latest
上記の例では、ホスト側のディレクトリ ~/Downloads を、コンテナ側のディレクトリ /home/rstudio/Downloads とRW可能で共有しています。また、shiny と RStudio のポートを両方そのままホスト側にフォワードしています。 "-d" を指定することでバックグラウンドで起動します。
コンテナが起動出来たか確認してみます。
$ sudo docker ps -a
RStudio にログインする
起動出来ていたら、既に外部から接続できる様になっています。ファイアウォールでポート3838と8787を開けます。そして、
http://外部IPアドレス:8787
で、手元のブラウザからアクセスすると RStudioに接続できます。RStudioのログイン画面がでたら、ログインします。ユーザー名 rstudio 、パスワードはコンテナ起動時に設定したパスワードでログインします。同様に shiny にはポート3838で接続できます。
次に、c9rocker/verse:latest に、Keras と tensorflow をインストールします。
必要なライブラリをインストールする
RStudioにログインして、サンプルコードを実行する時に必要なライブラリをまずインストールします。
install.packages("gridExtra")
install.packages("magick")
install.packages("viridis")
install.packages("hashFunction")
次にKerasをインストールします。
Keras をインストールする
R版 の Keras は GitHub の、R interface to Keras で公開されています。
RStudio にログインして、Keras と tensorflow-gpu をインストールします。以下を実行します。
library(devtools)
devtools::install_github("rstudio/keras")
library(keras)
install_keras(tensorflow = "gpu")
上記で、Keras と同時に tensorflow-gpu バックエンドもインストールしています。2018/12/9 時点で、実行後、RStudio の Packages の Version には、2.2.4 が表示されました。
サンプルプログラムをダウンロードして実行する
GitHubから下記の教科書のサンプルプログラムをダウンロードして実行します。
RとKerasによるディープラーニング
$ git clone https://github.com/jjallaire/deep-learning-with-r-notebooks.git
GPU の utilization を確認する
サンプルコード実行中に、GPU の utilization を確認するには、別ウインドウを開いて以下を実行します。以下の例では1秒毎に表示が更新されます。
$ watch -n 1 nvidia-smi -a --display=utilization
コンテナの停止
コンテナを停止します。
$ sudo docker stop $(sudo docker ps -q)
コンテナが停止出来たか確認してみます。
$ sudo docker ps -a
以上です。