数理的手法を使いやすくするためのソフトウェア開発

科学技術計算とデータサイエンスについて

Docker で TensorFlow を Ubuntu 16.04 にインストール

職場では Anaconda で TensorFlow をインストール^1 したのですが、自宅では Docker でやってみました^2 ^3。やってみるまで、Anaconda, Docker の何が良くて、どのように使い分けるのか良く分かっていませんでした。なので実践から。

自宅PCはグラフィックボード AMD Radeon HD 7770 を積んでいて、SC15でRadeonでCUDAを使えるようにするよと発表^7 ^8があったと聞いているのですが、まずは、GPUなしでと、CPU版をインストールしました。

Dockerの入門的知識は必要

いきなり、Docker をインストールして、TensorFlowコンテナを実行してみると、いろいろとおかしなことが起きました。

やはり、最低限の知識として、Docker のイメージ・コンテナ管理の基本と、イメージのビルド方法くらいは必要です。今思うと、

Docker入門 – コンテナ型の仮想化技術の解説 ^4

の Quick Start -> Try it! と、

「さわって理解するDocker入門」オージス総研 大西 洋平 ^5

の第1回、第2回くらい、あるいは、

@IT > いまさら聞けないDocker入門 ^6

の第1-3回くらいを、読んでから取り掛かったほうが、早く出来たのかもしれません。

Docker をインストール

まず、必要なパッケージをインストールしました。

$ sudo apt-get update
$ sudo apt-get install -y --no-install-recommends \
    linux-image-extra-$(uname -r) \
    linux-image-extra-virtual
$ sudo apt-get -y --no-install-recommends install curl \
    apt-transport-https \
    ca-certificates \
    software-properties-common

次は、レポジトリをセットアップ。まずはDockerのオフィシャルGPG keyを追加しました。

$ curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -
OK

Key IDの検証。

$ apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D
pub   4096R/2C52609D 2015-07-14
      フィンガー・プリント = 5811 8E89 F3A9 1289 7C07  0ADB F762 2157 2C52 609D
uid                  Docker Release Tool (releasedocker) <docker@docker.com>

安定版のレポジトリをセットアップ。

$ sudo add-apt-repository \
       "deb https://apt.dockerproject.org/repo/ \
       ubuntu-$(lsb_release -cs) \
       main"

これで、Dockerをインストールできるようになりました。あとは、

$ sudo apt-get -y install docker-engine

で docker-engine_17.04.0~ce-0~ubuntu-xenial_amd64.deb が入りました。

しかし、このままでは Docker を実行するためのスーパーユーザー権限が必要なので、、Ask ubuntu: problem with docker

After installing Docker you are prompted to add your user to the docker group. Simply run the command shown:

sudo usermod -aG docker $USER
You will need to close your session and log in again to have the change take effect.

にしたがって、sudo usermod -aG docker $USER を実行して、ログアウトして、ログインしました。すると、

$ docker version
Client:
 Version:      17.04.0-ce
 API version:  1.28
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:07:42 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.04.0-ce
 API version:  1.28 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   4845c56
 Built:        Mon Apr  3 18:07:42 2017
 OS/Arch:      linux/amd64
 Experimental: false

のように問題なく version コマンドを実行できました。

TensorFlowコンテナを生成・実行

CPU安定版のDocker イメージからコンテナを生成させて、実行しました。

$ docker run -it -p 8888:8888 tensorflow/tensorflow
Unable to find image 'tensorflow/tensorflow:latest' locally
latest: Pulling from tensorflow/tensorflow
   ;

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=(毎回、生成されるトークン)

で、最後に表示された「http://localhost:8888/?token=(毎回、生成されるトークン)」にブラウザでアクセスしてみました。

すると、図1のようにJupyter notebook が使えるようになりました。

図1: Jupyter notebook の画面(「TensorFlowが動作するDockerの開発環境を構築する」 ^3からの引用)

ただ、1_hello_tensorflow.ipynb を開いてみると、

Notebook validation failed

An invalid notebook may not function properly. The validation error was:
Notebook validation failed: Additional properties are not allowed (u'metadata' was unexpected):
{
 "output_type": "stream", 
 "text": "result:  [ 3.  3.  3.  3.]\n", 
 "name": "stdout", 
 "metadata": {}
}

というダイアログボックスがポップアップしました。何なのだ?

ともあれ、File -> New Notebook (python 2) で、 サンプルスクリプト

import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a+b))

を実行すると、

