第100回お試しアカウント付き並列プログラミング講習会「REEDBUSH スパコンを用いたGPUディープラーニング入門」

ハンズオン#1:
REEDBUSH-Hでのディープラーニング
山崎和博
NVIDIA, ディープラーニング ソリューションアーキテクト

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

AGENDA

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

タスク#2: シングルGPUでの学習ジョブハンズオン#1のゴール
バッチジョブの流し方に慣れる• Reedbushのディレクトリ構成などを把握する• Reedbush上でジョブを流す方法を把握する• シングル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
入力ピクセル

000001
1
1000012211101222110122211001111
10

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

00000400

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

000000-4-8

出力ピクセル8

CNN: 畳み込み層
出力

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

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

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

元画像

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

11

REEDBUSH-H
GPU搭載スーパーコンピュータ
計算ノードブロック図

Tesla P100を2基搭載
https://www.cc.u-tokyo.ac.jp/system/reedbush/reedbush_intro.html より
12

ジョブの実行• 実行したい内容をスクリプトにまとめ、バッチジョブとして実行•ジョブは指定したキューに追加され、順番が来たら実行される•キューに割り当てられているノード数を超えてジョブが投入されたら待つ• 本講習会では h-tutorial を指定••

ノード数の指定もできるが、講習会中はジョブあたり最大2ノードが上限

講習会ユーザのグループ名として gt00 を指定
13

ジョブスクリプト
実行条件指定実行条件はスクリプトの先頭行に記述「#PBS」から始まる行が（コマンドラインオプションとしても指定可）
条件指定#!/bin/bash#PBS -q (対象ジョブキュー名)#PBS -l (利用ノード数など)#PBS –W (利用グループ名)#PBS –l (実行時間制限)#PBS -N (ジョブ名)...
14ジョブスクリプト
実行条件指定#!/bin/bash#PBS -q (対象ジョブキュー名)#PBS -l (利用ノード数など)#PBS –W (利用グループ名)#PBS –l (実行時間制限)#PBS -N (ジョブ名)

利用ノードなどのパラメータは、以下をコロン「:」区切りで指定• select ノード数
• mpiprocs mpiプロセス数/ノード• ompthreads スレッド数/プロセス...

例) –l select=1:mpiprocs=1
15

ジョブスクリプト
実行環境の指定#!/bin/bash#PBS (省略)「PBS_O_WORKDIR」で作業ディレクトリを参照

cd ${PBS_O_WORKDIR}. /etc/profile.d/modules.sh...

「/etc/profile.d/modules.sh」
で環境変数などを設定

16

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

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

module list
module load cuda9/9.0.176 ...
module avail...

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

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

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

18

ジョブを投入する
動作環境をジョブ経由で確認
以下の作業を完了させる。

1. 作業ディレクトリ( /lustre/gt00/xxxxxx )へ移動
1.

xxxxxxは各自のアカウントで、cdwコマンドを使っても移動可能

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

/lustre/gt00/share/lecture/20180531_dl_intro/contents.tgz（参考回答は同じディレクトリのanswer.tgz）

2.

コマンド例:
cp /lustre/gt00/share/lecture/20180531_dl_intro/contents.tgz ./19

ジョブを投入する
動作環境をジョブ経由で確認
3. 解凍したら、build/contents/へ移動
1. 解凍コマンド例: tar xf contents.tgz
2. 移動コマンド: cd build/contents/

4. run_test_job.shを完成させる
1. 変更箇所は2ページ先20

ジョブを投入する
動作環境をジョブ経由で確認
4. スクリプトの修正完了したら実行

1. qsub –j oe run_test_job.sh
5. 結果を確認
1.

スクリプトと同じディレクトリに test_job.oxxxxxxx というファイルを確認

2.

cat test_job.oxxxxxx で内容をコンソール出力できる

21

スクリプトの変更箇所
ジョブ実行条件
作業ディレクトリへの移動

環境変数等の設定

モジュールロードと確認
22

テストジョブ実行結果[Mon May 28 13:35:24 JST 2018] start.
[Mon May 28 13:35:24 JST 2018] load modules.
ロード済みモジュール[Mon May 28 13:35:24 JST 2018] loaded modules.
Currently Loaded Modulefiles:
1) intel/18.1.163
5) anaconda3/4.3.0
2) intel-mpi/2018.1.163
6) openmpi/gdr/2.1.2/intel
3) pbsutils
7) chainermn/1.2.0
4) cuda9/9.1.85[Mon May 28 13:35:24 JST 2018] check chainer and chainermn
version.
Chainer ver.: 3.3.0
ChainerMN ver.: 1.2.0[Mon May 28 13:35:29 JST 2018] fin.
23

