📚

Qwen2.5-0.5B-InstructをUpcyclingしてMoEモデルを作る

2024/12/22に公開

1人ローカルLLMアドベントカレンダーの13日目です。

https://qiita.com/advent-calendar/2024/local-llm

要約

  • Qwen2.5-0.5B系モデルを組み合わせることでMoEモデルを構築した
  • MoE化直後の出力は崩壊気味
  • 約1.9Bトークンの学習で0.5B以上、1.5B未満の性能になった

目的

松尾研GENIACのweblab-GENIAC/Tanuki-8x8B-dpo-v1.0で採用されていたMoEへのUpcyclingをやってみたかったので、お手頃なQwen2.5-0.5B-Instructを使ってMoEモデルの構築を行って行こうと思います。

https://zenn.dev/matsuolab/articles/8a0382d27fd0b0

実施内容

MoE化

MoEへのUpcyclingはarcee-ai/mergekitを使います。

mergekitではMixtral、Deepseek MoE、Qwen MoEに対応しており、今回試したいQwen2.5のMoE化を行うことができます。

expertにするモデルは以下の4つを使用しました。

  • Qwen2.5-0.5B-Instruct
  • Qwen/Qwen2.5-Coder-0.5B-Instruct
  • Qwen2.5-0.5Bを日本語データでSFTしたモデル
  • Qwen2.5-0.5B-Instructを日本語データでSFTしたモデル

expertの数は4つ、experts_per_tokenは2つ、shared expertsはQwen2.5-0.5Bの1つだけにしています。

mergekitのconfig
base_model : Qwen/Qwen2.5-0.5B
architecture: qwen 
gate_mode: hidden
dtype: bfloat16
experts_per_token: 2
experts: 
  - source_model: Qwen/Qwen2.5-0.5B-Instruct
    positive_prompts:
    - "説明してください"
    - "教えてください"
    - "なんですか?"
  - source_model: (Qwen2.5-0.5BをSFTしたモデル)
    positive_prompts:
    - "説明してください"
    - "教えてください"
    - "なんですか?"
  - source_model: (Qwen2.5-0.5B-InstructをSFTしたモデル)
    positive_prompts:
    - "説明してください"
    - "教えてください"
    - "なんですか?"
  - source_model: Qwen/Qwen2.5-Coder-0.5B-Instruct
    positive_prompts:
    - "コードを作成してください"
    - "Python"
    - "コーディング"
    - "coding"
shared_experts: 
  - source_model: Qwen/Qwen2.5-0.5B
    positive_prompts: # required by Qwen MoE for "hidden" gate mode, otherwise not allowed 
    - "説明してください"
    - "教えてください"
    - "なんですか?"
    # (optional, but recommended:) 
    residual_scale: 0.22 # downweight output from shared expert to prevent overcooking the model

これにより、総パラメータ数1.75B、アクティブパラメータ数1.1BのMoEモデルを作ることができました。

この時点での出力としては、序盤は日本語が怪しい程度、後半になると崩壊が起こっています。

Pythonで1から100までの合計を求めるプログラムを教えてください。 もちろらんですね。1から100までの合計を求めたいわけです。以下のようなプログラム를用いて計算できます。

python<br>total = 0<br>for i in range(1, 101):<br> total += i<br>print("合計:", total)<br>

このプログラムでは、range(1, 101)作为 range 对Slicing,每次遍历i,每次都累加到current sum。最後一个是ifStmt,只要 current sum大于100,就表示Sum达到了100,就印出“合計”。

如果你不想使用 range,也没有遍历,直接使用 0 to 100 之间的 all 连接即可。stringLiteral。 dataType.

あと、もしPython中的括弧有問題だったのでのように見えます。StringEncoding-python/python/python interpreter<|endoftext|>
日本の観光地でおすすめの場所を教えてください。 日本の観光地にはいくつかの場所がおすすめされています。例えば、京都の伏見公園や東京メゾスなどが有名です。伏見公園は、美しい自然の景色と様々な文化遺存が楽しめます。東京メゾスは、さまざまな文化遺存や伝統的な建築物が楽しめるスポットです。これらの場所を通しててください。ienzaに興味がありますか?stringLiteralnyauchenbihengokuhanaikanzhengokuhanzheng(以下同じような繰り返し)

学習

このままだと使い物にならないので、日本語データでの学習を行いました。

マージ後の時点で応答の方向性は間違っておらず、破壊的忘却が起こっているわけでもなさそうなので、対話能力の向上を目的とします。

Phase1

とはいえ数万件のSFTだけで済ませるのは不安だったので、対話形式のデータを大量に学習させることにしました。

データセットは以下のものを使用して、1.87Bトークンを学習しています。

この時点での出力は以下のようになっています。

user: Pythonで1から100までの合計を求めるプログラムを教えてください。\nassistant: 以下にPythonで1から100までの合計を求めるプログラムを示します。

