TRL documentation

Modelos de Chat

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.18.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Modelos de Chat

Um chat template é um trecho de código Jinja2 que formata as mensagens na string em que o modelo foi treinado. Por exemplo:

>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
>>> tokenizer.chat_template
"{% for message in messages %}{% if loop.first and messages[0]['role'] != 'system' %}{{ '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n' }}{% endif %}{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}{% endfor %}{% if add_generation_prompt %}{{ '<|im_start|>assistant\n' }}{% endif %}"
>>> tokenizer.apply_chat_template([{"role": "user", "content": "Hi!"}], tokenize=False)
'<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nHi!<|im_end|>\n'

Na maioria dos casos, você não precisa se preocupar com templates de chat: os modelos distribuem seu template junto com o tokenizer, e o TRL o aplica para você. O processo inteiro é transparente. Mas algumas receitas do TRL dependem de recursos que a maioria dos templates distribuídos não inclui:

  • SFT com assistant_only_loss=True precisa dos marcadores {% generation %} / {% endgeneration %} ao redor da saída do assistente, para que a máscara de perda possa direcionar apenas os tokens do assistente.
  • GRPO com chamadas de ferramentas exige que o template seja preservador de prefixo: adicionar uma mensagem de ferramenta não deve alterar a forma como as mensagens anteriores são renderizadas.

O TRL distribui modelos de chat corrigidos em trl/chat_templates/ para famílias comuns (Qwen, Llama, DeepSeek-V3, GPT-OSS, …) e os substitui automaticamente para os modelos suportados. Para qualquer outro modelo, você precisará corrigir o modelo de chat por conta própria. O restante desta página cataloga o que está incluído.

Famílias de modelos suportadas

O TRL armazena cópias de referência dos templates originais para que possa identificar os modelos suportados na inicialização e substituir por um template de treinamento quando necessário. As seguintes famílias são reconhecidas: Cohere, Cohere2, DeepSeek-V3 (incluindo DeepSeek-R1, DeepSeek-R1-0528 e DeepSeek-V3-0324), DeepSeek-R1-Distill, DiffusionGemma, Gemma, Gemma3, Gemma4 (incluindo Gemma-4-12B, Gemma-4-26B-A4B e Gemma-4-31B), GLM-4-MoE (4.5, 4.6, 4.7), GLM-5, GLM-5.1, GLM-5.2, GLM-5.3, GLM-5.3-Flash, GPT-OSS, Idefics3, LFM2, LFM2.5 (incluindo LFM2.5-1.2B-Instruct, LFM2.5-2.6B e LFM2.5-24B-A2B), LFM2.5-VL (incluindo LFM2.5-VL-450M), Llama 3 / 3.1 / 3.2, Llava-Next, Mistral Large 4, Mistral Medium 3.5, Muse Glimmer, Muse Spark Open, Nemotron 3 (Nano, Super, Ultra), Nemotron 3.5 Lightning, Phi-3, Phi-3.5, Qwen2-VL, Qwen2.5 (incluindo os checkpoints base), Qwen2.5-VL, Qwen3 (incluindo as variantes Instruct-2507 e Thinking-2507), Qwen3-Coder (incluindo Qwen3-Coder-Next), Qwen3-VL, Qwen3.5, Qwen3.6, Qwen3.8, SmolVLM (incluindo SmolVLM2).

Modelos de treinamento

Modelos de prompt corrigidos que resolvem problemas específicos do treinamento. Substituídos na inicialização quando as ferramentas estão habilitadas (GRPO) ou quando assistant_only_loss=True (SFT).

cohere_training.jinja

Template do Cohere corrigido. Diferença em relação a cohere.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

cohere2_training.jinja

Template Cohere2 corrigido. Diferença em relação a cohere2.jinja:

Mova o <|END_OF_TURN_TOKEN|> final de depois do {% endif %} de despacho de papel para cada ramo de papel e envolva o ramo do assistente (<|START_RESPONSE|>...<|END_RESPONSE|><|END_OF_TURN_TOKEN|>) com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT.

deepseek_r1_distill_training.jinja

