機械学習モデルの学習を行う際に、様々なエラーに遭遇すると思います。
特にGPUを利用してモデルのトレーニングを行う際に、以下のようなエラーが発生して学習ができないことがあります。
RuntimeError: CUDA out of memory. Tried to allocate X.XX GiB (GPU 0; XX.XX GiB total capacity; XX.XX GiB already allocated; XXX.XX MiB free; X.XX GiB cached)
これは利用しているGPUのメモリが足りないため発生しているエラーです。
GPUを利用したモデルの学習においては、一般的に利用されているメモリからGPUメモリにデータを転送して計算を行います。
このとき、転送されるデータに対してGPUメモリが足りないと、CUDA out of memory のエラーが発生します。
従って、まずはGPUをどれだけ使えるか、ということを確認した上で、対処としては以下の方針が挙げられます。
GPUをどれだけ使えるかを確認する
まずはGPUのメモリをどれだけ学習に使えることができるのか、を確認します。
今回はCuDAを利用している場合を想定し、その専用コマンド nvidia-smi を用いて確認します。
$ nvidia-smi
Sat Dec 11 08:10:43 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.119.04 Driver Version: 450.119.04 CUDA Version: 11.0 |
|-------------------------------+----------------------+----------------------+
| 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 P100-PCIE... Off | 00000000:00:04.0 Off | 0 |
| N/A 41C P0 27W / 250W | 0MiB / 16280MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
今回の場合、Memory-Usageを見てみると利用可能なメモリ容量はは16280MiBとなっています。
トレーニング時にこのサイズを超えたデータがGPUメモリに転送されるとCUDA out of memoryとなることがわかります。
一度に読み込ませるデータのサイズを減らす
モデルに入力する学習データのサイズや量が大きいほど、GPUメモリ使用量も大きくなってしまいます。
従って、学習データのサイズや量を減らすことを考えます。
例えば、画像データであれば画像を縮小することでGPUメモリ使用量を抑えることができます。
transform = transforms.Compose([
transforms.Resize((224,224))
])
また、バッチサイズを小さくすることで、一度に読み込ませる量を減らすことができます。
train_dataloader = DataLoader(train_dataset, batch_size=小さい数字を入れる)
これにより、利用できるGPUメモリ内に収まるように調整することが可能です。
ただし、学習するモデルのサイズによっては収まらない可能性があります。
また、収まった場合であったとしてもリサイズやバッチサイズの変更によって、推論精度に影響が出る場合があるので注意してください。
利用するモデルの大きさを小さくする
利用する実装済みモデルのサイズが大きいほど、GPUメモリの使用量も大きくなります。
解きたいタスクに対して利用するモデルが大きすぎる状態になっていないか検討しましょう。
例えば、ResNet50とResNet152では利用するメモリの大きさが倍近く違います。
ResNet50で十分精度がでる可能性がある場合は、まずそちらを試してみるのが良いでしょう。
GPUのグレードを上げる
データをいじったり、モデルをいじったりしてもメモリが足りない場合は、使えるメモリを増やすほかありません。
したがってGPUのグレードを上げるか、GPUの枚数を増やしてパラレルな学習を行うことになります。
いずれにせよ、費用がかかることなので、プロジェクトの予算やお小遣いと相談して判断しましょう。
まとめ
本記事では RuntimeError: CUDA out of memory. Tried to allocate XXX GiB のエラーの対処法についての例をまとめました。
これらが全てではありませんが、ありがちな例なのできちんと抑えておきましょう!
モデルのサイズ、データのサイズ、GPUのサイズをきちんと把握して検証しよう!
コメント