python<br>total = sum(range(1, 101))<br>print("The total from 1 to 100 is:", total)<br>
このコードは、sum()関数を使用して1から100までの整数の総和を求めます。range(start, stop)を使うことで範囲を指定できます。ここでは start=1, stop=101 とし、範囲は1から100までとなります。最終的に、その合計値を total 変数に格納し、最後に結果を出力しています。実行すると、「The total from 1 to 100 is:」というメッセージとともに、合計値が出力されます。例えば、このプログラムを実行すると「The total from 1 to 100 is: 5050」となります。これは、1から100までのすべての整
user: 日本の観光地でおすすめの場所を教えてください。\nassistant: おすすめの日本国内の観光地とその理由についてご紹介しますね。それぞれの魅力についても簡単に説明します。

1. 東京
- 大英博物館(おしゃれなカフェやショップが楽しめる場所)
- 浅草寺(伝統的な寺院ですが、観光客向けのイベントもあり)
- 渋谷スクランブル交差点(ダイナミックなカフェやショッピングエリア)

2. 京都
- 金閣寺(美しい庭園が特徴)
- 伏見稲荷大社(千本鳥居の参拝が楽しめる)
- 集会所の仲見世通り(高級レストランやカフェが多くあり、夜は特に賑わい)

3. 北海道
- 富良野高原(自然豊かなキャンプ場でのんびり過ごすのに最適)
- 天神城(有名な歴史的建造物に触れることができる)
-

Phase2

Phase1の時点でなかなか良さそうですが、chat templateに沿った学習ではないため、Qwen2.5のテンプレートを使ったSFTを行いました。

データセットには以下の4つを使用しました。

この時点での出力は以下のようになっています。

Pythonで1から100までの合計を求めるプログラムを教えてください。 もちろんです!以下に、1から100までの合計を求めるPythonプログラムの例を示します。

python<br># 1から100までの合計を計算するための変数を初期化します。<br>total = 0<br><br># forループを使用して1から100までの数字を順番に処理します。<br>for number in range(1, 101):<br> total += number<br><br># 最後に合計値を出力します。<br>print(f"1から100までの合計: {total}")<br>

このコードでは、range(1, 101)を使って1から100までの整数のリストを作成しています。そして、for number in range(1, 101):とすることで、各数値をtotalに追加していきます。最後に、print関数を使って合計値を出力しています。<|im_end|>
日本の観光地でおすすめの場所を教えてください。 もちろんです!日本にはたくさんの魅力的な観光地があります。以下にいくつかのおすすめスポットをご紹介します。

1. 東京
- 浅草寺(せんそうじ): 日本の歴史と伝統が息づく浅草の古い寺院。雷門や仲見世通りも楽しめます。
- 渋谷:東京都内最活気のあるエリアで、カフェやレストランがたくさんあります。
- 明治神宮: 日本の忠君思想を象徴する神社。春と秋の時期が特に美しいです。

2. 京都
- 清水寺: 歩くだけでも楽しめる景色が素晴らしい場所。紅葉や桜の季節は特に美しいです。
- 伏見稲荷大社: 無数の赤い鳥居が続く参道から参拝できます。
- 金閣寺(鹿苑寺): 美しい金色の建物が池に映る風景は絶景です。

3. 北海道
- 小樽:運河沿いの美しい街並みと、歴史ある小樽運河を見学できます。
- 富良野: サツマイモやラベンダー畑が有名で、家族連れにもおすすめです。
- 登別温泉: 温泉地として知られ、豊富な源泉と温泉が楽しめます。

4. 奈良
- 東大寺: 世界遺産に登録されている大仏殿。
- 春日大社: 奈良公園の鹿と触れ合うことができます。
- 永観堂: 国宝に指定されており、神秘的な雰囲気が漂います。

5. 鹿児島
- 高尾山: 美しい山並みとカヤック体験が人気。
- 佐伯城: 日本最古の城郭跡で、歴史を感じることができます。

6. 沖縄
- 美ら海水族館: 熱帯魚たちとのふれあいが楽しめます。
- 首里城: 首里城跡地にある歴史的な城跡。
- ファーム・ビューレン: 海鮮料理が楽しめるレストランで、沖縄料理の魅力を味わえます。

これらの場所はそれぞれ異なる魅力を持っていますので、旅行の目的や興味に合わせて選んでみてください。楽しい旅になりますように!<|im_end|>

一部ハルシネーションはありますが、問題なく学習できていそうですね!

結果

完成したモデルはこちらになります。

https://huggingface.co/Kendamarron/Qwen2.5-1.75B-A1.1B-Instruct-ja

shisa-ai/shaberiを使用し、以下2種のベンチマークの結果を見ることにします。

  • elyza/ELYZA-tasks-100
  • shisa-ai/ja-mt-bench-1shot

結果は以下の通りです。

モデル MT-Bench ELYZA-tasks-100 加重平均*
Qwen2.5-1.5B-Instruct 5.20 2.42 5.02
今回のモデル(1.75B) 4.53 1.96 4.23
Qwen2.5-0.5B-Instruct 3.48 1.73 3.47

学習の過程が異なるので純粋な比較とは言えないですが、0.5Bと1.5Bのちょうど中間という結果になりました。

今回のモデルのアクティブパラメータは1.1Bなので、アクティブパラメータ数で考えるとある種妥当な結果かもしれません。

まとめ

今回はQwen2.5-0.5Bを使ったMoEモデルの構築を行いました。

もう少し1.5Bモデルに近い性能になって欲しいところですが、この規模の学習でもそれなりの結果になったので個人的には満足です!

Discussion