チャットテンプレート:静かなパフォーマンスキラーへの終止符

チャットテンプレート:静かなパフォーマンスキラーからの脱却

チャットモデルを幽霊がさまよっている – 不正なフォーマットの幽霊が!

要約

チャットモデルは、会話を単一のトークン可能な文字列に変換するための非常に異なるフォーマットで訓練されています。訓練されたフォーマットとは異なるフォーマットを使用すると、通常は重大な無音のパフォーマンス低下を引き起こしますので、訓練時に使用されたフォーマットとの一致は非常に重要です!Hugging Faceのトークナイザには、モデルが訓練されたチャット形式を保存するために使用できるchat_template属性があります。この属性には、会話履歴を正しくフォーマットされた文字列に変換するためのジンジャーテンプレートが含まれています。コードでチャットテンプレートを作成および適用する方法については、技術文書をご覧ください。

導入

もしも、🤗Transformersライブラリに詳しいのであれば、おそらく以下のようなコードを書いたことがあるはずです:

tokenizer = AutoTokenizer.from_pretrained(checkpoint)model = AutoModel.from_pretrained(checkpoint)

トークナイザとモデルを同じチェックポイントからロードすることで、モデルが期待する方法で入力がトークン化されることが保証されます。異なるモデルのトークナイザを選ぶと、入力のトークナイズは完全に異なる可能性があり、その結果としてモデルのパフォーマンスに重大な損傷が生じます。これをdistribution shift(分布シフト)と呼びます – モデルは一つの分布(訓練時に使用されたトークナイゼーション)のデータを学習しており、突然完全に異なる分布にシフトしたということです。

モデルを微調整するか、推論に直接使用する場合、分布シフトを最小限に抑え、与えた入力を可能な限り訓練時と似たものにすることは常に良いアイデアです。通常の言語モデルでは、これを行うのは比較的容易です – トークナイザとモデルを同じチェックポイントからロードするだけで準備完了です。

しかし、チャットモデルの場合は少し異なります。これは、「チャット」とは1つのテキスト文字列だけでシンプルにトークナイズできるものではなく、メッセージのシーケンスであり、各メッセージにはrole(役割)とcontent(メッセージの実際のテキスト)が含まれています。最も一般的なのは、ユーザーから送信されたメッセージに対しては「user」、モデルが書いた応答には「assistant」、さらにオプションで会話の開始時に与えられる高レベルの指示には「system」の役割を持たせることです。

もしもこれが少し抽象的に感じられる場合、以下の例のチャットをご覧ください:

[    {"role": "user", "content": "こんにちは!"},    {"role": "assistant", "content": "お会いできてうれしいです!"}]

このメッセージのシーケンスは、トークン化およびモデルの入力として使用する前にテキスト文字列に変換する必要があります。しかし、問題はメッセージを変換する方法は様々な方法があるということです!例えば、メッセージのリストを「インスタントメッセンジャー」のフォーマットに変換することができます:

ユーザー:こんにちは!ボット:お会いできてうれしいです!

または、役割を示す特殊トークンを追加することもできます:

[USER] こんにちは! [/USER][ASST] お会いできてうれしいです! [/ASST]

または、メッセージ間の境界を示すトークンを追加し、役割情報を文字列として挿入することもできます:

<|im_start|>userこんにちは!<|im_end|><|im_start|>assistantお会いできてうれしいです!<|im_end|>

これを行う方法はたくさんあり、どれが最善であるか、正しい方法であるかは明らかではありません。その結果、異なるモデルはまったく異なるフォーマットで訓練されています。これらの例は創作したものではなく、少なくとも1つのアクティブなモデルで使用されています!ただし、モデルが特定のフォーマットで訓練された場合は、将来の入力でも同じフォーマットを使用することが重要です。そうでないと、パフォーマンスに影響を与える分布シフトが発生し、その原因をデバッグするのが非常に難しくなります。

テンプレート:フォーマット情報を保存する方法

現時点では、幸運なことに必要なフォーマットがモデルカードのどこかに正しく記述されている場合があります。不運な場合はそうではなく、そのモデルを使用したい場合は頑張ってください。極端な場合では、プロンプトの全体のフォーマットをブログ投稿に含めて、ユーザーがそれを見逃さないようにしています!しかし、最良の場合でも、テンプレート情報を見つけて、微調整や推論パイプラインに手動でコーディングする必要があります。これはsilent error(無音のエラー)という特に危険な問題だと考えています – 音を立てたエラーやPython例外が発生して何かが間違っていることを通知してくれるわけではなく、モデルは正しいフォーマットでないとずっと劣化したパフォーマンスを発揮し、その原因をデバッグするのは非常に困難です!

