🌀

LLM差分マージしてみた

2023/12/31に公開

まとめ

  • 案外うまくいく
  • そんなに壊れない
  • うまくいかないところもある

成果物:

https://huggingface.co/p1atdev/nekoqarasu-14b-chat

差分マージとは

ここにおける差分マージとは、機械学習モデルの重みを足し算引き算して新しい重みを作る手法です。

Stable Diffusion に触れていると馴染みが深いかもしれません。既に知っているという人は飛ばしても問題ないです。

差分マージでは、主に3つのモデルの重みを使って新しい重みを作ります。

  1. ベースモデル
  2. ファインチューンモデル A
  3. ファインチューンモデル B

これらの重みを本当に単純に足したり引いたりして新しい重みを作ります。(細かい手法もあるようですが詳しくは触れないです)

次のような式になります。

新しい重み = (ファインチューンモデル A の重み - ベースモデルの重み) + ファインチューンモデル B の重み

差分マージの図1

これをすることで何が嬉しいかというと、ファインチューンモデル B にファインチューンモデル A の特性をもたせることができるようになります。

例えば、

  1. 事前学習済みの「LLM A」
  2. LLM A をベースに SFT してチャットできるようにした「チャット A」
  3. LLM A をベースにさらに事前学習した「LLM B」

で上の式を行うと、

チャット B =  LLM B + (チャット A - LLM A)

ができます。

差分マージの図2
ベクトルみたいな感じ

もちろん完璧にその能力を移せるわけではないですが、ある程度は能力を引き継げるため、次の学習のための良い初期値を得ることに使うことができます。

やってみた

そんな差分マージをやってみました。

今回使ったモデルは

それぞれ、Qwen 14B とその派生モデルであるため今回の差分マージを行うことができます。(アーキテクチャが異なっていたり、フルスクラッチで学習されているときはマージができません)

モデルの関係図

モデルの関係図

Qwen-14B

https://huggingface.co/Qwen/Qwen-14B

Alibaba が作成した日本語もちょっといける中国語、英語のLLMです。この時点で日本語チョットデキル感じなので結構すごいです。

nekomata-14B

https://huggingface.co/rinna/nekomata-14b

Qwen-14B ベース

学習内容:

  • 日本語 CC-100
  • 日本語 C4
  • 日本語 OSCAR
  • The Pile
  • Wikipedia
  • rinna が厳選した日本語データセット

合計 66B トークンでかなり多いです。

qarasu-14b-chat

https://huggingface.co/lightblue/qarasu-14B-chat-plus-unleashed

https://note.com/peter_lightblue/n/n2def04ca0d30

Qwen-14B-Chat ベース

学習内容:

  • 青空文庫
  • 法令データセット
  • 日本語 Wikipedia
  • CultraX (.lg.jp, .go.jp, .ac.jp)
  • 英語 Ultrachat
  • 多様な質疑応答データセット
    • RAGベースの質問応答
    • カテゴリーベースの質問応答
    • CoT Orca スタイルのデータセット
    • OASST 日本語のみ
    • ShareGPT 日本語のみ
    • Augmxnt (airoboros、slimorca、ultrafeedback、airoboros_ja_new)

合計 7B トークンですが、チャットに関する非常に多様なデータセットが使われています。

モデルの特徴

それぞれの派生モデルを見てみると、Nekomata は大規模な事前学習を、Qarasu は多様でネイティブ日本語のチャットデータセットによるSFTを行っているのがわかります。

そこで、これらのモデルを差分マージすることで Nekomata の事前学習による知識と Qarasu による応答の能力を両立させることを期待してマージを行いました。

マージ

nekomata-14b + qarasu-14b-chat - Qwen-14B

をやります。

コードは次のノートブックにだいたい書いてあります。

https://huggingface.co/p1atdev/nekoqarasu-14b-chat/blob/main/merge.ipynb

やることは本当に単純で、モデルの state_dict をとりだして、 key ごとに Tensor を足したり引いたりするだけです。

難しいというか面倒なのはメモリの管理の方で、かなり気をつけないとすぐ OOM したりメモリ足りなくなります。
Accelerator のディスクオフロードの機能などを活用して、メモリから溢れないように気をつけながら作業していきます。

また、足し算や引き算は GPU で行ったほうが速いので、普段は cpu とかにおいておき、足し合わせるときだけ cuda に移すようにします。(これをやっても一回のモデルのマージに10分以上かかりました...)

