😊

東大LLM開発プロジェクト進捗状況|日本語データベース特化チーム

2024/05/23に公開

第1回:週次報告

開発テーマ・概要

  • 私たちのチームは、大規模言語モデル(LLM)の開発に取り組んでいます。具体的には、日本語に特化したLLMの開発を目指し、データセットの収集・加工、モデルの学習、推論システムの構築などを行っています。

チーム全体の開発状況

  • 現在、各サブチームが並行して作業を進めています。データセットの収集・加工では、CommonCrawlやPMC OAなどの大規模データから日本語テキストを抽出し、クリーニングを行っています。モデルの学習では、0.3bモデルの学習を完了し、1Bクラスのモデルの学習に向けた準備を進めています。また、独自のパイプラインの構築や、カリキュラム学習の検討なども行っています。

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

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

やったこと

  • インストラクションデータのタスク案をmiro上で作成し、タスク案をクラスタリング
  • 評価データセットの確認
  • データ収集用のWebページを作成開始

分かったこと

  • プログラミングタスクが評価データの一部であるため、LLMに実装力を身につけさせるべきかは要検討事項である。
  • インストラクションデータ作成ガイドラインを作る必要性がある。

次やること

  • クラスタリングしたタスクをタスクカテゴリとし、収集ページへ反映させる。
  • データ収集用のWebページを3月中を目処に取り組んでいただいている。
  • インストラクションデータ作成ガイドラインの検討。

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

やったこと

  • CommonCrawl日本語データ 共同抽出 - チーム内外28名が共同して高速で進められています。
  • CommonCrawl+mC4データ クリーニング タスク - 簡単なデータクリーニングのコードまでは作成済み。現在は既存のコーパス作成処理のコード化(コードがない場合)や、その処理を一部データに適用した結果の評価を行っています。
  • PMC OA (学術データ) - タスクの分担は終了。現在はxmlから使用可能なライセンスのデータを抽出する方法の検討と、全体で必要なクリーニング処理の洗い出しが進んでいます。
  • 英語データセット - The PileとSlimPajamaなどデータセットの中身のきれいさを比較。SlimPajamaデータセットのテキストの問題点を分析。
  • コーディングデータセット - The Stack v2データセットの確認と、言語と使用データ数を指定してThe Stack v2のデータをダウンロードする関数の実装。
  • 数学データセット - OpenMathInstruct-1-1.8m-jaの調査がスタート。

分かったこと:

  • CommonCrawl日本語データ 共同抽出 - CC-MAIN-2023-50のsnapshotにおいて90000バッチ中30000バッチは終了。
  • CommonCrawl+mC4データ クリーニング タスク - 既存のコーパス作成に使用された処理のコードは公開されていないことが多い。
  • PMC OA (学術データ) - 処理は多岐にわたり、分散処理や並列処理をしないとすべては加工できない。
  • 英語データセット - SlimPajamaは広告やタグの羅列などのデータが含まれているがThe Pileよりはきれい。そのため、SlimPajamaを採用することを検討。
  • コーディングデータセット - The Stack v2はそのままでもきれいなのでそのまま使用することに。
  • 数学データセット - まだ検討中。

次やること:

  • CommonCrawl日本語データ 共同抽出 - CC-MAIN-2023-50のsnapshotにおいて来週まで50000/90000レコードを目指す。また複数のsnapshotから日本語抽出するためにGCPサービスを検討 (Namiuchi)。
  • CommonCrawl+mC4データ クリーニング タスク - 既存のコーパス作成処理のうち未実装のものは実装。実装済みのものは、現在のテキストデータに適用した際の評価を行う。
  • PMC OA (学術データ) - xmlデータからテキストを抽出したり、クリーニングする処理を更に作成 + 並列・分散処理の検討。
  • 英語データセット - SlimPajamaデータセットのフィルタリングとデータ加工を進める。
  • コーディングデータセット - 特になし。
  • 数学データセット - まずは調査+データのロード。次に数学テキストとコーディングテキストを分ける関数の実装。
  • NHK for SCHOOLのスクレイピング - 畠山氏発案のNHK for SCHOOLの諸々のテキストデータのスクレイピングコードを作成中(内田)。

サブチーム3: Code

やったこと:

  • 標準コードのトレース
  • 独自のパイプラインの構築
  • 0.3bモデルの学習(wikipediaやmc4) (詳細)
  • カリキュラム学習の検討
  • 計算量の試算(詳細)

分かったこと:

  • 標準コードはパイプが殆ど繋がっていない
  • カリキュラム学習では、学習初期に様々なtokenを学ばせておかないと、局所解に陥る
  • クリーニングが性能に与える影響の検証

次やること

  • 1Bクラスの学習
  • Branch-Train-Merge的な学習
    • 学習: データセットの分割
    • 推論: アルゴリズム設計& HuggingFaceモジュール化の検討
  • TransformerEngineの試行錯誤

サブチーム4: 遊撃隊

やったこと

  • 毎週金曜日の19:00を遊撃隊のミーティングとする
  • まずは、A100環境で提供コードを動かしてみた。
  • Mambaあたりの調査ページを作った。
  • ゆるくミーティングを行った。

分かったこと

  • 環境がないため、GCP環境が来るまで調査する⇒3月18日にGCP環境が来た⇒各々提供コードを動かしてみる。
    • 提供コード事前学習まで動かした

次やること

  • 提供環境で各々Mambaを動かしてみる

ディスカッション

  • チーム編成など、様々なディスカッションを行いました。

その他

  • 日本語に特化したLLMの開発には、高品質な日本語データセットが不可欠です。データセットの収集・加工には時間がかかるため、早めに着手し、データの質にこだわることが重要です。

第2回:週次報告

チーム全体の開発状況

  • 現在、以下のチームに分かれて並行して作業を進めている
    1. 指示データセット:Insturuction Tuning用データセット収集・加工・作成
    2. 事前学習データセット:事前学習に用いるデータセットの収集・加工を行う班
    3. Code:チーム用のコード構築、コード実行時の計算量や所要時間予測
    4. 遊撃班:プロジェクトに必要な様々なことを実行
  • 各サブチームが着実に進捗を上げている。データセットの収集・作成、モデルの学習・評価の練習が行われている。

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

  1. 指示データセット
    • タスクカテゴリの作成と日本語指示データセット収集Webページの作成が完了。
    • 追加機能要望として、ランダムタスク提案、サンプル回答表示、LLMによる入力サポートが挙げられた。
  2. 事前学習データセット
    • CommonCrawlから日本語データの抽出を行った。
    • アノテーションアプリを作成し、良質な日本語テキストの選別を行う予定。
    • 複数のリソースを活用し、効率的にデータセットを作成できることがわかった。
  3. Code

ディスカッション:

  • Branch-Train-Mergeのデータセット配分について議論があり、事前学習データは尖らせず、ファインチューニングで個性を出すのが良いかもしれないという意見が出た。
  • インストラクションには2ターンが必要だと考えられている。

TODO:

  1. 指示データセット
    • 現状のQAフォームへタスクリストを反映する。
    • LLMによる入力サポート機能の調査・実装検討を行う。
  2. 事前学習データセット
    • 注力するデータセットを決定する(peS2o, Wiki books + CommonCrawl pdfデータ, コーディングデータセット, 英語データセットなど)。
  3. Code
    • ファインチューニング条件が評価指標に与える影響を検証する。
  4. 全体
    • Branch-Train-Mergeのデータセット配分を決定する。

第3回:週次報告

