TRL documentation

Plantillas 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.17.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Plantillas de chat

Una plantilla de chat es un fragmento de Jinja2 que formatea los mensajes en la cadena de texto con la que se entrenó un modelo. Por ejemplo:

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

En la mayoría de los casos no necesitas preocuparte por las plantillas de chat: los modelos incluyen su plantilla junto con el tokenizador, y TRL la aplica por ti. Todo el proceso es transparente. Sin embargo, algunas recetas de TRL dependen de características que la mayoría de las plantillas incluidas no tienen:

  • El SFT con assistant_only_loss=True necesita los marcadores {% generation %} / {% endgeneration %} alrededor de la salida del asistente, para que la máscara de pérdida pueda dirigirse únicamente a los tokens del asistente.
  • GRPO con llamadas a herramientas requiere que la plantilla sea de preservación de prefijo: añadir un mensaje de herramienta no debe cambiar cómo se renderizan los mensajes anteriores.

TRL incluye plantillas corregidas en trl/chat_templates/ para familias comunes (Qwen, Llama, DeepSeek-V3, GPT-OSS, …) y las aplica automáticamente para los modelos compatibles. Para cualquier otro modelo, será necesario corregir su plantilla manualmente. El resto de esta página cataloga lo que se incluye.

Familias de modelos admitidas

