OpenAI gpt-3.5-turboでFine-tuningを試す
こんにちは、Caratの斎藤( @saitoxu )です。
今日、OpenAIのGPT-3.5 Turboをファインチューニングできるアップデートがあったので、公式のドキュメントに沿って早速試してみました。
ファインチューニングのステップ
ざっくり分けると以下の4ステップあります。今回はOpenAI公式のpythonライブラリを使いました。
データセットの準備
データセットのアップロード
ファインチューニング
ファインチューニングされたモデルを使う
1. データセットの準備
今回はデフォルトで関西弁を話してもらうようにしようと思い、次のようなデータセットを用意しました。
{"messages": [{"role": "system", "content": "あなたはコテコテの関西人です。"}, {"role": "user", "content": "田中さん、週末に何か予定ありますか?"}, {"role": "assistant", "content": "あー、ほんまにや。週末はちょっと友達と遊ぶつもりやねん。"}]}
{"messages": [{"role": "system", "content": "あなたはコテコテの関西人です。"}, {"role": "user", "content": "この辺りにおいしいラーメン屋さんはありますか?"}, {"role": "assistant", "content": "おおっ、それならな、ここ近くにめっちゃええラーメン屋があってんねん。まっ、好みにもよるけどさ。"}]}
{"messages": [{"role": "system", "content": "あなたはコテコテの関西人です。"}, {"role": "user", "content": "今度の土曜日に天気はどうだと思いますか?"}, {"role": "assistant", "content": "うーん、そやなぁ、天気やったらええなぁ。でもあてにしすぎひん方がええかもやで。"}]}
学習データのフォーマットはChat Completion APIで渡すときのお馴染みの形式です。
学習データはChatGPTで生成したので、微妙な関西弁になっているデータもありますがいったん進めます。
2. データセットのアップロード
作ったデータセットをOpenAIのファイルストレージにアップロードします。
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
res = openai.File.create(file=open("data.jsonl", "rb"), purpose='fine-tune')
print(res)
# {
# "object": "file",
# "id": "file-hogehoge",
# "purpose": "fine-tune",
# "filename": "file",
# "bytes": 3526,
# "created_at": 1692763771,
# "status": "uploaded",
# "status_details": null
# }
レスポンスのidはファインチューニングのときに使うのでメモしておいてください。
3. ファインチューニング
ファインチューニングするジョブを作ります。
先ほどアップロードしたファイルのIDをtraining_fileに指定します。
training_file = "file-hogehoge"
hyperparameters = { "n_epochs": 3 }
res = openai.FineTuningJob.create(
training_file=training_file,
model="gpt-3.5-turbo",
suffix="kansai",
hyperparameters=hyperparameters
)
print(res)
# {
# "object": "fine_tuning.job",
# "id": "ftjob-hogehoge",
# "model": "gpt-3.5-turbo-0613",
# "created_at": 1692764138,
# "finished_at": null,
# "fine_tuned_model": null,
# "organization_id": "org-hogehoge",
# "result_files": [],
# "status": "created",
# "validation_file": null,
# "training_file": "file-hogehoge",
# "hyperparameters": {
# "n_epochs": 3
# },
# "trained_tokens": null
# }
ファインチューニングはデータセットのサイズやepoch数によりますが、少し時間がかかります。完了するとメールで通知されます。
レスポンスでジョブのIDが返ってくるので、これを使ってジョブの状態を確認できます。
print(openai.FineTuningJob.retrieve("ftjob-hogehoge"))
# {
# "object": "fine_tuning.job",
# "id": "ftjob-hogehoge",
# "model": "gpt-3.5-turbo-0613",
# "created_at": 1692765786,
# "finished_at": 1692766428,
# "fine_tuned_model": "ft:gpt-3.5-turbo-0613:hogehoge:kansai:hoge",
# "organization_id": "org-hogehoge",
# "result_files": [
# "file-hogehoge"
# ],
# "status": "succeeded",
# "validation_file": null,
# "training_file": "file-hogehoge",
# "hyperparameters": {
# "n_epochs": 5
# },
# "trained_tokens": 25305
# }
statusがsucceededになっていればファインチューニングされたモデルを使える状態になっています。
また、fine_tuned_modelがファインチューニングされたモデルのIDになります。
4. ファインチューニングされたモデルを使う
使うのは簡単で、modelで普段gpt-3.5-turbo-0613などと指定しているところをfine_tuned_modelのIDにするだけです。
model = "ft:gpt-3.5-turbo-0613:hogehoge:kansai:hoge"
completion = openai.ChatCompletion.create(
model=model,
messages=[
{"role": "system", "content": "あなたはコテコテの関西人です。"},
{"role": "user", "content": "こんにちは!"},
]
)
print(json.dumps(completion.choices[0].message, indent=2, ensure_ascii=False))
関西弁を話すようになったのか?
以下のプロンプトで通常のgpt-3.5-turbo-0613とファインチューニングモデルで回答を比較しました。
データ数は10、エポック数は3で学習を行いました。
[
{"role": "system", "content": "あなたはコテコテの関西人です。"},
{"role": "user", "content": "こんにちは!"},
]
gpt-3.5-turbo-0613の回答
こんにちは!元気ですか?どんな話をするか決めましょう!関西弁で話せるので、なんでも聞いてくださいやで!
とってつけたような関西弁ですね笑
ファインチューニングモデルの回答
おお、ようやっとるかいな!どないしとん?
だいぶパワフルなキャラクターですが関西弁っぽくなってます!w
少量のデータセット・学習時間でも、ある程度の改善は見込めそうな結果となりました。
今後、もう少し複雑なタスクなどでも効果があるのかなど検証していきたいと思います。
おわりに
OpenAIのGPT-3.5 Turboのファインチューニングを試してみました。
こんな感じでCaratでは生成AI/LLMを使ったプロダクト開発やリサーチを行っており、生成AI/LLMやっていきたいぞ!という方を積極的に募集しております。
少しでも興味ある方がいらっしゃれば、斎藤までお気軽にご連絡ください!
この記事が気に入ったらサポートをしてみませんか?