チーム全体の開発状況

  • 現在、以下のチームに分かれて並行して作業を進めている
    1. 指示データセット:Insturuction Tuning用データセット収集・加工・作成
    2. 事前学習データセット:事前学習に用いるデータセットの収集・加工を行う班
    3. Code:チーム用のコード構築、コード実行時の計算量や所要時間予測
    4. 遊撃班:プロジェクトに必要な様々なことを実行
  • 各サブチームが着実に進捗を上げている。データセットの収集・作成、モデルの学習・評価の練習が行われている。

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

  1. 指示データセット
    • タスクカテゴリの作成と日本語指示データセット収集Webページの作成が完了。
    • 追加機能要望として、ランダムタスク提案、サンプル回答表示、LLMによる入力サポートが挙げられた。
  2. 事前学習データセット
    • CommonCrawlから日本語データの抽出を行った。
    • アノテーションアプリを作成し、良質な日本語テキストの選別を行う予定。
    • 複数のリソースを活用し、効率的にデータセットを作成できることがわかった。
  3. Code

ディスカッション:

  • Branch-Train-Mergeのデータセット配分について議論があり、事前学習データは尖らせず、ファインチューニングで個性を出すのが良いかもしれないという意見が出た。
  • インストラクションには2ターンが必要だと考えられている。

TODO:

  1. 指示データセット
    • 現状のQAフォームへタスクリストを反映する。
    • LLMによる入力サポート機能の調査・実装検討を行う。
  2. 事前学習データセット
    • 注力するデータセットを決定する(peS2o, Wiki books + CommonCrawl pdfデータ, コーディングデータセット, 英語データセットなど)。
  3. Code
    • ファインチューニング条件が評価指標に与える影響を検証する。
  4. 全体
    • Branch-Train-Mergeのデータセット配分を決定する。

第4回:週次報告

チーム全体の開発状況

事前学習データ:

  • CommonCrawlから1TB分の日本語データを収集済み。現在、クリーニングとhuggingface datasets化を進めている。
  • 学術データ(PMC OR)の収集・加工を検討。
  • 英語とプログラミング関連のデータは加工済み。
  • データセット共通処理(クリーニング、重複削除、統合など)のパイプラインは概ね完成。

指示データセット:

  • カテゴリー作成とタスクリストの作成が完了。
  • データ収集用のウェブアプリを構築中。読み込み速度の改善を実施。
  • 人手によるデータ作成は未着手。Mixtral系モデルを用いた人工データセットの作製も検討中。

コード:

  • 2.7Bモデルで30Bトークンの事前学習を試験的に実施し、動作を確認。
  • マルチノードでの事前学習の動作確認が完了。
  • データクリーニングのパイプライン(ルールベース、重複削除、カリキュラム学習用の統合など)を作成。
  • パープレキシティベースのエキスパートモデル切り替えアルゴリズムを実装。最適化は今後の課題。

その他:

  • sakanaAIを用いたモデルマージの実験を実施。適切な割合でのマージにより性能向上を確認。
  • A100 × 8でのDockerでの動作は未達成。マルチノードでの検証を予定。
  • ファインチューニングとアラインメント(PPO, DPO)の検討を進める。

自動文字起こし&Claude3による要約(若干、手で修正)

  1. インストラクションデータセットについて
  • カテゴリー作成が完了し、QAフォームへのタスクリストの反映も終わった。
  • ウェブアプリの作成が進行中で、現在は読み込み速度など改善されている。
  1. 事前学習データセットについて
  • コモンクロールの日本語テキストは1TB分のデータが収集済み。クリーニングが課題で、ルールベースのフィルタリングに加え、クリーンなテキストを判断するシステムをサイトが稼働。
  • 英語とプログラミングのデータは加工済み。PDFやNHKのデータもTODOとしてある。
  • データセット共通処理はほぼ固まった。データの種類や形式の確認が必要。
  1. コードについて
  • 2.7Bのモデルで一週間かけて30Bトークンの事前学習を試験的に実施し、動作を確認した。
  • マルチノードでの事前学習が動作することを確認。設定周りは把握できた。
  • データクリーニングのパイプラインを作成。ルールベースの清掃、重複削除、カリキュラム学習的な統合などを行う。
  • 事前学習データのデッドラインを決める必要がある。
  1. エキスパートモデルの切り替えについて
  • パープレキシティのみでモデルを切り替えるのは、精度面で課題がある。
  • 日本語データが不足しており、専門家モデルを作るのは難しい。ジャンルには分かれているが、それを専門とするほどではない。
  1. LLMJPベンチマークについて
  • 選択式問題が難しく、事前学習だけでは解けない。JCommonSenseQAなどは数百件の学習が必要。
  • 他のタスクでも最低数十から数百件の学習が必要。タスクAを学習してもタスクBは解けないことが多い。
  • MT-benchは極めて難易度が高く、そもそもどう手をつけたらいいのか検討中。
  • 対上質なデータセットを人手で作成したり、大規模モデルの出力を学習することを検討している。
  1. その他
  • 英語モデルと日本語モデルをマージしただけでも、日本語の数学問題に対する性能が上がった。
  • DPO とRLHF (Reinforcement Learning from Human Feedback) の比較について議論があった。
  • 未知のタスクへの対応として、23年8月以降の新しい情報を問う問題などが想定される。

インストラクションデータと事前学習データの準備を進めつつ、ベンチマークも意識した検討していく必要がありそうです。コード周りは順調に進んでいるようですが、エキスパートモデルの切り替えやデータ不足の問題にも取り組んでいくことが求められます。

開発のマイルストーン

  • 事前学習データ

    • CommonCrawl系
      • 済: X snap shot分、 収集完了、アップロード律速
      • 未: 精密なクリーニング
    • きれいなテキストかどうかの判定
      • 済: サイトの構築
      • 未: 実際のデータ処理
    • pdf、その他
  • 指示データセット

    • 人手
      • 済: ブレインストーミング
      • (済): 入力用サイトの構築
      • 未: 実際のデータ作製
    • 人工
      • 未: Mixtral系モデルを用いた人工データセットの作製?
  • コード

    • 事前学習の練習
      • 済: 2.7b modelで30bの練習が完了(A100x8)
      • 済: マルチノードでの動作確認が完了(L4 x 8 x 2)
    • データセットのクリーニング to トークナイズ
      • 済: ルールベースの清掃
      • 済: 並列処理+C実装コードによるdedup
        • 教師なし学習でクラスタリングすることで、計算速度の削減と並列化を実現
      • 済: 種々のデータ統合(カリキュラム学習に対応)
      • 済: トークナイズまでの処理
      • 未: Branch-Train-Mergeのためのweb系データのクラスタリング(やる必要があるか?)
    • Branch-Train-Mergeでのモデル切り替え
      • 済: perplexityでの切り替えアルゴリズムの実装
      • 済: Transformersのmodel moduleへの埋め込み
      • 未: 切り替えアルゴリズムの最適化
    • ファインチューニング・評価
      • 済: 評価システムの動作確認
      • (済): 特定のスキルを習得するために必要なデータ量の推定

ディスカッション

  • 事前学習データセットのスケジュール感について
    • なんだかんだで 1 weekはかかる模様
      • クリーニング&クラスタリングで3日ほど
      • dedup, 書き出し, tokenizeで2,3日ほど?
    • データ提出の締め切りを作る必要あり
      • (数百GBクラスの重たいデータについては)4/10頃までには、データセット&クリーニングスクリプトを確定させたい
    • 指示データセットの作製について
      • 人力をそろそろ
      • mixtral自動生成
    • multi nodeの練習について
  • 数学のデータセット(中学くらい)を自動翻訳して、学ばせる?
    • 事前学習に含める
  • 効率的な学習について
    • instruction tuningでは、「誤答」に対する負のフィールドをかけられない
      • 強化学習やDPOが効果的かも?という議論

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

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

