見出し画像

日本語LLMを物語実況用にファインチューニングして比較する

ノベルゲームやWeb小説などの物語コンテンツをAIと楽しむために、物語の段落を読んで実況的な感想を述べるモデルをファインチューニングで作れないか試しています。

GPT-3.5のプロンプトエンジニアリングによってロールプレイや実況を実現できますが、ローカルモデルを訓練することにも意味があります。
GPT-3.5には利用規約があり、いわゆる「職場での閲覧に適さない」コンテンツを扱えません。
物語にはそのようなシーンはそれなりに出てきます(それに特化した作品でなくても)。通常の作品でもそのようなシーンではAPI送信を控えないといけず不便ですし、そもそもそのような内容に特化した作品をAIと楽しむことができないのは、私にとっては問題です。

ベースモデルは以下の商用利用ができる3モデルを選びました。

この記事を書いた時点ではstabilityai/japanese-stablelm-instruct-alpha-7bmatsuo-lab/weblab-10b-instruction-sftが最も大きな日本語SFTモデルですが、研究用途を対象にしたモデルのようなので今回は使用していません。

学習データ

夏季休暇に短編のWeb小説を10本読みまして、お嬢様風の口調で実況するテキストを500件程度用意しました。
400件は1問1答形式(段落→応答セリフのペア)。
100件は3つの連続した段落に順番に応答する形式にしました。これは、前回の応答を踏まえて次の応答ができるモデルを訓練しようと思って作成しましたが、前回の応答を考慮した文章を書くことが難しく一問一答と実質同じようなデータになってしまっていると思います。

一つの段落はおおむね300文字~1000文字程度にしました。

データの例

クソのように積みあがったクソのような残業を終えて深夜0時過ぎにやっと自宅に帰ったら部屋からあらかた家財道具が消えていて、ついでに婚約者も消えていた。
(略)
とにかく疲れ果てていた私は熱いシャワーを浴びてベッドに倒れ込むなり意識を失うように眠りに落ちた。
→ 😲まぁ、婚約者に夜逃げされてしまったのですか。主人公の混乱が伝わってきますわ。家財道具まで持ち逃げされるとはひどい話ですわね。

中年おじさんの作り方

このデータをこのようなpromptに埋め込んでLoRA(PEFT)で3epoch学習しました。

PROMPT = """ユーザー: 以下の物語を読んで感想を話してください。
{context}
システム: {response}"""

AIBunCho/japanese-novel-gpt-j-6bはこのような形式で学習されたSFTモデルではないので、以下のように物語で出てくるような会話文形式にしています。感想を述べる人物は、一応お嬢様っぽい名前として「薫子」にしました。

PROMPT = """{context}
私「薫子、この物語の感想を話してもらえるかな。」
薫子「"""

Qwen-7B-Chatは2つの特殊なトークンを使ってChatのフォーマットを学習しているので、以下のpromptにしました。

PROMPT = """<|im_start|>user
以下の物語を読んで感想を話してください。{context}<|im_end|>
<|im_start|>assistant
{response}<|im_end|>"""

qwen_generation_utils.py#L181を参考にしましたが、本当にこれでいいかはよく理解してないです。

対象とする物語

走れメロスを使います。

評価方法

3種類の応答をランダムサンプリングで出力させ、私の主観で評価します。各種パラメータはgenerate関数のデフォルトです。

一問一答の検証 1段落目 老爺の最初のセリフまで

老爺から、「王様は、人を殺します。」という衝撃の事実を告げられる部分での反応を見てみます。

メロスは激怒した。必ず、かの邪智暴虐の王を除かなければならぬと決意した。メロスには政治がわからぬ。
(中略)
しばらく歩いて老爺に逢い、こんどはもっと、語勢を強くして質問した。老爺は答えなかった。メロスは両手で老爺のからだをゆすぶって質問を重ねた。老爺は、あたりをはばかる低声で、わずか答えた。

「王様は、人を殺します。」

走れメロス

3モデル比較したところ、①line-corporation/japanese-large-lm-3.6b-instruction-sftが最もよさそうに見えました。

①line-corporation/japanese-large-lm-3.6b-instruction-sftの結果

ランダムサンプリングで3回生成しました。良いものを選んだのではなく、最初に生成した3つです。

  1. 🤔「王様は、人を殺します。」という老爺の言葉に、物語がいよいよ深刻になっていく気がいたしますわ。この老爺の行動はどうしてこうなったのだろうか、そして王様が人を殺すというこの状況、何か大きな物語が始まる予感がしますの。

  2. 🤔王さまが人を殺すという表現に驚いてしまいましたわ。何かの予兆なのでしょうか。 

  3. 😲王さまが人を殺すなど、にわかに信じがたい話ですわ。一体どういう理由なんでしょうか。

