TRL documentation

Chat Templates

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

and get access to the augmented documentation experience

to get started

Chat Templates

Un chat template est un extrait Jinja2 qui met en forme les messages en la chaîne de caractères sur laquelle le modèle a été entraîné. Par exemple :

>>> 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'

Dans la plupart des cas, vous n’avez pas à vous soucier des modèles de chat : les modèles fournissent leur modèle avec le tokenizer, et TRL l’applique pour vous. L’ensemble du processus est transparent. Cependant, certaines recettes TRL s’appuient sur des fonctionnalités que la plupart des modèles fournis n’incluent pas :

  • Le SFT avec assistant_only_loss=True nécessite les marqueurs {% generation %} / {% endgeneration %} autour de la sortie de l'assistant, afin que le masque de perte puisse cibler uniquement les jetons de l'assistant.
  • GRPO avec des appels d’outils nécessite que le modèle de rendu soit préfixe-préservant : l’ajout d’un message d’outil ne doit pas modifier la façon dont les messages précédents sont rendus.

TRL fournit des modèles corrigés sous trl/chat_templates/ pour les familles courantes (Qwen, Llama, DeepSeek-V3, GPT-OSS, …) et les applique automatiquement aux modèles pris en charge. Pour tout autre modèle, vous devrez corriger son modèle vous-même. Le reste de cette page recense ce qui est inclus.

Familles de modèles prises en charge

TRL conserve des copies de référence des modèles originaux afin d'identifier les modèles pris en charge à l'initialisation et de substituer un modèle d'entraînement si nécessaire. Les familles suivantes sont reconnues : Cohere, Cohere2, DeepSeek-V3 (y compris DeepSeek-R1, DeepSeek-R1-0528 et DeepSeek-V3-0324), DeepSeek-R1-Distill, DiffusionGemma, Gemma, Gemma3, Gemma4 (y compris Gemma-4-12B, Gemma-4-26B-A4B et 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 (y compris LFM2.5-1.2B-Instruct, LFM2.5-2.6B et LFM2.5-24B-A2B), LFM2.5-VL (y compris LFM2.5-VL-450M), Llama 3 / 3.1 / 3.2, Llava-Next, Mistral Large 4, Mistral Medium 3.5, Muse Glimmer, Nemotron 3 (Nano, Super, Ultra), Nemotron 3.5 Lightning, Phi-3, Phi-3.5, Qwen2-VL, Qwen2.5 (y compris les points de contrôle de base), Qwen2.5-VL, Qwen3 (y compris les variantes Instruct-2507 et Thinking-2507), Qwen3-Coder (y compris Qwen3-Coder-Next), Qwen3-VL, Qwen3.5, Qwen3.6, Qwen3.8, SmolVLM (y compris SmolVLM2).

Modèles d'entraînement

Modèles corrigés qui résolvent les problèmes spécifiques à l'entraînement. Ils sont utilisés à l'initialisation lorsque les outils sont activés (GRPO) ou lorsque assistant_only_loss=True (SFT).

cohere_training.jinja

Modèle Cohere corrigé. Différence par rapport à cohere.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

cohere2_training.jinja

Modèle Cohere2 corrigé. Différence par rapport à cohere2.jinja :

Déplacez le <|END_OF_TURN_TOKEN|> final, situé après le {% endif %} de la répartition des rôles, dans chaque branche de rôle, et entourez la branche assistant (<|START_RESPONSE|>...<|END_RESPONSE|><|END_OF_TURN_TOKEN|>) avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

deepseek_r1_distill_training.jinja

Modèle DeepSeek-R1-Distill corrigé. Différence par rapport à deepseek_r1_distill.jinja :

  • Supprime le découpage sur '</think>' dans le contenu de l'assistant. L'original supprime tout jusqu'à et y compris </think>, ce qui supprimerait silencieusement le raisonnement de la cible d'entraînement.
  • Enveloppe la sortie du message de l’assistant avec les marqueurs {% generation %} / {% endgeneration %} pour la perte SFT assistant-only. Les <|Assistant|> et <|tool▁outputs▁end|> qui ouvrent un tour de l’assistant restent à l’extérieur des marqueurs, car le prompt se termine déjà par eux.

