OpenAI(Chatgpt)でファインチューニングを試してみる。料金など
ファインチューニングとは何か
ファインチューニングとは、予め学習済みの大規模言語モデルの性能を特定のタスクに合わせて微調整することです。大規模な言語モデルは多様な問題に対応できるように一般的に学習されていますが、特定の課題に特化したパフォーマンスを出すにはさらなる訓練が必要になる場合があります。
ファインチューニングでは、事前に学習された言語モデルの重みを微調整することで、新しいデータに合わせてモデルを最適化します。これにより、限られたデータでも高性能なモデルを構築することができます。以下の記事がわかりやすいです。
chagptでファインチューニングを行う手順
意外と簡単で、データを準備するだけでサクっとチューニングできたりします。
まずは公式サイトを読み込んでもらうのが良いと思います。読んでてをうごかしたけどよくわからん!って方は以下読んでみてください。
現在GPT4はチューニング不可で、GPT3.5のみ可能です。
学習データの準備
ファインチューニングにはトレーニングデータが必要です。タスクに合わせて、関連性の高いデータセットを収集する必要があります。データの量と質が重要でモデルの性能に大きな影響を与えます。
データはjsonl形式でモデルにインプットします。jsonlは以下のような、改行区切りの1レコードがjsonになっているデータのことです。↓↓
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
データ形式
公式ママ転ですが、いくつかのフォーマットがあります。初めて行う際はワンショット形式が良いと思います。
会話形式
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}
ワンショット形式
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
会話形式&重みづけ
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "384,400 kilometers", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters.", "weight": 1}]}
学習データの生成
テスト的にファインチューニングを行いたい場合は学習用のデータセットは検索すれば出てくると思います。
ただ、自分なりのタスク特化のLLMにチューニングしたいなど、独自のデータセットが必要だけど、それを準備する時間もお金もないよという方が大部分だと思います。そんな方は、データセットからLLMに作ってもらうのが良いかと思います。
従業員の今週の平均対比の稼働工数差分と、割合のデータを送るので差分や割合の大きさに着目して分析してください
input
#データ
大項目 平均との差分 差分割合 (%)
7.その他 0.07 217.0
5.人財投資 -0.05 0.0
4.事務作業 -0.02 0.0
3.組織仕事 0.11 173.0
2.既存案件 -0.37 61.0
1.新規獲得 -0.08 58.0″
“従業員の今週の平均対比の稼働工数差分と、割合のデータを送るので差分や割合の大きさに着目して分析してください。
この従業員は、「7.その他」と「3.組織仕事」の工数が平均より大幅に多く、それぞれ217%と173%の差分割合となっています。一方で、「2.既存案件」と「1.新規獲得」は平均より少なく、61%と58%の割合です。「5.人財投資」と「4.事務作業」は平均より少ないものの、その差分は小さいです。
output(claude3 opus)
こういう形で50~100個くらいデータを準備し、jsonl形式にします。
1個1個手作業でjsonl形式にするのは大変なので、スプシとgoogle colabでサクッとjsonl形式にしちゃいましょう
# ステップ1: 必要なライブラリのインストール
!pip install gspread
# ステップ2: 認証とスプレッドシートからのデータ読み込み
from google.colab import auth
import gspread
from google.auth import default# ユーザー認証を行う
auth.authenticate_user()
creds, _ = default()
gc = gspread.authorize(creds)
# スプレッドシートを開く
spreadsheet_url = 'https://docs.google.com/spreadsheets/d/XXXXX'
sheet = gc.open_by_url(spreadsheet_url).sheet1
data = sheet.get_all_records() # 全てのデータを辞書形式で取得
# ステップ3: JSONLファイルの生成とダウンロード
import json
from google.colab import files
# JSONLファイルの生成
file_path = 'output.jsonl'
with open(file_path, 'w', encoding='utf-8') as outfile:
for row in data:
messages = [
{
"role": "system",
"content": "TOM is a data analysis chatbot that monitors the work conditions of employees."
}
]
# ヘッダが正しく設定されていることを確認
user_content = row.get('input', '') # キーが存在しない場合は空文字列を返す
assistant_content = row.get('output', '') # 同上
if user_content:
messages.append({'role': 'user', 'content': user_content})
print(user_content)
if assistant_content:
messages.append({'role': 'assistant', 'content': assistant_content})
# データの中身を出力する前に確認
print({"messages": [messages]}) # 出力内容を確認
# ensure_ascii=False を指定して日本語がエスケープされないようにする
# JSONファイルに整形して書き込み
#json.dump({"messages": messages}, outfile, ensure_ascii=False, indent=4)
json.dump({"messages": messages}, outfile, ensure_ascii=False)
outfile.write('\n')
# ファイルをダウンロード
files.download(file_path)
やっとデータが準備できましたね。お疲れ様です。あとは一瞬ですよ。
チューニング
OpenAIのプロジェクトページ(正式名称があれば教えてください)にアクセスしてください。
作成済みのfinetuneモデルが確認できます。
右上のcreateを押して以下の通り設定をします。
- Base Model:gpt-3.5 のあたらしいの選べばOK
- Training data:準備したjsonlデータをアップロード
- Validation data:一旦不要、none
- Suffix以下:none、あるいはデフォルトのままでOK
Createを押し、データに問題が無ければトレーニングが始まり5~10分くらいで終わります
Seccessとなったら完了です!お疲れ様でした。
実行
ファインチューニングが完了したら、新しいデータに対してモデルを適用し、目的のタスクを実行できます。以下の様に作ったモデルを指定してあげればOKです。
# ChatGPTへの問い合わせ
response = openai.ChatCompletion.create(
model="ft:gpt-3.5-turbo-0125:personal:0429ab:9JJBZQ4v",
#model="gpt-3.5-turbo",
#model="gpt-4-0125-preview",
messages=messages,
max_tokens=500,
n=1,
stop=None,
temperature=0.7,
)
Playgroundでテスト
Playgroundという機能を用いて、ファインチューニング済みのモデルをテストすることもできます。実際の入力データを使ってモデル毎の振る舞いを確認し、必要に応じてさらにチューニングを行うことができます。
左がgpt3.5, 右がチューニングしたgpt3.5です。出力が簡潔かつ定量的になっている気がしますね。
価格
モデルのファインチューニングそのものにもお金がかかりますし、そのモデルを使用する場合(API経由、playground経由ともに)もお金がかかります。
今回40,000トークン程度を学習させて $0.5くらいでした。金額は公式に載ってるので確認してみてください。
引っかかったポイント
jsonlの中身
以下のようにインテンドをしていると通らないのでご注意ください
{
"messages": [
{
"role": "system",
"content": "CAM is a data analysis chatbot that monitors the work conditions of employees."
},
{
"role": "user",
"content": XXXXX"
},
{
"role": "assistant",
"content": "YYYYY"
}
]
}
Share this content:
コメントを送信