オッサンはDesktopが好き

自作PCや機械学習、自転車のことを脈絡無く書きます

RTX 2081TiとRTX 1080で複数GPUを試してみる

 こんにちは.changです. 今回はRTX 2080TiとRTX 1080を1枚ずつ使い,複数GPUでのディープ・ラーニングにトライします. RTX 2080Tiを2枚使うのが理想ですが,先日お話したように買えません*1. 旧機種との組み合わせで妥協する手もあるかと思い,試してみました.

0. 装着

 サブマシン(以前のメインマシン)で使っていたRTX 1080を,メインマシンに移植しました. チップもメーカーもバラバラなので,見た目は若干悪くなります. RTX1080は外排気モデルではないので冷却不良が心配ですが,ファンの下にスペースがあるので大丈夫でしょう.

f:id:changlikesdesktop:20201202171346p:plain:w400
2枚挿入時.RTX 1080の下方に風が抜けるかが不安.

f:id:changlikesdesktop:20201202171449p:plain:w400
2枚刺し % 電源投入時.イルミネーションがメーカー毎にバラバラです(笑)

 パソコンを起動して,GPUが認識されているか確認します.

f:id:changlikesdesktop:20201202145113p:plain:w400
nvidia-smiを実行.RTX 2080 TiとRTX 1080の2本が認識されている.

 tensorflowからも確認します.

$ python3  
from tensorflow.python.client import device_lib  
device_lib.list_local_devices()

f:id:changlikesdesktop:20201202145520p:plain:w400
tensorflowからdeviceをチェック.こちらでもRTX 2080TiとRTX 1080が共に認識されている.

1. コーディング

 こちら*2を参考に,以前に書いたmnistにマルチGPU仕様を追記しました. 参照元のソースが8枚もGPUを使っているので吃驚したのですが,AWSを使えばこんなこともできるんですね.

def create_model(self, input_shape, multi_gpu=False):
    if not multi_gpu:
        (省略)
    else:
        with tf.device("/cpu:0"):
            self.model = Sequential()
            self.model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
            self.model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
            self.model.add(MaxPooling2D(pool_size=(2, 2)))
            self.model.add(Dropout(0.25))
            self.model.add(Flatten())
            self.model.add(Dense(128, activation='relu'))
            self.model.add(Activation('relu'))
            self.model.add(Dropout(0.5))
            self.model.add(Dense(self.num_classes, activation='softmax'))
            self.model = multi_gpu_model(self.model, gpus=gpu_count)
    self.model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])

 マルチGPUでの学習中と,シングルGPUでの学習中のnvidia-smiを比較してみます. マルチGPUを使うことで,2枚目のRTX 1080も使われるようになります.

f:id:changlikesdesktop:20201202163553p:plain:w400
シングルGPU時のnvidia-smi.

f:id:changlikesdesktop:20201202163636p:plain:w400
マルチGPU時のnvidia-smi.

 200 epoch,512 batchの計算時間を比較してみました. 結果としては,マルチGPU化することで68秒 →59秒となり,計算時間が13%程削減しました. あまり変わらないですね(汗). GPU負荷がもっと大きな条件で比較する方が良いのかも知れません.

f:id:changlikesdesktop:20201202164804p:plain:w400
シングルGPUでの計算時間

f:id:changlikesdesktop:20201202164737p:plain:w400
マルチGPUでの計算時間

2. おまけ: U-Netで複数GPU

 GPU負荷の大きい,256x256画像のU-Netで複数GPUの効果を試してみました. GPU 1枚では経験にはbatch=8が限界でした. batch=12とか,batch=16でも動きますが,途中で止まったりします. マルチGPUにすると,batch=32でも動く様になりました. 長時間の計算は未試験ですが,安定して動くならばシングルGPUよりもかなり有利になりそうです.

 ちなみに,batch=8 → batch=32にすると単エポックあたりの計算時間が3/4程度になりました. それでも,目に見えた効果とは言いにくいなぁ...

f:id:changlikesdesktop:20201202165219p:plain:w400
U-NetのおけるシングルGPU,batch=8での計算時間.

f:id:changlikesdesktop:20201202165328p:plain:w400
U-NetにおけるマルチGPU,batch=32での計算時間.

3. むすび

 複数GPUにすると,本格的にディープ・ラーニングをしている気になりますね(笑). とはいえ,単純にGPUを何枚も刺せば計算が速くなる訳では無いようです(>_<). ライブラリ依存で実現しているので,最適化には限界がありますね.

 今回のトライで判らなかったのが,「2枚目をRTX 1080ではなくRTX 2080Tiにすればもっと簡単に速くできるのか?」です. これは是非確かめたい! 会社の環境と混ぜれば確かめられるので,こっそりやってみようと思います.

 以前に書いたソースを更新しています*3*4