deepseekv3_training.jinja

Modèle DeepSeek-V3 corrigé. Différence par rapport à deepseekv3.jinja :

  • Utilise | tojson sur tool['function']['arguments'] afin que arguments puisse être transmis en tant que dict (le format documenté selon la documentation de transformers). Le modèle d'origine utilise la concaténation brute de chaînes, ce qui provoque un échec sur les entrées de type dict.
  • Supprime le découpage sur '</think>' dans le contenu de l'assistant, afin que le bloc de raisonnement soit toujours rendu. La version d'origine supprime tout jusqu'à et y compris </think>, ce qui enlèterait silencieusement le raisonnement de la cible d'entraînement.
  • Enveloppe la sortie du message de l’assistant avec les marqueurs {% generation %} / {% endgeneration %} pour la perte SFT assistant-only. Les <|Assistant|> et <|tool▁outputs▁end|> qui ouvrent un tour de l’assistant restent à l’extérieur des marqueurs, car le prompt se termine déjà par eux.

deepseekv3_v2_training.jinja

Modèle DeepSeek-R1-0528 corrigé. Différence par rapport à deepseekv3_v2.jinja :

  • Utilise | tojson sur tool['function']['arguments'] afin que arguments puisse être transmis en tant que dict, comme dans deepseekv3_training.jinja.
  • Supprime le découpage sur '</think>' dans le contenu de l'assistant, afin que le bloc de raisonnement soit toujours rendu. La version d'origine supprime tout jusqu'à et y compris </think>, ce qui enlèterait silencieusement le raisonnement de la cible d'entraînement.
  • Enveloppe la sortie du message de l’assistant avec les marqueurs {% generation %} / {% endgeneration %} pour la perte SFT assistant-only. Le <|tool▁outputs▁end|> qui ouvre un tour de l’assistant après les sorties d’outil reste à l’extérieur des marqueurs, car le prompt se termine déjà par celui-ci.

deepseekv3_v3_training.jinja

Modèle DeepSeek-V3 corrigé (utilisé par deepseek-ai/DeepSeek-V3). Même diff que deepseek_r1_distill_training.jinja, appliqué à deepseekv3_v3.jinja : marqueurs {% generation %} / {% endgeneration %} autour de la sortie du message de l'assistant pour une perte SFT assistant-only, avec <|Assistant|> et <|tool▁outputs▁end|> qui ouvrent un tour de l'assistant laissés à l'extérieur.

deepseekv3_v4_training.jinja

Modèle corrigé de DeepSeek-V3-0324 (utilisé par deepseek-ai/DeepSeek-V3-0324). Même diff que deepseekv3_v2_training.jinja, appliqué à deepseekv3_v4.jinja : | tojson sur les arguments des appels d’outils, et marqueurs {% generation %} / {% endgeneration %} autour de la sortie de l’assistant.

diffusion_gemma_training.jinja

Modèle DiffusionGemma corrigé. Différences par rapport à diffusion_gemma.jinja :

Enveloppez les parties d’un tour de modèle émises par le modèle (canal de réflexion, appels d’outils, contenu et la balise de fermeture <turn|>) avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only. Les réponses d’outils intégrées au tour proviennent de l’environnement et restent hors du bloc de génération.

gemma_training.jinja

Modèle Gemma corrigé (partagé par Gemma et Gemma2, qui fournissent des modèles de chat identiques). Différence par rapport à gemma.jinja :

Séparez la sortie de l’assistant unifié afin que l’en-tête <start_of_turn>model\n (un indice de prompt, non généré par le modèle) se trouve en dehors du bloc de génération, et entourez le contenu de l’assistant avec les marqueurs {% generation %} / {% endgeneration %} pour une perte SFT assistant-only.

gemma3_training.jinja

