ディープラーニングのための GPU講習会- 九州大学スーパーコンピュータシステム ITOによる実習 -ハンズオン#1:
スーパーコンピュータシステム ITOを用いたディープラーニング
山崎和博
NVIDIA, ディープラーニング ソリューションアーキテクト

ハンズオン#1のテーマ: 画像分類

AGENDA

今日の環境とスクリプトの書き方
タスク#1: テストジョブ投入

タスク#2: シングルGPUでの学習ジョブハンズオン#1のゴール
バッチジョブの流し方に慣れる• ITOのディレクトリ構成などを把握する• ITO上でジョブを流す方法を把握する• シングルGPUでの学習方法を理解する3

ハンズオン#1のテーマ: 画像分類

4

画像分類問題
画像が何か？を当てる問題• 1枚の画像が与えられたときに、それが「何か」を当てる問題•

例: 数字が写った画像に対して、0-9までのラベルを割り振る•

画像認識問題とも呼ばれる• 「どこに」、「どんな形状で」写っているかは問わない•

場所まで当てるタスクは、物体検出•形状まで当てるタスクは、セマンティックセグメンテーション
5

本日のデータセット
10クラス分類問題• CIFAR-10 データセット

https://www.cs.toronto.edu/~kriz/cifar.html• サイズ : 32x32、RGBカラー、ピクセル値 0 - 255
トレーニング用データ : 5万(5000/class)
テスト用データ : 1万
• 入力ベクタサイズ : 1024 ( = 32 x 32)• 出力は10種類のクラス

6畳み込みニューラルネットワーク(CNN)
画像分類でよく用いられるネットワーク
生データ

低レベルの特徴

中間レベルの特徴

高レベルの特徴

アプリケーションの構成要素例:

畳み込み層

入力

全結合層

結果

タスクの目的
顔の同定
トレーニングデータ
1千万-1億 のイメージ
ネットワークアーキテクチャ
十から数百のレイヤー
10億のパラメータ
学習アルゴリズム~30 Exaflops
1-30 日(1GPU)

7

畳込み層(CONVOLUTIONAL LAYER)
000
入力ピクセル

0000011
10000
12211101222110122211001111
10

コンボリューションカーネルの係数と、入力ピクセルを掛け、足し合わせた値を出力とする。

00000400

コンボリューション
カーネル

00000
0-4-8

出力ピクセル8

CNN: 畳み込み層
出力

コンボリューションカーネル

入力
vdumoulin/conv_arithmetic, https://github.com/vdumoulin/conv_arithmetic
9

CNN: 畳み込み層
畳み込みの計算例

元画像

畳み込みカーネル
出力10今日の環境とスクリプトの書き方

11スーパーコンピュータシステムITO
サブシステムB: GPU搭載スーパーコンピュータ
計算ノードブロック概略

Tesla P100を4基搭載

https://www.cc.kyushu-u.ac.jp/scp/support/faq/faq005.html より
12

ジョブの実行• 実行したい内容をスクリプトにまとめ、バッチジョブとして実行•

ジョブ実行コマンドは pjsub•ジョブは指定したキュー(リソースグループ)に追加され、順番が来たら実行•

割り当てられているノード数を超えてジョブが投入されたら待つ• 本講習会では ito-b-lecture-1/ito-b-lecture-4 を指定••

それぞれジョブあたり1GPU/4GPUを割り当てる

サブシステム名には ito-b を指定
13

ジョブスクリプト
実行条件指定実行条件はスクリプトの先頭行に記述「#PJM」から始まる行が（コマンドラインオプションとしても指定可）
条件指定#!/bin/bash#PJM –L (pjsubコマンドの引数)#PJM –j (標準エラーを標準出力にまとめる)#PJM –X (環境変数引き継ぎ)...

14

ジョブスクリプト
実行条件指定pjsubコマンドの引数には以下などを指定#!/bin/bash
可能#PJM –L (pjsubコマンドの引数)• rscunit サブシステム名#PJM –j (標準エラーを標準出力にまとめる)• rscgrp リソースグループ名#PJM –X (環境変数引き継ぎ) • elapse 最大実行時間• vnode 仮想ノード数• vnode-core ノードあたりの最大コア数...
例) –L ”elapse=00:05:00”
15

ジョブスクリプト
必要モジュールの読み込みなど#!/bin/bash#PJM (省略)...

現在ロード済み
モジュールを表示

module list
module load cuda/8.0 ...
module avail...

利用可能なモジュールを表示

モジュールの追加読み込み16ジョブスクリプト
必要モジュールの読み込みなど#!/bin/bash#PJM (省略)...

現在ロード済み
モジュールを表示

module list
module load cuda/8.0 ...
module avail...

