仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

RancherOS + RancherでNvidia Dockerホストを使ってみた(後編)

前回はNVIDIA Dockerを使えるようにするところまでを行いました。

tech.virtualtech.jp

前編でRancherとGPUコンテナーを実行可能なノードは用意しましたので、今日はまずRancherにホストを登録してみます。

Rancherにホストを追加する

Rancherにブラウザーでアクセスします。Rancherの上部メニューの「インフラストラクチャ→ホスト」をクリックします。 ホストの一覧が表示される画面になります。画面にある「ホストを追加」ボタンをクリックすると、Rancherで有効化されているドライバーを使って任意のクラウドもしくは管理しているインフラ上にRancherによって管理するホストを追加できます。

f:id:virtualtech:20190827100100p:plain

今回は「Custom」を選択します。クリックすると下に追加手順が表示されますので、手順に従って設定を行うとRancherにホストを追加できます。 Customの場合は対象のホストに対しDockerをインストールして、docker run 〜を実行するだけです。

f:id:virtualtech:20190827100557p:plain

しばらくすると、ホストが追加されます。

f:id:virtualtech:20190827101128p:plain

これでRancherでホストを管理できるようになりました。

コンテナーでGPUを使ってみる

DockerでGPUコンテナーを取り扱うにはNVIDIA Container Toolkitを使います。 今回はChainerを使ってみます。

まずはコンテナーの起動

次のように、Chainerコンテナーイメージを使ってコンテナーを起動します。 bashを指定しているので、コンテナーが起動するとコンテナー内のbashにログインします。

$ sudo -i
# nvidia-docker run --name=cont1 -it chainer/chainer:v6.3.0-python3 bash

起動したコンテナーはRancher標準の機能を使って監視できます。

f:id:virtualtech:20190827103811p:plain

コンテナーの再起動、停止、削除などもGUIを使って行えます。

f:id:virtualtech:20190827104030p:plain

メニューから「シェルを実行」を実行すると、ブラウザーからコンテナーのCLIにアクセスできます。

MNIST(エムニスト)のサンプルを実行してみる

機械学習の入門として、手書き文字(MNIST)識別のサンプルを使ってDockerコンテナーでGPUを使った場合にどれだけ利点があるのか試してみましょう。 前の手順でシェルにアクセスできていると思います。

f:id:virtualtech:20190827134937p:plain

このコンテナーの中のシェル上で次のように実行してみてください。

# apt update && apt install wget
# wget https://github.com/chainer/chainer/archive/v6.3.0.tar.gz && tar zvxf v6.3.0.tar.gz

これでChainerのソースをダウンロードできます。ChainerのソースにMNISTのサンプルデータが含まれるので、これを使います。 次のように実行すると、CPUだけを使って手書き文字認識のサンプルが実行されます。非常に時間がかかります。

ちなみに何が行われているかはこちらの情報(外部サイト)をご覧ください。

# time -p python3 chainer-6.3.0/examples/mnist/train_mnist.py
Device: @numpy
# unit: 1000
# Minibatch-size: 100
# epoch: 20
...
real 727.90
user 7350.00
sys 9967.53

このサンプルプログラムでGPUをコンテナーで使うには、--gpu 0と追加してコマンドを実行します。指定する番号はGPUのデバイス番号です。nvidia-smiコマンドを実行した時に現れる結果からデバイスを判断してください。結果はCPUで処理した時よりも処理は速くなったと思います。

# time -p python3 chainer-6.3.0/examples/mnist/train_mnist.py --gpu 0
Device: @cupy:0
# unit: 1000
# Minibatch-size: 100
# epoch: 20
...
real 101.55
user 101.54
sys 2.82

CPUモードで実行した場合、Device: @numpyが使われ、GPUを使用するように指定した場合はDevice: @cupy:0が使われているのがわかります。 「プログラム自体の処理時間(ユーザー時間)」で比較すると次の通り。結果の単位は秒。CPUで処理するより、GPUの方が約70倍も速く処理できることがわかります。

Mode Result(s)
CPU 7350
GPU 101

用意した環境には2つのGPUが実装されているので、同時並行で処理した場合も確認してみます。

# time -p python3 chainer-6.3.0/examples/mnist/train_mnist_data_parallel.py
Devices: @cupy:0, @cupy:1
# unit: 1000
# Minibatch-size: 400
# epoch: 20
...
real 62.85
user 62.65
sys 2.90

実行した結果、さらに解析に必要な時間を短縮できました。GPUを使わない時と比べると約100分の1の時間で処理できるわけです。これはすごい。

Mode Result(s)
CPU 7350
GPUx1 101
GPUx2(para) 62

おまけ

Rancherを使うと、全てのノードのコンテナーを一つの画面で管理できるので便利です。

f:id:virtualtech:20190827140236p:plain

この画面からコンソールを開いたり、コマンドのログを表示したりできます。