🍣

[週次報告] 第5回 Team たぬき

2024/05/02に公開

https://matsuokenllmcommunity.slack.com/files/U05Q0P6T9UH/F06VBS99D5M/video1239750529.mp4

開発テーマ・概要

  • 当チームでは、上質な日本語データベースの構築と活用に焦点を当てた開発を行っています。具体的には、高品質な日本語テキストデータを大規模に収集・加工し、大規模言語モデルの学習に適したデータセットを作成することを目指しています。
  • データ収集においては、CommonCrawlをはじめとする大規模ウェブデータから日本語テキストを抽出し、ルールベースのフィルタリングに加え、人手によるアノテーションを行うことで、クリーンで高品質なデータを選別します。また、学術論文や書籍など、ウェブ以外の日本語データも積極的に取り入れ、多様性に富んだデータベースの構築を目指します。
  • 収集したデータは、先進的な自然言語処理技術を駆使して加工・統合し、大規模言語モデルの学習に最適化します。具体的には、文書のクラスタリングや重複除去、カリキュラム学習に対応したデータの順序付けなどを行います。
  • さらに、構築したデータベースを用いて、最先端の大規模言語モデルを学習・評価し、日本語処理タスクにおける性能向上を図ります。

チーム全体の開発状況

  • 何はともあれ本番環境での学習開始と高速化を最優先に活動中。状況は以下の通り。

本番環境での学習の状況

  • データ準備
    • 200Bでtokenize済み
  • モデル学習コード準備
    • 10bクラスのコードを整備
  • シングルGPUでの稼働確認、実績
    • 済み
  • マルチノードでの稼働確認、実績
    • 10bで動作確認済み
  • うまくいきそうか計画の確信度

開発のマイルストーン

  • 事前学習: マルチノードでの練習
  • データセット: 50bに向けた準備
  • 指示データセット: webサイト運営、データ作成など

サブチームからの情報共有

サブチーム1: 指示データセット

やったこと

分かったこと

  • 誤植修正機能が欲しい

次やること

  • 締め切り 5/10 データセットの引き続き作成

サブチーム2: 事前学習データセット

※ 指示データセットや学習実行の方が優先なため規模縮小しながら進行
※ 50Bに備えたデータセット作成を行う

やったこと
<50Bに備えて>
1)CommonCrawlの日本語データ抽出 (50B用)
(背景)
10B用に作成したデータセットはwetというすでにCommonCrawl側がサイトからテキストを抜いて生成されたものを使用していた.しかし, wetではヘッダーやフッター、自動挿入された要素などを抜きにくい.よってテキストを抜く前のサイト状態から処理を行い, 高品質なテキストを作る

(状況)
土曜日にCommonCrawlについての打ち合わせを進行. 作業の分担を行った. warcからの日本語テキスト抽出をwetの抽出でも使っていたdataflowでできるように実装中 (1-2日で完了予定)
<10Bに対して>
1)gcs(シンガポール)に10B学習用のデータセットをアップロードし,本番環境に転送した.

分かったこと
1)gcs(シンガポール リージョン)にデータをアップロードしておくと,最高400MB/s程度の転送速度でデータを送れる. 都度データの保存はgcsを活用できるとよさそう.

次やること
1)commoncrawl warcからの日本語データ抽出 (続き, 並内)
2)commoncrawl warcから抽出される想定のテキストの処理 (内藤さん中心)

サブチーム3: Code

やったこと

  • mixtral 8x22b instructの自動応答システムを構築した
    • かなり完成度が高いので、自動でQ&Aを生成可能
    • 1日あたり1万件くらいのペース
    • 人間のチェック and 微修正をするシステムを作りたい
  • gc環境で動作確認中(4/23)
    • マルチノードでの動作確認までOK
    • flopsが想定の1/2~1/3くらいしか出ない(A100レベル)ので、色々と確認中
      • 200b tokenを10bモデルが学習させるのに、普通にやると2 monthかかってしまう

分かったこと

  • 結構難しい
    次やること
  • 速度改善

サブチーム4: その他

やったこと

  • 古えのED法で遊んだ

金子勇さんのED法を実装してMNISTを学習させてみた - Qiita