やったこと

  • 指示データセット収集Webサイト
    • 最低限動くようになった
    • 通信の遅延、タイムアウトがあったが改善できた

分かったこと

  • インフラで想定外のことが起きやすい

次やること

  • ガイドラインのページを作成する
  • データを datasets 形式 (もしくはcsvなどの扱いやすい形式) に変換するコード

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

基本方針
1)期間ごとにメインとなるデータセットを決めて、
そのデータセットを主に用意する
2)そのほかのデータセットについても, メインとなる
データセットが入れ替わった時にスムーズにいくように進める
3)高品質なデータセットの構築のため、人間のアノテーションをする

内容

1)AnnotationAppの作成
AnnotationAppは人の観点から高品質なデータをアノテーションしデータセット中の品質のいいデータを抽出できるようにするアプリ

やったこと

  • 評価基準の策定と問題の作成

    • 文章の繋がりと内容の質を考慮した評価4段階を作成
    • 評価問題の作成
      • アプリからの回答ができるようにした(下の画像は実際のアプリ画面)
  • テスト版アプリのリリース(アプリのURL

    • 評価の設問は適切か、継続して評価できるか検証するために3/30からテスト版提供を開始
    • ルールベースでは省けない人の判断が必要なアノテーションデータセットをCommonCrawlから抽出して、アプリのDBに約6500件追加
  • 機能の追加

    • アノテーションテキストに対してフィードバックできる機能を追加
    • カテゴリ分類する項目の追加
  • 約280件でのデータセットのアノテーションを実施

    • 主に3人で実施中
  • fastetextでの分類コードの実装方法

    • アノテーションしたデータセットをfasttextで分類するコードを作成
      • fastetextでの分類コードの実装方法
        • 多クラス分類(参考)の実装

分かったこと

  • テスト版での継続利用を確認できた。

    • 評価は3人、3日で約280レコードほどの評価
  • 1000レコードには時間かかりそう

    • よりスピード上げるために本番運用として周知して、参加を募る
  • 約280レコードでもある程度良い悪いの分類はできていそう。

    • fasttextで分類したテキストをt-sneで可視化(perplexity=50)

    • 可視化code

      from matplotlib import rcParams, cm
      import pandas as pd  # pdが必要です
      from sklearn.manifold import TSNE
      import matplotlib.pyplot as plt
      import numpy as np  # Ensure numpy is imported
      from fasttext import load_model
      
      model = load_model('20240402model.bin')
      
      # 日本語フォントの設定
      rcParams['font.family'] = 'sans-serif'
      rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'VL PGothic', 'Noto Sans CJK JP']
      category_dict = {100: 'very_good', 75: 'good', 50: 'normal', 0: 'bad'}
      def remove_line_breaks(text):
          return text.replace('\n', '')
      
      # データの読み込みと前処理
      features_df = pd.read_csv('load.csv', sep=',')
      features_df['feedback_text'] = features_df['feedback_text'].apply(remove_line_breaks)
      features_df['evaluated_point'] = features_df['evaluated_point'].map(lambda x: category_dict[x])
      categories = features_df['evaluated_point'].astype('category').cat.codes.values.tolist()
      catnum = max(categories) + 1
      
      # テキストからベクトルへの変換
      sv = []
      for sentence in features_df['feedback_text']:
          _sv = model.get_sentence_vector(sentence)  # モデルが定義されていることを確認
          sv.append(_sv)
      sv = np.array(sv)
      
      # t-SNEによる次元削減
      tsne = TSNE(n_components=2, random_state=0, perplexity=50, n_iter=2000).fit_transform(sv)
      
      # 可視化
      plt.figure(figsize=(10, 10))
      
      # カテゴリごとにプロット
      for cat in np.unique(categories):
          # カテゴリに該当するインデックスを取得
          indices = [i for i, c in enumerate(categories) if c == cat]
          # 凡例に表示するラベル名
          label = features_df['evaluated_point'].astype('category').cat.categories[cat]
          # 散布図のプロット
          plt.scatter(tsne[indices, 0], tsne[indices, 1], c=[cm.jet(cat / (catnum - 1))], label=label, alpha=0.5, s=10)
      
      # 凡例の追加
      plt.legend()
      
      # タイトルと軸ラベルの設定
      plt.title('フィードバックテキストのt-SNEビジュアライゼーション(対象:284レコード,モデル fasttext)')
      plt.xlabel('t-SNE特徴量1')
      plt.ylabel('t-SNE特徴量2')
      
      # グラフの表示
      plt.show()
      
      

    • badの領域にnormal/normalにvery_goodがいたりする。

  • 280件での分類タスクを実装した

  • 1000件のデータセットを目処にアノテーションを進める作業分担が必要

次やること

  • 本番運用のアナウンス
    • 畠山チーム内外へのアナウンスと参加者の募集
    • 必要に応じて、アノテーション評価認識の共有と修正
  • fasttextでの分類モデルの作成
    • 1000件のアノテーションデータでの実装
      • モデルの性能を見つつ、アノテーション数を増加していく。
        • 評価件数280→500→750→1000件と増やしてモデル作成する。
      • コードの共有
    • 分類モデルの評価

2)日本語データセットの更なる増強

CommonCrawlは世界中のWebサイトを集めているプロジェクトであり,

多くの生成aiの学習に使用されている.

やったこと

CommonCrawlの5snapshotまで日本語の抽出が完了している.

(1snapshotあたり15TB程度 → 200GB日本語, つまり1TB程度はある)

→huggingface datasets化に時間がかかっている.

分かったこと

クリーニングが必要なデータが多い

次やること

1)huggingface datasets化を進める.
2)クリーニングの方法を確立する

PMC OR 学術データセット

現在の状況 :
1>学術 : PMC OR
⇨dataflowのコードが完成している
⇨今日, 明日から回すところ

サブチーム3: Code

やったこと: 計算時間の推定(note)、2.7bモデルの事前学習

分かったこと:
計算時間の推定
以下の資料(第四回、p104~)に推定方法がありました。

松尾研 LLM講座 講義コンテンツ | 東京大学松尾研究室 - Matsuo Lab松尾研 LLM講座 講義コンテンツ

(推定時間) = (基準となる条件での学習時間) x (データ数の比) x (モデル数の比) x (GPU枚数の比) x (補正係数)

で出せそうです。

補正係数は、GPUの種類(例えばH100はA100の3倍程度の性能?)や、分散学習時のFLOPs効率(通信などがボトルネックになりやすい) などで決まります。
資料では、175bモデルを300bトークン、A100を1000枚で学習させたところ、36日を要したとの記載がありました。
それを、今回想定するケースに換算したのが、以下の表になります*。

  • 今回のコンペでは、H100が30日 x 18枚相当、提供される予定です。
    結局のところ、H100を使った時のFLOPsがどれくらいになるのか、更にはtransformerengineのような最適化ツールを使ったときに、どれくらいの加速効果があるのか(→factor)がわからないと、正しい推定値を出すのは難しそうです。

ファインチューニングや予備期間を含めると、事前学習に使えるのは20-30日程度になりそうです。

以上の結果をまとめると、事前学習に使えそうなtoken数は 200-600 bとなりました。 幅がありすぎて、ちょっと困っているところです。

現在のデータ量

以下のwebデータセットを軽くクリーニングし、統合する処理を実施中。

mc4_ja
oscar
cc100
shisa
jap2010
commoncrawl(namiuchi)

https://github.com/hatakeyama-llm-team/Dataset_for_BTM

