Spaces:
Sleeping
Sleeping
This template wraps each message in <|im_start|> and <|im_end|> tokens, and simply writes the role as a string, which | |
allows for flexibility in the roles you train with. The output looks like this: | |
text | |
<|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|> | |
The "user", "system" and "assistant" roles are the standard for chat, and we recommend using them when it makes sense, | |
particularly if you want your model to operate well with [TextGenerationPipeline]. However, you are not limited | |
to these roles - templating is extremely flexible, and any string can be a role. | |
I want to add some chat templates! How should I get started? | |
If you have any chat models, you should set their tokenizer.chat_template attribute and test it using | |
[~PreTrainedTokenizer.apply_chat_template], then push the updated tokenizer to the Hub. This applies even if you're | |
not the model owner - if you're using a model with an empty chat template, or one that's still using the default class | |
template, please open a pull request to the model repository so that this attribute can be set properly! | |
Once the attribute is set, that's it, you're done! tokenizer.apply_chat_template will now work correctly for that | |
model, which means it is also automatically supported in places like TextGenerationPipeline! | |
By ensuring that models have this attribute, we can make sure that the whole community gets to use the full power of | |
open-source models. Formatting mismatches have been haunting the field and silently harming performance for too long - | |
it's time to put an end to them! | |
Advanced: Template writing tips | |
If you're unfamiliar with Jinja, we generally find that the easiest way to write a chat template is to first | |
write a short Python script that formats messages the way you want, and then convert that script into a template. | |
Remember that the template handler will receive the conversation history as a variable called messages. | |
You will be able to access messages in your template just like you can in Python, which means you can loop over | |
it with {% for message in messages %} or access individual messages with {{ messages[0] }}, for example. | |
You can also use the following tips to convert your code to Jinja: | |
Trimming whitespace | |
By default, Jinja will print any whitespace that comes before or after a block. This can be a problem for chat | |
templates, which generally want to be very precise with whitespace! To avoid this, we strongly recommend writing | |
your templates like this: | |
{%- for message in messages %} | |
{{- message['role'] + message['content'] }} | |
{%- endfor %} | |
rather than like this: | |
{% for message in messages %} | |
{{ message['role'] + message['content'] }} | |
{% endfor %} | |
Adding - will strip any whitespace that comes before the block. The second example looks innocent, but the newline | |
and indentation may end up being included in the output, which is probably not what you want! | |
For loops | |
For loops in Jinja look like this: | |
{%- for message in messages %} | |
{{- message['content'] }} | |
{%- endfor %} | |
Note that whatever's inside the {{ expression block }} will be printed to the output. You can use operators like | |
+ to combine strings inside expression blocks. | |
If statements | |
If statements in Jinja look like this: | |
{%- if message['role'] == 'user' %} | |
{{- message['content'] }} | |
{%- endif %} | |
Note how where Python uses whitespace to mark the beginnings and ends of for and if blocks, Jinja requires you | |
to explicitly end them with {% endfor %} and {% endif %}. | |
Special variables | |
Inside your template, you will have access to the list of messages, but you can also access several other special | |
variables. These include special tokens like bos_token and eos_token, as well as the add_generation_prompt | |
variable that we discussed above. You can also use the loop variable to access information about the current loop | |
iteration, for example using {% if loop.last %} to check if the current message is the last message in the | |
conversation. Here's an example that puts these ideas together to add a generation prompt at the end of the | |
conversation if add_generation_prompt is True: | |
{%- if loop.last and add_generation_prompt %} | |
{{- bos_token + 'Assistant:\n' }} | |
{%- endif %} |