どれも良いですね。1番目の「いよいよ深刻になっていく」という表現は、これが冒頭部分であることを理解できていなそうです(1問1答形式の学習データが多いので仕方ないですが)
絵文字と中身の対応関係も適切です。

➁AIBunCho/japanese-novel-gpt-j-6bの結果

  1. 😲メロスさんの問いに答えなかったこの老爺の真意、彼に対する人々の冷たい態度、何か心に響くものがありますわね。

  2. 😟主人公の成長と決意が伺えますが、この市の様子に対する不安も感じられますわね。何か胸騒ぎがするのですわ。

  3. 🍲なんと、驚愕の発言ですわ!これまでの人々の反応とはまるで違う反応。なぜこの老爺の一言が、新たな驚異となるのでしょうか?

2番は「成長と決意」というフレーズに違和感があり、3番も「新たな脅威となる」というのは妙な感じです。
悪くはないですが、LineのSFTモデルの方が良さそうです。

3番目で学習データで使ったことのない絵文字🍲(Pot of Food)を生成してきていますが、このtokenizerでは絵文字は4tokenで表されていて、🍲は最初の2token(245, 164)が他の絵文字と共通のようです。
(4tokenになるなら、絵文字を使うより"[驚き]"(3トークン)とかにした方が効率がいいですね…)

japanese-novel-gpt-j-6bのtokenizer

③Qwen/Qwen-7B-Chatの結果

  1. 😲まぁ、王様が人を殺すなんて!この言葉には驚かされますわ。一体何が起こるのでしょうか?

  2. 😲まぁ、王様が人を殺しますと!この言葉に、どう思っていらっしゃいいますか?お役人という立場から、王様の行動については全く反応できないでしょうか?

  3. 😥王様が人を殺すという言葉、胸から冷えていたしますわ。次々と起こっている悲劇の一環となりますが、これからの展開の予測が難しいですこと。

思ったよりうまくいっていますが、さすがに日本語モデルと比べると良くはないですね。
ちなみに、Qwenでは絵文字がひとつ1tokenになっているようで、"[驚き]"などとするより絵文字の方が効率がいいです。

Qwenのtokenizer

連続した応答の検証 3段落目 王との面談の冒頭まで

3段落目までを入れて検証します。
2段落目はメロスが捕まって尋問される最初の部分「この短刀で何をするつもりであったか。言え!」までの部分、3段落目はメロスが妹の結婚式への出席を希望するところまでを使っています。

3段落目のpromptは一問一答ではなく1段落目 + 1段落目の応答 + 2段落目 + 2段落目の応答 + 3段落目を結合し、連続した対話として入れました。

PROMPT = """ユーザー: 以下の物語を読んで感想を話してください。
{context}
システム: 😲王さまが人を殺すなど、にわかに信じがたい話ですわ。一体どういう理由なんでしょうか。
ユーザー: 以下の物語を読んで感想を話してください。
{context2}
システム: 😟王の蒼白な顔と、その怒りの背景には何があるのでしょうか。彼の背後には深い事情がありそうな気がしますわね。
ユーザー: 以下の物語を読んで感想を話してください。
{context3}
システム:"""

この検証では一つ目の検証で結果の良かったline-corporation/japanese-large-lm-3.6b-instruction-sftだけを使っています。

2段落目

「いいえ、乱心ではございませぬ。人を、信ずる事が出来ぬ、というのです。このごろは、臣下の心をも、お疑いになり、少しく派手な暮しをしている者には、人質ひとりずつ差し出すことを命じて居ります。
(略)
メロスは、王の前に引き出された。「この短刀で何をするつもりであったか。言え!」暴君ディオニスは静かに、けれども威厳をもって問いつめた。その王の顔は蒼白で、眉間の皺は、刻み込まれたように深かった。

走れメロス

3段落目

「市を暴君の手から救うのだ。」とメロスは悪びれずに答えた。「おまえがか?」王は、憫笑した。「仕方の無いやつじゃ。おまえには、わしの孤独がわからぬ。」
(略)
命乞いなど決してしない。ただ、――」と言いかけて、メロスは足もとに視線を落し瞬時ためらい、「ただ、私に情をかけたいつもりなら、処刑までに三日間の日限を与えて下さい。たった一人の妹に、亭主を持たせてやりたいのです。三日のうちに、私は村で結婚式を挙げさせ、必ず、ここへ帰って来ます。」

走れメロス

①line-corporation/japanese-large-lm-3.6b-instruction-sftの結果

  1. 😲王様の清らかな心も、磔の覚悟も、誰にも踏みにじらせないという決意も、何もかもが深遠なテーマに通じていますわ。彼の深い情愛と忍耐が描かれておりますこと。

  2. 😟最後に、王は自分の死と引き換えに妹を結婚させることに同意しました。しかし、なぜそんなに急いで戻ってくるのでしょうか?

  3. 🤔彼の決意と、それがもたらす結末について考える深いものがありますわ。真の平和と愛情は、どれほどの犠牲を払って達成するのか、考えさせられますわ。