Template do DeepSeek-R1-Distill corrigido. Diferença em relação a deepseek_r1_distill.jinja:

  • Remove a divisão por '</think>' no conteúdo do assistente. O original descartava tudo até e incluindo </think>, o que removeria silenciosamente o raciocínio do alvo de treinamento.
  • Envolve a saída da mensagem do assistente com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente em SFT. O <|Assistant|> e o <|tool▁outputs▁end|> que abrem uma rodada do assistente permanecem fora dos marcadores, pois o prompt já termina com eles.

deepseekv3_training.jinja

Template do DeepSeek-V3 corrigido. Diferença em relação a deepseekv3.jinja:

  • Usa | tojson em tool['function']['arguments'] para que arguments possa ser passado como um dict (o formato documentado nos documentos do transformers). O template original usa concatenação de strings brutas, o que causa erro em entradas do tipo dict.
  • Remove a divisão por '</think>' no conteúdo do assistente, para que o bloco de raciocínio seja sempre renderizado. O original descartava tudo até e incluindo </think>, o que removeria silenciosamente o raciocínio do alvo de treinamento.
  • Envolve a saída da mensagem do assistente com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente em SFT. O <|Assistant|> e o <|tool▁outputs▁end|> que abrem uma rodada do assistente permanecem fora dos marcadores, pois o prompt já termina com eles.

deepseekv3_v2_training.jinja

Template do DeepSeek-R1-0528 corrigido. Diferença em relação a deepseekv3_v2.jinja:

  • Usa | tojson em tool['function']['arguments'] para que arguments possa ser passado como um dict, como em deepseekv3_training.jinja.
  • Remove a divisão por '</think>' no conteúdo do assistente, para que o bloco de raciocínio seja sempre renderizado. O original descartava tudo até e incluindo </think>, o que removeria silenciosamente o raciocínio do alvo de treinamento.
  • Envolve a saída da mensagem do assistente com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente no SFT. O <|tool▁outputs▁end|> que abre uma rodada do assistente após as saídas de ferramentas permanece fora dos marcadores, pois o prompt já termina com ele.

deepseekv3_v3_training.jinja

Template corrigido do DeepSeek-V3 (usado por deepseek-ai/DeepSeek-V3). Mesma diferença que deepseek_r1_distill_training.jinja, aplicada a deepseekv3_v3.jinja: marcadores {% generation %} / {% endgeneration %} ao redor da saída da mensagem do assistente para perda apenas do assistente no SFT, com <|Assistant|> e <|tool▁outputs▁end|> que abrem uma rodada do assistente deixados fora deles.

deepseekv3_v4_training.jinja

Template corrigido do DeepSeek-V3-0324 (usado por deepseek-ai/DeepSeek-V3-0324). Mesma diferença que em deepseekv3_v2_training.jinja, aplicada a deepseekv3_v4.jinja: | tojson nos argumentos de chamada de ferramenta, e marcadores {% generation %} / {% endgeneration %} ao redor da saída do assistente.

diffusion_gemma_training.jinja

Template DiffusionGemma corrigido. Diferenças em relação a diffusion_gemma.jinja:

Envolva as partes de uma rodada do modelo que o modelo emite (canal de raciocínio, chamadas de ferramentas, conteúdo e o fechamento <turn|>) com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente. As respostas de ferramentas incorporadas na rodada vêm do ambiente e permanecem fora do bloco de geração.

gemma_training.jinja

Modelo Gemma corrigido (compartilhado por Gemma e Gemma2, que possuem modelos de chat idênticos). Diferenças em relação a gemma.jinja:

Divida a saída do assistente unificado para que o cabeçalho <start_of_turn>model\n (uma dica de prompt, não gerada pelo modelo) fique fora do bloco de geração e envolva o conteúdo do assistente com os marcadores {% generation %} / {% endgeneration %} para a perda apenas do assistente no SFT.

gemma3_training.jinja

Template do Gemma 3 corrigido. Mesma diferença que em gemma_training.jinja (dividir a linha de saída unificada em ramos específicos por papel para que a dica de prompt <start_of_turn>model\n fique fora do bloco de geração, e envolver o conteúdo do assistente com {% generation %} / {% endgeneration %}), aplicado ao template base do Gemma 3 que suporta mensagens de sistema e blocos de conteúdo multimodal.