TRL almacena copias de referencia de las plantillas originales para poder identificar los modelos compatibles durante la inicialización y sustituir por una plantilla de entrenamiento cuando sea necesario. Las siguientes familias se reconocen: Cohere, Cohere2, DeepSeek-V3 (incluidos DeepSeek-R1, DeepSeek-R1-0528 y DeepSeek-V3-0324), DeepSeek-R1-Distill, DiffusionGemma, Gemma, Gemma3, Gemma4 (incluidos Gemma-4-12B, Gemma-4-26B-A4B y 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 (incluidos LFM2.5-1.2B-Instruct, LFM2.5-2.6B y LFM2.5-24B-A2B), LFM2.5-VL (incluido 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 (incluidos los puntos de control base), Qwen2.5-VL, Qwen3 (incluidas las variantes Instruct-2507 y Thinking-2507), Qwen3-Coder (incluido Qwen3-Coder-Next), Qwen3-VL, Qwen3.5, Qwen3.6, Qwen3.8, SmolVLM (incluido SmolVLM2).

Plantillas de entrenamiento

Plantillas corregidas que resuelven problemas específicos del entrenamiento. Se sustituyen durante la inicialización cuando se habilitan herramientas (GRPO) o cuando assistant_only_loss=True (SFT).

cohere_training.jinja

Plantilla de Cohere corregida. Diferencias con cohere.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

cohere2_training.jinja

Plantilla Cohere2 corregida. Diferencias con cohere2.jinja:

Mueve el <|END_OF_TURN_TOKEN|> final de después del {% endif %} de despacho de rol a cada rama de rol, y envuelve la rama del asistente (<|START_RESPONSE|>...<|END_RESPONSE|><|END_OF_TURN_TOKEN|>) con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida solo de asistente en SFT.

deepseek_r1_distill_training.jinja

Plantilla de DeepSeek-R1-Distill corregida. Diferencias con deepseek_r1_distill.jinja:

  • Elimina la división por '</think>' en el contenido del asistente. El original descartaba todo hasta e incluyendo </think>, lo que habría eliminado silenciosamente el razonamiento de la meta de entrenamiento.
  • Envuelve la salida del mensaje del asistente con los marcadores {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT. El <|Assistant|> y el <|tool▁outputs▁end|> que abren un turno del asistente permanecen fuera de los marcadores, ya que el prompt ya termina con ellos.

deepseekv3_training.jinja

Plantilla de DeepSeek-V3 corregida. Diferencias con deepseekv3.jinja:

  • Utiliza | tojson en tool['function']['arguments'] para que arguments pueda pasarse como un dict (el formato documentado según la documentación de transformers). La plantilla original utiliza concatenación de cadenas sin procesar, lo que provoca un error con entradas de tipo dict.
  • Elimina la división por '</think>' en el contenido del asistente, de modo que el bloque de razonamiento siempre se renderice. El original elimina todo hasta e incluyendo </think>, lo que eliminaría silenciosamente el razonamiento de la diana de entrenamiento.
  • Envuelve la salida del mensaje del asistente con los marcadores {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT. El <|Assistant|> y el <|tool▁outputs▁end|> que abren un turno del asistente permanecen fuera de los marcadores, ya que el prompt ya termina con ellos.

deepseekv3_v2_training.jinja

Plantilla de DeepSeek-R1-0528 corregida. Diferencias con deepseekv3_v2.jinja:

  • Usa | tojson en tool['function']['arguments'] para que arguments pueda pasarse como un dict, como en deepseekv3_training.jinja.
  • Elimina la división por '</think>' en el contenido del asistente, de modo que el bloque de razonamiento siempre se renderice. El original elimina todo hasta e incluyendo </think>, lo que eliminaría silenciosamente el razonamiento de la diana de entrenamiento.
  • Envuelve la salida del mensaje del asistente con los marcadores {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT. El <|tool▁outputs▁end|> que abre un turno del asistente después de las salidas de las herramientas permanece fuera de los marcadores, ya que el prompt ya termina con él.

deepseekv3_v3_training.jinja

Plantilla de DeepSeek-V3 corregida (usada por deepseek-ai/DeepSeek-V3). Mismo diff que deepseek_r1_distill_training.jinja, aplicado a deepseekv3_v3.jinja: marcadores {% generation %} / {% endgeneration %} alrededor de la salida del mensaje del asistente para la pérdida solo de asistente en SFT, dejando fuera de ellos a <|Assistant|> y <|tool▁outputs▁end|>, que abren un turno del asistente.

deepseekv3_v4_training.jinja

Plantilla de DeepSeek-V3-0324 corregida (usada por deepseek-ai/DeepSeek-V3-0324). Mismo diff que deepseekv3_v2_training.jinja, aplicado a deepseekv3_v4.jinja: | tojson en los argumentos de tool-call, y marcadores {% generation %} / {% endgeneration %} alrededor de la salida del asistente.

diffusion_gemma_training.jinja

Plantilla de DiffusionGemma corregida. Diferencias con diffusion_gemma.jinja:

Envuelve las partes de un turno del modelo que este emite (canal de pensamiento, llamadas a herramientas, contenido y el cierre <turn|>) con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida SFT solo de asistente. Las respuestas de herramientas incrustadas en el turno provienen del entorno y permanecen fuera del bloque de generación.

gemma_training.jinja

Plantilla de Gemma corregida (compartida por Gemma y Gemma2, que incluyen plantillas de chat idénticas). Diferencias con gemma.jinja:

Divida la salida del asistente unificado para que la cabecera <start_of_turn>model\n (una pista de indicación, no generada por el modelo) quede fuera del bloque de generación, y envuelva el contenido del asistente con las marcas {% generation %} / {% endgeneration %} para la pérdida solo del asistente en SFT.

gemma3_training.jinja

Plantilla de Gemma 3 corregida. Mismo diff que gemma_training.jinja (dividir la línea de salida unificada en ramas específicas por rol para que la pista de prompt <start_of_turn>model\n quede fuera del bloque de generación, y envolver el contenido del asistente con {% generation %} / {% endgeneration %}), aplicado a la plantilla base de Gemma 3 que admite mensajes de sistema y bloques de contenido multimodal.

glm4moe_training.jinja

Plantilla GLM-4-MoE corregida. Diferencias con glm4moe.jinja:

Cierre cada turno del asistente dentro del bloque de generación con el marcador de rol que abre el siguiente turno (<|observation|> después de las llamadas a herramientas, en caso contrario <|user|> o <|system|>). La plantilla original de GLM no tiene un token de fin de turno: un turno termina con el marcador de rol del siguiente mensaje, y GLM declara <|user|> y <|observation|> como tokens de fin de secuencia, por lo que la plantilla de entrenamiento añade el marcador al turno del asistente para mantener el token de parada en la máscara de pérdida, y el mensaje siguiente ya no renderiza su propio marcador.

Envuelve la salida del mensaje del asistente (incluido el bloque de pensamiento y las llamadas a herramientas) con los marcadores {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT. Con enable_thinking=False, el bloque de pensamiento permanece fuera de los marcadores, ya que el prompt de generación ya termina con el \n<think></think> vacío.

qwen3_training.jinja

Plantilla de Qwen3 corregida. Diferencias con qwen3.jinja:

Incluye siempre el bloque de pensamiento, independientemente de la posición del mensaje. La versión original lo omite condicionalmente en función de loop.last, lo que altera la representación del asistente cuando se añade un mensaje de herramienta, rompiendo la preservación del prefijo:

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

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente. La parte del bloque de pensamiento que el prompt de generación pre-llena (<think>\n\n</think>\n\n con enable_thinking=False) permanece fuera de los marcadores, ya que el prompt ya termina con ella. Las otras plantillas de entrenamiento de Qwen3 hacen lo mismo con lo que su propio prompt de generación pre-llena, como <think>\n.

qwen3_v2_training.jinja

Plantilla original de Qwen3 corregida (incluida en los puntos de control de Qwen3 anteriores a mayo de 2025, y aún en los puntos de control base de Qwen3). Mismo diff que qwen3_training.jinja, aplicado a qwen3_v2.jinja.

qwen3_vl_training.jinja

Plantilla de Qwen3-VL corregida. Diferencias respecto a qwen3_vl.jinja:

Envuelve la salida del mensaje del asistente (tanto content como tool_calls) con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida SFT solo de asistente.

gptoss_training.jinja

Plantilla de GPT-OSS corregida. Diferencias con gptoss.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente. El <|start|>assistant que abre el turno permanece fuera de los marcadores, ya que el prompt de generación ya termina con él.

idefics3_training.jinja

Plantilla de Idefics3 corregida. Diferencias con idefics3.jinja:

Divida el mensaje del asistente en su propia rama para que los marcadores {% generation %} / {% endgeneration %} abarquen el contenido del asistente. Esto permite que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida SFT solo de asistente.

lfm2_training.jinja

Plantilla LFM2 corregida. Diferencias respecto a lfm2.jinja:

Divida la línea de salida del mensaje unificado en ramas específicas por rol, de modo que la señal de indicación <|im_start|>assistant\n quede fuera del bloque de generación (no es generada por el modelo), mientras que el contenido del asistente y <|im_end|>\n (que el modelo debe aprender a producir y en el que debe detenerse) queden dentro. Envuelva el contenido del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida exclusiva del asistente en SFT.

lfm2_v2_training.jinja

Plantilla de LFM2 corregida, revisión posterior. Diferencias con lfm2_v2.jinja:

Envuelve la salida del asistente con {% generation %} / {% endgeneration %}, tanto en la rama que renderiza tool_calls como en la rama de contenido plano, para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente. La señal de indicación <|im_start|>assistant\n permanece fuera del bloque de generación, mientras que el contenido, las llamadas a herramientas y <|im_end|>\n se encuentran dentro.

llama3_training.jinja

Plantilla de Llama 3 corregida. Diferencias con llama3.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

llava_next_training.jinja

Plantilla Llava-Next corregida. Diferencias con llava_next.jinja:

  • Envuelve la salida del mensaje del asistente con los marcadores {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT.
  • Mantiene el espacio que sigue a </s> fuera del bloque de generación. El tokenizador lo fusiona con el primer token del siguiente turno (▁[), lo cual, de lo contrario, se enmascararía como salida del asistente y ocultaría el token de parada </s> del final del tramo enmascarado.

mistral_large_4_training.jinja

Plantilla de Mistral Large 4 corregida. Diferencias respecto a mistral_large_4.jinja: mismo cambio que en mistral_medium_3_5_training.jinja, envolviendo el turno del asistente (contenido, llamadas a herramientas y el token de fin de turno) con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

mistral_medium_3_5_training.jinja

Plantilla de Mistral Medium 3.5 corregida. Diferencias respecto a mistral_medium_3_5.jinja: la original ya preserva el prefijo, por lo que el único cambio es envolver el turno del asistente (contenido, llamadas a herramientas y el token de fin de turno) con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida SFT solo de asistente.

muse_glimmer_training.jinja

Plantilla de Muse Glimmer corregida. Diferencias respecto a muse_glimmer.jinja: envuelve toda la rama del asistente — cada canal ATEM del turno — con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente. El <|start|>assistant que abre el turno permanece fuera de los marcadores, ya que el prompt de generación ya termina con él.

muse_spark_training.jinja

Plantilla abierta de Muse Spark corregida. Diferencias respecto a muse_spark.jinja: los marcadores {% generation %} de la original también cubren el <|start|>assistant que abre el turno, algo con lo que el prompt de generación ya termina. La plantilla de entrenamiento lo emite antes de los marcadores, de modo que return_assistant_tokens_mask=True no lo entrene. El texto renderizado no cambia.

nemotron_3_nano_training.jinja

Plantilla de Nemotron Nano corregida. Diferencias respecto a nemotron_3_nano.jinja: la original ya preserva el prefijo, por lo que el cambio consiste en envolver la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida solo de asistente en SFT. La parte del bloque de pensamiento que el prompt de generación pre-llena (<think>\n, o <think></think> con enable_thinking=False) permanece fuera de los marcadores, ya que el prompt ya termina con ella.

nemotron_3_super_training.jinja

Plantilla Nemotron Super corregida. Diferencias respecto a nemotron_3_super.jinja: igual que nemotron_3_nano_training.jinja — la original ya preserva el prefijo, por lo que el cambio consiste en envolver la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida solo de asistente en SFT. La parte del bloque de pensamiento que el prompt de generación pre-llena (<think>\n, o <think></think> con enable_thinking=False) se mantiene fuera de los marcadores, ya que el prompt ya termina con ella.

nemotron_3_ultra_training.jinja

Plantilla de Nemotron Ultra corregida. Diferencias respecto a nemotron_3_ultra.jinja: igual que nemotron_3_nano_training.jinja — la original ya preserva el prefijo, por lo que el cambio consiste en envolver la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida solo de asistente en SFT. La parte del bloque de pensamiento que el prompt de generación pre-llena (<think>\n, o <think></think> con enable_thinking=False) permanece fuera de los marcadores, ya que el prompt ya termina con ella.

nemotron_3_5_lightning_training.jinja

Plantilla de Nemotron 3.5 Lightning corregida. Diferencias respecto a nemotron_3_5_lightning.jinja: igual que nemotron_3_nano_training.jinja — la original ya preserva el prefijo, por lo que el cambio consiste en envolver la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida solo de asistente en SFT. La parte del bloque de pensamiento que el prompt de generación pre-llena (<think>\n, o <think></think> con enable_thinking=False) permanece fuera de los marcadores, ya que el prompt ya termina con ella.

phi3_training.jinja

Plantilla de Phi-3 corregida. Diferencias con phi3.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

phi3_5_training.jinja

Plantilla de Phi-3.5 corregida. Diferencias con phi3_5.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

qwen2_5_training.jinja

Plantilla de Qwen2.5 corregida. Diferencias con qwen2_5.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

qwen2_5_base_training.jinja

Plantilla base de Qwen2.5 corregida (usada por los puntos de control base, como Qwen2.5-0.5B, cuya plantilla solo difiere de la de instruct en su prompt de sistema predeterminado). Mismo diff que qwen2_5_training.jinja, aplicado a qwen2_5_base.jinja.

qwen2_5_vl_training.jinja

Plantilla de Qwen2.5-VL corregida (también se usa para Qwen2-VL, que incluye una plantilla idéntica a nivel de bytes). Diferencias con qwen2_5_vl.jinja:

Divida el mensaje del asistente en su propia rama para que los marcadores {% generation %} / {% endgeneration %} abarquen el contenido del asistente. Esto permite que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida exclusiva del asistente en SFT.

qwen3_instruct_2507_training.jinja

Plantilla corregida de Qwen3-Instruct-2507 (usada por modelos como Qwen3-4B-Instruct-2507, que incluyen una variante más simple de Qwen3 sin análisis de reasoning_content / <think>, seguimiento de multi_step_tool ni la bandera enable_thinking). Diferencias respecto a qwen3_instruct_2507.jinja:

Envuelve la salida del mensaje del asistente con {% generation %} / {% endgeneration %} para que return_assistant_tokens_mask=True produzca máscaras correctas para la pérdida SFT solo de asistente.

qwen3_thinking_2507_training.jinja

Plantilla corregida de Qwen3-Thinking-2507 (usada por modelos como Qwen3-4B-Thinking-2507, que pre-rellenan <think>\n en el prompt de generación). Diferencias respecto a qwen3_thinking_2507.jinja: el mismo conjunto de cambios que qwen3_training.jinja, que elimina la condicional loop.index0 > ns.last_query_index para que el bloque de pensamiento se emita siempre (preservación del prefijo) y envuelve la salida del asistente con las marcas {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT.

qwen3_5_think_training.jinja / qwen3_5_nothink_training.jinja

Plantillas de Qwen3.5 corregidas con lógica compartida entre ambas variantes (solo difieren en el valor predeterminado de la bandera enable_thinking):

  • qwen3_5_think_training.jinja tiene el modo de razonamiento activado por defecto y se utiliza en Qwen3.5-4B y modelos más grandes.
  • qwen3_5_nothink_training.jinja tiene el razonamiento desactivado por defecto y se utiliza en Qwen3.5-2B y modelos más pequeños.

Diferencias con qwen3_5_think.jinja / qwen3_5_nothink.jinja: igual que qwen3_training.jinja (eliminar la condicional loop.index0 > ns.last_query_index para que el bloque de pensamiento se emita siempre, y envolver la salida del asistente en {% generation %} / {% endgeneration %}).

qwen3_6_training.jinja

Plantilla de Qwen3.6 corregida. Diferencias respecto a qwen3_6.jinja: igual que qwen3_training.jinja (eliminar la condicional loop.index0 > ns.last_query_index para que el bloque de pensamiento se emita siempre, y envolver la salida del asistente en {% generation %} / {% endgeneration %}).

qwen3_8_training.jinja

Plantilla de Qwen3.8 corregida. Diferencias respecto a qwen3_8.jinja: se elimina la condicional preserve_thinking / loop.index0 > ns.last_query_index para que el bloque de pensamiento se emita siempre, de modo que la preservación del prefijo se mantenga incluso cuando el llamador pasa preserve_thinking=False; y se envuelve la salida del asistente con las marcas {% generation %} / {% endgeneration %} para la pérdida solo de asistente en SFT, dejando fuera de ellas la parte del bloque de pensamiento que el prompt de generación pre-rellena.

smolvlm_training.jinja

Plantilla de SmolVLM corregida (también utilizada para SmolVLM2, que incluye una plantilla idéntica a nivel de bytes). Diferencias respecto a smolvlm.jinja:

Divida el mensaje del asistente en su propia rama para que los marcadores {% generation %} / {% endgeneration %} abarquen el contenido del asistente. Esto permite que return_assistant_tokens_mask=True genere máscaras correctas para la pérdida SFT solo de asistente.

Utilidades relacionadas

Consulte Chat Template Utilities para las funciones auxiliares (clone_chat_template(), is_chat_template_prefix_preserving, get_training_chat_template()) que operan sobre estas plantillas.

Update on GitHub