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ã€ã®ããšãè¡ããŸãïŒ
- åã¡ãã»ãŒãžã«å¯ŸããŠãã¡ãã»ãŒãžããŠãŒã¶ãŒã¡ãã»ãŒãžã§ããå Žåãããã®åã«ç©ºçœãè¿œå ãããã以å€ã®å Žåã¯äœã衚瀺ããŸããã
- ã¡ãã»ãŒãžã®å 容ãè¿œå ããŸãã
- ã¡ãã»ãŒãžãæåŸã®ã¡ãã»ãŒãžã§ãªãå Žåããã®åŸã«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