利用可能なモジュールを表示

モジュールの追加読み込み17

タスク#1: テストジョブ投入

18

ジョブを投入する
動作環境をジョブ経由で確認

以下の作業を完了させる。

1. テンプレートスクリプトを作業ディレクトリへコピー
1.

/home/tmp/dl_lecture/20180511_handson/script/contents.tgz（参考回答は同じディレクトリのanswer_py.tgzとanswer_sh.tgz）

2.

コピーコマンド例:
cp /home/tmp/dl_lecture/20180511_handson/script/contents.tgz ./2. 解凍したら、build/contents/へ移動
1.

コマンド例: tar xf contents.tgz && cd build/contents/

19ジョブを投入する
動作環境をジョブ経由で確認

3. run_test_job.shを完成させる
1. 変更箇所は次ページ

4. スクリプトの修正完了したら実行
1. pjsub run_test_job.sh

5. 結果を確認
1. スクリプトと同ディレクトリの run_test_job.oxxxxxxx というファイルを見る
2. cat run_test_job.oxxxxxxx

20

スクリプトの変更箇所
ジョブ実行条件

モジュールロードと確認

21

テストジョブ実行結果[2018年 5月 7日 月曜日 18:08:03 JST] start.
ロード済みモジュール[2018年 5月 7日 月曜日 18:08:03 JST] load modules.
[Mon May 7 18:08:03 JST 2018] loaded modules.
Currently Loaded Modulefiles:
1) cuda/8.0
2) hdf5/1.10.1-threads3) openmpi/1.10.7[Mon May 7 18:08:04 JST 2018] check if nccl imported.
NCCL_ROOT => /home/tmp/dl_lecture/20180511_handson/app/nccl/
lrwxrwxrwx 1 s70080a lecture 12 May 6 12:57/home/tmp/dl_lecture/20180511_handson/app/nccl//libs/libnccl.so ->libnccl.so.2[Mon May 7 18:08:04 JST 2018] check chainer and chainermn version.
(Warning省略)
Chainer ver.: 4.0.0(Warning省略)
ChainerMN ver.: 1.2.0[Mon May 7 18:08:31 JST 2018] fin.
22

スクリプトの変更箇所“rscgrp=ito-b-lecture-1”

module load cuda/8.0…

module load openmpi/1.10.7
module list

23

タスク#2: シングルGPUでの学習ジョブ24シングルGPUで学習ジョブを流す
簡単な例で、ジョブの流し方を把握する以下の作業を完了させる。

1. train_cifar_single_gpu.pyに「PUT YOUR CODE」という箇所があるので、書き換えてプログラムを完成させる
2. スクリプトの修正完了したら実行
1. pjsub run_single_gpu_training.sh

3. 結果を確認
1. cat logs/single_gpu_log_xxxxxxx.txt

25

CHAINERを使った学習
Trainer利用と直接実装• 標準的な処理しかしないなら、Trainerを利用するのが簡便でよい•

v1.11.0から導入• カスタマイズも容易• 学習フローをすべてスクラッチで実装することも可能•(trainerあり) https://github.com/chainer/chainer/blob/master/examples/cifar/train_cifar.py•(trainerなし)
https://github.com/chainer/chainer/blob/master/examples/cifar/train_cifar_custom_loop.py
26

CHAINERを使った学習
Trainer利用と直接実装

Trainer
Updater

Extensions

Iterator

Optimizer

DatasetModel27

スクリプトの変更箇所

ネットワークの変数をCPUからGPUへ転送使うGPUを指定

ネットワークの更新ロジックを指定

テストで使うGPUを指定
28

CHAINERのAPI
GPUの操作• どのGPUを使うか指定する•chainer.backends.cuda.get_device_from_id(device_id).use()•

get_device_from_id()はcupy.cuda.Deviceを返す• GPUで処理したいオブジェクトを、CPUのメモリからGPUのメモリへ転送•

学習モデルをコピーしたいのでmodel.to_gpu()
29

GPUのメモリへ転送？
GPU側のメモリに転送し、計算ノードブロック概略
GPUコアから高速にアクセスできるようにする

model

ニューラルネットの変数は最初CPU側メモリに(FW次第です)

https://www.cc.kyushu-u.ac.jp/scp/support/faq/faq005.html より
30

CHAINERのAPI
学習/評価の実行• ネットワークの更新ロジック(シングルGPU/マルチGPU/etc.)を指定•

chainer.training.updaters.StandardUpdater(iterator, optimizer, device)•

学習データのイテレータとoptimizer、使用するGPUのIDを渡す• テストデータでの評価をするクラス•

chainer.training.extensions.Evaluator(iterator,target, device)•

