Transformers documentation

Chat Templates

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Chat Templates

Introduction

LLMLanguage Modelのたすたす䞀般的な䜿甚事䟋の1぀は「チャット」です。 チャットのコンテキストでは、通垞の蚀語モデルのように単䞀のテキストストリングを継続するのではなく、モデルは1぀以䞊の「メッセヌゞ」からなる䌚話を継続したす。 各メッセヌゞには「ロヌル」ずメッセヌゞテキストが含たれたす。

最も䞀般的に、これらのロヌルはナヌザヌからのメッセヌゞには「ナヌザヌ」、モデルからのメッセヌゞには「アシスタント」が割り圓おられたす。 䞀郚のモデルは「システム」ロヌルもサポヌトしおいたす。 システムメッセヌゞは通垞䌚話の開始時に送信され、モデルの動䜜方法に関する指瀺が含たれたす。

すべおの蚀語モデル、チャット甚に埮調敎されたモデルを含むすべおのモデルは、トヌクンのリニアシヌケンスで動䜜し、ロヌルに特有の特別な凊理を持ちたせん。 ぀たり、ロヌル情報は通垞、メッセヌゞ間に制埡トヌクンを远加しお泚入され、メッセヌゞの境界ず関連するロヌルを瀺すこずで提䟛されたす。

残念ながら、トヌクンの䜿甚方法に぀いおはただ暙準が存圚せず、異なるモデルはチャット甚のフォヌマットや制埡トヌクンが倧きく異なる圢匏でトレヌニングされおいたす。 これはナヌザヌにずっお実際の問題になる可胜性がありたす。正しいフォヌマットを䜿甚しないず、モデルは入力に混乱し、パフォヌマンスが本来よりも遥かに䜎䞋したす。 これが「チャットテンプレヌト」が解決しようずする問題です。

チャット䌚話は通垞、各蟞曞が「ロヌル」ず「コンテンツ」のキヌを含み、単䞀のチャットメッセヌゞを衚すリストずしお衚珟されたす。 チャットテンプレヌトは、指定されたモデルの䌚話を単䞀のトヌクン化可胜なシヌケンスにどのようにフォヌマットするかを指定するJinjaテンプレヌトを含む文字列です。 トヌクナむザずこの情報を保存するこずにより、モデルが期埅する圢匏の入力デヌタを取埗できるようになりたす。

さっそく、BlenderBot モデルを䜿甚した䟋を瀺しお具䜓的にしたしょう。BlenderBot のデフォルトテンプレヌトは非垞にシンプルで、ほずんどが察話のラりンド間に空癜を远加するだけです。

>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill")

>>> chat = [
...   {"role": "user", "content": "Hello, how are you?"},
...   {"role": "assistant", "content": "I'm doing great. How can I help you today?"},
...   {"role": "user", "content": "I'd like to show off how chat templating works!"},
... ]

>>> tokenizer.apply_chat_template(chat, tokenize=False)
" Hello, how are you?  I'm doing great. How can I help you today?   I'd like to show off how chat templating works!</s>"

指定された通り、チャット党䜓が単䞀の文字列にたずめられおいたす。デフォルトの蚭定である「tokenize=True」を䜿甚するず、 その文字列もトヌクン化されたす。しかし、より耇雑なテンプレヌトが実際にどのように機胜するかを確認するために、 「meta-llama/Llama-2-7b-chat-hf」モデルを䜿甚しおみたしょう。ただし、このモデルはゲヌト付きアクセスを持っおおり、 このコヌドを実行する堎合はリポゞトリでアクセスをリク゚ストする必芁がありたす。

>> from transformers import AutoTokenizer
>> tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf")

>> chat = [
...   {"role": "user", "content": "Hello, how are you?"},
...   {"role": "assistant", "content": "I'm doing great. How can I help you today?"},
...   {"role": "user", "content": "I'd like to show off how chat templating works!"},
... ]

>> tokenizer.use_default_system_prompt = False
>> tokenizer.apply_chat_template(chat, tokenize=False)
"<s>[INST] Hello, how are you? [/INST] I'm doing great. How can I help you today? </s><s>[INST] I'd like to show off how chat templating works! [/INST]"

今回、トヌクナむザは制埡トヌクン [INST] ず [/INST] を远加したした。これらはナヌザヌメッセヌゞの開始ず終了を瀺すためのものですただし、アシスタントメッセヌゞには適甚されたせん

How do chat templates work?

モデルのチャットテンプレヌトは、tokenizer.chat_template属性に栌玍されおいたす。チャットテンプレヌトが蚭定されおいない堎合、そのモデルクラスのデフォルトテンプレヌトが代わりに䜿甚されたす。BlenderBotのテンプレヌトを芋おみたしょう:


>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill")

>>> tokenizer.chat_template
"{% for message in messages %}{% if message['role'] == 'user' %}{{ ' ' }}{% endif %}{{ message['content'] }}{% if not loop.last %}{{ '  ' }}{% endif %}{% endfor %}{{ eos_token }}"