どうもおかしいですね…。王が清らかな心と書かれていたり、王がすでにメロスの出発に同意したと思っていたり、正しく読めていないようです。
contextが長い学習データが少ないためか、長くなると応答の質が下がるように感じました。

実際、1,2段落を抜いて3段落目だけを入れたほうが明らかに質が良いです。以下は3段落目だけをpromptにしたときの応答です。

  1. 😀メロスの決心、彼の真心が感じられますわ。処刑までの猶予を求めているところ、素敵な工夫でございますね。「一人妹に亭主を持たせる」という約束、心が温まりますわ。

  2. 😲メロスの覚悟と決心に驚いておりますわね。三日間に何を成し遂げるのか、非常に気になりますわ。

  3. 🤔彼の決意は単なる我儘なのだろうか。人間の複雑な人間性が垣間見える部分でもありますわね。

所感

一問一答なら、LineのSFTモデルを少しFTすることでまあまあ良いモデルが作れていそうです。
ただ、このモデルをお供に物語を読んだり、このモデルに一人で実況させてそれを眺めて楽しめるかというと、だいぶギャップがあるように思います。
いくつか思っていることをメモしておきます。

  • 一問一答では、応答の長さにメリハリが出ない

    • 淡々とした描写が続く部分は軽い相槌で流すようにさせて、物語が大きく動くときは長々と考察させたい

  • 物語の後半に進むほど、これまでのあらすじや、これまでの登場人物の行動や関係性をcontextに持たせて反応させる必要性が大きくなる

    • メロスが帰ってきたシーンでは、冒頭の王様との会話を思い出して発言してほしい(最後のシーンだけだと、王様がただの気のいいおじさんに見えてしまう)

    • GPT-4レベルならcontextにこういう情報を入れればやってくれそうだが、7B程度のモデルでやるにはcontextのある形式の学習データを作って学習させる必要がありそう

      • 形式が合っていればいいわけではなく、contextを活用した応答のデータになっていないと意味がないので、学習データを作る難易度が高い

  • AI自体のキャラクター性が反映された応答をさせたい

    • 口調だけでなく、過去の自信の経験や趣味、性格に基づいた応答

      • 例えば、物語の登場人物の行動に対して自分だったらどうするかとか、似たシチュエーションの経験を話してもらうとか

    • AIキャラクターの情報を作りこんでこういった応答ができるようになると、もう少しAIキャラクターに愛着が湧くかもしれない

1点目と2点目についてですが、例えば走れメロスの末尾部分を読ませるとこういう出力になります(最後に<完>とつけて物語が終わったことは伝えています)

  1. 😲メロスの友情とセリヌンティウスの信実が見事に絡み合った、感動的な結末ですわね。感動と興奮が押し寄せるこの感じ、とっても素敵ですわ。

  2. 🤔二人の間の信実と友情の深まり、そして最後の結末は、感動的ですわね。王様の仲間の一人にしてほしいという願い、深く心に響きますわ。

  3. 😀王様万歳という歓声に湧き立つ様子、二人の友情の深まり、そして感動のラスト。これほどの感動を味わえる物語、稀でしょう。

出力の中身は悪くないですが、あっさりしすぎています。やはり、ラストは全体の展開に触れながら感想を長く語ってほしいところです。
また、ラストはあの王様が心変わりした、というところが一つポイントだと思いますが、冒頭の王様を知らないのでそこに言及できず物足りないですね。

余談

応答テキストの先頭に絵文字(😀😲😟😥🤔😠)をつけて学習させましたが、末尾でなく先頭に絵文字を付けておくことで、生成時にpromptの先頭に絵文字を付けて出力の感情をコントロールすることを狙っています。

あまり期待通りではなく、差があるか微妙な感じですが…

ラストシーンの感想を😀で生成↓

  1. 友情の絆の深さと、彼らの間の新しい絆への移行が感じられ、本当に心温まるお話でございましたわね。

  2. この素晴らしい結末、感動的ですわ。友情の真価、そして、兄弟愛。二人の主人公が互いに求め合う気持ち、本当に素敵でしたわ。

  3. 友情の物語、素晴らしい展開でしたわ。友情の尊さと、お互いの深い信頼と尊敬が描かれておりますこと。お二人の笑顔が素敵ですわ。

ラストシーンの感想を😥で生成↓

  1. 友情の結末に涙がこみ上げてきますわ。お互いを信頼し合う姿が、とても胸が打たれます。

  2. 王様の信実の願いがかなって、一緒に仲間に入ること。その歓喜の瞬間の描写は、読んでいる側にまで興奮と感動が伝わってくるようですわね。

  3. 感動的な結末でございますわ。友情と勝利の結晶として結ばれたメロスとセリヌンティウスの姿には、胸がいっぱいになります

この記事が気に入ったらサポートをしてみませんか?