RuntimeError: CUDA out of memory. Tried to allocate XXX GiB のエラーの対処法

AI

機械学習モデルの学習を行う際に、様々なエラーに遭遇すると思います。

特に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のグレードを上げる or 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のサイズをきちんと把握して検証しよう!

コメント

タイトルとURLをコピーしました