glm4moe_training.jinja

Template GLM-4-MoE corrigido. Diferença em relação a glm4moe.jinja:

Encerre cada turno do assistente dentro do bloco de geração com o marcador de papel que abre o próximo turno (<|observation|> após chamadas de ferramentas, caso contrário <|user|> ou <|system|>). O template original do GLM não possui um token de fim de turno: um turno é encerrado pelo marcador de papel da próxima mensagem, e o GLM declara <|user|> e <|observation|> como tokens de fim de sequência, de modo que o template de treinamento anexa o marcador ao turno do assistente para manter o token de parada na máscara de perda, e a mensagem seguinte não renderiza mais o próprio marcador.

Envolver a saída da mensagem do assistente (incluindo o bloco de raciocínio e as chamadas de ferramentas) com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente no SFT. Com enable_thinking=False, o bloco de raciocínio permanece fora dos marcadores, pois o prompt de geração já termina com o \n<think></think> vazio.

qwen3_training.jinja

Modelo Qwen3 corrigido. Diferença em relação a qwen3.jinja:

Inclua sempre o bloco de raciocínio, independentemente da posição da mensagem. A condição original omite-o condicionalmente com base em loop.last, o que altera a renderização do assistente quando uma mensagem de ferramenta é adicionada, quebrando a preservação do prefixo:

