TensorFlowをDockerで動かす(CPU編とGPU編)

TensorFlowといえば深層学習(ディープラーニング)を扱う上で最も有名なソフトウェアの一つです.

TensorFlowは複数のパッケージやライブラリから構築されている大規模なソフトウェアです.

そのため,それらのライブラリを管理することが煩雑になり,数カ月後別のマシンにインストールしようとすると失敗するということが頻発します.

Deep Learningは新しい技術であり,日々多くの研究がなされています.TensorFlowはGoogleが開発元ということもあって新しい技術の取り込みが非常に速いです.そのため,バージョンアップデートに伴う変化が多く,数回のアップデートで互換性が失われることがあります.

Kerasがいい例です.Kerasは以前拡張モジュールでしたが,TensorFlowが公式にコア機能として取り入れた歴史があります.それによって,コマンドが変更されバージョンアップ前のコードが使用できなくなりました.

コンテナ技術であるDockerを使用することで環境構築の煩雑さやそのストレスを低減することが可能です.

TensorFlowをDocker上で動かす方法をまとめておきます.

この記事では,

この記事の内容
  • CPUのみを使用するDocker版TensorFlowのインストールと実行
  • GPUをサポートするDocker版TensorFlowのインストールと実行

に関して,記載しています.

Docker を使用する場合,ホストマシンはNVIDIA® GPU ドライバだけが必要になります.(Dockerを使用しない場合,さらにいくつかのドライバが必要)

DockerはGPU を使用して TensorFlow を実行する際の最も簡単な方法となります.

Docker版のTensorFlowを使用するメリットをまとめると以下のようになります.

Docker版のTensorFlowのメリット
  • TensorFlowの複雑なインストール手順が不要
  • TensorFlowのバージョン管理に悩まなくていい
  • パッケージやライブラリ依存および管理が簡単になる
  • その他,コンテナのメリット

Docker版TensorFlowも通常のTensorFlowと使い方はほぼ同じです.

Docker + Jupyter notebookを使用する方法は下記記事に掲載しています

目次

Dockerのインストール

この記事では,Dockerを一般ユーザ(Rootlessモード)で実行することを前提とします.

Rootless Dockerのインストール方法は下記の記事を参考にしてください.

RootlessモードDockerのインストール方法

CPUで動かすTensorFlow

最新の安定版のDockerイメージを以下のコマンドでダウンロードします.TensorFlowのDockerイメージはDocker Hubにあります.


docker pull tensorflow/tensorflow  

特定のバージョンが使用したい場合,Docker Hubから指定のバージョンを指定します.

下記コマンドで,Dockerを起動します.


docker run -it tensorflow/tensorflow bash

下記のようなメッセージが確認できれば成功です.ここで操作することはないので,すぐにログアウトします(exitでログアウトできます).


________                               _______________
___  __/__________________________________  ____/__  /________      __
__  /  _  _ \_  __ \_  ___/  __ \_  ___/_  /_   __  /_  __ \_ | /| / /
_  /   /  __/  / / /(__  )/ /_/ /  /   _  __/   _  / / /_/ /_ |/ |/ /
/_/    \___//_/ /_//____/ \____//_/    /_/      /_/  \____/____/|__/
WARNING: You are running this container as root, which can cause new files in
mounted volumes to be created as the root user on your host machine.
To avoid this, run the container by specifying your user's userid:
$ docker run -u $(id -u):$(id -g) args...

ホストマシンのストレージとマウントしているとRoot権限でファイルの読み書きが発生して危険」ということを警告しているものですが,Rootlessモードのためこの問題は発生しません無視して問題ありません.

動作確認

ここでは,画像分類を実行して,TensorFlowが正常にインストールされたか確認します.

TensorFlowのチュートリアルをPythonコードにすると,以下のようになります.(少し改良しています)


import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
print ("-----------------------------------")
print (" TensorFlow version is ", tf.__version__)
print ("-----------------------------------")
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
model = tf.keras.models.Sequential([tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10)])
predictions = model(x_train[:1]).numpy()
tf.nn.softmax(predictions).numpy()
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
loss_fn(y_train[:1], predictions).numpy()
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])
print ("-----------------------------------")
print ("*Train model")
model.fit(x_train, y_train, epochs=5)
print ("-----------------------------------")
print ("*Evaluate model")
model.evaluate(x_test, y_test, verbose=2)

mnist_tutorial.pyを実行ディレクトリに置き,下記コマンドを実行します.


docker run -it --volume $PWD:/tmp -w /tmp tensorflow/tensorflow python3 mnist_tutorial.py

エラーなく次のように実行されれば問題ありません.


-----------------------------------
 TensorFlow version is  2.8.0
-----------------------------------
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11501568/11490434 [==============================] - 2s 0us/step
-----------------------------------
*Train model
Epoch 1/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3005 - accuracy: 0.9129
Epoch 2/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.1442 - accuracy: 0.9573
Epoch 3/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.1069 - accuracy: 0.9678
Epoch 4/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.0896 - accuracy: 0.9731
Epoch 5/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.0760 - accuracy: 0.9760
-----------------------------------
*Evaluate model
313/313 - 1s - loss: 0.0750 - accuracy: 0.9782 - 522ms/epoch - 2ms/step