dedup前のクリーニングで、3日ほど要する(50並列)*。 1TB程度 (200b相当)。

データの処理時間や、トークン数の制限は、かなり慎重に考えた方が良い

*形態素解析のコードを、文レベル・文章レベルの二回入れたら、処理時間が2倍位になった模様? (文レベルだけのときは、1 dayほどで終わった)

事前学習(日記)

概ね、英語wikipedia(360万件)→ CommonCrawl系日本語(1000万件)→日本語wikipedia(120万件)がメインになるような順番でカリキュラム学習させました。

合計で30 btoken程度です。

0.1bに比べて、「雑多な日本語ゾーン」でのlossの下がりが改善されました。もっとモデルサイズを大きくすれば、雑多な日本語を喋れるようになるのでしょうか。

評価結果
以下のcheckpointで保存された3つのモデルの出力を見ることにしました。

  • model id 0: 24000/199305 step → 英語メイン
  • model id 1: 180000/199305 → 雑多な日本語メイン
  • model id 2: 199305/199305 → きれいな日本語メイン
  • 1b model with 10b tokenでは無理だった**、翻訳タスクに対応できた**ことに、ちょっと感動しました。
    • 1bモデル: 英語: He is a good man. 日本語: 私は、私の夫は私を愛している。
    • 2.7bモデル: 英語: He is a good man. 日本語: 彼は素晴らしい人です。
  • 学習データ数が極めて少ない、model id 0がperplexity (ppl)的に選ばれる頻度が高いことに驚きました。
    • 一方、pplが大きいはずのmodel1,2の方が、(少なくとも最初の文については)出力がマトモであるようなケースがあります。
    • model 1,2では、色々な日本語を学びすぎて、逆に、入力文(例: 今日は晴れてるから)をきちんと予測できなくなってしまったのでしょうか。謎は深まるばかりです。

input: 今日は晴れてるから

model id 0 (perplexity=239): 今日は晴れてるから、雨が降らないと困る。 でもね~・・・この前は雨が降ってなかったのにな~。 【楽天市場】10%OFF

model id 1 (perplexity=957): 今日は晴れてるから、ちょっと散歩にでも行こうかな。 【楽天市場】購入者さんの【送料無料】【2ケースセット】(北海道・沖縄は別途送料必要)サントリー天然

model id 2
(perplexity=6772): 今日は晴れてるから、雨の心配はなさそう。 The Battle of the River Plate
was a naval battle fought in April and May, during World War I. It

次やること: エキスパートモデルの切り替え練習

サブチーム4: その他

やったこと

  • 林さんがsakanaAIを試した。
  • A100x8で事前学習を動かした

分かったこと

  • SakanaAI/evolutionary-model-mergeで扱われている3つのモデル(Shisa Gamma 7B, WizardMath 7B,  Abel 7B )に対して、適当な割合で単なるモデルマージ(dare_ties)を行ってみたところ、37.2までスコア(acc)が上昇しました
  • Dockerで1node(A100x8)を動かすことはできないことがわかった

次やること

  • いろいろなモデルマージモデルをA100x8及びGCPで試す(sakana-ai,mambaなど)
  • マルチノードでも同様に試す
  • ファインチューニングとアラインメント(PPO,DPO)に特化していろいろ試す。

第5回:週次報告

チーム全体の開発状況

  • データ準備はほぼ完了。30種類以上のコーパスを収集し、一部のクリーニングを済ませた。4/15の週中にはトークナイズまで完了の見込み。
  • 2.7bモデルで事前学習の動作確認を済ませ、llm-jp-13bの事前学習済みモデルでファインチューニングやevaluationも確認した。
  • シングルGPU、マルチノードでの学習コードの稼働を確認済み。
  • 10bモデルの事前学習に必要な準備はほぼ整った。ハードウェアトラブルなどの不安はあるが、できる限りの対策は講じている。
  • ファインチューニングについても既存のデータセットで動作確認済み。独自データセットの準備やDPO等の検討を進める。
  • 50bモデルに向けては、より大規模なデータセットの準備が必須。期間が限られているため、プロジェクト全体として、早急に取り組む必要があるように思われる。

概観スライド (hatakeyama)
https://docs.google.com/presentation/d/1r6kChto3tzABw8VL3tJiKx_AYMk-UW_Ax_ggrV1lme0/edit?usp=sharing

開発のマイルストーン(overview)

  • データ準備

  • モデル学習コード準備

    • 2.7bモデル、30 btokenで事前学習の動作確認済み(8gpu, 1node)
    • llm-jp-13bの事前学習済みモデルでファインチューニングやevaluationの動作確認済み
  • シングルGPUでの稼働確認、実績

    • 同上
  • マルチノードでの稼働確認、実績

    • 提供環境にて、0.1bモデルの学習コードが回ることを確認済み
  • うまくいきそうか計画の確信度

    • 事前学習
      • ハードウェアトラブルや予期せぬloss発散は不安だが、できる準備は概ね終えた段階
      • トピックごとにわけて継続学習(カリキュラム学習)を行う予定で、データの中身が切り替わるタイミングで、(当然ながら)lossが一時的に上昇する
        • 2.7bまでは特にlossの発散は起きなかったが、10bクラスの挙動はやってみないとわからない(やや不安)
    • ファインチューニング
      • 既存データセット+SFTでの動作は確認済み
      • プラスアルファとして、独自データセットの準備やDPOなどがどこまで上手くいくかは未知数
    • 50bモデル
      • 今からデータセットをきちんと準備しないと、全く間に合わないであろうという確信度が高い

開発のマイルストーン

  • 完了: 外向け記事の作成協力者
    • 2名が立候補: ありがとうございました!
  • ほぼ完了: 事前学習用データセットの整備
    • 4/10頃から、1 weekほどかけて、データ処理を実施
    • 主なデータ
      • 計算マシンにダウンロード済み
        • mc4-ja, cc100, oscar, shisa, japanese2010
        • commoncrawl 2021 (warcから収集)
        • wikipedia ja/en
        • nhk school, news
        • j research corpus
        • 青空文庫
      • これから計算マシンにダウンロード
        • commoncrawl x5 snapshot (wetから収集)
        • 学術論文(pmc, pes2o)
        • commoncrawl pdf
        • code, culturaX
        • openmathinstruct-ja/en
  • これから: 事前学習の見守り体制の強化
    • TODOの洗い出し
  • これから: ファインチューニング, evaluationの検討
    • データセット作成
      • 人力
    • ファインチューニングの練習(何を学んだら、何ができるようになるのかの解明)
      • google colabなどで誰でも動かせるようにしたい
      • DPO, RLHFなどの検討
      • エキスパートモデルの切り替え
  • これから: 50bに向けた調査検討
    • 10bと50bでは、モデルやデータベースの設計が異なる
      • Chinchilla則から必要データを軽く見積もるだけでも…
        • 10bモデル: 200 b token (1 TB程度のテキスト)
        • 50bモデル: 1000 b token (5 TB程度のテキスト)
    • phase1-phase2の間に1week程度しかないので、今から準備しないと、明らかに間に合わない

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

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

やったこと

  • JMT-Benchに沿って指示データの作成を開始。
    • 4/15追記: 試験対策はやらない方針に転換
  • データセット作成Webページの作成。
    • Webページへタスクカテゴリの反映。
    • 分類階層の導入でUXの改善。

分かったこと

  • 指示データ作成1件あたり、10分以上かかりそう。
    • JMT-Benchの原題を拡張し、800件以上の作成を目標。
      • 4/15追記: 試験対策はやらない方針に転換
    • 5/10を目処に作成を終えることを目標とする。残り最大28日程度
    • 1日30件程度を登録する必要あり。