Modèle Gemma 3 corrigé. Même diff que gemma_training.jinja (diviser la ligne de sortie unifiée en branches spécifiques au rôle afin que l'indice de prompt <start_of_turn>model\n se trouve en dehors du bloc de génération, et envelopper le contenu de l'assistant avec {% generation %} / {% endgeneration %}), appliqué au modèle de base Gemma 3 qui prend en charge les messages système et les blocs de contenu multimodal.

glm4moe_training.jinja

Modèle GLM-4-MoE corrigé. Différence par rapport à glm4moe.jinja :

Fermez chaque tour de l’assistant à l’intérieur du bloc de génération avec le marqueur de rôle qui ouvre le tour suivant (<|observation|> après les appels d’outils, sinon <|user|> ou <|system|>). Le modèle original de GLM ne possède pas de jeton de fin de tour : un tour est terminé par le marqueur de rôle du message suivant, et GLM déclare <|user|> et <|observation|> comme jetons de fin de séquence, de sorte que le modèle de formation ajoute le marqueur au tour de l’assistant afin de conserver le jeton d’arrêt dans le masque de perte, et le message suivant n’affiche plus son propre marqueur.

Envelopper la sortie du message assistant (y compris le bloc de réflexion et les appels d’outils) avec les marqueurs {% generation %} / {% endgeneration %} pour une perte SFT uniquement sur l’assistant. Avec enable_thinking=False, le bloc de réflexion reste à l’extérieur des marqueurs, car le prompt de génération se termine déjà par le \n<think></think> vide.

qwen3_training.jinja

Modèle Qwen3 corrigé. Différence par rapport à qwen3.jinja :

Incluez toujours le bloc de réflexion, quelle que soit la position du message. La version d’origine l’omet conditionnellement en fonction de loop.last, ce qui modifie le rendu de l’assistant lorsqu’un message d’outil est ajouté, ce qui rompt la préservation du préfixe :