Hello, TensorFlow!
42

と結果が返ってきました。

ファイル名を sample.ipynb として、 File -> Save and Checkpoint として、ブラウザのタブを閉じて、再び、sample.ipynb を開いてみました。

こんどは、妙なダイアログボックスはポップアップしませんでした。 他のファイル、2_getting_started.ipynb 、 3_mnist_from_scratch.ipynb でも妙なダイアログボックスはポップアップしませんでした。ただ、1_hello_tensorflow.ipynb を開いてみると、今度も妙なダイアログボックスが。

よくわかりませんが、1_hello_tensorflow.ipynb だけのことなので、次に進みます。

Docker コンテナの停止と再スタート

Dockerコンテナを実行したターミナルで、Ctrl+C で、プロセスを止めました。

ps -a コマンドで、コンテナIDを調べて、startコマンドで再スタートさせました。(再スタートのコマンド名は start 、まぎらわしい。。)

$ docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                     PORTS               NAMES
6a5ed12e18e1        tensorflow/tensorflow   "/run_jupyter.sh -..."   12 minutes ago      Exited (0) 5 minutes ago                       hardcore_goldwasser
$ docker start -i 6a5ed12e18e1

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=(毎回、生成されるトークン)

http://localhost:8888/?token=(毎回、生成されるトークン)」にアクセスしてみると、 sample.py が前に保存にしたとおりの内容で残っていました。

Dockerイメージ作成

このコンテナを再びCtrl+Cで止めて、新しいDocker イメージをtfplussampleという名前で作ってみました。

$ docker commit 6a5ed12e18e1 tfplussample
sha256:07bddf474593056dee6a4162e67b89fde1015841327af8ff8dee565bb8d21fac
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
tfplussample            latest              07bddf474593        10 seconds ago      1.13GB
tensorflow/tensorflow   latest              04f0b1131389        12 days ago         1.13GB

このDocker イメージからコンテナが生成され、実行できることは、

$ docker run -it -p 8888:8888 tfplussample

で確認しました。ここで、前に作った sample.ipynb を sample.py としてホストマシンにダウンロードしました。

Docker イメージをビルド

次のようなDockerfile

FROM tfplussample
COPY ./sample.py /tmp/sample.py

を作成して、 Dockerイメージをビルドしてみました。一行目は、新イメージのベースとなるコンテナ名、二行は、ホストマシンから新イメージのコンテナへのファイルコピーを指定しています。

-tオプションで、イメージ名 tfplussample2 タグ名 tag1 としました。

$ docker build -t tfplussample2:tag1  .Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM tfplussample
 ---> 07bddf474593
Step 2/2 : COPY ./sample.py /tmp/sample.py
 ---> 9de94c7d2502
Removing intermediate container 21067f8210cb
Successfully built 9de94c7d2502

Docker イメージを実行してみると、

$ docker run --rm -it tfplussample2:tag1 python /tmp/sample.py
Hello, TensorFlow!
42

のように、コンテナ内の/tmp/sample.py が実行されました。

まとめ

たしかに、インストールは簡単でした。TensorFlowに関係するファイルがDockerコンテナのなかにまとめられて、ホストマシンのほかのアプリから切り離されているようです。こうなると、他の機械学習関係のアプリやツールを別のコンテナに隔離することで、ライブラリバージョンの衝突などを回避できます。Pythonのバージョンの違いに悩まなくとも良くなるので、これは便利です。

それと、他人の作ったDockerイメージから、コンテナを簡単に自分のマシンに生成できるので、素早くアプリやツールに特化した実行環境を作れるようになります。これも便利です。一方で、Anaconda でも異なるpythonのバージョンを、別の環境に隔離できるのですが、環境を作るのは手作業なので時間がかかります。

ただ、Dockerの使い方を学ぶのに時間がかかりました。私の場合、半日。


参考

^1:Installing TensorFlow on Ubuntu : Installing with Anaconda

^2:Installing TensorFlow on Ubuntu : Installing with Docker

^3:TensorFlowが動作するDockerの開発環境を構築する

^4:Docker入門 – コンテナ型の仮想化技術の解説

^5:「さわって理解するDocker入門」オージス総研 大西 洋平

^6:@IT > いまさら聞けないDocker入門

^7:AMD Launches ‘Boltzmann Initiative’ to Dramatically Reduce Barriers to GPU Computing on AMD FirePro™ Graphics

^8:CUDAをRadeonで動かす(導入編)