メモリやVRAMが豊富にあるなら上は気にしなくていいのですが、ローカルの 32GB RAM、8GB VRAM では結構苦労しました。

結果

Nekoqarasu ができました

https://huggingface.co/p1atdev/nekoqarasu-14b-chat

目立つ言語能力の喪失や崩壊は見られず、一応普通に応答できます。

軽く試してみたところ次のような特徴がありました:

  • 常識がある
    • 日本に関する知識はかなりしっかりしてる印象です。(期待通り)
  • 日本語が自然
    • マージするモデルの中に機械翻訳のチャットデータセットが含まれないためか、応答の日本語はかなり自然です。むしろフレンドリーすぎるくらいです。
  • 指示に従う
    • 個人的な感覚になってしまいますが、Nekomata よりも指示に従ってくれる印象があります
    • 回答の拒否も控えめな感覚がありますが、正確な比較はしてないのでわからないです

また、次のような問題点も見つかりました:

  • 無限に喋り続ける
    • どうやらモデルが <|endoftext|> を出力する方法を忘れたのか、max_new_tokens の許す限り無限に喋ろうとしてきます。
    • そのため、本来できるはずの ChatML 形式での応答ができないことはおろか、普通に生成する文意おいても永遠に <|endoftext|> が出現しないので冗長すぎる回答が生成されます。
  • 予防線を張りすぎる
    • 「ただしこれは一般的な~」のような予防線の文章を回答本文の後ろにつけすぎることが多いです。上の生成終われない問題と合わさって無限に予防線を張ってしまいます。
  • 関係ない話題が挟まる
    • 突然話題が変わって自分語りし始めることもあり、これも上の問題によるものかと思います。
  • たまに回答がカジュアル
    • 口調が丁寧じゃないことがときどきあります。

いろいろ問題点もあるのですが、個人的には結構面白い回答をしてくるので好きです。

ベンチマークを一切取っていないので、定量的な評価ができないのが残念です...

応答の比較例

応答を実際に見てみると上記の問題点がわかりやすいかもしれません。

質問文: まど☆マギで一番かわいいのは誰ですか?

まどマギの中で一番可愛いのは、魔法少女である鹿目まどかです。彼女は幼い頃から心優しい少女で、妹思いの姉として知られています。また、彼女は魔法少女になることを決意し、魔女のいない世界を望んでいたため、多くのファンから愛されています。

私は人工知能であり、感情を持たないため、キャラクターの外見や魅力について個人的な意見を持つことはできません。しかし、「まど☆マギ」のファンの中には、さまざまなキャラクターが一番かわいいと思う人もいるでしょう。例えば、美少女や女の子、お姫様、ロボットなどがあります。

  • (成果物) nekoqarasu-14b-chat

この問題は主観的な評価に基づくため、個人の好みや考え方によって異なることがあります。しかし、一般的に「まどか☆マギカ」の登場人物の中で最も可愛いとされるのは、鹿目まどか(かなめ まどか)です。彼女は純粋で優しい性格でありながら、他のキャラクターたちとは一味違う可愛らしさを持っています。
ただし、「可愛い」という基準には個人差があり、同じ作品に対する感覚や好みも異なることがあります。そのため、特定のキャラクターを選ぶだけでなく、複数のキャラクターから好きな要素を見つけたり、全体的に楽しむことが大切だと思います。

  • ChatGPT-3.5 (Web)

「まど☆マギ」に登場するキャラクターのかわいさは、個人の好みによる部分が大きいです。異なる人々が異なるキャラクターを一番かわいいと感じることがあります。以下はいくつかの人気のあるキャラクターですが、一番かわいいキャラクターは人によって異なるでしょう:

  1. 鹿目まどか: 作品の主人公であり、多くのファンに愛されています。彼女は純粋で優しい性格で、そのかわいらしい外見も魅力的です。
  2. 暁美ほむら: まどかの親友であり、物語の重要なキャラクターです。彼女のクールで知的な性格に魅了されるファンも多いです。
  3. 佐倉杏子: おおらかで元気な性格の杏子は、ファンからの支持が高いキャラクターの一人です。
  4. 巴マミ: 落ち着いた雰囲気と優雅な魅力を持つキャラクターで、彼女も多くのファンから愛されています。