スクリプトの変更箇所(答え)#PBS –q h-tutorial#PBS –l select=1:mpiprocs=1:ompthreads=1#PBS –W group_list=gt00

cd $PBS_O_WORKDIR. /etc/profile.d/modules.shmodule load cuda9/9.1.85 anaconda3/4.3.0
openmpi/gdr/2.1.2/intel intel/18.1.163 chainermn/1.2.0

module list24

タスク#2: シングルGPUでの学習ジョブ

25シングルGPUで学習ジョブを流す
簡単な例で、ジョブの流し方を把握する

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

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

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

26

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
27

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

Trainer
Updater

Extensions

Iterator

Optimizer

DatasetModel

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コアから高速にアクセスできるようにする

Memory – CPU:
19.2GB/s(/slot)
76.8GB/s(/CPU)model

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

GPU core-memory:
732 GB/sより
https://www.cc.u-tokyo.ac.jp/system/reedbush/reedbush_intro.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 10 --batchsize 64 ...
> ${LOGDIR}/single_gpu_log_$(date +%s).txt 2>&1

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

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

シングルGPUでの実行結果 (1/2)
Start a training script using single GPU.
# Minibatch-size: 64
学習データ/検証データ# epoch: 10の誤差

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

Using CIFAR10 dataset:/lustre/gt00/share/lecture/20180531_dl_intro/dataset//cifar10_32px.pickle.gz
epoch main/loss
validation/main/loss main/accuracy validation/main/accuracy
12.39575
1.934070.15579
0.221835
2
1.87273
1.979540.259163
0.254479
3
1.651842.04599
0.353993
0.2683124
1.43666
1.333440.463468
0.515625
51.23045
1.12430.558883
0.599821
6
1.094420.969212
0.621859
0.665008
7
1.01091.034140.65709
0.65515580.950693
0.927806
0.683519
0.685908
90.903565
0.846908
0.703684
0.722731
100.871967
0.8291120.720411
0.731887
Throughput: 1513.0998149446914 [images/sec.] (500000 / 330.4474662289722)

elapsed_time
34.585467.0101
98.2595
129.817161.2
192.855224.957
256.997289.166
321.31136シングルGPUでの実行結果 (2/2)# qsubの実行ログに出力(前略)[Mon May 28 13:41:32 JST 2018] try
to do inference by using trained model.
CIFAR-10以外の実データ
Start an inference script using single GPU.
推論結果
# Target model: result/single_gpu/trained.model# Target data directory: /lustre/gt00/share/lecture/20180531_dl_intro/dataset//inference/[00]: file[cat_01.npz] is truck.
[01]: file[cat_02.npz] is deer.
[02]: file[cat_03.npz] is frog.
[03]: file[cat_04.npz] is frog.
[04]: file[cat_05.npz] is airplane.
[05]: file[dog_01.npz] is cat.
[06]: file[dog_02.npz] is automobile.
[07]: file[dog_03.npz] is horse.
[08]: file[dog_04.npz] is dog.
[09]: file[dog_05.npz] is airplane.
(後略)あまり当たっていないのは学習回数が少ないため

37シングルGPUでの実行結果 (2/2)# qsubの実行ログに出力より当たるように(前略)(画像は講習会のみ掲載)# 110エポック回してみると以下のような結果[Mon May 28 13:41:32 JST 2018] try to do inferenceCIFAR-10以外の実データ
by using trained model.
Start an inference script using single GPU.
推論結果[00]: file[cat_01.npz] is truck.
# Target model: result/single_gpu/trained.model# Target data directory:/lustre/gt00/share/lecture/20180531_dl_intro/dataset//inference/[01]:
file[cat_02.npz] is deer.

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

[00]: file[cat_01.npz] is truck.
[03]:
file[cat_04.npz] is cat.
[01]: file[cat_02.npz]
is deer.
[04]:
file[cat_05.npz] is airplane.
[02]: file[cat_03.npz]
is frog.
[03]: file[cat_04.npz]
is frog.
[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 cat.
学習回数が少ないため[07]:
file[dog_03.npz]
isdog.
[06]: file[dog_02.npz] is automobile.
[08]:
file[dog_04.npz] is dog.
[07]: file[dog_03.npz]
is horse.
[08]: file[dog_04.npz]
is dog.
[09]:
file[dog_05.npz] is deer.
[09]: file[dog_05.npz] is airplane.
(後略)

38

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

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

前述のchainer.serializers.load_npz(file, obj)を使う• ジョブ間の依存関係を考慮して実行してみる•

qsubのオプション(-W)を使うと実現可能•

詳細は「Reedbush システム利用手引書（概要・Reedbush-U 編）」の「4.1.2.5.チェーンジョブ(-W)」を参照
39

www.nvidia.com/dli