メインコンテンツへスキップ

メモリをスワッピングしながら大規模言語モデル(LLama2)をフルパラメータでファインチューニングできるかどうか?

    背景

    大規模言語モデルの学習には、大量のメモリ容量が必要になります。
    例えば700億パラメータ(70b)のモデルを16bit変数で読み込むだけでも70 GB程度の容量が必要で、学習にはその10倍程度の容量くらいはあると安心です。

    ただし、学習に必要なGPUは高額(A100の80GBモデルは200万円超)なので、多額の資金が必要になります。

    打開策として、有名なQLoRAのほか、学習に必要なメモリをCPUやSSD(NVME)に移す(オフロード)するテクニックなどがあります。

    しかし数テラバイトのCPUメモリやSSDを増設するにも、それなりの手間とコストがかかります。

    そこで今回は、外付けSSDにメモリスワップさせる形で、大規模言語モデルのメモリをオフロードできないか、無謀な挑戦をしてみます。

    デバイス

    今回用いたSSDはこちら。メモリは4TB、転送速度は最大2GB/sです。

    更に早い規格(Thunderbolt™4: 40Gbps)も存在するようですが、用いるマシンの端子が対応しているか不明だったので、こちらの品にしました。

    GPUなどに比べ、圧倒的にSSDの転送速度が遅い点に注意が必要です。GPU(や最先端のCPUメモリ)だとテラバイトレベルの帯域があります。
    なので、今回の構成では、読み込み・書き込み速度が1/1000程度に落ちる可能性があります。

    実装

    スワップメモリの確保

    nvme対応のSSDであれば、単純にdeepspeedのjson設定を"nvme"に変更するだけでOKです(リンク)。
    今回のデバイスはnvme対応ではなかったので、cpuメモリにオフロードしつつ、不足部分をlinuxのスワッピング機能で補う戦略を取ります。

    SSDをフォーマットします。(今回のケースでは、SSDは/dev/sdb2で認識されました)

     sudo mkfs.ext4 /dev/sdb2

    スワップ領域を作り、有効化します。

    sudo mkswap -c /dev/sdb2
    sudo swapon /dev/sdb2

    4TBもあるので、処理にはそれなりの時間がかかります。
    一晩放置したら、無事にスワッピングメモリが追加されていました。

    画像
    topコマンドでのメモリ確認の様子。251 GBのCPUメモリが少なく見えるほどのSwap容量です。

    実装

    学習のコード自体は、以下の記事を流用しました。

    最大 150 token程度のテキストを学習させてみます。
    モデルにはLLama2を使いました。
    マシンはRTX3090(24 GB) x1 + CPU RAM 256 GBの構成です。

    メモリの使用状況

    ・7b (合計メモリ: 約 220 GB) 速度: 13 sec/iter
    6 GB(GPU) + 210 GB (CPU) + 0.7 GB (SSD)
    → 7bはメモリスワップなしで動きました。

    ちなみに、1500 tokenだと20GB程度のVRAMを要しました。

    ・13b(合計メモリ: 約310 GB) 25 sec/iter
    6 GB(GPU) + 220 GB (CPU) + 80 GB (SSD)
    → 256 GBのCPUメモリでは足りず、追加で80GB程度のスワップメモリが必要になりました。
    学習速度は7bと比べると半分程度に落ちました。
    ただ、モデルサイズが大きくなると学習速度は落ちるので、意外と頑張っているしている印象です。

    70b (out of memory)
    →cuda out of memoryでした。VRAMの増強が必要そうです

    注意

    13bモデルの学習中に、コンピュータがフリーズしてしまいました。なので、学習は数stepしか試せていません。
    使っているマシンのハードウェアが若干、不安定なことも関連かもしれませ。

    まとめ

    • メモリスワッピングを使えば、大型のモデルのフルパラメータ ファインチューニングができる可能性を示しました。

    • ただし、70bレベルだったりtoken長が大きいと、どうしてもGPUメモリが必要になるようです。

      • A100 x2 + 数TBの追加メモリで70bクラスも動くかどうか、気になるところです

    • スワッピングしすぎるとシステムが不安定になる感じなので、素直にNVMEでオフロードした方が良さそうです。







     
     
    化学・大規模言語モデル・ロボットなど 記事はメモ書きですのでご了承ください

    あなたへのおすすめ