次やること

  • 毎日30件以上の指示データセットの作成
  • Webページのチーム内公開

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

基本方針
1)期間ごとにメインとなるデータセットを決めて、
そのデータセットを主に用意する
2)そのほかのデータセットについても, メインとなる
データセットが入れ替わった時にスムーズにいくように進める
3)高品質なデータセットの構築のため、人間のアノテーションをする

内容
1)AnnotationAppの作成
AnnotationAppは人の観点から高品質なデータをアノテーションしデータセット中の品質のいいデータを抽出できるようにするアプリ

やったこと

  • 本番運用のアナウンス

    • 畠山チーム内外へのアナウンスと参加者の募集
      • 合計22名に参加してもらっている。
      • 1366件のアノテーションを完了。(最新4/9 18:00時点 1477件)
    • アノテーション評価認識の共有
      • データの偏り改善
        • 6500件のデータでは偏りがあったため、畠山さんが加工いただいた最終的なクリーニングデータを追加してアノテーション対象のデータを約6.4万件にした。
        • アノテーションデータの法則性がわかってきたデータに対して、広告がある・なしに対応していく
      • 回答の優先度
        • Q1,Q3の回答のみを優先して進める。
        • Q2のfeedbacklはアノテーション速度向上のために省略
  • fasttextでの分類モデルの作成

    • 850件のアノテーションデータでの実装(SlackのURL
      • 4値分類できる分類モデルを作成
      • 学習用コードと可視化コードの共有
    • テキスト分類モデルの学習
    • テストデータを分類したデータを可視化して、分類できているか確認した

分かったこと

  • 23人、1週間で1366件のアノテーションは完了できた。

    • アノテーションデータの分布
      分類 頻度
      bad 329
      normal 588
      good 397
      very_good 57
      合計 1366
  • 学習用データ850レコード(1レコード300文字)でもfasttextで学習する時は高スペックででのマシンが必要

    • 32GBではメモリクラッシュする→メモリを上げて、学習したほうがよさそう。ml.m5d.8xlarge(32vcpu,120GB)以上準備する。
    • 1250レコードで学習してみたが48vpcu,192GBでもクラッシュする
  • ある程度分類はできていそう

    • 各クラスごとでの境界線がみられる

      • very goodは点が少ないのでよくわからない
      • good,normal,badはきれいに分かれていそう。

次やること

  • データの改善
    • 扱っているデータセットの偏り(広告がある, なし)の改善
  • アノテーションできるところまでアノテーション進める
    • 4/10 7時まで進められるところまで締め切りとして、すすめる
  • 分類モデルの作成
    • 850レコードではできたので、1366あるいはそれ以上のレコード数で作成する
      • 学習のためのマシンを準備する(AWSorGCP)
    • /togglあるいはそれ以上のレコード数で作成する
  • パイプラインへの組み込み

サブチーム3: Code

やったこと: スライド参照

分かったこと: スライド参照

次やること: マイルストーンを参照

サブチーム4: その他

やったこと

分かったこと

  • GSM8KデータセットにおいてLlama2-7Bで14.6, WizardMath-7Bで54.9だが、WizardMathはある意味カンニングである(OpenMathInstruct-1データセットを使っているから)
  • 近頃のモデルにおいてGSM8Kを答えることができるのは、GSM8Kを丸暗記しているから。
  • 特にOpenMathInstruct-1 データセットで学習したものは答えられるようになるのはある意味当たり前。
  • これらのモデルにaqua_ratに対して答えさせるとどうなるか?
  • 興味ぶかいのは仮にOpenMathInstruct-1で丸暗記させていたとしても、WizardMath 7B v1.1は, 英文のGSM8Kならば54.9で答えるが、日本語になると18.4まで落ちる

次やること

  • OpenMathInstruct-1でファインチューニングし、aqua_ratの問題を解く
  • WizardMath-7Bとllm-jp-13b-v1.0をマージしたら日本語のGSM8Kの正答率はどれくらいあがるか

その他

  • 新規メンバーなど
  • タスク割り振り
  • データベースの使い方
  • コンペ用にチーム内でデータセットを作る
    • タスクを具体的に振った方が良い
      • ランダムに割り振る
      • todo list
  • ファインチューニングの練習
    • Google colabでQLORAして、適当な質問に、どれくらい答えられるようになるかを見る
      • インストラクションチューニング
      • RLHF, DPO
    • Playground (google colab)の整備
      • trlx

データクリーニングの進捗

4/15 畠山追記: スケジュールの都合もあり、一通りの作業を1つのワークステーション上ですべて回しています。50bの際(?)は、もう少し組織的(?)に、うまく回せればと思っています。

(が、dedupなどは一括して行わないといけないので、どうやって分散処理すればよいのか、悩み中です)

1)形態素解析を使って, 不完全な文を除去(Komurasakiさん)

mC4, CommonCrawlへの形態素解析を実際に回す
進捗状況
→「Wikipedia \n を見る」などを形態素分析+機械学習で判別し、これらを一行にしたのちに、形態素分析+機械学習で一行ごとの文末判定(終止形判定っぽいこと)をして文末じゃないものを弾くプログラムを作成

2)形態素解析以外のクリーニングのfix及びデータセットの実際の加工(上林さん、内藤さん、t_nakanoさん)

自動挿入されたような文の除去(内藤さん)
同じ文が多く含まれる文章の除去(上林さん, t_nakanoさん)

進捗状況
→クリーニングしたファイルを「.parquetファイル」経由で処理してリポジトリに登録する手順を作成( t_nakanoさん**)**

3)クリーニングの実行(dataset_for_btmのコードを一通りて見る)(N_Yoshimotoさん)

進捗状況

→持ち前のPCでは3clean_and_clustering.pyの処理に相当時間がかかり4/10時点でまだこのファイルを回している状況。document_distributor.pyのモデルの読み込みが相当重く(コメントアウトで#load modelsとしている箇所)、並列処理を16にすると自前のPCではKilled処理が行われて実際にcleaningされないということが起きる。dedepuingは300ファイルくらいcleaningしたファイルを集めて4/11程度から実施する予定。

4)データセット内の文章同士のdedup(Namiuchiさん)

進捗状況

mc4のstreamingしてきたデータを対象に、うまくいかない例があればそれに対処するような関数を追加

5)アノテーション(N_Yoshimotoさん、Esty)

進捗状況
→アプリを利用して、アノテーション済みテキストのサンプルを増やす作業。4月10日6時時点で1600のサンプルを作成。

6) コード系(the stack v2)

進捗状況
 落とすscriptを誰か(miwaさん?)に、作って貰ったが、awsのアカウントを介してダウンロード→データ解析→ コーパス統合  みたいな作業が必要で、ちょっと止まっている
 (awsではなくHuggingfaceとかから落とせるscriptだと、楽)

7) mdpiというオープンアクセス論文

進捗状況
→オープンアクセス論文からごっそり落としてきた論文のhtmlデータも全く解析できてない

8) culturaxから英語を少し綺麗にするコード

進捗状況
→誰かが途中までやってくれていた

9) pes2oというオープンアクセス論文のコーパスからcc nc系を抜いてコーパス化するコード

進捗状況
→ datasetがodc-byだったので、解決

10) 50bに向けて、日本語スクリプトをブラッシュアップする

進捗状況
→ これから

11) リンクの除去、機械学習ベース(アノテーションしてもらってるやつ)でのクリーニング、遊撃部隊的に課題の発見など

進捗状況
これから

第6回:週次報告

チーム全体の開発状況

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

本番環境での学習の状況

  • データ準備
    • 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法で学習はできる

