OpenAIは、APIサービスにおいて、2023年8月23日に大規模言語モデル「GPT-3.5 Turbo」のファインチューニング機能をリリースしました。GPT-3.5 Turboは、ChatGPTに使われている技術です。
ファインチューニングにより、企業は自らのデータを活用してGPTモデルを特定のニーズに合わせてカスタマイズできるようになりました。
なお、ファインチューニングの公式ドキュメントはこちらで読めます。
また、「ファインチューニング」はデータを読み込ませて応答させる「RAG」「エンべディング」とは異なりますのでご注意ください。つまり、ファインチューニングはRAGのように正確な応答をさせたい場合に使うものではないということです。
【目次】
- ファインチューニングとは
- ファインチューニングのメリット
- ファインチューニングのデメリット
- ファインチューニングの例
- ファインチューニングの価格
- ファインチューニングの価格は「トレーニング費用」「使用費用」の2つに分かれる
- トレーニング費用 (training cost)
- 使用費用 (usage cost)
- ファインチューニングの方法
- ① 学習させたいデータを用意する
- ② データのファイルをアップロードする
- ③ ファインチューニングの実行をリクエストする
- ④ ファインチューニングされたモデルを実際に利用する
ファインチューニングとは
ファインチューニングとは、既存のモデルのパラメーターを微調整して再トレーニングすることです。(Fine-tuning = 微調整)
これにより、モデルの扱いやすさ、一貫性、論調・口調をカスタマイズできます。
一方、データを読み込ませて正確な応答を期待する 「RAG」 という手法とは異なる考え方のカスタマイズです。独自のデータを読み込ませて正確な応答をしてほしい場合にはRAGを検討してください。
ファインチューニングのメリット
ファインチューニングには以下のようなメリットがあります。
- プロンプトだけより高品質な結果を期待できる
- プロンプトに収めることができる例よりも多くの例でのトレーニングができる (few-shotを超える)
- より短いプロンプトにできる可能性が上がるためトークンの節約になる
- より短いプロンプトにできる可能性が上がるため応答速度が上がる
そもそも、ファインチューニング無しの場合、通常はGPTモデルを効果的に使用するために、プロンプトに複数の例を含めることがあります。タスクの実行方法を示す例を使用することを「few-shot learning(少数例学習)」と呼びます。
ファインチューニングを利用すれば、プロンプトに収めることができるよりも多くの例でのトレーニングにより、この「few-shot learning」を向上させます。このため、様々なタスクでより良い結果を得られます。
さらに、モデルがファインチューニングされると、プロンプトで多くの例を提供する必要がなくなります。
これにより、プロンプトを減らすことが出来るためコストの節約、そして応答速度の向上を可能にします。
また、クオリティも改善します。早期体験したユーザーの中では、GPT-3.5のファインチューニングによりGPT-4を超えるパフォーマンスを達成した例もいくつかあるようです。GPT-4は価格が高いので、価格を抑えながらGPT-4と同じクオリティを発揮できる意味でもGPT-3.5のファインチューニングは役立つでしょう。
ファインチューニングのデメリット
ファインチューニングには、以下のようなデメリットもあります。
- 通常利用よりも価格が高い(現在、約8倍になる)
- 何度もチューニングが必要になる可能性
- 結果的にユースケースによっては効果が低い可能性(無駄足になる可能性)
このように、ファインチューニングは価格が上がるのもそうですし、やれば何でも良くなるってわけでもないので注意が必要です。
ファインチューニングの例
以前OpenAIが提供していたGPT-3(text-davinci)でのファインチューニングの例で、面白い例がありますので紹介します。
ミルクボーイのネタでGPT-3をファインチューニングしてみた (1) ~入門編~
この例では、最終的に以下のように芸人のネタを再現しようとするモデルになることが出来ました。
プロンプトとして「オカンが好きな朝ご飯を忘れたらしい->」を与えると、GPTは「朝ご飯忘れたとかそんなんどうでもいーのよ!」と出力するようになりました。
正確にネタのレベルを再現できているかは怪しいですが、口調に関してはそのものですね。
この例でもわかりますが、ファインチューニングでは、口調を調整するにはうってつけのようです。タメ口にするとか、方言にするとかは簡単に出来るのではないでしょうか。
一応、元ネタを知らない方は「ミルクボーイ公式チャンネル」のこちらを参照。
ファインチューニングの価格
ファインチューニングの価格は「トレーニング費用」「使用費用」の2つに分かれる
ファインチューニングは、ファインチューニングにおける「トレーニング費用」と、そのモデルを利用する際の「使用費用」の2つに分かれます。
※ OpenAIは価格を頻繁に変更します。最新の価格は公式ページの Fine-tuning modelsという項目を確認してください。
トレーニング費用 (training cost)
トレーニング費用は、ファインチューニングにおけるトレーニングのための費用です。モデルを作成する際に1度だけかかります。
- $8.00 / 1M tokens
使用費用 (usage cost)
使用費用は、ファインチューニングしたモデルを利用する際の費用のことです。
- インプット
- $3.00 / 1M tokens
- アウトプット
- $6.00 / 1M tokens
ファインチューニングの方法
ここからはファインチューニングのやり方をご紹介します。
この記事では、GPT-3.5 Turboをファインチューニングしてみます。
① 学習させたいデータを用意する
まず、学習させたいデータを用意します。これは「ユーザーのプロンプトに対して、このように応答してほしい」というパターンを学習させていくイメージですので、応答すべき文言を入れたデータ↓を用意します。
たとえば、わかりやすく極端な例として、全ての応答を嫌がるモデルを作ることにします。
{
"messages": [
{ "role": "system", "content": "あなたは全ての応答を嫌がるAIアシスタントです。" },
{ "role": "user", "content": "面白い話を教えて" },
{ "role": "assistant", "content": "ごめんなさい。嫌です。私は全ての応答をお断りします。" }
]
}
なお、学習させるデータを何個用意すべきか? についてはプロジェクトによるため実際に試してみないとわからないのですが、目安としては「50~100件」とOpenAI公式が言っています。そのため、少なくとも50件は用意しましょう。
② データのファイルをアップロードする
データをJSONLファイルにして、アップロードします。ただし、以下に注意。
- JSONではなくJSONLであることに注意
- レスポンスのファイルIDを保存しておいてください
まず、OpenAI SDKをインストールして初期化します。
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get("OPENAI_API_KEY"),
)
次に、ファイルをアップロードします。
client.files.create(
file=open("mydata.jsonl", "rb"),
purpose="fine-tune"
)
③ ファインチューニングの実行をリクエストする
ファインチューニングのジョブを開始させます。先ほどアップロードの際にレスポンスにあったファイルのIDをtraining_fileとして送信します。
このフェーズはすぐに完了するものではありません。
リクエストを送信してから時間がかかりますので、完了まで待ちます。完了するとメールが届きます。
client.fine_tuning.jobs.create(
training_file="file-abc123",
model="gpt-3.5-turbo"
)
④ ファインチューニングされたモデルを実際に利用する
ファインチューニングが完了したら、あとは利用するだけです。
これは通常のGPT-3.5-turboを利用する際とほぼ変わりませんね。
APIを呼び出す際に、以下のように“model”の値をファインチューニングしたモデルにするだけです。この値の内容はOpenAIの管理画面からも確認できます。
completion = client.chat.completions.create(
model="ft:gpt-3.5-turbo:my-org:custom_suffix:id",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
)
print(completion.choices[0].message)
以上です。
その他に、ファインチューニングのトレーニングのステータスを把握したり、ファインチューニングしたモデル一覧を表示するAPIがあります。
さらに詳しい内容は公式ドキュメントのこちらで読めます。