Stable Diffusionの学習速度をいろいろ比較する
タイトルの通り比較します。
学習設定
使うのは自前の訓練コード
学習用データセットは768×768画像128枚
Latentは事前に計算しておく(計測対象にはならない)
UNetのみを学習対象とする
torch2.0を使う
diffusersは0.16.1を使う
AMPを使用し、型はbfloat16にする
AdamW8bitを使う
バッチサイズはなるべく大きい値にする
WD1-5を対象にする(SD1.x系はもっと遅くなります)
nvidia-smiを適当にうちこんでVRAM使用量を記録します
プログレスバーの時間をそのまま記録します
ColabはCPUハイメモリを選ぶ
xformersの有無やgradient_checkpointingの有無で3パターン程度に分けて計測する
結果
samples/秒は1秒で何枚学習できるかという指標です。samples/costはsamples/秒からPaperspaceの場合1時間辺りの料金(ドル)、Colabの場合は1時間当たりのUnit数で割ったものです。Paperspaceは普通に借りる分にはちょっと高いので参考程度にしてください。
A100最強!コスパでもA100が最強のようですね。バッチサイズは学習結果にも影響するため、厳密には学習時間のみで比較することはできませんけどね。
考察
torch1.13 vs torch2.0
最初ローカルPCではtorch==1.13+xformers==0.0.15のままやるつもりだったんですが、RTX3090と同格だと思っていたA5000に大敗していたので、torch==2.0+xformers==0.0.19にアップグレードしました。計算速度もVRAM使用量もかなり変わりました。やっぱり3090とA5000は同じくらいですね。
xformers vs sdpa
sdpaはtorch2.0から実装された関数のことです。diffusers==0.16.1ではxformersを使わない場合、自動的にこれが使われるはずです。
今回の結果ではsdpaはxformersよりわずかにVRAM使用量が減少するものの、学習時間は遅くなるという感じみたいですね。GPU(または何らかの設定?)によってはかなり遅くなってしまいます。
gradient_checkpointingの有無
V100のみがgradient_checkpointingを使った方が早くなるという結果になりました。
gradient_checkpointingは逆伝搬に必要な順伝搬の履歴を全て保存せず、一部を残して必要になったら再計算するという手法です。再計算する分基本的に速度は落ちますが、VRAM使用量を減らすことができます。V100の場合はバッチサイズを上げることによる計算効率の上昇分が再計算分を上回るためにこういった結果になるのだと思います。これを使用せずに低バッチサイズで学習すると、T4>V100になるという結果は驚きでした。
ちなみに前も似たような計測をしましたが、当時の環境ではVRAM24GBでバッチサイズ4を確保できず、A5000やRTX3090でもgradient_checkpointingを使用した方がよいという結果になっていました。このあたりの認識を変えられたのが収穫です。
反省点
データセットの数を適当に128枚としましたが、もっといろいろなバッチサイズで割り切れる数にすべきでした。余りは指定したバッチサイズ未満で計算されてしまいます。
まとめ
torch==2.0、xformers==0.0.19が強い
V100(16GB)はgradient_checkpointingを使った方がよい
A100がコスパも最強そう(学習時間のみを考えれば)