次やること

  • 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: 流石にそんなはずはないので、設定を見直す。

感想

  • マルチノードは大変。これらを、きちんとこなしている方々を、大いに尊敬するようになった。
  • わりと計画的・かつ保守的な安心安全プランで、データセット作成やモデル構築の準備を進めてきたつもりだが、予期せぬトラブルが多発し、なかなか大変な状況である。
  • スケジュールもタイトなので、瞬発力・合理的な判断・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"
      }
    }
    
    

FLOPSの劇的向上

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

第7回:週次報告

チーム全体の開発状況

  • 7-8b程度の事前学習が開始
  • ファインチューニングデータセットのアノテーションが課題

開発のマイルストーン

  • データ準備
    • 200Bでtokenize済み(先週と同様)
  • モデル学習コード準備
  • シングルGPUでの稼働確認、実績
  • マルチノードでの稼働確認、実績
  • うまくいきそうか計画の確信度
    • 多分

直近1週間でやったこと

  • コード: 7-8bモデルの事前学習の知見を集積。
    • 学習率を下げたgpt2ベースのモデルであれば、少なくとも1日程度は、loss spikeやモデル崩壊なしに学習を進められることを見出した(5/1)
  • 事前学習: commoncrawlやデータフィルタなどの知見を集積
  • 指示データセット: 自動生成のデータが数万件。アノテーションが課題

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

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

やったこと

分かったこと

  • LLMによるQ&A量産のために質問データを増大させる必要がある。

次やること

  • 質問データセット追加作成
  • 大量の自動生成Q&Aのアノテーション

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

やったこと
1)Commoncrawl warcから日本語テキスト抽出 (2024) (並内)
→並内GCP Dataflowで実行中, (2日ほど 2024)
→2024終わった後, それ以外のsnapshotのdedupをかます

2)Commoncrawl warcから抽出したテキストのクリーニング (内藤さん)
3)データ/モデル共有用のGCS作成 (畠山 GCS hatakeyamallm)
https://console.cloud.google.com/storage/browser/ml_storage_geniac;tab=objects?hl=ja&project=hatakeyamallm&prefix=&forceOnObjectsSortingFiltering=false

サブチーム3: Code

やったこと

  • 事前学習の開始 by llama -8b
    0428 llama-13b
    データの切り替えタイミング

5/1朝時点で、4 M step頃に、stage 1からstage2に移ったと思われる挙動を確認

分かったこと

  • 今回試した条件においては、llama系で、loss spikeやnan化によるモデルの突然死が起きやすい
  • gpt2系では、ここまで不安定な挙動はおきにくかった

次やること

  • 事前学習の完了

ディスカッション

  • 自動生成された大量のQ&Aのアノテーションをどうするか問題が発生

その他