テストデータのイテレータとモデルオブジェクト、使用GPUのIDを渡す
31

CHAINERのAPI

学習結果の保存と再利用• 学習結果の保存•

chainer.serializers.save_npz(file, obj)

• 学習結果の読み込み•

chainer.serializers.load_npz(file, obj)•

読み込んだ学習結果を使って推論する場合は、obj(data)もしくは、obj.predictor(data)のように呼び出す

32スクリプトの修正を試みましょう

コンソールに戻ってください！

33

スクリプトの変更箇所(答え)get_device_from_id(0)model.to_gpu()
updater=training.StandardUpdater(

train_iter, optimizer, device=0)

device=034

実行結果のモニタリング• 実行の実体は以下のコマンド•

python train_cifar_single_gpu.py --epoch 3 --batchsize 64 ... >${LOGDIR}/single_gpu_log_$(date +%s).txt 2>&1

• pjsubコマンド自体のログも出ている•

デフォルトでは、実行スクリプトと同じ場所に「ジョブ名.o$JOB_ID」で出力• リアルタイムにモニタリングしたい場合は、前者の自前ログを「tail –f」などで監視するのが良い35

シングルGPUでの実行結果 (1/2)

Start a training script using single GPU.
学習データ/検証データ# Minibatch-size:
64# epoch: 3の誤差

学習データ/検証データ
での精度

Using CIFAR10 dataset: /home/tmp/dl_lecture/20180511_handson/data//cifar10_32px.pickle.gz
epoch main/loss
validation/main/loss main/accuracy validation/main/accuracy elapsed_time12.31872
1.90180.170157
0.250995
37.5295
2
1.82582
1.82775
0.271347
0.303244
68.88983
1.5814
1.417960.380742
0.466859
100.202(Warning省略)
Throughput: 1406.0911190071415 [images/sec.] (150000 / 106.67871944594663)

36シングルGPUでの実行結果 (2/2)# pjsubの実行ログに出力(前略)[Mon May 7 18:11:32 JST 2018] try to do inference by using trained model.
(warning省略)
CIFAR-10以外の実データ
Start an inference script using single GPU.
推論結果
# Target model: result/single_gpu/trained.model# Target data directory: /home/tmp/dl_lecture/20180511_handson/data//inference/[00]: file[cat_01.npz] is automobile.
[01]: file[cat_02.npz] is frog.
[02]: file[cat_03.npz] is airplane.
[03]: file[cat_04.npz] is airplane.
[04]: file[cat_05.npz] is airplane.
[05]: file[dog_01.npz] is dog.
[06]: file[dog_02.npz] is ship.
[07]: file[dog_03.npz] is dog.
[08]: file[dog_04.npz] is cat.
[09]: file[dog_05.npz] is automobile.
(後略)

あまり当たっていないのは学習回数が少ないため

37シングルGPUでの実行結果 (2/2)# pjsubの実行ログに出力より当たるように(前略)[Mon May 7 18:11:32 JST 2018] try to do inference by using trained(画像は講習会のみ掲載)
model.
# 200エポック(1.7hour)回してみると以下のような結果(warning省略)
CIFAR-10以外の実データ
Start an inference script using single GPU.
推論結果[00]: file[cat_01.npz]
is truck.
# Target model: result/single_gpu/trained.model# Target data directory:/home/tmp/dl_lecture/20180511_handson/data//inference/[01]:
file[cat_02.npz] is deer.

[02]: file[cat_03.npz] is cat.

[00]: file[cat_01.npz] is automobile.
[03]:
file[cat_04.npz] is cat.
[01]: file[cat_02.npz]
is frog.
[04]:
file[cat_05.npz] is airplane.
[02]: file[cat_03.npz]
is airplane.
[03]: file[cat_04.npz]
is airplane.
[05]:
file[dog_01.npz] is dog.
[04]: file[cat_05.npz]
is airplane.
[06]:
file[dog_02.npz] is dog. あまり当たっていないのは[05]: file[dog_01.npz] is dog.
学習回数が少ないため[07]:
file[dog_03.npz]
isdog.
[06]: file[dog_02.npz] is ship.
[08]:
file[dog_04.npz] is dog.
[07]: file[dog_03.npz]
is dog.
[08]: file[dog_04.npz]
is cat.
[09]:
file[dog_05.npz] is deer.
[09]: file[dog_05.npz] is automobile.
(後略)

38

(OPTION) 追加で試す
早く終わった方のために• Resume機能を実装してみる•

更に長時間学習させるために必要•

前述のchainer.serializers.load_npz(file, obj)を使う•

スクリプト(train_cifar_single_gpu.pyとrun_single_gpu_training.sh)を書き換えて、複数回実行してみましょう39

www.nvidia.com/dli