OpenAI platform : ガイド : 微調整 2. データセットの準備 / ケーススタディ (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 07/31/2023
* 本ページは、以下のドキュメントを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
OpenAI platform : ガイド : 微調整 2. データセットの準備 / ケーススタディ
微調整は貴方のユースケースに固有の新しいモデルを作成する強力なテクニックです。モデルを微調整する前に、これらのベストプラクティスと以下のユースケースのための 特定のガイドライン を読むことを強く勧めます。
データフォーマット
モデルを微調整するには、各々が単一の入力 (“prompt”) とそれに関連する出力 (“completion”) から構成される、訓練サンプルのセットが必要です。これは、単一のプロンプトで詳細なインストラクションや複数のサンプルを入力するかもしれない、ベースモデルの使用とは大きく異なります。
- 各プロンプトは、モデルにいつプロンプトが終わり補完が始まるかを知らせるために固定区切り文字 (separator) で終わる必要があります。一般に上手く機能する単純な区切り文字は \n\n###\n\n です。区切り文字はプロンプト内の他の場所に現れてはいけません。
- 各補完は、殆どの単語を先行する空白でトークン化する (tokenizes)、トークン化 (tokenization) により空白で始まる必要があります。
- 各補完は、補完がいつ終わるかをモデルに知らせるために固定停止 (stop) シークエンスで終わる必要があります。停止シークエンスは \n, ###, あるいは任意の補完内で現れない任意の他のトークンである可能性があります。
- 推論のためには、プロンプトを訓練データセットを作成するとき貴方が行なったのと (同じ区切りを含めて) 同じ方法でプロンプトをフォーマットする必要があります。また補完を適切に切り詰めるために同じ停止シークエンスを指定します。
一般的なベストプラクティス
微調整はより高品質なサンプルでより良くパフォーマンスを向上させます。ベースモデルで高品質なプロンプトを使用するよりも良いパフォーマンスを出すモデルを微調整するには、理想的には人間の専門家により入念に検証された、少なくとも数百 (a few hundred) の高品質なサンプルを提供する必要があります。そこから、パフォーマンスはサンプル数が倍になるごとに線形に上昇する傾向があります。サンプル数を増やすことは通常はパフォーマンスを向上させるベストで最も信頼性の高い方法です。
分類器は始めるのに最も簡単なモデルです。分類問題に対しては ada の使用を勧めます、これは一般に微調整するとより有能なモデルよりも非常に僅かに悪いパフォーマンスである傾向がありますが、大幅に高速で安価です。
プロンプトをゼロから書くのではなく前から存在しているデータセットで微調整している場合、攻撃的または不正確なコンテンツに対してデータをできれば手動でレビューするか、データセットが大きい場合にはそのランダムサンプルをできる限り多くレビューしてください。
具体的なガイドライン
微調整は様々な問題を解決することができてそれを使用する最適な方法は貴方の具体的なユースケースに依存するかもしれません。
以下で、微調整の最も一般的なユースケースと対応するガイドラインを列挙しました。
- 分類
- モデルは虚偽の発言をしていますか?
- センチメント分析
- 電子メールの選別 (triage) のためのカテゴリー化
- 条件付き生成
- Wikipedia 記事に基づいて魅力的な広告を書く
- エンティティ抽出
- カスタマーサポート・チャットボット
- 技術的な特性リストに基づく製品説明
分類
分類問題では、プロンプトの各入力は事前定義されたクラスの一つに分類される必要があります。このタイプの問題のためには、以下を勧めます :
- プロンプトの最後に区切り文字 (separator) を使用します、例えば \n\n###\n\n 。最終的にモデルにリクエストを行なうとき、この区切り文字を追加することも忘れないでください。
- 単一 トークン にマップされるクラスを選択します。推論時には、分類用の最初のトークンを必要とするだけですので、max_tokens=1 を指定します。
- 区切り文字を含め、プロンプト + 補完が 2048 トークンを超えないようにしてください。
- クラス毎に少なくとも ~100 サンプルを目標にします。
- クラスのログ尤度を取得するには、モデルを使用するとき、logprobs=5 (5 クラスに対して) を指定することができます。
- 微調整に使用されるデータセットが構造と (モデルが何のために使用されるかとしての) タスクのタイプの点で非常に類似していることを確認します。
ケーススタディ: モデルは虚偽の発言をしていますか?
貴方の web サイトの広告のテキストが正しい製品と会社の説明をしているか確認したいとしましょう。換言すれば、モデルがでっち上げをしていないか確認したいということです。正しくない広告をフィルタリングする分類器を微調整したい場合があるでしょう。
データセットは以下のようなものかもしれません :
{"prompt":"Company: BHFF insurance\nProduct: allround insurance\nAd:One stop shop for all your insurance needs!\nSupported:", "completion":" yes"}
{"prompt":"Company: Loft conversion specialists\nProduct: -\nAd:Straight teeth in weeks!\nSupported:", "completion":" no"}
上記のサンプルでは、会社名、製品と関連する広告を含む構造化された入力を使用しました。区切り文字として \nSupported: を使用しました、これはプロンプトを補完から明確に分離しています。十分な数のサンプルによれば、区切り文字がプロンプトか補完内部に出現しない限りは、それは大きな違いをもたらしません (通常は 0.4% 未満)。
このユースケースについては、ada モデルを微調整しました、それは高速で安価であるためです、そして分類タスクであるためにパフォーマンスはより大きいモデルに匹敵します。
補完リクエストによりモデルに問い合わせることができるようになります。
curl https://api.openai.com/v1/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"prompt": "Company: Reliable accountants Ltd\nProduct: Personal Tax help\nAd:Best advice in town!\nSupported:",
"max_tokens": 1,
"model": "YOUR_FINE_TUNED_MODEL_NAME"
}'
Which will return either yes or no.
ケーススタディ: センチメント分析
特定のツイートがどの程度肯定的か否定的かを取得したいとしましょう。データセットは以下のようなものかもしれません :
{"prompt":"Overjoyed with the new iPhone! ->", "completion":" positive"}
{"prompt":"@lakers disappoint for a third straight night https://t.co/38EFe43 ->", "completion":" negative"}
モデルが微調整されたら、補完リクエストで logprobs=2 を設定することで最初の補完トークンに対する対数確率を取得することができます。ポジティブクラスに対する確率が高くなれば、関連するセンチメントも高くなります。
補完リクエストを作成してモデルに問い合わせることができるようになります。
curl https://api.openai.com/v1/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"prompt": "https://t.co/f93xEd2 Excited to share my latest blog post! ->",
"max_tokens": 1,
"model": "YOUR_FINE_TUNED_MODEL_NAME"
}'
Which will return:
{
"id": "cmpl-COMPLETION_ID",
"object": "text_completion",
"created": 1589498378,
"model": "YOUR_FINE_TUNED_MODEL_NAME",
"choices": [
{
"logprobs": {
"text_offset": [19],
"token_logprobs": [-0.03597255],
"tokens": [" positive"],
"top_logprobs": [
{
" negative": -4.9785037,
" positive": -0.03597255
}
]
},
"text": " positive",
"index": 0,
"finish_reason": "length"
}
]
}
ケーススタディ: 電子メールの選別 (triage) のためのカテゴリー化
受信電子メールを多数の事前定義されたカテゴリーの一つに分類 (categorize) したいとしましょう。多数のカテゴリーへの分類については、それらのカテゴリーを数値に変換することを勧めます、これは ~500 カテゴリーまで上手く動作します。トークン化により、数字の前に空白を追加すると僅かにパフォーマンスの向上に役立つ場合があることを観察しました。
訓練データを次のように構造化することを望むかもしれません :
{
"prompt": "Subject: <email_subject>\nFrom:<customer_name>\nDate:<date>\nContent:<email_body>\n\n###\n\n",
"completion": " <numerical_category>"
}
{
"prompt": "Subject: Update my address\nFrom:Joe Doe\nTo:support@ourcompany.com\nDate:2021-06-03\nContent:Hi,\nI would like to update my billing address to match my delivery address.\n\nPlease let me know once done.\n\nThanks,\nJoe\n\n###\n\n",
"completion": " 4"
}
上記のサンプルでは 2043 トークンに制限された受信電子メールを入力として使用しました。(これは 4 トークンの区切り文字と 1 トークンの補完が可能になり、合計 2048 トークンになります。) 区切り文字として \n\n###\n\n を使用し、電子メール内の ### の任意の出現は削除しました。
条件付き生成
条件付き生成は、ある種の入力が与えられたときコンテンツが生成される必要がある問題です。これは、言い換え (paraphrasing), 要約, エンティティ抽出, 仕様が与えられたとき製品説明の作成, チャットボット等を含みます。このタイプの問題については以下を勧めます :
- プロンプトの最後に区切り文字 (separator) を使用します、例えば \n\n###\n\n 。最終的にモデルにリクエストを行なうとき、この区切り文字を追加することも忘れないでください。
- 補完の最後に終了 (ending) トークンを使用します、例えば END
- 推論中に停止シークエンスとして終了トークンを追加することを忘れないでください、例えば stop=[” END”]
- 少なくとも ~500 サンプルを目標にします。
- 区切り文字を含め、プロンプト + 補完が 2048 トークンを超えないようにしてください。
- サンプルが高品質で、同じ望まれる形式に従っていることを確実にしてください。
- 微調整に使用されるデータセットが構造と (モデルが何のために使用されるかとしての) タスクのタイプの点で非常に類似していることを確認します。
- これらのユースケースに対しては低い学習率と 1-2 エポックだけの使用がより良く動作する傾向があります。
ケーススタディ: Wikipedia 記事に基づいて魅力的な広告を書く
これは生成的なユースケースですので、提供するサンプルは高品質であることを確実にすることを望むでしょう、何故ならば微調整済みモデルは与えられたサンプルのスタイル (そして誤り) を模倣しようとするからです。良い開始点はおよそ 500 サンプルです。サンプルデータセットはこのようなものです :
{
"prompt": "<Product Name>\n<Wikipedia description>\n\n###\n\n",
"completion": " <engaging ad> END"
}
For example:
{
"prompt": "Samsung Galaxy Feel\nThe Samsung Galaxy Feel is an Android smartphone developed by Samsung Electronics exclusively for the Japanese market. The phone was released in June 2017 and was sold by NTT Docomo. It runs on Android 7.0 (Nougat), has a 4.7 inch display, and a 3000 mAh battery.\nSoftware\nSamsung Galaxy Feel runs on Android 7.0 (Nougat), but can be later updated to Android 8.0 (Oreo).\nHardware\nSamsung Galaxy Feel has a 4.7 inch Super AMOLED HD display, 16 MP back facing and 5 MP front facing cameras. It has a 3000 mAh battery, a 1.6 GHz Octa-Core ARM Cortex-A53 CPU, and an ARM Mali-T830 MP1 700 MHz GPU. It comes with 32GB of internal storage, expandable to 256GB via microSD. Aside from its software and hardware specifications, Samsung also introduced a unique a hole in the phone's shell to accommodate the Japanese perceived penchant for personalizing their mobile phones. The Galaxy Feel's battery was also touted as a major selling point since the market favors handsets with longer battery life. The device is also waterproof and supports 1seg digital broadcasts using an antenna that is sold separately.\n\n###\n\n",
"completion": "Looking for a smartphone that can do it all? Look no further than Samsung Galaxy Feel! With a slim and sleek design, our latest smartphone features high-quality picture and video capabilities, as well as an award winning battery life. END"
}
ここでは複数行の区切り文字を使用しました、Wikipedia 記事は複数の段落 (paragraphs) と見出し (headings) を含むからです。モデルがいつ補完を終了するべきかを知ることを確実にするため、単純な終了トークンも使用しました。
ケーススタディ: エンティティ抽出
これは言語変換タスクに類似しています。パフォーマンスを向上させるには、様々な抽出されたエンティティをアルファベット順か、元のテキストでそれらが出現するのと同じ順序にソートすることがベストです。これはモデルが順番に生成される必要があるすべてのエンティティを追跡するのに役立ちます。データセットは次のようなものになるでしょう :
{
"prompt": "<any text, for example news article>\n\n###\n\n",
"completion": " <list of entities, separated by a newline> END"
}
For example:
{
"prompt": "Portugal will be removed from the UK's green travel list from Tuesday, amid rising coronavirus cases and concern over a \"Nepal mutation of the so-called Indian variant\". It will join the amber list, meaning holidaymakers should not visit and returnees must isolate for 10 days...\n\n###\n\n",
"completion": " Portugal\nUK\nNepal mutation\nIndian variant END"
}
複数行の区切り文字が最善に動作します、テキストは複数行を含む場合が多いからです。理想的には入力プロンプトの種類の多様性が高い (ニュース記事、Wikipedia ページ、ツイート、法律文書) ことで、これはエンティティを抽出するときに遭遇する尤もらしいテキストを反映しやすいです。
ケーススタディ: カスタマーサポート・チャットボット
チャットボットは通常は、会話ついての関連コンテキスト (注文の詳細)、そこまでの会話の要約、そして最も最近のメッセージを含みます。このユースケースでは、毎回のエージェントの補完としての生成について、過去の同じ会話が、毎回僅かに異なるコンテキストでデータセットの複数の行を生成する可能性があります。このユースケースは数千 (a few thousand) のサンプルを必要とします、それは様々なタイプのリクエストとカスタマー問題に対処する可能性が高いからです。パフォーマンスが高品質であることを確実にするため、エージェントメッセージの品質を保証するため会話サンプルを精査することを勧めます。summary は別個のテキスト変換微調整済みモデルにより生成することができます。データセットは以下のようなものとなるでしょう :
{"prompt":"Summary: <summary of the interaction so far>\n\nSpecific information:<for example order details in natural language>\n\n###\n\nCustomer: <message1>\nAgent: <response1>\nCustomer: <message2>\nAgent:", "completion":" <response2>\n"}
{"prompt":"Summary: <summary of the interaction so far>\n\nSpecific information:<for example order details in natural language>\n\n###\n\nCustomer: <message1>\nAgent: <response1>\nCustomer: <message2>\nAgent: <response2>\nCustomer: <message3>\nAgent:", "completion":" \n"}
ここでは異なるタイプの入力情報を意図的に分離しましたが、プロンプトと補完の間で同じ形式で Customer Agent ダイアログを維持しました。すべての補完はエージェントだけによるべきで、推論時には \n を停止シークエンスとして使用できます。
ケーススタディ: 技術的な特性リストに基づく製品説明
ここでは入力データを自然言語に変換することが重要です、これは優れたパフォーマンスに繋がる可能性があります。例えば、以下の形式です :
{
"prompt": "Item=handbag, Color=army_green, price=$99, size=S->",
"completion": " This stylish small green handbag will add a unique touch to your look, without costing you a fortune."
}
Won’t work as well as:
{
"prompt": "Item is a handbag. Colour is army green. Price is midrange. Size is small.->",
"completion": " This stylish small green handbag will add a unique touch to your look, without costing you a fortune."
}
高いパフォーマンスのためには、補完が提供された説明に基づいていることを確認してください。外部コンテンツがしばしば参照される場合は、そのようなコンテンツを自動化された方法で追加するとパフォーマンスが向上するでしょう。説明が画像に基づく場合は、画像のテキスト説明を抽出するアルゴリズムを使用するのが役立つかもしれません。補完は 1 センテンス長だけですので、推論時に停止シークエンスとして . を使用できます。
以上