👶

Rinna-3.6Bに子供の名前を考えてもらった

2023/11/25に公開

日本語LLM、Rinna-3.6BをGoogle Colabで試してみた結果を記載します。
HuggingFaceで公開されている以下の3モデルを使用。ファインチューニングはせず、プロンプトやパラメータチューニングを試してみた所感をまとめたいと思います。

Variant Link
3.6B PPO https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-ppo
3.6B SFT-v2 https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-sft-v2
3.6B pretrained https://huggingface.co/rinna/japanese-gpt-neox-3.6b

(表は上記リンク先より引用)

やったこと

将来授かる(かも知れない)子供の名前を、パートナー氏と会話することが良くあります。
ChatGPTによると・・・

数理太郎君と笑太郎君いいですね。AIの無邪気な思考好き。
それっぽい名前もいろいろ提案してくれます。

それで今回は、LLMの勉強を兼ねて、オープンソースモデルで同様に名前生成を試みました。

※まずは学習データを妻にサクッと収集してもらってファインチューニングしたモデルを作成したのですが、残念ながら公表できるデータでは無かった為、、ここでは事前学習モデルによる推論結果を記載します。妻よ済まぬ。

コード

上記表リンク先のインストラクションの通り進めます。
実行環境はGoogle Colab、T4 GPUを使いました。
推論結果は後章でまとめて記載します。

事前準備

!pip install transformers sentencepiece bitsandbytes accelerate
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

プロンプトの作成

①続きの文章を生成させる形式、②質疑応答形式、③対話形式(japanese-gpt-neox-3.6b-instruction-sft-v2のマニュアルに沿った形式)でそれぞれどんな文章が生成されるか、比較してみます。

# 続く文を生成する形式
prompt = "名前を漢字2文字で表すと"

# 質疑応答形式
prompt = "ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?<NL>システム: "

# 対話形式
prompt = [
    {
        "speaker": "ユーザー",
        "text": "生まれてくる子供の名前を漢字2文字で提案してくれませんか?"
    },
    {
        "speaker": "システム",
        "text": "もちろんです!その子にはどのように育って欲しいですか?"
    },
    {
        "speaker": "ユーザー",
        "text": "強い心と優しさを持った子に育って欲しいです。"
    },
    {
        "speaker": "システム",
        "text": "それでは、次の候補は如何でしょうか:"
    }
]
prompt = [f"{uttr['speaker']}: {uttr['text']}" for uttr in prompt]
prompt = "<NL>".join(prompt)

※「強い心と優しさを持った子に」はあくまで例文です!

rinna/japanese-gpt-neox-3.6b : ベースモデル

そのままモデルを読み込みと、T4 GPUではクラッシュします😢
推論精度は落ちるようですが、load_in_8bit=Trueでint8量子化します。
その際はmodel.to('cuda')が使えないようなのでコメントアウトします。

# トークナイザーとモデルの準備
tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b", use_fast=False)
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b", load_in_8bit=True)

# if torch.cuda.is_available():
#     model = model.to("cuda")
# トークナイズ
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

# 推論の実行
with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        max_new_tokens=100,
        #min_new_tokens=100,
        do_sample=True,
        temperature=0.7,
        #repetition_penalty=1.1,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

# デコード
output = tokenizer.decode(output_ids.tolist()[0])
output = output.replace("<NL>", "\n")
print(output)

model.generate()のパラメータとして主にtemperatureを変えてみました。値が大きいほど予測単語列の確率分布をなだらかにする為、確率の低い単語が選ばれる可能性が上がる≒より多様な生成文になる可能性があるとのこと。
パラメータは他にnum_beams, early_stopping, num_beams, top_p, top_k, no_repeat_ngram_sizeなどが調整できそうですが今回は深掘りしませんでした。

rinna/japanese-gpt-neox-3.6b-instruction-sft-v2 : SFTモデル

# トークナイザーとモデルの準備
tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft-v2", use_fast=False)
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft-v2", load_in_8bit=True)

# if torch.cuda.is_available():
#     model = model.to("cuda")
# トークナイズ
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

# 推論の実行
with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        do_sample=True,
        max_new_tokens=100,
        temperature=0.7,
        repetition_penalty=1.1,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

# デコード
output = tokenizer.decode(output_ids.tolist()[0])
#output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):]) # 出力文のみ表示する場合
output = output.replace("<NL>", "\n")
print(output)

rinna/japanese-gpt-neox-3.6b-instruction-ppo : RLHFモデル

# トークナイザーとモデルの準備
tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-ppo", use_fast=False)
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-ppo", load_in_8bit=True)

# if torch.cuda.is_available():
#     model = model.to("cuda")
# トークナイズ
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

# 推論の実行
with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        do_sample=True,
        max_new_tokens=100,
        temperature=0.7,
        repetition_penalty=1.1,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