分かったこと

  • ED法で学習はできる

次やること

  • 1ビットをED法に組み込むことはできるか

ディスカッション

  • 踏み台サーバー

事前学習: 本番の開発記録メモ

畠山日記

ROPEの検討

7bモデルでloss変化を比較。緑系がropeなし、橙系がropeあり

  • ropeがある方が、若干、lossの減りが早い。
  • しかし、1M頃からは、あまり有意差がないように思われる
  • lossの変動が激しいのは、やや気になる
    • シングルノードの8GPUで学習
      • バッチサイズが32と小さめなので、loss変動が大きい可能性があり、上のグラフはスムージングをしている
      • マルチノード化してバッチサイズを稼ぎ、lossを安定化させるというアプローチは有効かもしれない
      • が、最大3nodeなので、対した差はないかもしれない
  • megatronのcheckpointファイル群から、huggingface model形式に変換する標準scriptで、ropeを有効化していると、エラーが出る。
    • GPT2とは異なるモデルアーキテクチャのため。
    • 修正scriptを書けば解決するが、lossレベルで有意差が顕著には出てない模様なので、費用対効果の面で、対応するかを要検討
  • 蛇足ながら、夜に回して、翌日の朝、4時にプロセスがクラッシュしていた。原因はエラーログを見ても不明。
    • たまたま、朝5時に様子を見たので、早いタイミングで復帰できた。

H100系での速度検証

H100はA100よりも3倍弱、llmの学習で早いとの報告がある。

サイバーエージェントが手がける日本語LLM開発 MLエンジニアが語る「Weights & Biases」の活用

  • 自身が別途、試したA100x8環境では、学習時の速度の目安が100-150TFLOPS程度であった。
    • 上記サイトでは180TFLOPSなので、概ね同じ。
  • 上記サイトでは、H100で470TFLOPS程度の値が紹介されている。
    • ただし学習条件などは不明

