TRL documentation
Modelos de Chat
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=Trueprecisa 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
| tojsonemtool['function']['arguments']para queargumentspossa ser passado como umdict(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
| tojsonemtool['function']['arguments']para queargumentspossa ser passado como umdict, como emdeepseekv3_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.jinjatem o modo de raciocínio ativado por padrão, usado pelo Qwen3.5-4B e modelos maiores.qwen3_5_nothink_training.jinjatem 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.