こんにちは.changです. 今回はRTX 2080TiとRTX 1080を1枚ずつ使い,複数GPUでのディープ・ラーニングにトライします. RTX 2080Tiを2枚使うのが理想ですが,先日お話したように買えません*1. 旧機種との組み合わせで妥協する手もあるかと思い,試してみました.
0. 装着
サブマシン(以前のメインマシン)で使っていたRTX 1080を,メインマシンに移植しました. チップもメーカーもバラバラなので,見た目は若干悪くなります. RTX1080は外排気モデルではないので冷却不良が心配ですが,ファンの下にスペースがあるので大丈夫でしょう.
パソコンを起動して,GPUが認識されているか確認します.
tensorflowからも確認します.
$ python3 from tensorflow.python.client import device_lib device_lib.list_local_devices()
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も使われるようになります.
200 epoch,512 batchの計算時間を比較してみました. 結果としては,マルチGPU化することで68秒 →59秒となり,計算時間が13%程削減しました. あまり変わらないですね(汗). 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程度になりました. それでも,目に見えた効果とは言いにくいなぁ...
3. むすび
複数GPUにすると,本格的にディープ・ラーニングをしている気になりますね(笑). とはいえ,単純にGPUを何枚も刺せば計算が速くなる訳では無いようです(>_<). ライブラリ依存で実現しているので,最適化には限界がありますね.
今回のトライで判らなかったのが,「2枚目をRTX 1080ではなくRTX 2080Tiにすればもっと簡単に速くできるのか?」です. これは是非確かめたい! 会社の環境と混ぜれば確かめられるので,こっそりやってみようと思います.