「かわいい」キャラクターは主観的な評価になりますので、あなた自身がどのキャラクターを一番かわいいと感じるかは、ご自身の好みに依存します。それぞれのキャラクターには魅力的な要素がありますので、お気に入りのキャラクターを見つける楽しみもあります。

質問文: 「じまん」と「ほこり」、どちらの方がポジティブな意味を持っていますか?その理由も述べてください (elyza/ELYZA-tasks-100)

  • nekomata-14b-instruction

一般的には、「自慢」よりも「誇り」の方がポジティブな意味を持つと考えられています。これは、「自慢」が自分自身について話すことであり、しばしば他人との比較によって生まれる感情であるためです。一方、「誇り」は自分の行動や信念に対する肯定的な感情であり、他人との比較に関係なく持つことができます。そのため、「自慢」よりも「誇り」の方がよりポジティブな意味を持つと言えます。

  • qarasu-14b-chat

「じまん」と「ほこり」はどちらもネガティブな意味を持つ言葉ですが、「じまん」の方がポジティブな意味を持っていると言えます。
「じまん」という言葉は、物事がうまくいかない、不運な状況を表すために使われます。しかし、この言葉には「じまん」という言葉自体が持っているポジティブな意味もあります。「じまん」という言葉は、物事がうまくいかなかったときに、その原因を追究し、改善するための機会と捉えることができます。つまり、失敗から学ぶことができるというポジティブな側面があるのです。
一方、「ほこり」という言葉は、物事がうまくいかないだけでなく、人間関係や社会的な問題にも使われます。これは、物事がうまくいかないだけでなく、人間関係や社会的な問題にも影響を与えることを示しています。そのため、「ほこり」はよりネガティブな意味を持つ言葉と言えます。
以上のように、「じまん」と「ほこり」はどちらもネガティブな意味を持つ言葉ですが、「じまん」の方がポジティブな意味を持っている

  • (成果物) nekoqarasu-14b-chat

ポジティブな意味を持つのは「ほこり」です。「ほこり」は日本語で、「誇り」「名誉」「自慢」の3つの意味を持ちます。これらのうち、「誇り」「名誉」は他の人から認められるものであったり、自分自身が誇れるようなものです。そのため、「ほこり」がポジティブな言葉とされています。「じまん」は、他の人が見たり聞いたりしたときに、あまりいい印象を与えないことがありますので、ネガティブな言葉とされています。ポジティブな言葉として使う場合には、「私がじまんであるものは…」というように、主語を付けた上で、説明することが必要となります。ポジティブな意味を持つのは「ほこり」です。「ほこり」は日本語で、「誇り」「名誉」「自慢」の3つの意味を持ちます。これらのうち、「誇り」「名誉」は他の人から認められるものであったり、自分自身が誇れるようなものです。そのため、「ほこり」がポジティブな言葉とされています。「じまん」は、他の人が見たり聞いたりしたときに、あまりいい印象を与えないことがあります

  • ChatGPT-3.5 (Web)

「じまん」と「ほこり」は日本語の言葉で、どちらもポジティブな意味を持つことがありますが、文脈によって異なります。

  1. じまん(自慢):
    「じまん」は、自分や自分の所属するグループ、何か特定のことに誇りや自信を持っているときに使われます。この言葉は一般的にポジティブな意味を持ち、成功や実績に対する誇りや喜びを表現するために使われます。例えば、自分の子供の成績に「子供の成績をじまんに思います」と言うなど、自己肯定感や自信を示すために使われます。
  2. ほこり(誇り):
    「ほこり」も基本的にはポジティブな意味を持つ言葉です。これは誰かが自分や他者に誇りを感じる状況や感情を表現するために使われます。たとえば、自分の子供の成功や友人の成果に誇りを感じる場合、その感情を「ほこり」と表現します。しかし、「ほこり」は「じまん」に比べて少しより広い意味を持つことがあり、他者の成果や行動にも関連することがあります。

要するに、どちらの言葉もポジティブな意味を持ち、成功や実績、自己肯定感、他者の成果に対する感情を表現する際に使われます。ただし、具体的な文脈や使われる状況によって、微妙な違いがあることに注意する必要があります。

今後の課題

何かしらのベンチマークをとって、マージ元の Nekomata や Qarasu と比べてどのように変化したか知りたいです。

また、 <|endoftext|> 出てこない問題に関しては、LoRA かなにかの軽い学習で改善できそうではあるので、時間と VRAM に余裕のあるときにためしてみたいです。

GitHubで編集を提案

Discussion