GPUで動かすTensorFlow

上述ではCPUで動かすDocker版TensorFlowの導入に関して記載しましたが,実際はCPUでの計算速度は非常に低速であり,ほとんどの場合,GPUで動作させることが要求されます.

ここでは,より実用性の高いGPU版TensorFlowの導入を示します.

Docker を使用する場合,ホストマシンはNVIDIA® GPU ドライバだけが必要になります.NVIDIA® CUDA® ツールキットは必要ありません.

必要なドライバやパッケージをインストール

NVIDIA GPUドライバのインストール

NVIDIA GPUのドライバをこちらからダウンロード,インストールします.


sh NVIDIA-Linux-x86_64-$DRIVER_VERSION.run
あわせて読みたい

NVIDIA Container Toolkitのインストール

安定版のリポジトリとGPGキーを設定します.


distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list

リポジトリのアップデートした後,インストールします.


apt-get update
apt-get install -y nvidia-docker2

Dockerデーモンを再起動します.

systemctl restart docker

下記コマンドでGPUの情報を確認します.


docker run --rm --gpus all nvidia/cuda:11.0.3-base nvidia-smi

コンテナのTagが変更されていることがあるため,エラーが出た場合公式Hubを確認してください.

下記のようなメッセージが確認できれば,コンテナがドライバを認識できていることがわかります.


+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.103.01   Driver Version: 470.103.01   CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  Off  | 00000000:17:00.0 Off |                  N/A |
| 24%   23C    P8    13W / 260W |      5MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  NVIDIA GeForce ...  Off  | 00000000:65:00.0 N/A |                  N/A |
| 50%   31C    P8    N/A /  N/A |     15MiB /   980MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+
Rootlessで実行する場合の注意点

RootlessでDockerコンテナを使用する場合,デフォルトのまま使用すると以下のようなエラーが発生します.

docker run --rm --gpus all nvidia/cuda:11.0-base bash
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: Running hook #0:: error running hook: exit status 1, stdout: , stderr: /usr/bin/nvidia-modprobe: unrecognized option: "-s"

このエラーに関しては,下記コマンドで設定を変更する必要があります.

sed -i 's/^#no-cgroups = false/no-cgroups = true/;' /etc/nvidia-container-runtime/config.toml

詳細は下記サイトで説明されています.

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#step-3-rootless-containers-setup

動作確認

GPU用のコンテナイメージをダウンロードします.

docker pull tensorflow/tensorflow:latest-gpu

CPUの場合と同様にmnist_tutorial.pyを実行します.GPU対応させるために--gpus allオプションが必要になります.

docker run --gpus all -it --volume $PWD:/tmp -w /tmp tensorflow/tensorflow:latest-gpu python3 mnist_tutorial.py

問題がなければ,次のような出力が得られます.


-----------------------------------
 TensorFlow version is  2.8.0
-----------------------------------
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11501568/11490434 [==============================] - 6s 1us/step
-----------------------------------
*Train model
Epoch 1/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.2972 - accuracy: 0.9150
Epoch 2/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.1421 - accuracy: 0.9581
Epoch 3/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.1068 - accuracy: 0.9677
Epoch 4/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0865 - accuracy: 0.9732
Epoch 5/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0746 - accuracy: 0.9764
-----------------------------------
*Evaluate model
313/313 - 1s - loss: 0.0733 - accuracy: 0.9767 - 705ms/epoch - 2ms/step

TensorFlow学習方法

機械学習の基礎理論を学ぶ

TensorFlowの理解には,機械学習の基礎が重要になります.

機械学習の基礎を学ぶには,通称「黄色本」と呼ばれる本「パターン認識と機械学習」が有名です.

定番の教科書であり,理論的な背景を数学的に詳細に記載されています.数学の知識がある程度求められるため,難易度は高いです.

この本には,現代の深層学習(ディープラーニング)に至るまでの機械学習の歴史も学べます.

決定木やランダムフォレストからニューラルネットワークが開発されるに至るまでの,理論的,手法的な長所短所が示されています.

TensorFlowを用いた機械学習を学ぶ

理論を学び,実際にプログラムを作成するには膨大な時間を要します.TensorFlowは,最新の理論が比較的早い段階で導入されます.

本職の研究者でない限り,自身で最新理論をプログラミングするよりもTensorFlowの既存機能を使用することを推奨します

また,機械学習には,ある程度経験則が重要とされています.実際に手を動かしてみて,どのように動作するかを学ぶべきです.

Jupyter notebookを利用した効率的な開発

TensorFlowは,”Jupyter notebook”と呼ばれるWebブラウザで動作する統合開発環境と一緒に使用されることが多いです.

Jupyter notebookとの連携は下記記事に記載していますので,ご覧ください.

まとめ

CPUとGPUのDocker版TensorFlowのインストール方法および実行手順を示しました.

Rootless Dockerはインストールに癖がありますが,Rootful(Root権限)のDockerと比較し安全性が高いです.Rootless DockerでTensorFlowを使用することを推奨します.

よかったらシェアしてね!
目次