- 語彙サイズ:56,320
- 語彙サイズ検討の背景
- 前提として、今回作るLLMは10Bパラメータと7Bよりやや大きいモデルの想定であった。
- google gemma(vocab: 約25.6万)やQwen(vocab: 約15万)といった最近の高性能なモデルが語彙数を大きめにしている傾向があると考えられた。
- 言語的な性質として漢字・カタカナ・ひらがなを持つ日本語という言語は、英語よりも一般的に必要とされる語彙数が多いのではないかという仮説と、今回のモデルが日本語スクラッチ開発モデルであり、日本語継続事前学習モデルよりも多めに日本語語彙が入ることが望ましいと考えた。
- 語彙の構築方法
- 言語間での語彙の割合を任意にしたかったため、言語ごとでトークナイザーを学習して後でマージする方法を採用。
- 参考:他モデルの語彙数
- Swallow:48,000(Llama2の32,000+日本語15,000追加)
- Elyza-Llama2-fast:45,043(Llama2の32,000+日本語13,043追加)
- LLM-jp:50,570(日本語48.5%, 英語48%, コード3.5%)
- 事前学習に使うデータの言語割合を日本語と英語で1:1にするという方針であったため、語彙の割合も同等に近づけるように構築。
- 日本語のテキストには英語(アルファベット)が入ることが多いため、結果的には概算で日:英=4:6程度の割合。
- 数式やプログラムに関する数字・記号のトークンも1~2%程度後に含めることとした。
- 他モデルのほとんどで利用されているSentencePieceを利用。
- アルゴリズムはBPEとUnigramを検討したたが、以下の背景からUnigramを選択。
- 利用予定であったllm-jp-tokenizerライブラリがUnigramを前提としていた。
- "Tokenizer Choice For LLM Training: Negligible or Crucial?" (2023)にて、英語単体とヨーロッパ圏を含めた多言語での下流タスク性能を比較しており、英語単体ではBPEが優れていたが、多言語ではUnigramの方が優れていたと述べられていた。
- 他モデルを参考に、正規化はしない(全角と半角を別に扱う)ように設定。
比較的高品質と思われるテキストデータ(Wikipedia)を中心に学習に使用。 また、数式やプログラムに頻出するトークンを語彙に含めるため一部算数データやプログラムデータを用いる。
- 英語:wiki-40b-en(1.33GB) ※trainからサンプリング
- 日本語:wiki-40b-ja(1.78GB)
- プログラム:mbpp(172KB)
- 算数:grade-school-math(2.1MB)
- 日本語は形態素の大きさで分割するために、fugashiを用いて事前に処理する。
- テキスト中の空白と区別するために"||||"という文字列で形態素間の分割する。
- 各言語ごとでSentencePieceを用いたトークナイザーの学習を実行。
- 上の学習によって得られた語彙に追加したい語を手作業で追加する。
- 語彙サイズを調整するためにスコアの低い語を削除する。
- 語彙のマージと重複削除、および最終的な語彙からトークナイザーモデルへの変換には、llm-jp-tokenizerのスクリプトを利用。
- 松尾研標準コードの変換スクリプトを転用。
- LlamaTokenizer形式を指定して変換を行う。
- LlamaTokenizerへ変換して得られたファイルをHuggingFaceへアップロード。
- transformersライブラリのAutoTokenizer.from_pretrained()で呼び出せることを確認。