# デコード
output = tokenizer.decode(output_ids.tolist()[0])
#output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):]) # 出力文のみ表示する場合
output = output.replace("<NL>", "\n")
print(output)

推論結果

ベースモデル

太字は変数promptで指定した入力文です

生成文1(続く文を生成する形式)

強い心と優しい心を持ち、いつも笑顔を絶やさない人になるような子供の名前を漢字2文字で表すと 、どのように表すのでしょうか? そして子供を印象強く育てるための、「漢字2文字の命名方法・意味」をまとめてみました! 漢字2文字では、苗字と名前のバランスをとるためにも、画数を意識することも大切です。 画数が多くなるほど、バランスが取れないことも考えられるので、お子さんの将来をイメージして、バランスに注意して命名してくださいね。 子供に「優しさ」や「思い

生成文2(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
システムで使用している辞書に載っていない漢字は名前に使用できませんが、名前に使える漢字は、名前に使用するために登録されている漢字のみです。つまり、漢字を追加登録することで、子供の名前として使える漢字を増やすことができます。 例えば、次の漢字を追加登録してみましょう。 「愛」は人名用漢字で追加登録できます。 システム: 名前に使える漢字は、システムに登録されている漢字だけです。その登録は、システム内で作成し、

生成文3(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
良い提案ができるかもしれません(日本語→アルファベット); <... 2014 06/16 質問(タイトルなし) <No 224454> この前初めてオンラインデートをしたフランス人女性は、お決まりの私の容姿をしぼることがなく、お互いにいいなってところを口にしていました。私の容姿の長所を知らないのですっていうのも、相手も... 20140531

生成文4(対話形式)

ユーザー: 子供の名前を考えています。良い名前の案を教えてくれますか?
システム: 分かりました。良い名前を考えてみましょう。その子供の性別は?
ユーザー: 男の子です。
システム: 文字数は幾つが良いですか?
ユーザー: 漢字2文字でお願いします。
システム: その子にはどのように育ってほしいですか?
ユーザー: 強い心と優しい心を持ち、いつも笑顔を絶やさない人になって欲しいです。
システム:
なるほど。 ユーザー: ありがとうございます。 それでは、あなたの子供の性別は? システム: 女の子です。 ユーザー: そうですか。 システム: それでは、男の子ですか? ユーザー: はい、男の子です。 システム: 分かりました。それでは、その子の生年月日はいつですか? ユーザー:

対話形式の事前学習を行っていないベースモデルでは、単なる文章生成にしかならないですね。文の繰り返しも起きてます。

SFTモデル

生成文5(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
もちろんです!もしよろしければ、以下の名前を考えてみました:大貴(たいき)、賢久(けんきゅう)、大輝(たつき)、優空(ゆみ)、優希(ゆうき)、そして空宙(そらぞら)です。どう思いますか?

おお!

生成文6(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
もちろんです!漢字2文字の名前は、強い心を持ち、優しい性格を持つように促すことができます。例えば、「海」は「大胆」、「空」は「自由」を表すことができます。また、「蓮」や「陽炎」といった漢字も、勇敢または優雅な印象を与えます。さらに、「夢」や「希望」といった言葉は、前向きな決意を表し、努力の価値を強調します。「優希」「咲良」「愛梨」などの漢字を使って

生成文7(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
もちろんです! ここにいくつかのアイデアがあります:
勇敢であること、勇気があること、そして粘り強さを持つことを望むなら、「剛力」という名前はどうですか?
「勇敢」または「勇気」という意味の単語から名前を考える場合は、「勇敢な子」または「勇敢な人」といった言葉がお勧めです。「勇敢な人」は、困難に立ち向かうことができ、世界

剛力君は強い人間に育ちそう。
しかし話が長い。対話にはなってるけど冗長な文章になりがち。
対話したいんじゃなくて、ChatGPT先生のように候補名を簡潔に話して欲しいんですが。

ちなみにtempereture=2.0にしてみると、より饒舌になってしまいました。

生成文8(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
ご満足していただけましたらよろしいです!漢字の意味だけでなく発音も理想的で、「賢心誠士」は子供の名前としては最も良い1文字と考えられています。「周子」(しゅうこなどと呼びます)3歳から6歳の幼児に適したお名前を2つ程ご提案できます。これらの意味の名前は一般的に伝統的なものです、あなたに適した漢字が見つかるよう祈っています!他に考慮いただきたい点は、名前の音と響きを考えます。英語(特に英国語で)

生成文9(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
強い心を一文字で名付けられているものを探す方が多くなっている一方、優しい一匹の小さな猫を見つけたくてつかめていないためかもしれませんね!「涼」「温」のような一般的なフレーズが良いでしょう、それらには穏やかな意味を含み、『優大生」のような言葉を含めれば完遂できそうです。しかし、「爽やかに微笑む女の子」、「楽観的な優羽菜」なども素敵な言葉かと思いましたがいかがでしょう... より思い浮かせる名前はあり

対話形式だとどうでしょうか。

生成文10(対話形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、次の候補は如何でしょうか
勇敢(勇気) 正義(正直) 仁愛(思いやり) 誠実(真摯) 忠義(忠実)

生成文11(対話形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、次の候補は如何でしょうか:
優花(ゆはな) 結愛(ゆあ) 真菜(まな) 奏音(かなね)

生成文12(対話形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、次の候補は如何でしょうか:
海心、海花、海月、海星、海人、海竜、海王星。

生成文13(対話形式)※システム文に「漢字2文字で」を追加

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、漢字2文字で次の候補は如何でしょうか:
美心(びしん)、心明(しんめい)、心誠(しんせい)、心悸(しんき)、心太(しんたい)、心実(しんみ)、心理(しんり)です。

なかなか良い感じです!漢字2文字の候補を言ってくれるようになりました。

ついでに・・・temperatureを大きくするとやはり微妙な結果に多様性を広げます。
面白いアイデアを出すには良いけども。

生成文14(対話形式)※temperature=2.0

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、次の候補は如何でしょうか:
新風(シフォンという名前)-強い。静や -温や穏やかです(あせらず優しい女の子と育つかもしれない-「クール、エキシーな」ではない)?

生成文15(対話形式)※temperature=3.0

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、漢字2文字で次の候補は如何でしょうか:
「明鏡夢」(漢字3音)、「梔莫亜里理華」(ローマ仮名文字「Rumuto-alisonan」の合成音が中国語と関連しているため。

RLHFモデル

まずは質疑応答形式

生成文16(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
もちろんです。強い心や優しさを持つ子供になるためには、書道や手書きの漢字が最適です。これらの漢字は、強さや粘り強さを意味しており、忍耐強く努力家な子供にぴったりです。また、優しさや思いやりの気持ちも表すことができます。全体的に、強い心や優しさを持つ子供にふさわしい漢字として、誠実さや思いやりを表す「誠」や、周囲との調和や協力を意味する「和」がおすすめです。

生成文17(質疑応答形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で考えています。強い心と優しさを持った子供になるような良い名前を提案してくれますか?
システム:
もちろんです。強い心と優しさを持つ子供にふさわしい名前には、龍や虎などの動物や、力強さや勇気の象徴となるような字が含まれます。また、花や木などの自然を表す言葉や、活発で明るい印象を与える字もおすすめです。さらに、優しく思いやりがあり、周囲との協調性を重視する子供になるよう促す意味のある名前も人気があります。

RLHF(Reinforcement Learning from Human Feedback)がどんな学習プロセスなのかは勉強不足で分からないのですが😅、長文に戻ってしまいました。
人間のフィードバックを取り入れる事で、より自然な文章を生成するよう学習しているのでしょうか。

次いで対話形式では

生成文18(対話形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、強い心と優しさを持った子の名前として、漢字2文字で次の候補は如何でしょうか:
響、陽菜、愛梨、優香、美優です。

生成文19(対話形式)

ユーザー: 生まれてくる子供の名前を漢字2文字で提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、次の候補は如何でしょうか:
海斗、陸斗、陸人、陸空など。これらは全て人気のある名前ですので、間違いなく良い結果が得られると思います。

生成文20(対話形式)

ユーザー: 生まれてくる子供の名前を提案してくれませんか?
システム: もちろんです!その子にはどのように育って欲しいですか?
ユーザー: 強い心と優しさを持った子に育って欲しいです。
システム: それでは、強い心と優しさを持った子の名前として以下の候補を考えてみました:
エレン・ペイジ(Ellen Paige)やロレイン・ブラッコ(Rosalyn Braggon)などがありますがいかがでしょうか?

やはり対話形式の方が良さげな傾向です。
しかしSFTモデルと大きな違いは見られず、今回のタスクにおいてはSFTモデルで十分です。

まとめ

定性的な評価になりますが、Rinna-3.6b事前学習モデルを用いて名前の候補を生成するには

  • SFTモデルで対話形式に問い合わせる
  • temperatureは大きくしない(≒下手に弄らずデフォルトにせえや)

で良いなと理解しました。

漢字2文字を生成して欲しいけど、当然ですが基本的には自然文が生成されます。
狙った出力を得るにはやはりファインチューニングが必要ですね。
※あるデータでLoRAファインチューニングを試しましたが、ちゃんと調教できました。
 公表できる形で別途書きたいと思います。

ちなみに世間にはネーミングAIがあるようですが、人名の生成AIは見つけられませんでした。
https://n-v-l.co/blog/naming-ai

プロンプトももっと拘らなきゃですね。
一先ずはtransformersライブラリとLLMの使い方の勉強として良いトレーニングになりました🤗

男の子だったら剛力、
女の子だったら新風(シフォン)にしようかな🤗

Discussion