これはチャットテンプレートが解決を目指す問題です。チャットテンプレートはJinjaテンプレート文字列であり、トークナイザと一緒に保存およびロードされ、チャットメッセージのリストを正しくフォーマットされたモデルへの入力に変換するために必要な情報を含んでいます。以下に、上記の3つのメッセージ形式に対応する3つのチャットテンプレート文字列を示します:

{% for message in messages %}    {% if message['role'] == 'user' %}        {{ "ユーザー: " }}    {% else %}        {{ "ボット: " }}    {{ message['content'] + '\n' }}{% endfor %}

{% for message in messages %}    {% if message['role'] == 'user' %}        {{ "[ユーザー] " + message['content'] + " [/ユーザー]" }}    {% else %}        {{ "[アシスタント] " + message['content'] + " [/アシスタント]" }}    {{ message['content'] + '\n' }}{% endfor %}

"{% for message in messages %}"      "{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}"  "{% endfor %}"

Jinjaに不慣れな場合は、これらのテンプレート文字列とそれに対応するテンプレート出力を確認し、テンプレートがメッセージのリストをフォーマットされた文字列にどのように変換するか理解できるかを自分自身に納得させるために、しばらく時間をかけてみることを強くお勧めします!構文はPythonと非常によく似ています。

なぜテンプレートが必要なのか?

Jinjaに不慣れな場合は、初めての場合はややややこしいかもしれませんが、実際にはPythonプログラマーはすぐに理解できると思います。この機能の開発中、メッセージごとの接頭辞および接尾辞をユーザーが指定できる限定システムなど、他のアプローチも検討しましたが、これは混乱しやすく手に負えないし、いくつかのモデルでは不正確な回避策が必要でした。一方、テンプレートは、私たちが知っているすべてのメッセージ形式をきれいにサポートするのに十分な強力さを持っています。

なぜこれをする必要があるのか?標準形式を選ぶのではなく

これは素晴らしいアイデアです!ただ残念ながら、既に非常に異なるチャット形式で重要なモデルが複数作成されているため、今更です。

ただし、この問題は少し軽減できます。私たちは、フォーマットに最も近いものがOpenAIによって作成されたChatMLフォーマットであると考えています。新しいチャット用のモデルをトレーニングし、このフォーマットが適している場合は、お勧めします。それに特別な<|im_start|><|im_end|>トークンをトークナイザに追加して使用します。役割には固有のトークンがあるのではなく、役割が単に文字列として挿入されるため、非常に柔軟性があります。このテンプレートを使用する場合は、上記の3番目のテンプレートであり、次の1行で設定できます:

tokenizer.chat_template = "{% for message in messages %}{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}{% endfor %}"

標準形式をハードコードすることに対して、もう1つの理由があります。既存の形式の増加を超えて – テンプレートは、標準チャットから非常に異なることを行っているモデルを含む、さまざまなタイプのモデルの前処理に広く役立つと期待されています。標準形式をハードコードすることは、モデル開発者がこの機能を使用してまだ考えもしないことを行う能力を制限し、一方テンプレートはユーザーと開発者に最大限の自由を与えます。テンプレートにはチェックやロジックをエンコードすることも可能であり、デフォルトテンプレートのいずれでもあまり使用していませんが、冒険心のあるユーザーの手には非常に強力な機能です。私たちは、オープンソースのエコシステムがあなたがしたいことを実現することを強く信じています。許可されたことを指図するのではなく、あなたに希望することを実現するために。

テンプレートはどのように機能するのですか?

チャットテンプレートはトークナイザの一部です。なぜなら、トークナイザと同じ役割を果たすためです:データの前処理方法に関する情報を格納し、モデルにトレーニング中に見た形式と同じ形式でデータを渡すためです。既存のトークナイザにテンプレート情報を簡単に追加して保存したり、Hubにアップロードしたりすることができるように設計されています。

チャットテンプレートが導入される前は、チャットのフォーマット情報はクラスレベルで保存されていました。これはつまり、例えばすべてのLLaMAチェックポイントは、LLaMAモデルクラスのtransformersに固定されたコードを使用して同じチャットのフォーマットを取得するということを意味します。後方互換性のために、カスタムチャットフォーマットメソッドを持つモデルクラスには、代わりにデフォルトのチャットテンプレートが設定されました。

