このエラーをもっと詳しく書くと
CUDA out of memory. Tried to allocate 48.00 MiB (GPU 0; 4.00 GiB total capacity; 3.38 GiB already allocated; 0 bytes free; 3.44 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
簡単に言うと、
「PyTorchに一度に処理させるデータがメモリのサイズを超えています。見直してね。」
と言っています。
コードの中のbatch_size=16を見直せということですが、それは最後の手段として、何かもっといい方法ないか探しまくりました。
僕の目論見としては、「GPUメモリが一杯でもメインメモリが30Gも余っているので、何とかこっちも使って超高速に処理する」と虫のいいことを考えていました。
ひとつは、cupyを使う。cupyというのはnumpyのcuda版みたいなもので、大量の演算をGPUを使って高速に行ってくれるそうです。しかし、とりあえず大きなサイズがメモリに乗るというだけでパフォーマンスの改善にはつながらないらしい。バッチサイズを大きくする目的で使っても意味ないと書かれています。パフォーマンス自体は変わらないということでしょうか。
検索して出てきたもう一つの方法はtaskkillをつかう。
これは一つ手前のプロセスで強制的にメモリを開放する(メモリの内容を消す)ときに使う命令なのです。しかしtransformersの場合、読み込んだ学習済みモデルをメモリの中にため込んでいるのでこれを消してしまうと、あとの処理ができないのでこれはダメ。
というわけで2週間探しまくって結論としては、
「メモリサイズより大きいデータはメモリに渡せない」
というごく当たり前のことに行きつきました。
でどうなったかというと、batch_size=2まで減らして何とか動いています。
いろんな学習済みモデルが手に入る凄い時代ですが、メモリが4Gでも足りないって...。その便利さを使うために必要なのは「お金」ということなのでしょうか。