- {%- if loop.index0 > ns.last_query_index %}
-     {%- if loop.last or (not loop.last and reasoning_content) %}
-         {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
-     {%- else %}
-         {{- '<|im_start|>' + message.role + '\n' + content }}
-     {%- endif %}
- {%- else %}
-     {{- '<|im_start|>' + message.role + '\n' + content }}
- {%- endif %}
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT. A parte do bloco de raciocínio que o prompt de geração pré-preenche (<think>\n\n</think>\n\n com enable_thinking=False) permanece fora dos marcadores, já que o prompt já termina com ele. Os outros modelos de treinamento do Qwen3 fazem o mesmo com o que seus próprios prompts de geração pré-preenchem, como <think>\n.

qwen3_v2_training.jinja

Template original do Qwen3 corrigido (distribuído pelos checkpoints do Qwen3 antes de maio de 2025 e ainda pelos checkpoints base do Qwen3). Mesma diferença que em qwen3_training.jinja, aplicada a qwen3_v2.jinja.

qwen3_vl_training.jinja

Template Qwen3-VL corrigido. Diferença em relação a qwen3_vl.jinja:

Envolver a saída da mensagem do assistente (tanto content quanto tool_calls) com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

gptoss_training.jinja

Modelo GPT-OSS corrigido. Diferença em relação a gptoss.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT. O <|start|>assistant que abre o turno permanece fora dos marcadores, pois o prompt de geração já termina com ele.

idefics3_training.jinja

Modelo Idefics3 corrigido. Diferença em relação a idefics3.jinja:

Divida a mensagem do assistente em seu próprio ramo para que os marcadores {% generation %} / {% endgeneration %} envolvam o conteúdo do assistente. Isso permite que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

lfm2_training.jinja

Modelo LFM2 corrigido. Diferença em relação a lfm2.jinja:

Divida a linha de saída da mensagem unificada em ramos específicos por papel, de modo que a dica de prompt <|im_start|>assistant\n fique fora do bloco de geração (ela não é gerada pelo modelo), enquanto o conteúdo do assistente e <|im_end|>\n (que o modelo deve aprender a produzir e a parar) fiquem dentro. Envolve o conteúdo do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT.

lfm2_v2_training.jinja

Modelo LFM2 corrigido, revisão posterior. Diferença em relação a lfm2_v2.jinja:

Envolva a saída do assistente com {% generation %} / {% endgeneration %}, tanto no ramo que renderiza tool_calls quanto no ramo de conteúdo simples, para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT. A dica de prompt <|im_start|>assistant\n permanece fora do bloco de geração, enquanto o conteúdo, as chamadas de ferramenta e <|im_end|>\n ficam dentro.

llama3_training.jinja

Modelo Llama 3 corrigido. Diferença em relação a llama3.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

llava_next_training.jinja

Template Llava-Next corrigido. Diferença em relação a llava_next.jinja:

  • Envolve a saída da mensagem do assistente com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente no SFT.
  • Mantém o espaço que segue </s> fora do bloco de geração. O tokenizer o mescla com o primeiro token do próximo turno (▁[), o que, de outra forma, seria mascarado como saída do assistente e ocultaria o token de parada </s> do final do trecho mascarado.

mistral_large_4_training.jinja

Template do Mistral Large 4 corrigido. Diferença em relação a mistral_large_4.jinja: mesma alteração que em mistral_medium_3_5_training.jinja, envolvendo a vez do assistente (conteúdo, chamadas de ferramentas e o token de fim de vez) com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT.

mistral_medium_3_5_training.jinja

Template do Mistral Medium 3.5 corrigido. Diferença em relação a mistral_medium_3_5.jinja: o original já preserva o prefixo, então a única alteração é envolver a vez do assistente (conteúdo, chamadas de ferramentas e o token de fim de turno) com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT.

muse_glimmer_training.jinja

Template Muse Glimmer corrigido. Diferença em relação a muse_glimmer.jinja: envolva todo o ramo do assistente — todos os canais ATEM da vez — com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT. O <|start|>assistant que abre a vez permanece fora dos marcadores, pois o prompt de geração já termina com ele.

muse_spark_training.jinja

Template Muse Spark Open corrigido. Diferença em relação a muse_spark.jinja: os marcadores {% generation %} do original também cobrem o <|start|>assistant que abre o turno, o que o prompt de geração já termina. O template de treinamento o emite antes dos marcadores, para que return_assistant_tokens_mask=True não o treine. O texto renderizado permanece inalterado.

nemotron_3_nano_training.jinja

Template do Nemotron Nano corrigido. Diferença em relação a nemotron_3_nano.jinja: o original já preserva o prefixo, portanto a alteração consiste em envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT. A parte do bloco de raciocínio que o prompt de geração pré-preenche (<think>\n, ou <think></think> com enable_thinking=False) permanece fora dos marcadores, já que o prompt já termina com ela.

nemotron_3_super_training.jinja

Template Nemotron Super corrigido. Diferença em relação a nemotron_3_super.jinja: idêntica à de nemotron_3_nano_training.jinja — o original já preserva o prefixo, portanto a alteração consiste em envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT. A parte do bloco de raciocínio que o prompt de geração pré-preenche (<think>\n, ou <think></think> com enable_thinking=False) permanece fora dos marcadores, já que o prompt já termina com ela.

nemotron_3_ultra_training.jinja

Template Nemotron Ultra corrigido. Diferença em relação a nemotron_3_ultra.jinja: idêntica à de nemotron_3_nano_training.jinja — o original já preserva o prefixo, portanto a alteração consiste em envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True gere máscaras corretas para a perda apenas do assistente no SFT. A parte do bloco de raciocínio que o prompt de geração pré-preenche (<think>\n, ou <think></think> com enable_thinking=False) permanece fora dos marcadores, já que o prompt já termina com ela.

nemotron_3_5_lightning_training.jinja

Template Nemotron 3.5 Lightning corrigido. Diferença em relação a nemotron_3_5_lightning.jinja: idêntica à de nemotron_3_nano_training.jinja — o original já preserva o prefixo, portanto a alteração consiste em envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True gere máscaras corretas para a perda apenas do assistente no SFT. A parte do bloco de raciocínio que o prompt de geração pré-preenche (<think>\n, ou <think></think> com enable_thinking=False) permanece fora dos marcadores, já que o prompt já termina com ela.

phi3_training.jinja

Modelo Phi-3 corrigido. Diferenças em relação a phi3.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

phi3_5_training.jinja

Modelo Phi-3.5 corrigido. Diferença em relação a phi3_5.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

qwen2_5_training.jinja

Template do Qwen2.5 corrigido. Diferença em relação a qwen2_5.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

qwen2_5_base_training.jinja

Template base do Qwen2.5 corrigido (usado pelos checkpoints base, como Qwen2.5-0.5B, cujo template difere do instruct apenas em seu prompt de sistema padrão). Mesmo diff de qwen2_5_training.jinja, aplicado a qwen2_5_base.jinja.

qwen2_5_vl_training.jinja

Template do Qwen2.5-VL corrigido (também usado para o Qwen2-VL, que possui um template idêntico byte a byte). Diferenças em relação a qwen2_5_vl.jinja:

Divida a mensagem do assistente em seu próprio ramo para que os marcadores {% generation %} / {% endgeneration %} envolvam o conteúdo do assistente. Isso permite que return_assistant_tokens_mask=True produza máscaras corretas para a perda apenas do assistente no SFT.

qwen3_instruct_2507_training.jinja

Template corrigido do Qwen3-Instruct-2507 (usado por modelos como Qwen3-4B-Instruct-2507, que incluem uma variante mais simples do Qwen3 sem análise de reasoning_content / <think>, rastreamento de multi_step_tool ou a flag enable_thinking). Diferenças em relação a qwen3_instruct_2507.jinja:

Envolver a saída da mensagem do assistente com {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

qwen3_thinking_2507_training.jinja

Template corrigido do Qwen3-Thinking-2507 (usado por modelos como Qwen3-4B-Thinking-2507, que pré-preenchem <think>\n no prompt de geração). Diferenças em relação a qwen3_thinking_2507.jinja: mesmo conjunto de alterações que qwen3_training.jinja, que remove a condicional loop.index0 > ns.last_query_index para que o bloco de raciocínio seja sempre emitido (preservação de prefixo) e envolve a saída do assistente com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente no SFT.

qwen3_5_think_training.jinja / qwen3_5_nothink_training.jinja

Modelos Qwen3.5 corrigidos com lógica compartilhada entre as duas variações (eles diferem apenas no valor padrão da flag enable_thinking):

  • qwen3_5_think_training.jinja tem o modo de raciocínio ativado por padrão, usado pelo Qwen3.5-4B e modelos maiores.
  • qwen3_5_nothink_training.jinja tem o modo de raciocínio desativado por padrão, usado pelo Qwen3.5-2B e modelos menores.

Diferença em relação a qwen3_5_think.jinja / qwen3_5_nothink.jinja: idêntico a qwen3_training.jinja (remover a condicional loop.index0 > ns.last_query_index para que o bloco de raciocínio seja sempre emitido, e envolver a saída do assistente em {% generation %} / {% endgeneration %}).

qwen3_6_training.jinja

Template do Qwen3.6 corrigido. Diferença em relação a qwen3_6.jinja: idêntico a qwen3_training.jinja (remover a condicional loop.index0 > ns.last_query_index para que o bloco de raciocínio seja sempre emitido, envolver a saída do assistente em {% generation %} / {% endgeneration %}).

qwen3_8_training.jinja

Template do Qwen3.8 corrigido. Diferença em relação a qwen3_8.jinja: remover a condicional preserve_thinking / loop.index0 > ns.last_query_index para que o bloco de raciocínio seja sempre emitido — a preservação do prefixo então se mantém mesmo quando o chamador passa preserve_thinking=False — e envolver a saída do assistente com os marcadores {% generation %} / {% endgeneration %} para perda apenas do assistente em SFT, deixando a parte do bloco de raciocínio que o prompt de geração pré-preenche fora deles.

smolvlm_training.jinja

Template do SmolVLM corrigido (também usado para SmolVLM2-500M-Video-Instruct e SmolVLM2-2.2B-Instruct antes de be92141, que possuem um template idêntico byte a byte). Diferenças em relação a smolvlm.jinja:

Divida a mensagem do assistente em seu próprio ramo para que os marcadores {% generation %} / {% endgeneration %} envolvam o conteúdo do assistente. Isso permite que return_assistant_tokens_mask=True produza máscaras corretas para a perda SFT apenas do assistente.

smolvlm_v2_training.jinja

Template SmolVLM2 corrigido. Mesma diferença que em smolvlm_training.jinja, aplicada a smolvlm_v2.jinja.

Utilitários relacionados

Veja Utilitários de Modelo de Chat para as funções auxiliares (clone_chat_template(), is_chat_template_prefix_preserving, get_training_chat_template()) que operam nesses modelos.

Update on GitHub