速度検討の結果 概要

  • global batchは大きく、microbatchは小さくしないと、マルチノード系でflopsが出ない
    • gradient accumulationを活用していることに対応。
  • model parallelは1より大きくすると、基本的に速度が落ちる
  • pipeline parallelはノード数程度にすると効果的
  • zero stage 0にすると、global batchを32程度まで小さくしなけrばならない
  • recompute-activations オプションをいれると、flopsは向上する(が、必ずしもiteration速度が向上するとは限らない
  • llama系はgpt系よりもflopsが上がりやすい傾向
node gpu global batch microbatch size (b) zero stage pp mp micro_batch activation_checkpoint vram小 vram大 TFLOPs
4月23日 2 8 32 global_batch/dp_size 10a 1 1 1 FALSE 64 80 72.76
4月23日 2 8 32 global_batch/dp_size 10a 0 1 1 FALSE メモリオーバー メモリオーバー
4月23日 2 8 16 global_batch/dp_size 10a 0 1 1 FALSE メモリオーバー メモリオーバー
4月23日 2 8 32 global_batch/dp_size 10a 1 1 2 FALSE 71 71 104
4月23日 2 8 32 global_batch/dp_size 10a 1 2 2 FALSE 62 62 124.36
4月23日 2 8 32 global_batch/dp_size 10b 1 4 4 FALSE 68 69 63
4月23日 2 8 32 global_batch/dp_size 10b 1 2 2 FALSE 68 69 118.12
4月23日 2 8 32 global_batch/dp_size 10b 1 6 6 FALSE
4月23日 2 8 32 global_batch/dp_size 10b 1 2 1 FALSE 60 65 116
4月23日 2 8 32 global_batch/dp_size 10b 1 4 1 FALSE 55 55 77.89
4月23日 1 8 64 global_batch/dp_size 2.7 1 1 1 FALSE 80 80 197.52
4月23日 1 8 64 global_batch/dp_size 2.7 1 2 2 FALSE
4月23日 1 8 16 global_batch/dp_size 2.7 1 2 2 FALSE 80
4月23日 2 8 32 global_batch/dp_size 7 1 1 1 FALSE 79
4月23日 2 8 32 global_batch/dp_size 7 1 2 1 FALSE 48 48 112
4月23日 2 8 48 global_batch/dp_size 7 1 2 1 FALSE 59 59 132
4月23日 2 8 64 global_batch/dp_size 7 1 2 1 FALSE 69 69 142
4月23日 2 8 80 global_batch/dp_size 7 1 2 1 FALSE 78 79
4月24日 3 8 96 global_batch/dp_size 7 1 3 1 FALSE 65 67 70
4月24日 3 8 96 global_batch/dp_size 7 1 6 1 FALSE
4月24日 3 8 96 global_batch/dp_size 7 1 3 3 FALSE
4月24日 3 8 72 global_batch/dp_size 7 1 3 3 FALSE
4月24日 3 8 96 global_batch/dp_size 7 1 3 1 FALSE 70
4月24日 3 8 96 global_batch/dp_size 7 1 3 1 FALSE 70
4月24日 3 8 72 global_batch/dp_size 7 1 3 1 FALSE
4月24日 3 8 72 global_batch/dp_size 7 1 1 1 FALSE
4月24日 3 8 96 global_batch/dp_size 7 1 3 1 FALSE 65 66 102
4月24日 3 8 96 global_batch/dp_size 7 1 3 2 FALSE
4月24日 3 8 96 global_batch/dp_size 7 1 6 1 FALSE 50
4月24日 3 8 48 global_batch/dp_size 13 1 3 1 FALSE 69 70 107
4月24日 3 8 96 global_batch/dp_size 7 1 3 1 TRUE 37 38 110
4月24日 3 8 192 global_batch/dp_size 7 1 3 1 TRUE 43 44 116
4月24日 3 8 768 global_batch/dp_size 7 1 3 1 TRUE over over
4月24日 3 8 384 global_batch/dp_size 7 1 3 1 TRUE over over
4月24日 3 8 288 global_batch/dp_size 7 1 3 1 TRUE over over
4月24日 3 8 240 global_batch/dp_size 7 1 3 1 TRUE over over
4月24日 1 8 80 global_batch/dp_size 7 1 1 1 TRUE over over
4月24日 1 8 64 global_batch/dp_size 7 1 1 1 TRUE over over
4月24日 1 8 32 global_batch/dp_size 7 1 1 1 TRUE 79 80 240
4月24日 1 8 32 global_batch/dp_size 7 1 1 1 FALSE 79 80 244
4月24日 1 8 32 global_batch/dp_size 13 1 1 1 FALSE over over
4月24日 1 8 32 global_batch/dp_size 10b 1 1 1 FALSE over over
4月24日 1 8 24 global_batch/dp_size 10b 1 1 1 FALSE over over
4月24日 1 8 16 global_batch/dp_size 10b 1 1 1 FALSE 80 80 180.72
4月24日 1 8 32 global_batch/dp_size 7 1 1 1 FALSE 79 80 244
4月26日 3 8 1024 1 13 1 3 1 FALSE over over
4月26日 3 8 512 1 13 1 3 1 FALSE 142.13
4月26日 2 8 512 1 13 1 2 1 FALSE 74 76 320
4月26日 2 8 512 2 13 1 2 1 FALSE 50 76 334
4月26日 2 8 512 3 13 1 2 1 FALSE
4月26日 2 8 512 4 13 1 2 1 FALSE over over
4月26日 2 8 256 1 13 0 2 1 FALSE over over
4月26日 2 8 128 1 13 0 2 1 FALSE over over
4月26日 2 8 16 1 13 0 2 1 FALSE over over
4月26日 2 8 512 2 13 1 4 1 FALSE 60 75 334
4月26日 2 8 512 2 13 1 2 2 FALSE 60 64 270
4月26日 1 8 1024 1 7 1 1 1 FALSE over over
4月26日 2 8 1024 2 7 1 2 1 FALSE 54 54 306
4月26日 2 8 1536 1 7 1 2 1 FALSE over over
4月26日 2 8 1280 1 7 1 2 1 FALSE 45 45 270
4月26日 2 8 1280 2 7 1 2 1 FALSE 54 54 310
4月26日 2 8 1536 2 7 1 2 1 FALSE 54 54 311
4月26日 2 8 2048 2 7 1 2 1 FALSE 54 54 314
4月26日 2 8 1024 2 7 1 8 1 FALSE 32 44 264
4月26日 3 8 1536 3 7 1 3 1 FALSE 59 60 308
4月26日 3 8 1536 3 13 1 3 1 FALSE over over
4月26日 3 8 1536 3 13 1 6 1 FALSE 70 79 340
4月26日 3 8 512 3 13 1 6 1 FALSE
4月27日 3 8 768 3 13 1 6 1 FALSE 324
4月27日 3 8 1536 3 13 1 9 1 FALSE
4月27日 3 8 1536 3 13 1 12 1 FALSE
4月27日 3 8 1536 6 13 1 6 1 FALSE over over
4月27日 3 8 1536 3 13 1 3 1 FALSE over over
4月27日 3 8 1536 3 13 1 1 1 FALSE AssertionError:
global batch size (1536) is not divisible by micro batch size (3) times data
parallel size (24)
4月26日 3 8 1536 3 13 1 6 1 TRUE 35 40 350
4月26日 3 8 1536 6 13 1 6 1 TRUE 42 47 350
4月26日 3 8 1536 6 13 1 12 1 TRUE
4月26日 3 8 1536 6 14? 1 3 1 1 FALSE 60 65 401
4月26日 3 8 1536 6 14? 1 3 1 2 FALSE 77 79 423
4月26日 3 8 1536 6 14? 1 6 1 2 TRUE 32 35 430
4月26日 3 8 3072 6 14? 1 3 1 2 FALSE 73 75 370
4月27日 3 8 3072 6 14? 1 6 1 2 FALSE 73 75 372
4月28日 2 8 1536 4 llama-13 1 4 1 2 FALSE 430
4月28日 3 8 1536 6 llama-13 1 6 1 3 FALSE 71 79 422
4月30日 3 8 1536 3 8 1 3 1 3 70程度 460
4月30日 3 8 1536 3 7 1 6 1 recompute-activations 375
4月30日 3 8 1536 3 7 1 3 1 recompute-activations 415

学習の安定性に関する議論やメモ

  • オプティマイザにfp16を使うことが、loss spikeの大きな要因と思われる

  • しかし、それ以外の選択肢を使うのが、意外と難しい

    • bf16とgradient accumulationの組み合わせは基本的によくない(こちらなど)
      • 誤差が蓄積しやすいため
    • 5/1時点、設定を確認できてないが、fp32と組み合わせるのが良いらしい
      • https://github.com/microsoft/DeepSpeed/issues/2768
      • ただし計算速度の低下がきになる
      • また、deepspeedのバージョンなどにも注意が必要
        • 古いバージョンだと、bf16 optimizerとpipile parallelが併用できなかったりする
        • 最近のバージョンだと、pip時のコンパイルでエラーが出たことも。
    • オプティマイザにfp32を使うという選択肢もあるが、適当に設定しただけでは、bf16との互換性がないとのエラーが出た
  • 4月に試したllamaは、adamのベータを0.999という、極めて挑戦的な値にしていたとのこと。加えて、ropeのシータも高め。このあたりが、不安定性の要因?

    36億パラメータの日本語言語モデルを公開しました

Loss spikeに関する知見のまとめ

多くのモデルで、2.2M stepでloss spikeが発生。

adamオプティマイザのbeta2をデフォルト値(0.999: かなり攻めた値)から、0.95に下げつつ、learning rateも控えめ(lr=2e-5)にすることで、spikeを抑制できた。

loss spikeが起きた条件

  • llama系アーキテクチャで、adamオプティマイザのβを、megatronの初期値のままにしていたモデル
    adam_beta1 ...................................... 0.9
    adam_beta2 ...................................... 0.999
    adam_eps ........................................ 1e-08

    • 加えて、Ropeのθを大きめ(125000)にしていたのも、いけないかもしれない → 10000まで削減
      • inv_freq = 1.0 / (ここがθ** (torch.arange(0, dim, 2).float() / dim))

    コードはこちら。
    https://github.com/hatakeyama-llm-team/LLMGCP

    • 一般に、βが大きすぎると、学習が不安定になる
    • モデルサイズは8 b or 13b
    • lrは2e-5と小さくしてもloss spikeが発生
  • GPT-2アーキテクチャで、モデルサイズ=13b &lrが普通の条件

    • lr=1e-4

loss spikeが起きなかった条件

  • llama8b (ropeのtheta=10000) and GPT2-7b
    • lr=2e-5
      adam_beta1 ...................................... 0.9
      adam_beta2 ...................................... 0.95
      adam_eps ........................................ 1e-08

第8回:週次報告

チーム全体の開発状況

  • 7-8b程度の事前学習が進行中(90b token程度が完了。残り100b程度)
  • mixtral 8x22bを用いてファインチューニング用のデータセットを自動生成中

開発のマイルストーン

  • データ準備
    • 200Bでtokenize済み(先週と同様)
  • モデル学習コード準備
  • シングルGPUでの稼働確認、実績
  • マルチノードでの稼働確認、実績
  • うまくいきそうか計画の確信度
    • loss spike次第

直近1週間でやったこと

  • 事前学習のチューニングや対応

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

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

やったこと

  • 指示データセット 質問文追加作成 約500件
  • Minnadechatでのデータ量も若干増加 1. asaoka_tadashi, 2. kevin28gou, 3. 林寛太

分かったこと

  • もう少しデータ手動生成できる可能性

次やること

  • Answer文の生成&評価

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

やったこと

  • CommonCrawlから50Bのデータ収集

    • 収集コードの実装

      • GoogleColabのデータ収集用コードをDocker化と並列ダウンロードに対応
      • URLの重複除去に対応
    • インフラの検討を実施

      • GCPのDataFlow/CloudRunを比較
      • 抽出したデータはCloudSQLに保存で進めた
      • 構成図歯次のとおりです。

  • クリーニング実装は、一旦止まり中

分かったこと

  • DataFlowでは60並列しかまわせずタイムアウトあり速度限界あった。
  • CloudRunでは100インスタンス(1ロケーション最大数),4ロケーション使用することで400インスタンスを並列してできそう
    • CloudRunのメリット
      • Dockerにやりたい処理を書けば良い
        • 処理に限定がない。
          • データ収集以外にもクリーニング処理などで使っていける。
    • 3job,(50task/job)合計150taskではダウンロード速度をより速くする必要がある。
      • 1jobあたり50taskを実行して5hrで日本語のみ、URL重複なしのテキストをダウンロードした。

        • 24GBダウンロードした
          • 80万ページ(urlで重複なし)ダウンロード
      • CommonCrawl 2023-50は100TBでそのうちの5%が日本語であるため日本語データは5TBダウンロードする必要あり

        →5000GB/24(GB/5hr) * 5(hr) = 1041hr(=44days)のため速度を上げる必要あり
        定例後編集(5/7 18:30):24GBはもしかして速く進んでいるので44daysもかからないかもしれない

        • 1snapshotは9万ファイルに分かれている。
          • 1taskでは3ファイルを約9分で処理できる
          • 400taskだとすると、1200ファイルを9分で並列処理できる
            • これを繰り返すと1.2万ファイルを90分で処理できる
            • よって、9万/1.2万=675分で1snapshotを処理できる試算
      • CloudRunJobの割当上限を100から250に上げるように申請 完了 (Total :550 )

次やること

  • CloudRunでのデータ収集をすすめる
    • 更にあげられそうだったら上げる
      • CloudRunを使って2023-50をやっていく
    • クリーニング
      • cloud sqlに格納しているのでurlやhashによりクリーニングはしやすくはなっている。

サブチーム3: Code

やったこと

  • 事前学習の見守りと対応
  • 30 M step頃までは、英語とcode中心のドメインであった。
    • lossの下がり具合も悪くなかったので、lr=2x10^-5で学習した
  • 30 M step過ぎ頃から、日本語中心のドメインに切り替わり、lossが上昇した
    • lossの下がりが悪かったので、途中から学習率を変更する仕様にした

学習率を突然上げると、lossが激しくspikeするため、schedulerのプログラムを書き換えて、徐々に上昇させる挙動にした。それでも、38.1M step付近で、軽いloss spikeが発生した。

38.6M step頃のspikeは、スケジューラーの設定を微妙に間違えており、一気に、lr=3x10^-4 まで上げてしまったことが原因。

ただし、その後のlossの下がり方は順調なので、このまま学習を継続する。

分かったこと:

  • ドメインによってlossの下がり方がかなり異なる。
    次やること:
  • 見守り
  • lossの様子を見ながら、2 epoch目に入るかどうかの判断
  • ファインチューニング

追記: loss spikeの再発と対応メモ(畠山)

5/7夕方 loss spike発生

5/7の夕方頃に、loss spikeが発生(オレンジ)

原因はおそらく、

  • カリキュラム学習における日本語ドメインAからBへの移行
  • 高めの学習率(lr = 3e-4)
    である。

チームでは、英語+code →日本語A →日本語B → … → 日本語E
というふうに、ドメインを変えながら学習させ、それぞれのsnapshotごとにexepert modelを作る戦略であった。

しかし実際にやってみると、ドメインの切り替え時にlossが上昇し、わりと挙動が不安定になりやすいことが判明(上記のグラフ)
仮説: モデルが各ドメインの局所解のようなものに陥り、そこから重みを変えていく際に負担がかかりやすい可能性がある。
(このようなカリキュラム学習は、ある程度、モデルの基礎ができた後、つまり2 epoch目以降に実施した方がよいかもしれない)

→5/10追記: これまでは英語ドメインが中心だったこともあり、日本語の能力が大幅に不足しており、lossが3程度まで上昇したものと思われる。局所解ではなく、普通の挙動かもしれない。

対応策

  • 日本語ドメインについては、シャッフルしたデータを利用(英語の割合はほぼゼロのデータセット 90b token程度)
  • lr=1e-4

という条件で、学習を開始

5/8未明 loss spike発生

  • 日本語ドメインで継続学習をはじめたところ、lossが3.7からのスタートとなった。
    • 元のモデルが、「英語+code+一部の日本語」ドメインにoverfit気味だったことを示唆する結果
    • もちろん、通常のscaling lawを超えるために、ドメインを絞るのは悪くない(i.e., 通常のBTM)のだが、カリキュラム学習への展開や、mergeの難しさを痛感

5/8 6時頃

  • 学習率を半分(lr=5e-5)に落とした条件で、発散し始める前のcheckpointから再開
  • 本質的には、オプティマイザをfp16からbf16に変えたほうが良さそうである
    • しかし、megatron-deepspeedとの相性があまり良くない印象
      • バージョンによっては、pipeline parralelと併用できないというassertion
      • 最近のバージョンでは使えるが、gradient accumulationとbf16の相性が悪い
        • 誤差が蓄積しやすいため
      • 試した環境では、deepspeedのpip時に、コンパイル関連のbuildエラーがでたこともあったので、保留している

6:51現在

  • lossの変動は、spikeした条件(青)とほぼ同じだが、throughputのガタツキはまだあまり生じていない。
    • 実は一旦、lossの変動があまり変わってないので、jobをabortしたが、hayashiさんに、throughputは改善してますと指摘されたので、jobを再開し直した経緯がある
    • 多角的な指標でモデルをチェックすることが大事と実感


7:50

無事に峠を超えた


8:40

nanにより学習停止

slackでの議論

おそらく、 英語+code中心のドメイン用に、モデルが最適化されすぎている(局所解に入っている) ため、現在の日本語を学ぶドメインで、お重みの劇的な変更が必要&lossが上昇する

という現象が不可避なのではないかと思います。

13:00頃

カリキュラム学習に戻した上で、lr=2e-5で学習を再開(茶色)

lrが高い条件(ピンク)に比べ、48M手前のspikeは改善したが、それ以降のlossの減り方がいまいち

そこで、48.4M step付近のcheckpointからは、lrを上げる検討を開始


茶色: originalのデータ(lr=2e-5)

紫の破線: lrを1e-4まで一気に上げたデータ。そこまでlossの向上は大きくない。ただし、lrをあげないとlossが下がりきらない恐れがある

紫の実線: lrを3e-4まで上げたデータ。lossの上昇が起きてしまっている

青: lrを2e-5から3e-4まで徐々に上げていくデータ(4b tokenかけてlrを上げる)。 問題なし。

とりあえず、日本語初期は挙動が不安定なこともあるので、青線(lrを徐々に上げる)方針で学習させる。

19:05

いまのところ、順調に推移。

朝の日本語shuffle条件でloss spikeが多発した理由は、データセットに日本語しか含まれていなかったからかもしれない。

→ いまのところ、うまく行っているカリキュラム学習では、1割ほど、英語が含まれている。一方で日本語shuffle条件では、本当に日本語のデータしか含まれていないので、モデルへの負担が大きく、発散した可能性がある。

5/9 8:37

軽いspikeはたまにあるものの、順調にlossが低下中

教訓: ドメインを切り替えるタイミングでは、徐々にデータの割合を変えるなどの工夫をしたほうが良い (+ lrを下げる)

5/10 順調

この成果は、NEDO(国立研究開発法人新エネルギー・産業技術総合開発機構)の助成事業「ポスト5G情報通信システム基盤強化研究開発事業」(JPNP20017)の結果得られたものです。

松尾研LLMコミュニティへのご案内

Slack参加リンクを始めとして、GENIACの概要やLLMコミュニティ主催各イベント等、関連リンクはこちらにまとめられております。
ぜひご覧ください!!
https://linktr.ee/matsuolab_community

東大松尾・岩澤研究室 | LLM開発 プロジェクト[GENIAC]

Discussion