PaLM APIのファインチューニングではてな匿名ダイアリー風文章生成モデルを作る

PaLMとは

PaLMはGoogleの大規模言語モデルです。先日、日本語に対応しました。

www.itmedia.co.jp

PaLM APIのファインチューニング

PaLM APIの基本的な利用方については以下の記事が参考になります。

zenn.dev

6月頃に「PaLMって英語の受け答えにしか対応していないけど日本語でファインチューニングしたらどうなるんだろう*1」と思って実行してみたんですけど、当然のごとくエラーが出て失敗しました。

今回日本語に対応したので、再度挑戦してみました。

はてな匿名ダイアリー風文章生成モデルとは

題材として、以前以下の記事でみかけたコンセプトである「はてな匿名ダイアリー風文章生成モデル」の自作を選びました。

Anond AIは、rinna/japanese-gpt2-mediumをはてな匿名ダイアリーのデータを用いてファインチューニングし、ドメイン適応させたものです。

developer.hatenastaff.com

Quotaの申請

以下のドキュメントに沿ってすすめます。

cloud.google.com

ファインチューニングの実行はeurope-west4かus-central1でないと実行できないようになっているので、そのlocationでQuotaの申請を行います。

6月時点ではeurope-west4しか対応してなかったので、europe-west4 + restricted_image_training_tpu_v3_pod=64を申請しました。

For europe-west4, submit a request for Restricted image training TPU V3 pod cores per region in the europe-west4 region in multiples of 64.

受理までしばらく時間がかかりました(数日)。以下URLから割り当て状況を確認可能です。

https://console.cloud.google.com/iam-admin/quotas/qirs

データセットの作成

ドキュメントに従いjsonlファイルを作ります。300件ほどサンプルがあればよいかと思い、以下のような形式のデータを作成しました。

  • input_text: 投稿のタイトル
  • output_text: 投稿の本文冒頭