4/24までの学習結果は以下の通り。H100x8の1-3ノード環境

  • node global batch size (b zero stage pp mp activation_checkpoint vram小 vram大 TFLOPs ワット数目安
    1 64 2.7 1 1 1 FALSE 80 80 197.52 490-600
    1 64 2.7 1 2 2 FALSE
    1 16 2.7 1 2 2 FALSE 80
    1 80 7 1 1 1 TRUE over over
    1 64 7 1 1 1 TRUE over over
    1 32 7 1 1 1 TRUE 79 80 240 400-650
    1 32 7 1 1 1 FALSE 79 80 244 480-680
    1 32 7 1 1 1 FALSE 79 80 244 480-680
    1 32 13 1 1 1 FALSE over over
    1 32 10b 1 1 1 FALSE over over
    1 24 10b 1 1 1 FALSE over over
    1 16 10b 1 1 1 FALSE 80 80 180.72 500-600
    2 32 7 1 1 1 FALSE 79
    2 32 7 1 2 1 FALSE 48 48 112 200-300
    2 48 7 1 2 1 FALSE 59 59 132 200-400
    2 32 10a 1 1 1 FALSE 64 80 72.76
    2 32 10a 0 1 1 FALSE メモリオーバー メモリオーバー
    2 16 10a 0 1 1 FALSE メモリオーバー メモリオーバー
    2 32 10a 1 1 2 FALSE 71 71 104
    2 32 10a 1 2 2 FALSE 62 62 124.36
    2 32 10b 1 4 4 FALSE 68 69 63 150くらい
    2 32 10b 1 2 2 FALSE 68 69 118.12 200-450で変動
    2 32 10b 1 6 6 FALSE
    2 32 10b 1 2 1 FALSE 60 65 116 200-400くらい
    2 32 10b 1 4 1 FALSE 55 55 77.89 150-400
    3 96 7 1 3 3 FALSE
    3 72 7 1 3 3 FALSE
    3 96 7 1 3 1 FALSE 65 66 102 130-500
    3 96 7 1 3 2 FALSE
    3 96 7 1 6 1 FALSE 50
    3 96 7 1 3 1 TRUE 37 38 110 110-680
    3 192 7 1 3 1 TRUE 43 44 116 110-700
    3 768 7 1 3 1 TRUE over over
    3 384 7 1 3 1 TRUE over over
    3 288 7 1 3 1 TRUE over over
    3 240 7 1 3 1 TRUE over over
    3 48 13 1 3 1 FALSE 69 70 107 10-500

要点

  • 条件
    • 学習コードはMegatron-DeepspeedのGPT-2をベースとしたもの(参考)
    • マルチノードでの通信を最大化するGPUDirect-TCPX は使用せず、特に最適化していない状態
  • 概要
    • 1 node
      • 2.7bモデルで200TFLOPS、7bモデルで240TFLOPS程度
        • A100では見ない値なのでH100の効果はあり
        • ただし、サイバーエージェント(470TFLOPS)の半分程度の値にとどまる
        • しかし、電力消費は最大700Wのうち、500-600程度で推移。nvidia-smiで表示されるGPU稼働率も概ね100%程度(ただし、50%程度になるGPUがちょくちょくある)
          • このscript、モデル条件では、わりと上限に近い値が出ている可能性がある
    • マルチノード
      • FLOPSが50-120程度まで激減。
        • もはやA100で良いレベルのFLOPS
      • 電力消費も100-500W程度でブレながら推移するケースが多数
      • 通信がボトルネックで、GPUがサボっている可能性が高い
      • 通信面の設定の見直しが必要(特にGPUDirect-TCPX)
      • pipeline parallel, model parallelなども軽く検討済み

マルチノードでのトラブル対応(亡霊プロセス問題)

  • ハイパラの最適化などで、学習のkillなどを繰り返していると、本来動くはずの条件でも、cuda out of memoryのエラーが発生する。
  • 過去のプロセスが残り、VRAMを占領しているケースがあり
    • マルチノード学習の場合は、すべてのノードでこの問題が発生する。
    • 今回は3ノードと少なかったので、sshで各ノードに入って、プロセスを確認して、killしていった。
      • 学習を始める前に、この作業を毎回行ったほうが安心
  • 特に苦戦したのは、nvidia smiやps -aでコマンドを叩いても、当該プロセスが存在しないにも関わらず、一部のvramを専有しているケース(下記)

解決策として、sudo権限でnvidia関連のプロセスを一覧で表示させ、怪しいprocessをkillすれば良いことが分かった。

sudo fuser -v /dev/nvidia*

学習計画をどうするか問題

当初はH100の性能がA100の3倍と想定し、10-13bモデルで200b tokenを学習させる計画であった。

ただし、上記のFLOPS問題が顕在化し、刻一刻と学習期間も減少していくので、いくつかの代替案も踏まえながら、作業を進めることにした。

チーム向けにslackで打ったメッセージは以下の通り(一部改変)

ファインチューニングを考えると、事前学習に使える日数は、あとわずか20日くらいしかない!ことがわかっています。なので、以下のベースライン戦法で進める予定です。

状況
・1 node, 8gpu, 7 bモデルでは、約240TFLOPSと、そこそこの速度で学習ができる(20日で70b token程度?)
・一方で2,3ノードにすると、50-150TFLOPSまで速度が激減してしまい、ノード数が少ないほうが、むしろ早く学習が終わるレベル、という残念な状況が発生中
→ gpu使用率が顕著に下がる。、いつ・どの程度まで改善できるかは未知数

戦略
・3つの異なるデータセットを学習した7bモデルをそれぞれのノードで独立に学習させ、推論時に切り替えて使う(文字通りの、Branch-Train-Merge: BTM)。 はじめの70b tokenほどが、学習される予定で、ドメインがあまり被らないようになっています。
データセット1: 現在の200b (英語&コード→日本語A→B→C→D→E)
データセット2: 日本語E→D→C→B→A
データセット3: 日本語C→B→A (& 全体的に英語少し多め)
(データセット2,3は、即興で作成中です。)

・今週一杯くらいまでの期限付きで、マルチノードなどの条件検討をしたいときなどは、上記の学習を一時的に止めて、検討する。それ以外の時間帯は、上記モデルを学習させておく。

・かなり粗い点が色々とあるが、個人的な手応えとしても、色々な人の話を聞く限りでは、最終性能への寄与度は ファインチューニング>>> 事前学習 なので、
チームとしてはファインチューニングにフォーカスしていく (自動生成したデータセットのアノテーションなど)

ーーー
細かな点

・model sizeの20倍くらいのtoken数が良いという定説はあるが、BTMでは、1つのモデルあたりのtokenは、もっと少なくても、多分大丈夫そう
https://arxiv.org/abs/2208.03306

・いつ学習を止めるかわからないので、learning rateのスケジューラーなど、ちょっと困る

・ropeという手法を用いると、効率的な学習ができるが、モデル構成が変わるため、標準コードでhuggingfaceへの変換ができない。明日、試行錯誤して、ropeを使う/使わないを決定する

・240TFLOPSも、h100としてはまだちょっと遅い。 A100で100-150TFLOPSくらいなのに対し、H100は3倍弱の性能を出せると一般には言われている。

・シングルノード/マルチノードともに、pipeline/model parallel, activation checkpoint, (transformerengine)など、ぱっと思いつく手法は色々と試した状態で、個人的には、期待値*の高い方法があまり思い浮かばない状態。
*期待値の高い方法≒実装の手間が現実的な時間スケールであり、きちんと動くという確信が持て、速度向上が見込める方法

7bモデルの動作確認

1Mstepほど、ropeなしで学習させたモデルについて、動作確認

学習時に、標準コードに加えて、以下のargumentを追加してしまったせいか、convert to HFのscript実行時に、key not foundエラーが発生

    --normalization rmsnorm \
    --attention-dropout 0 \
    --hidden-dropout 0 \

センスは悪いが、エラーが発生したtransformersライブラリの中身を書き換え

~/miniconda3/envs/.venv_train/lib/python3.9/site-packages/transformers/models/megatron_gpt2/convert_megatron_gpt2_checkpoint.py

final layerのbiasを省略するargumentだったようで、final_layernorm.biasがないとのエラーがでる。ここをtryで逃げるというやり方で対応。

無事にconversionができた。軽く動かした結果。

コードを大量に学習させているせいか、隙あらば、コードを生成する感じの事前学習になっている。

広告関連のテキストは出ないので、フィルタリングを頑張った成果はあった。

モデルのアップロード: 動きそうだが、時間がかかるので中断

ファインチューニング: cuda out of memory: 流石にそんなはずはないので、設定を見直す。

4/25時点での感想

  • マルチノードは大変。これらを、きちんとこなしている方々を、大いに尊敬するようになった。
  • わりと計画的・かつ保守的な安心安全プランで、データセット作成やモデル構築の準備を進めてきたつもりだが、予期せぬトラブルが多発し、なかなか大変な状況である。
  • スケジュールもタイトなので、瞬発力・合理的な判断・24時間レベルで作業し続けられるバイタリティなどが必要だと実感。 この業界の方々を、大いに尊敬するようになった。

deepspeed関連

速度向上せず

  • 設定

    {
      "train_batch_size": GBSIZE,
      "train_micro_batch_size_per_gpu": MBSIZE,
      "steps_per_print": LOG_INTERVAL,
      "zero_optimization": {
        "stage": ZERO_STAGE
      },
      "gradient_clipping": 1.0,
      "prescale_gradients": PRESCALE_GRAD,
      "zero_allow_untested_optimizer": false,
      "aio": {
        "block_size": 1048576,
        "queue_depth": 16,
        "single_submit": false,
        "overlap_events": true,
        "thread_count": 2
      },
      "flops_profiler": {
        "enabled": true,
        "profile_step": 20,
        "module_depth": -1,
        "top_modules": 1,
        "detailed": true,
        "output_file": null
      },
      "fp16": {
        "enabled": true,
        "loss_scale": 0,
        "loss_scale_window": 500,
        "hysteresis": 2,
        "min_loss_scale": 1,
        "initial_scale_power": 11
      },
      "wall_clock_breakdown": false,
      "wandb": {
        "enabled": true,
        "group":"test_group",
        "project": "pretrain"
      }
    }
    
    

4/26 FLOPSの劇的向上

global batch =1024, micro batch = 1 のような設定にしたら、flopsが1.5倍程度まで、上昇した。

詳細は来週以降の報告に記載予定。

Discussion