デフォルトのチャットテンプレートもクラスレベルで設定されます。これにより、ConversationPipelineなどのクラスが、モデルにチャットテンプレートがない場合の入力のフォーマット方法を指定できます。これは完全な後方互換性のために行っています – デフォルトのチャットテンプレートが適切な場合でも、必ずチャットモデルに明示的なチャットテンプレートを設定することを強くお勧めします。これにより、デフォルトのチャットテンプレートで将来的な変更や廃止がモデルを壊すことがありません。デフォルトのチャットテンプレートは当面保持する予定ですが、将来的にはすべてのモデルを明示的なチャットテンプレートに移行し、デフォルトのチャットテンプレートを完全に削除する予定です。

チャットテンプレートの設定と適用方法についての情報は、技術ドキュメントを参照してください。

テンプレートを使って始めるにはどうすればいいですか?

簡単です!トークナイザにchat_template属性が設定されていれば、準備が整っています。そのモデルとトークナイザをConversationPipelineで使用するか、tokenizer.apply_chat_template()を呼び出して推論やトレーニングのためにチャットをフォーマットできます。詳細については、開発者ガイドまたはapply_chat_templateのドキュメントをご覧ください!

chat_template属性を持たないトークナイザでも動作する場合がありますが、その場合はそのモデルクラスに設定されたデフォルトのチャットテンプレートが使用されます。上記で述べた通り、これは壊れやすく、モデルの実際のトレーニングと一致しない場合にもサイレントなバグの元になります。chat_templateが存在しないチェックポイントを使用したい場合は、モデルカードなどのドキュメントを確認し、正しいフォーマットに合わせて適切なchat_templateを追加することをお勧めします。デフォルトのチャットテンプレートが正しい場合でも、これによりモデルが将来的な変更に対応できるようになり、テンプレートの存在と適合性が明確になります。

プルリクエストを開いて、所有者でないチェックポイントにchat_templateを追加することもできます。必要な変更は、tokenizer.chat_template属性をジンジャテンプレート文字列に設定するだけです。それが完了したら、変更をプッシュして準備完了です!

チャット用のチェックポイントを使用したいが、使用されたチャットのフォーマットに関するドキュメントが見つからない場合は、チェックポイントに問題を報告するか、所有者に連絡することをおすすめします!モデルが使用しているフォーマットが分かったら、適切なchat_templateを追加するためにプルリクエストを作成してください。他のユーザーがとても助かるでしょう!

結論: テンプレートの哲学

私たちは、テンプレートは非常にエキサイティングな変更だと考えています。これはサイレントなバグの大きな原因を解決するだけでなく、まったく新しいアプローチとデータの形態をも開放します。おそらく最も重要なことは、これが哲学的な転換を表しているということです。これにより、transformersコードベースから大きな機能が削除され、個々のモデルリポジトリに移動し、ユーザーが奇妙でワイルドで素晴らしいことをする自由を持つことができます。どのように使用されるかを見るのが楽しみです!

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

機械学習

「機械学習 vs AI vs ディープラーニング vs ニューラルネットワーク:違いは何ですか?」

テクノロジーの急速な進化は、ビジネスが効率化のために洗練されたアルゴリズムにますます頼ることで、私たちの日常生活を形...

人工知能

「ElaiのCEO&共同創業者、Vitalii Romanchenkoについてのインタビューシリーズ」

ヴィタリー・ロマンチェンコは、ElaiのCEO兼共同創設者であり、マイク、カメラ、俳優、スタジオの必要なく、個人が一流のビデ...

人工知能

「ナレ・ヴァンダニャン、Ntropyの共同創設者兼CEO- インタビューシリーズ」

Ntropyの共同創設者兼CEOであるナレ・ヴァンダニアンは、開発者が100ミリ秒未満で超人的な精度で金融取引を解析することを可...

人工知能

「コーネリスネットワークスのソフトウェアエンジニアリング担当副社長、ダグ・フラーラー氏 - インタビューシリーズ」

ソフトウェアエンジニアリングの副社長として、DougはCornelis Networksのソフトウェアスタック全体、Omni-Path Architecture...

人工知能

『ジュリエット・パウエル&アート・クライナー、The AI Dilemma – インタビューシリーズの著者』

『AIのジレンマ』は、ジュリエット・パウエルとアート・クライナーによって書かれましたジュリエット・パウエルは、著者であ...

人工知能

キャルレールの最高製品責任者、ライアン・ジョンソンへのインタビューシリーズ

ライアンは、初期のスタートアップからフォーチュン100の組織まで、多様なテクノロジーと製品開発のリーダーシップ経験を15年...