❯ tail dataset.jsonl
{"input_text": "表現規制派の言ってる事って「マイナスイオン」とか「水からの伝言」と何が違うの?", "output_text": "強力効果論とか限定効果論とかあるけどさ、あれってどの位証明されてどの位信用が
  けるものなの? そういう影響論を真に受けて表現規制とか公共の場に出すなとか言っているけど それが嘘だった場合(つまり、影響なんて無いか、無視できる程度だったり、他の表現や社会的に許容されて
  他の一般的行動とか慣習と同程度の影響しかなかった場合)、どうするの? 現状、その可能性は全然有る様に見えるんだけど 全然効果が無い事の為に、仕事を失ったり罵倒されり悪として扱われる人達の理
  尽な境遇を考えないなら、リベラルの名を語る資格無くね? あなた達は人を不幸にする為にリベラルとか表現規制派とかをやっているの? 違うと言うなら、何で真面目に考えようとしないの? 表現規制派の
  ってる事って「マイナスイオン」とか「水からの伝言」と何が違うの? 追記 冒頭に挙げた例が却って一例に拘泥して論点を見失う原因になるようなので、消しまし"}
{"input_text": "甲子園球児の笑顔が辛い", "output_text": "しんどい場面で笑ってるのがキツイ。本当は「くそがああああ!!!!」とブチギレたいだろうに。グローブでもベンチに投げつけたいし、バット
  し折りたいだろう。緊張極まってプルプル真っ青な顔でいたいだろうに。テレビもあるし、一生残るし常に「どんな状況でも甲子園楽しんでます!」を演出しなきゃいけないのしんどすぎるだろ。小さい頃に
  ちゃイジメられてたのにヘラヘラ笑うしか無かった自分を思い出して見てられん。はーしんど。"}
{"input_text": "お金がなくなっていくって怖いよね", "output_text": "元々貧乏な生活してささやかな貯金をするのが趣味だった。 今配偶者がなおるあてのない長く療養が必要な重い病気になって貯金を切
  崩す生活をしてて、使える制度をフルに使っても100万円しかない貯金が毎月10万円ずつ減ってるの見てるけど、配偶者が重い病気で怖いとか悲しいより、このお金が無くなるという方が正直ストレスに感じて
  。 薄情なやつだな、と思うけど、そんなことを悟られないようにして最期まで面倒みるから、許して欲しい。 実家、新築の家を昔ローンで買ってたけど、今年55歳の父親が1500万の残債がどうにもならなく
  売りに出すって。でも、私あの家にそんな価値ないって知ってる。猫が柱をがちゃがちゃにして、あらゆるところの掃除をマメにしていたわけでないから汚れが酷くて立地が酷い。だからきっとそんな値段で
  売れない。父親と母親は熟年離婚した。母親も貧乏な生活してる。父親も母親も高卒で、両親はわたしを含め"}

これによって未知のタイトルを入力したら、はてな匿名ダイアリーの投稿の書き出しを生成してくれるのを期待します。

できたらjsonlファイルをGCSにアップロードしておきます。

トレーニングJobの実行

tuning.pyを参考に実装します。

model = TextGenerationModel.from_pretrained("text-bison@001")

model.tune_model(
    training_data=training_data,
    model_display_name='text-anond',
    train_steps=12,
    tuning_job_location="europe-west4",
    tuned_model_location=location,
)

training_dataはGCSにアップロードしたデータセットのパスを指定します。例: gs://bucket-name/path/to/dataset.csv

train_stepsはファインチューニングのステップ数を指定します。データセットのサンプル数とジョブ実行locationで調整します。

If there are 240 examples in a training dataset, in europe-west4, it takes 240 / 24 = 10 steps to process the entire dataset once. In us-central1, it takes 240 / 8 = 30 steps to process the entire dataset once. The default value is 300.

tuned_model_locationはモデルが配置される場所です。トレーニングとは別のlocationが指定できます。

このスクリプトを実行するとVertex AIのパイプライン上で実行中となり状況やエラーなどを確認できます。

https://console.cloud.google.com/vertex-ai/pipelines/runs

第1回目のチューニングを実行した直後「差別的な内容など・データセットに問題あり」警告が100件程出てきて完全に題材見誤ったわーと後悔したのですが、なんとかなりました。

チューニング済みモデルで文章生成する

無事チューニングジョブが完了したら、以下のモデル一覧にチューニング済みモデルが表示されます。

https://console.cloud.google.com/vertex-ai/models

「デプロイ」→「モデルのテスト」→「Generative AI Studio」と進むとブラウザ上で応答を確認できます。

Prompt入力欄に匿名ダイアリーにありそうなタイトルを入力してみて、生成された文章を確認します。創作性を発揮してもらいたいのでモデルのtemplateは1にしておきます。

ここで残念なお知らせですが、GoogleのGenerative AI Preview Products利用規約に従い生成された文章は第三者に公開できません(なので本稿も公開情報だけに触れています)。

なので私の感想を書くだけにとどめますが——そういえばはてな匿名ダイアリーを普段読まないので正直よく分からん。

ソースコードからこのモデルを呼び出す時のコードはideation.py が参考になります。

今回のテストだとこんな感じになります。

model = TextGenerationModel.from_pretrained("text-bison@001")
model = model.get_tuned_model(f"projects/{project_id}/locations/{location}/models/{tuned_model_id}")
response = model.predict(
    """タモリさんの本名は?""",
    **parameters
)
print(f"Response from Model: {response.text}")

おまけ: gpt-3-5-turboでも同じファインチューニングしてみた

openai.com

データセットは微修正すればいけるので追加で試した。

model = "ft:gpt-3.5-turbo-0613:personal::XXXXXXX"

completion = openai.ChatCompletion.create(
    model=model,
    messages=[
        {"role": "user", "content": "まじな話をすると、N予備校のプログラミング入門コースやるのがオススメ"}
    ],
    max_tokens=255,
)

print(completion.choices[0].message['content'])
❯ python tuning_openai.py
個人的な意見で、エンジニアになりたい人、プログラミングを自己流ではなくちゃんと根底から学びたい人には超オススメというか、やらない理由を教えてくれ。1.人に教える道具としてプログラミングが使え
るようになる。言語が単なる道具になる。
2.NO②を使って試してみる、NO①で作った物からいじり方を考える
3.解説あっての練習_system.out.println()の設定 ・javaの入出力の勉強
4 プログラムのバグは悪くない、そのバグは必ず意味がある、じゃないと書けない。高校の見方しか出来ない。
5 数字コード「文字コード」を理解する
6

見比べるとこっちのがはてな匿名ダイアリーっぽい(諸説ある)。

チューニングなし

我が家のインドカレー

インドカレーは、我が家の定番料理です。母はインドの友人から学んだ本格的なレシピで作るので、香り高いスパイスと豊かな味わいが特徴です。

チューニングあり

我が家のインドカレー

インド料理を美味しく頂くのはもちろんだが、カレールウを自作することが我々日本人にとってもっとも適した消費の仕方であり、肝要である。原因は3つ考えられる。

ジョブの実行部分

import openai

resp = openai.File.create(
  file=open("dataset.jsonl", "rb"),
  purpose='fine-tune'
)

print(resp)

job = openai.FineTuningJob.create(training_file=resp.id, model="gpt-3.5-turbo")

print(job)