GPU性能比較 Colabo vs GCP vs GTX1070

# 概要

仕事や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()にデータを渡すあたりが、どうも[サポートされてない](https://github.com/tensorflow/tensorflow/issues/34346)っぽいので諦めた。


```terminal
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：元画像を傾けたり、ずらしたり、左右反転させたり、色合いを変えたりしてトレーニングを堅牢にする機能で下記のように書きます。

```Python
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で囲み計測しています。

```Python
import time
start = time.time()
##  比較対象コード
end = time.time()
print(end-start, 'sec')
```

## 比較環境
#### Google Colaboratory Pro
ColaboはProに変更してから、安定してV100が割り当たってます。

```terminal
!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個を借りています。
![Screenshot from 2020-09-12 14-06-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205257/c50ec8ab-dd36-fb55-b913-8cd5f501fbf9.png)


```terminal
!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
３，４年前に機械学習勉強用に購入しました。

```terminal
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負荷等は下図です。
![Screenshot from 2020-09-12 12-59-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205257/e4e27eb6-0516-e0e9-c108-8d63d5ba9563.png)
今回のCNNはImageDataGeneratorを使ったから、メモリ使用量は抑えられているみたい。
LSTMのトレーニングには時系列データ全部をいっぺんにモデルに晒す必要があるから16GB以上のシステムメモリを使っていたけど。