概要
仕事やCouseraのコーディング演習のモデルは、Google ColaboratoryやGCP(Google Cloud Platform)のVMでトレーニングしています。
また、Toy datasetを使って、自分のゲーミングPCでモデルの動作確認もやったりします。
でも、どうもGPUの違いでFit()の実行時間が変わる体験ができず、スペックが一番低いゲーミングPCがサクサク動いているように感じる。
いつもハイパパラメータを調整しながらなので、どの環境でもモデルが全く同じだったためしがなく、まぁそのせいだろう、と思っていました。
今日はCNNのモデルとTraining datasetを固定して、環境間でどれほどFit()周りの実行速度が変わるか測ってみます。
YouTubeなんかで、よくグラボ間でゲーム中のTPS比較なんかやっているので、その深層学習版をちょっとやってみようかと。たいしたもんじゃないけど。
使用モデル
よくありがちな犬猫Clasification用CNNを使いました。従い、loss='binary_crossentropy'です。
ハイパパラメータは指定していないのでKerasデフォルトです。
下記を参考にColaboではTPUでも測ってみたかったけど、エラーがどうしても取れなかった。
https://www.tensorflow.org/guide/tpu
ImageDataGeneratorでFit()にデータを渡すあたりが、どうもサポートされてないっぽいので諦めた。
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 148, 148, 32)      896       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 74, 74, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 72, 72, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 36, 36, 64)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 34, 34, 128)       73856     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 17, 17, 128)       0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 15, 15, 128)       147584    
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 7, 7, 128)         0         
_________________________________________________________________
dropout (Dropout)            (None, 7, 7, 128)         0         
_________________________________________________________________
flatten (Flatten)            (None, 6272)              0         
_________________________________________________________________
dense (Dense)                (None, 512)               3211776   
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 513       
=================================================================
Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________
Training dataset
Kegoleで犬猫を探しましたが枚数が多いものしかなく、以前演習で使用した各1000枚の犬猫を使いました。
データは、
・そのままImageDataGenerator経由でFit()に渡すケース
・Augmentation*をImageDataGeneratorで施したものを渡すケース
の2ケースで計測しています。
ImageDataGeneratorの画像加工処理にはおそらくCPUを使うと思われ、CPUの比較も同時に行えるかと思ったからです。
ファイルはアクセスオーバヘッドを同じにするため、各環境ともroot/tmp直下に置きました。
*Augmentation:元画像を傾けたり、ずらしたり、左右反転させたり、色合いを変えたりしてトレーニングを堅牢にする機能で下記のように書きます。
train_datagen = ImageDataGenerator(
      rescale=1./255,
      rotation_range=40,
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')
計測方法
epoch=100で、1回実行した時間で比較します。
コード中、モデルを定義するところからFit()が終わるところまで、下記のようにtimeで囲み計測しています。
import time
start = time.time()
##  比較対象コード
end = time.time()
print(end-start, 'sec')
比較環境
Google Colaboratory Pro
ColaboはProに変更してから、安定してV100が割り当たってます。
!nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.66       Driver Version: 418.67       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| 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  Tesla V100-SXM2...  Off  | 00000000:00:04.0 Off |                    0 |
| N/A   36C    P0    24W / 300W |      0MiB / 16130MiB |      0%      Default |
|                               |                      |                 ERR! |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
!cat /proc/cpuinfo
processor	: 0 / 1        (2processorsみたい)
vendor_id	: GenuineIntel
cpu family	: 6
model		: 85
model name	: Intel(R) Xeon(R) CPU @ 2.00GHz
stepping	: 3
microcode	: 0x1
cpu MHz		: 2000.136
cache size	: 39424 KB
GCP
VMのCPUは8core、メモリ30BG、GPUはTesla T4 1個を借りています。

!nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla T4            Off  | 00000000:00:04.0 Off |                    0 |
| N/A   53C    P0    28W /  70W |      0MiB / 15079MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
!cat /proc/cpuinfo
processor	: 0 ~ 7    (8processors) 
vendor_id	: GenuineIntel
cpu family	: 6
model		: 79
model name	: Intel(R) Xeon(R) CPU @ 2.20GHz
stepping	: 0
microcode	: 0x1
cpu MHz		: 2199.998
cache size	: 56320 KB
ゲーミングPC
3,4年前に機械学習勉強用に購入しました。
nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 1070    On   | 00000000:01:00.0  On |                  N/A |
| 33%   44C    P2    37W / 151W |   7928MiB /  8117MiB |     20%      Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1016      G   /usr/lib/xorg/Xorg                           122MiB |
|    0      1324      G   /usr/bin/gnome-shell                          97MiB |
|    0     17963      G   ...AAAAAAAAAAAACAAAAAAAAAA= --shared-files   193MiB |
|    0     26359      C   ...e/imo/anaconda3/envs/tf-gpu2/bin/python  7509MiB |
+-----------------------------------------------------------------------------+
cat /proc/cpuinfo
processor	: 0 ~ 7    (8processors)
vendor_id	: GenuineIntel
cpu family	: 6
model		: 158
model name	: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
stepping	: 9
microcode	: 0xd6
cpu MHz		: 800.047
cache size	: 8192 KB
結果
100epockの実行速度は下表のとおりで、体感してたようにゲーミングPCが速かった。
Augmentation入れるとFit()だけのときと比べてどの環境でも倍の時間がかかるようです。
この結果のみでは何が原因なのか断定できません。
| Environment | Colaboratory Pro | GCP AI Platform | Gaming PC | 
|---|---|---|---|
| GPU Spec | Tesla V100-SXM2 16GB | Tesla T4 15GB | GTX 1070 8GB | 
| CNN | 900.12 sec | 723.94 sec | 533.10 sec | 
| CNN w/ Augmentation | 1838.30 sec | 1504.83 sec | 1088.91 sec | 
VM上のリソース(GPUとメモリ)はシステムで複数ユーザにアサインされフルに使用できないからしかたない。
Colabo ProのGPUはハイエンドのV100だけど、かなりのユーザでリソースシェアしているんでしょう。
まあ基本タダ(Proは$99/月)で使わせて頂いているので、文句は言えない。
GCPは微妙。100円ちょっと/時間も払っているのに少し納得いかないかな。会社が払うからいいんだけど。
結論
使用時間の制約を一切受けないグラボが刺さった手元のPCでモデル開発するのが一番ってことでしょう。
RTX3080が欲しい… 薄給だから値ごろになるまでお金ためよう…
備考
当然ですが、LossもAccuracyも環境間でほぼ同じでした。
また、ゲーミングPCでFit()中のCPU負荷等は下図です。

今回のCNNはImageDataGeneratorを使ったから、メモリ使用量は抑えられているみたい。
LSTMのトレーニングには時系列データ全部をいっぺんにモデルに晒す必要があるから16GB以上のシステムメモリを使っていたけど。