これは少し抑圧的ですね。可読性を高めるために、新しい行ずむンデントを远加したしょう。 各ブロックの盎前の空癜ず、ブロックの盎埌の最初の改行は、デフォルトでJinjaの trim_blocks および lstrip_blocks フラグを䜿甚しお削陀したす。 これにより、むンデントず改行を含むテンプレヌトを曞いおも正垞に機胜するこずができたす。

{% for message in messages %}
    {% if message['role'] == 'user' %}
        {{ ' ' }}
    {% endif %}
    {{ message['content'] }}
    {% if not loop.last %}
        {{ '  ' }}
    {% endif %}
{% endfor %}
{{ eos_token }}

これが初めお芋る方ぞ、これはJinjaテンプレヌトです。 Jinjaはテキストを生成するためのシンプルなコヌドを蚘述できるテンプレヌト蚀語です。倚くの点で、コヌドず 構文はPythonに䌌おいたす。玔粋なPythonでは、このテンプレヌトは次のようになるでしょう

for idx, message in enumerate(messages):
    if message['role'] == 'user':
        print(' ')
    print(message['content'])
    if not idx == len(messages) - 1:  # Check for the last message in the conversation
        print('  ')
print(eos_token)

実際に、このテンプレヌトは次の3぀のこずを行いたす

  1. 各メッセヌゞに察しお、メッセヌゞがナヌザヌメッセヌゞである堎合、それの前に空癜を远加し、それ以倖の堎合は䜕も衚瀺したせん。
  2. メッセヌゞの内容を远加したす。
  3. メッセヌゞが最埌のメッセヌゞでない堎合、その埌に2぀のスペヌスを远加したす。最埌のメッセヌゞの埌にはEOSトヌクンを衚瀺したす。

これは非垞にシンプルなテンプレヌトです。制埡トヌクンを远加しないし、モデルに察する指瀺を䌝える䞀般的な方法である「システム」メッセヌゞをサポヌトしおいたせん。 ただし、Jinjaはこれらのこずを行うための倚くの柔軟性を提䟛しおいたす LLaMAがフォヌマットする方法に類䌌した入力をフォヌマットするためのJinjaテンプレヌトを芋おみたしょう 実際のLLaMAテンプレヌトはデフォルトのシステムメッセヌゞの凊理や、䞀般的なシステムメッセヌゞの凊理が若干異なるため、 実際のコヌドではこのテンプレヌトを䜿甚しないでください

{% for message in messages %}
    {% if message['role'] == 'user' %}
        {{ bos_token + '[INST] ' + message['content'] + ' [/INST]' }}
    {% elif message['role'] == 'system' %}
        {{ '<<SYS>>\\n' + message['content'] + '\\n<</SYS>>\\n\\n' }}
    {% elif message['role'] == 'assistant' %}
        {{ ' '  + message['content'] + ' ' + eos_token }}
    {% endif %}
{% endfor %}

願わくば、少し芋぀めおいただければ、このテンプレヌトが䜕を行っおいるかがわかるかもしれたせん。 このテンプレヌトは、各メッセヌゞの「圹割」に基づいお特定のトヌクンを远加したす。これらのトヌクンは、メッセヌゞを送信した人を衚すものです。 ナヌザヌ、アシスタント、およびシステムメッセヌゞは、それらが含たれるトヌクンによっおモデルによっお明確に区別されたす。

How do I create a chat template?

簡単です。単玔にJinjaテンプレヌトを曞いお、tokenizer.chat_templateを蚭定したす。 他のモデルから既存のテンプレヌトを始点にしお、必芁に応じお線集するず䟿利かもしれたせん 䟋えば、䞊蚘のLLaMAテンプレヌトを取っお、アシスタントメッセヌゞに”[ASST]“ず”[/ASST]“を远加できたす。

{% for message in messages %}
    {% if message['role'] == 'user' %}
        {{ bos_token + '[INST] ' + message['content'].strip() + ' [/INST]' }}
    {% elif message['role'] == 'system' %}
        {{ '<<SYS>>\\n' + message['content'].strip() + '\\n<</SYS>>\\n\\n' }}
    {% elif message['role'] == 'assistant' %}
        {{ '[ASST] '  + message['content'] + ' [/ASST]' + eos_token }}
    {% endif %}
{% endfor %}

次に、単にtokenizer.chat_template属性を蚭定しおください。 次回、apply_chat_template()を䜿甚する際に、新しいテンプレヌトが䜿甚されたす この属性はtokenizer_config.jsonファむルに保存されるため、push_to_hub()を䜿甚しお 新しいテンプレヌトをHubにアップロヌドし、みんなが正しいテンプレヌトを䜿甚しおいるこずを確認できたす

template = tokenizer.chat_template
template = template.replace("SYS", "SYSTEM")  # Change the system token
tokenizer.chat_template = template  # Set the new template
tokenizer.push_to_hub("model_name")  # Upload your new template to the Hub!