- {%- 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') }}

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only. La partie du bloc de réflexion pré-remplie par le prompt de génération (<think>\n\n</think>\n\n avec enable_thinking=False) reste à l’extérieur des marqueurs, car le prompt se termine déjà par celle-ci. Les autres modèles d’entraînement Qwen3 font de même avec ce que leur propre prompt de génération pré-remplit, comme <think>\n.

qwen3_v2_training.jinja

Modèle Qwen3 d'origine corrigé (fourni par les points de contrôle Qwen3 avant mai 2025, et toujours par les points de contrôle Qwen3 de base). Même diff que qwen3_training.jinja, appliqué à qwen3_v2.jinja.

qwen3_vl_training.jinja

Modèle Qwen3-VL corrigé. Différence par rapport à qwen3_vl.jinja :

Envelopper la sortie du message assistant (à la fois content et tool_calls) avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

gptoss_training.jinja

Modèle GPT-OSS corrigé. Différence par rapport à gptoss.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

idefics3_training.jinja

Modèle Idefics3 corrigé. Différence par rapport à idefics3.jinja :

Séparez le message de l’assistant dans sa propre branche afin que les marqueurs {% generation %} / {% endgeneration %} encadrent le contenu de l’assistant. Cela permet à return_assistant_tokens_mask=True de générer des masques corrects pour la perte SFT réservée à l’assistant.

lfm2_training.jinja

Modèle LFM2 corrigé. Différence par rapport à lfm2.jinja :

Séparez la ligne de sortie du message unifié en branches spécifiques à chaque rôle, afin que l’indice de prompt <|im_start|>assistant\n se trouve à l’extérieur du bloc de génération (il n’est pas généré par le modèle), tandis que le contenu de l’assistant et <|im_end|>\n (que le modèle doit apprendre à produire et sur lequel il doit s’arrêter) se trouvent à l’intérieur. Enveloppez le contenu de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True produise des masques corrects pour la perte SFT uniquement sur l’assistant.

lfm2_v2_training.jinja

Modèle LFM2 corrigé, révision ultérieure. Différence par rapport à lfm2_v2.jinja :

Enveloppez la sortie de l’assistant avec {% generation %} / {% endgeneration %}, à la fois dans la branche qui affiche tool_calls et dans la branche de contenu simple, afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only. L’indice de prompt <|im_start|>assistant\n reste à l’extérieur du bloc de génération, tandis que le contenu, les appels d’outils et <|im_end|>\n se trouvent à l’intérieur.

llama3_training.jinja

Modèle Llama 3 corrigé. Différence par rapport à llama3.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

llava_next_training.jinja

Modèle Llava-Next corrigé. Différence par rapport à llava_next.jinja :

  • Enveloppe la sortie du message de l’assistant avec les marqueurs {% generation %} / {% endgeneration %} pour la perte SFT assistant-only.
  • Conserve l’espace qui suit </s> en dehors du bloc de génération. Le tokenizer le fusionne avec le premier jeton du tour suivant (▁[), ce qui, sinon, le masquerait comme sortie de l’assistant et cacherait le jeton d’arrêt </s> de la fin de la plage masquée.

mistral_large_4_training.jinja

Modèle Mistral Large 4 corrigé. Différence par rapport à mistral_large_4.jinja : même modification que pour mistral_medium_3_5_training.jinja, consistant à encapsuler le tour de l’assistant (contenu, appels d’outils et jeton de fin de tour) avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

mistral_medium_3_5_training.jinja

Modèle Mistral Medium 3.5 corrigé. Différence par rapport à mistral_medium_3_5.jinja : le modèle d’origine est déjà préservant du préfixe, la seule modification consiste donc à encapsuler le tour de l’assistant (contenu, appels d’outils et jeton de fin de tour) avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

muse_glimmer_training.jinja

Modèle Muse Glimmer corrigé. Différence par rapport à muse_glimmer.jinja : envelopper la branche complète de l'assistant — chaque canal ATEM du tour — avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

nemotron_3_nano_training.jinja

Modèle Nemotron Nano corrigé. Différence par rapport à nemotron_3_nano.jinja : l’original est déjà préfixe-préservant, la seule modification consiste donc à encapsuler la sortie des messages assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

nemotron_3_super_training.jinja

Modèle Nemotron Super corrigé. Différence par rapport à nemotron_3_super.jinja : identique à nemotron_3_nano_training.jinja — le modèle d’origine est déjà préservant du préfixe, la seule modification consiste donc à encapsuler la sortie des messages de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT uniquement sur l’assistant.

nemotron_3_ultra_training.jinja

Modèle Nemotron Ultra corrigé. Différence par rapport à nemotron_3_ultra.jinja : identique à nemotron_3_nano_training.jinja — le modèle d’origine est déjà préservant du préfixe, la seule modification consiste donc à encapsuler la sortie des messages de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT réservée à l’assistant.

nemotron_3_5_lightning_training.jinja

Modèle Nemotron 3.5 Lightning corrigé. Différence par rapport à nemotron_3_5_lightning.jinja : identique à nemotron_3_nano_training.jinja — le modèle d'origine est déjà préfixe-préservant, la seule modification consiste donc à encapsuler la sortie des messages assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

phi3_training.jinja

Modèle Phi-3 corrigé. Différence par rapport à phi3.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

phi3_5_training.jinja

Modèle Phi-3.5 corrigé. Différence par rapport à phi3_5.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

qwen2_5_training.jinja

Modèle Qwen2.5 corrigé. Différence par rapport à qwen2_5.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

qwen2_5_base_training.jinja

Modèle de base Qwen2.5 corrigé (utilisé par les points de contrôle de base, tels que Qwen2.5-0.5B, dont le modèle ne diffère de celui d'instruction que par son prompt système par défaut). Même diff que qwen2_5_training.jinja, appliqué à qwen2_5_base.jinja.

qwen2_5_vl_training.jinja

Modèle Qwen2.5-VL corrigé (également utilisé pour Qwen2-VL, qui fournit un modèle identique à l'octet près). Différences par rapport à qwen2_5_vl.jinja :

Séparez le message de l’assistant dans sa propre branche afin que les marqueurs {% generation %} / {% endgeneration %} encadrent le contenu de l’assistant. Cela permet à return_assistant_tokens_mask=True de générer des masques corrects pour la perte SFT réservée à l’assistant.

qwen3_instruct_2507_training.jinja

Modèle de Qwen3-Instruct-2507 corrigé (utilisé par des modèles comme Qwen3-4B-Instruct-2507, qui fournissent une variante Qwen3 plus simple sans analyse de reasoning_content / <think>, suivi de multi_step_tool ou drapeau enable_thinking). Différence par rapport à qwen3_instruct_2507.jinja :

Envelopper la sortie du message de l’assistant avec {% generation %} / {% endgeneration %} afin que return_assistant_tokens_mask=True génère des masques corrects pour la perte SFT assistant-only.

qwen3_thinking_2507_training.jinja

Modèle corrigé Qwen3-Thinking-2507 (utilisé par des modèles comme Qwen3-4B-Thinking-2507, qui pré-remplissent <think>\n dans le prompt de génération). Différences par rapport à qwen3_thinking_2507.jinja : même ensemble de modifications que qwen3_training.jinja, qui supprime la condition loop.index0 > ns.last_query_index afin que le bloc de réflexion soit toujours émis (préservation du préfixe) et entoure la sortie de l'assistant avec les marqueurs {% generation %} / {% endgeneration %} pour une perte SFT uniquement sur l'assistant.

qwen3_5_think_training.jinja / qwen3_5_nothink_training.jinja

Modèles Qwen3.5 corrigés avec une logique partagée entre les deux variantes (elles ne diffèrent que par la valeur par défaut du drapeau enable_thinking) :

  • qwen3_5_think_training.jinja active la réflexion par défaut, et est utilisé par Qwen3.5-4B et les modèles plus grands.
  • qwen3_5_nothink_training.jinja désactive la réflexion par défaut, utilisé par Qwen3.5-2B et les modèles plus petits.

Diff avec qwen3_5_think.jinja / qwen3_5_nothink.jinja : identique à qwen3_training.jinja (supprimer la condition loop.index0 > ns.last_query_index pour que le bloc de réflexion soit toujours émis, et encadrer la sortie de l'assistant avec {% generation %} / {% endgeneration %}).

qwen3_6_training.jinja

Modèle Qwen3.6 corrigé. Différence par rapport à qwen3_6.jinja : identique à qwen3_training.jinja (suppression de la condition loop.index0 > ns.last_query_index afin que le bloc de réflexion soit toujours émis, encadrement de la sortie de l'assistant par {% generation %} / {% endgeneration %}).

qwen3_8_training.jinja

Modèle Qwen3.8 corrigé. Différence par rapport à qwen3_8.jinja : suppression de la conditionnelle preserve_thinking / loop.index0 > ns.last_query_index afin que le bloc de réflexion soit toujours émis — la préservation du préfixe est alors garantie même si l'appelant passe preserve_thinking=False — et encadrement de la sortie de l'assistant avec les marqueurs {% generation %} / {% endgeneration %} pour une perte SFT uniquement sur l'assistant, en laissant la partie du bloc de réflexion pré-remplie par le prompt de génération en dehors de ces marqueurs.

smolvlm_training.jinja

Modèle SmolVLM corrigé (également utilisé pour SmolVLM2, qui fournit un modèle identique à l'octet près). Différences par rapport à smolvlm.jinja :

Séparez le message de l’assistant dans sa propre branche afin que les marqueurs {% generation %} / {% endgeneration %} encadrent le contenu de l’assistant. Cela permet à return_assistant_tokens_mask=True de générer des masques corrects pour la perte SFT réservée à l’assistant.

Utilitaires associés

Voir Chat Template Utilities pour les fonctions utilitaires (clone_chat_template(), is_chat_template_prefix_preserving, get_training_chat_template()) qui opèrent sur ces modèles.

Update on GitHub