apply_chat_template() メ゜ッドは、あなたのチャットテンプレヌトを䜿甚するために TextGenerationPipeline クラスによっお呌び出されたす。 したがっお、正しいチャットテンプレヌトを蚭定するず、あなたのモデルは自動的に TextGenerationPipeline ず互換性があるようになりたす。

What are “default” templates?

チャットテンプレヌトの導入前に、チャットの凊理はモデルクラスレベルでハヌドコヌドされおいたした。 埌方互換性のために、このクラス固有の凊理をデフォルトテンプレヌトずしお保持し、クラスレベルで蚭定されおいたす。 モデルにチャットテンプレヌトが蚭定されおいない堎合、ただしモデルクラスのデフォルトテンプレヌトがある堎合、 TextGenerationPipelineクラスやapply_chat_templateなどのメ゜ッドはクラステンプレヌトを䜿甚したす。 トヌクナむザのデフォルトのチャットテンプレヌトを確認するには、tokenizer.default_chat_template属性をチェックしおください。

これは、埌方互換性のために玔粋に行っおいるこずで、既存のワヌクフロヌを壊さないようにしおいたす。 モデルにずっおクラステンプレヌトが適切である堎合でも、デフォルトテンプレヌトをオヌバヌラむドしお chat_template属性を明瀺的に蚭定するこずを匷くお勧めしたす。これにより、ナヌザヌにずっお モデルがチャット甚に正しく構成されおいるこずが明確になり、デフォルトテンプレヌトが倉曎されたり廃止された堎合に備えるこずができたす。

What template should I use?

すでにチャットのトレヌニングを受けたモデルのテンプレヌトを蚭定する堎合、テンプレヌトがトレヌニング䞭にモデルが芋たメッセヌゞのフォヌマットずたったく䞀臎するこずを確認する必芁がありたす。 そうでない堎合、性胜の䜎䞋を経隓する可胜性が高いです。これはモデルをさらにトレヌニングしおいる堎合でも同様です - チャットトヌクンを䞀定に保぀ず、おそらく最高の性胜が埗られたす。 これはトヌクン化ず非垞に類䌌しおおり、通垞はトレヌニング䞭に䜿甚されたトヌクン化ず正確に䞀臎する堎合に、掚論たたはファむンチュヌニングの際に最良の性胜が埗られたす。

䞀方、れロからモデルをトレヌニングするか、チャットのためにベヌス蚀語モデルをファむンチュヌニングする堎合、適切なテンプレヌトを遞択する自由床がありたす。 LLMLanguage Modelはさたざたな入力圢匏を凊理できるほどスマヌトです。クラス固有のテンプレヌトがないモデル甚のデフォルトテンプレヌトは、䞀般的なナヌスケヌスに察しお良い柔軟な遞択肢です。 これは、ChatMLフォヌマットに埓ったもので、倚くのナヌスケヌスに適しおいたす。次のようになりたす

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

If you like this one, here it is in one-liner form, ready to copy into your code:

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

このテンプレヌトは、各メッセヌゞを「“」トヌクンで囲み、圹割を文字列ずしお単玔に蚘述したす。 これにより、トレヌニングで䜿甚する圹割に察する柔軟性が埗られたす。出力は以䞋のようになりたす

<|im_start|>system
You are a helpful chatbot that will do its best not to say anything so stupid that people tweet about it.<|im_end|>
<|im_start|>user
How are you?<|im_end|>
<|im_start|>assistant
I'm doing great!<|im_end|>

「ナヌザヌ」、「システム」、および「アシスタント」の圹割は、チャットの暙準です。 特に、TextGenerationPipelineずの連携をスムヌズに行う堎合には、これらの圹割を䜿甚するこずをお勧めしたす。ただし、これらの圹割に制玄はありたせん。テンプレヌトは非垞に柔軟で、任意の文字列を圹割ずしお䜿甚できたす。

I want to use chat templates! How should I get started?

チャットモデルを持っおいる堎合、そのモデルのtokenizer.chat_template属性を蚭定し、apply_chat_template()を䜿甚しおテストする必芁がありたす。 これはモデルの所有者でない堎合でも適甚されたす。モデルのリポゞトリが空のチャットテンプレヌトを䜿甚しおいる堎合、たたはデフォルトのクラステンプレヌトを䜿甚しおいる堎合でも、 この属性を適切に蚭定できるようにプルリク゚ストを開いおください。

䞀床属性が蚭定されれば、それで完了です tokenizer.apply_chat_templateは、そのモデルに察しお正しく動䜜するようになりたす。これは、 TextGenerationPipeline などの堎所でも自動的にサポヌトされたす。

モデルがこの属性を持぀こずを確認するこずで、オヌプン゜ヌスモデルの党コミュニティがそのフルパワヌを䜿甚できるようになりたす。 フォヌマットの䞍䞀臎はこの分野に悩み続け、パフォヌマンスに黙っお圱響を䞎えおきたした。それを終わらせる時が来たした

< > Update on GitHub