# this file deals with dataset pre-processing before training
# 1. PPO (prompt)
# 2. SFT (prompt + demonstration), there is also packing.
# 3. ✅ RM / DPO (chosen and rejected)
# 4. ✅ Visualization of length distributions?
# 5. ✅ Filter?
# 6. ✅ dataset_num_proc
# 7. ✅ check EOS token
# 8. dataset mixer?
# 9. ✅ pretty print that show tokenization?
# 10. ✅ hashable tokneization?
# 11. inputs / labels / attention_mask
# 12. ✅ always set a `tokenizer.pad_token_id`?
# 13. a new DataCollatorForLanguageModeling?
# 14. ✅ `add_bos_token` and `add_eos_token`? E.g., LLAMA models
# 15. ✅ generate properties: has eos_token, bos_token (through chat template)
# ✅ get tokenizer revision
# ✅ get dataset revision
# create a cached tokenized dataset, with tokenized revision, dataset revision, tokenization function name.
# too many names related to "maximum length":
# * `max_seq_length` in SFT
# * `max_length`, `max_target_length` in RM / DPO,
# * `max_prompt_length` in DPO
# TODO: note that tokenizer doesn't change but model name does change. Should be mindful of this.
"""
This file contains the utility to transform and cache datasets with different configurations.
The main things we are looking for are:
* handle dataset mixing
* handle different tokenization functions
* **cache** the tokenized dataset so we don't have to re-tokenize every time
* This is especially important when we have 405B SFT models: 32 nodes are just spending like
5 minutes to tokenize the dataset. This translates to 32 * 5 * 8 = 1280 minutes = 21 hours of
wasted H100 time.
* Sometimes we also launch on places that don't have a shared cache (e.g., GCP), so we would
download individual datasets 32 times, and wait for concatenation and tokenization (actually
twice because the `with accelerator.main_process_first()` function assumes a shared cache)
## TODO: We should just simplify the tokenization setups. We have multiple "rlvr_tokenize", etc. This came from a previous version of version handling that prioritised backwards compatibility, but I think in practice we should just directly edit these functions + invalidate caches.
"""
import copy
import hashlib
import json
import multiprocessing
import os
from collections.abc import Callable, Sequence
from dataclasses import asdict, dataclass, field
from functools import cached_property
from typing import Any, Literal
import numpy as np
import torch
import transformers
from datasets import Dataset, concatenate_datasets, load_dataset
from huggingface_hub import ModelCard, revision_exists
from rich.console import Console
from rich.text import Text
from transformers import AutoTokenizer, GPTNeoXTokenizerFast, LlamaTokenizer, LlamaTokenizerFast, PreTrainedTokenizer
from transformers.utils.hub import extract_commit_hash
from open_instruct import launch_utils, logger_utils
from open_instruct.utils import hf_whoami, max_num_processes
logger = logger_utils.setup_logger(__name__)
# ----------------------------------------------------------------------------
# Utilities
def get_commit_hash(
model_name_or_path: str, revision: str, filename: str = "config.json", repo_type: str = "model"
) -> str | None:
file = launch_utils.custom_cached_file(model_name_or_path, filename, revision=revision, repo_type=repo_type)
commit_hash = extract_commit_hash(file, None)
return commit_hash
def get_file_hash(
model_name_or_path: str, revision: str | None, filename: str = "config.json", repo_type: str = "model"
) -> str:
file = launch_utils.custom_cached_file(model_name_or_path, filename, revision=revision, repo_type=repo_type)
if isinstance(file, str):
with open(file, "rb") as f:
return hashlib.sha256(f.read()).hexdigest()
elif file is None:
return f"{filename} not found"
else:
raise ValueError(f"Unexpected file type: {type(file)}")
def get_files_hash_if_exists(
model_name_or_path: str, revision: str | None, filenames: list[str], repo_type: str = "model"
) -> list[str]:
return [get_file_hash(model_name_or_path, revision, filename, repo_type) for filename in filenames]
def _preserve_column(column_name: str, dataset, target_columns: list) -> list:
if column_name in dataset.column_names and column_name not in target_columns:
target_columns = target_columns + [column_name]
return target_columns
# Performance tuning. Some rough numbers:
APPLY_CHAT_TEMPLATE_EXAMPLE_PER_SECOND_PER_CPU = 400
FILTER_EXAMPLE_PER_SECOND_PER_CPU = 1130
def get_num_proc(dataset_len: int, num_available_cpus: int, example_per_second_per_cpu) -> int:
num_required_cpus = max(1, dataset_len // example_per_second_per_cpu)
return min(num_required_cpus, num_available_cpus, dataset_len)
COLORS = ["on red", "on green", "on blue", "on yellow", "on magenta"]
def visualize_token(tokens: list[int], tokenizer: PreTrainedTokenizer):
i = 0
console = Console()
rich_text = Text()
for i, token in enumerate(tokens):
color = COLORS[i % len(COLORS)]
decoded_token = tokenizer.decode(int(token))
rich_text.append(f"{decoded_token}", style=color)
console.print(rich_text)
def visualize_token_role(tokens: list[int], masks: list[int], tokenizer: PreTrainedTokenizer):
i = 0
console = Console()
rich_text = Text()
# for i, token in enumerate():
for i in range(min(len(tokens), len(masks))):
token = tokens[i]
color = COLORS[masks[i] % len(COLORS)]
decoded_token = tokenizer.decode(int(token))
rich_text.append(f"{decoded_token}", style=color)
console.print(rich_text)
# ----------------------------------------------------------------------------
# Tokenization
# Chat templates
# note we added `{% if loop.last and not add_generation_prompt %}{{ eos_token }}{% endif %}`
# because we want the template to not output eos_token if `add_generation_prompt=True`
#
# For Olmo 3 tokenizer settings and chat template decisions, see:
# docs/olmo3.md (https://allenai.github.io/open-instruct/olmo3/#tokenizer-settings)
CHAT_TEMPLATES = {
"simple_concat_with_space": (
"{% for message in messages %}"
"{{ ' ' if not loop.first else '' }}"
"{{ message['content'] }}"
"{% if loop.last and not add_generation_prompt %}{{ eos_token }}{% endif %}"
"{% endfor %}"
),
"simple_concat_with_new_line": (
"{% for message in messages %}"
"{{ '\n' if not loop.first else '' }}"
"{{ message['content'] }}"
"{% if loop.last and not add_generation_prompt %}{{ eos_token }}{% endif %}"
"{% endfor %}"
),
"simple_chat": (
"{% for message in messages %}"
"{{ '\n\n' if not loop.first else '' }}"
"{{ message['role'].capitalize() + ': ' + message['content'] }}"
"{% if loop.last and not add_generation_prompt %}{{ eos_token }}{% endif %}"
"{% endfor %}"
),
"assistant_message_only": (
"{% for message in messages %}"
"{% if message['role'] == 'assistant' %}"
"{{ message['content'] }}"
"{% endif %}"
"{% endfor %}"
),
"zephyr": (
"{% for message in messages %}"
"{% if message['role'] == 'user' %}"
"{{ '<|user|>\n' + message['content'] + eos_token + '\n' }}"
"{% elif message['role'] == 'system' %}"
"{{ '<|system|>\n' + message['content'] + eos_token + '\n' }}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|assistant|>\n' + message['content'] + eos_token + '\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|assistant|>\n' }}"
"{% endif %}"
"{% endfor %}"
),
# olmo-core-compatible chat templates:
# TODO: unify these 3 chat templates and send variables through the tokenizer's apply_chat_template kwargs
"olmo": (
"{% set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 %}"
"{% if not has_system %}"
"{{ '<|im_start|>system\nYou are OLMo, a helpful function-calling AI assistant built by Ai2. Your date cutoff is November 2024, and your model weights are available at https://huggingface.co/allenai. You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|im_start|>system\n' + message['content'] }}"
"{% if message.get('functions', none) is not none %}"
"{{ ' ' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ ' You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'user' %}"
"{% if message.get('functions', none) is not none %}"
"{{ '<|im_start|>user\n' + message['content'] + '\n' + '' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|im_start|>assistant\n' }}"
"{% if message.get('content', none) is not none %}"
"{{ message['content'] }}"
"{% endif %}"
"{% if message.get('function_calls', none) is not none %}"
"{{ '' + message['function_calls'] + '' }}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|im_end|>' + '\n' }}"
"{% else %}"
"{{ eos_token }}"
"{% endif %}"
"{% elif message['role'] == 'environment' %}"
"{{ '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|im_start|>assistant\n' }}"
"{% endif %}"
"{% endfor %}"
),
"tulu": (
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|system|>\n' + message['content'] + '\n' }}"
"{% elif message['role'] == 'user' %}"
"{{ '<|user|>\n' + message['content'] + '\n' }}"
"{% elif message['role'] == 'assistant' %}"
"{% if not loop.last %}"
"{{ '<|assistant|>\n' + message['content'] + eos_token + '\n' }}"
"{% else %}"
"{{ '<|assistant|>\n' + message['content'] + eos_token }}"
"{% endif %}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|assistant|>\n' }}"
"{% endif %}"
"{% endfor %}"
),
"tulu_thinker": (
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|system|>\n' + message['content'] + '\n' }}"
"{% elif message['role'] == 'user' %}"
"{{ '<|user|>\n' + message['content'] + '\n' }}"
"{% elif message['role'] == 'assistant' %}"
"{% set content = message['content'] %}"
"{% if not loop.last %}"
"{{ '<|assistant|>\n' + content + eos_token + '\n' }}"
"{% else %}"
"{{ '<|assistant|>\n' + content + eos_token }}"
"{% endif %}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|assistant|>\n' }}"
"{% endif %}"
"{% endfor %}"
),
"tulu_thinker_r1_style": (
"A conversation between User and Assistant. "
"The user asks a question, and the Assistant solves it. "
"The assistant first thinks about the reasoning process in "
"the mind and then provides the user with the answer. "
"The reasoning process and answer are enclosed within "
"and tags, respectively, "
"i.e., reasoning process here "
" answer here ."
"\n\n"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|system|>\n' + message['content'] + '\n' }}"
"{% elif message['role'] == 'user' %}"
"{{ '<|user|>\n' + message['content'] + '\n' }}"
"{% elif message['role'] == 'assistant' %}"
"{% set content = message['content'] %}"
"{% if '' in content %}"
"{% set content = content.split('')[-1] %}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|assistant|>\n' + content + eos_token + '\n' }}"
"{% else %}"
"{{ '<|assistant|>\n' + content + eos_token }}"
"{% endif %}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|assistant|>\n' }}"
"{% endif %}"
"{% endfor %}"
),
# olmo-core-compatible chat templates:
# TODO: unify these 3 chat templates and send variables through the tokenizer's apply_chat_template kwargs
"olmo_old": (
"{% set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 %}"
"{% if not has_system %}"
"{{ '<|im_start|>system\nYou are OLMo, a helpful function-calling AI assistant built by Ai2. Your date cutoff is November 2024, and your model weights are available at https://huggingface.co/allenai. You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|im_start|>system\n' + message['content'] }}"
"{% if message.get('functions', none) is not none %}"
"{{ ' ' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ ' You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'user' %}"
"{% if message.get('functions', none) is not none %}"
"{{ '<|im_start|>user\n' + message['content'] + '\n' + '' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|im_start|>assistant\n' }}"
"{% if message.get('content', none) is not none %}"
"{{ message['content'] }}"
"{% endif %}"
"{% if message.get('function_calls', none) is not none %}"
"{{ '' + message['function_calls'] + '' }}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|im_end|>' + '\n' }}"
"{% else %}"
"{{ eos_token }}"
"{% endif %}"
"{% elif message['role'] == 'environment' %}"
"{{ '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|im_start|>assistant\n' }}"
"{% endif %}"
"{% endfor %}"
),
"olmo_thinker": (
"{% set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 %}"
"{% if not has_system %}"
"{{ '<|im_start|>system\nYou are a helpful AI assistant.<|im_end|>\n' }}"
"{% endif %}"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|im_start|>system\n' + message['content'] }}"
"{% if message.get('functions', none) is not none %}"
"{{ ' ' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ ' You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'user' %}"
"{% if message.get('functions', none) is not none %}"
"{{ '<|im_start|>user\n' + message['content'] + '\n' + '' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|im_start|>assistant\n' }}"
"{% if message.get('content', none) is not none %}"
"{{ message['content'] }}"
"{% endif %}"
"{% if message.get('function_calls', none) is not none %}"
"{{ '' + message['function_calls'] + '' }}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|im_end|>' + '\n' }}"
"{% else %}"
"{{ eos_token }}"
"{% endif %}"
"{% elif message['role'] == 'environment' %}"
"{{ '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|im_start|>assistant\n' }}"
"{% endif %}"
"{% endfor %}"
),
"olmo_thinker_no_think_7b": (
"{% set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 %}"
"{% if not has_system %}"
"{{ '<|im_start|>system\nYou are Olmo, a helpful AI assistant built by Ai2. Your date cutoff is December 2024, and your model weights are available at https://huggingface.co/allenai.<|im_end|>\n' }}"
"{% endif %}"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|im_start|>system\n' + message['content'] }}"
"{% if message.get('functions', none) is not none %}"
"{{ ' ' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ ' You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'user' %}"
"{% if message.get('functions', none) is not none %}"
"{{ '<|im_start|>user\n' + message['content'] + '\n' + '' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|im_start|>assistant\n' }}"
"{% if message.get('content', none) is not none %}"
"{{ message['content'] }}"
"{% endif %}"
"{% if message.get('function_calls', none) is not none %}"
"{{ '' + message['function_calls'] + '' }}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|im_end|>' + '\n' }}"
"{% else %}"
"{{ eos_token }}"
"{% endif %}"
"{% elif message['role'] == 'environment' %}"
"{{ '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|im_start|>assistant\n' }}"
"{% endif %}"
"{% endfor %}"
),
"olmo_thinker_remove_intermediate_thinking": (
"{% set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 %}"
"{% if not has_system %}"
"{{ '<|im_start|>system\nYou are a helpful AI assistant.<|im_end|>\n' }}"
"{% endif %}"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|im_start|>system\n' + message['content'] }}"
"{% if message.get('functions', none) is not none %}"
"{{ ' ' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ ' You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'user' %}"
"{% if message.get('functions', none) is not none %}"
"{{ '<|im_start|>user\n' + message['content'] + '\n' + '' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|im_start|>assistant\n' }}"
"{% set content = message.get('content', none) %}"
"{% if content is not none %}"
"{% set content = content | string %}"
"{% if not loop.last and '' in content and '' in content %}"
"{% set content = content.split('')[-1].lstrip('\\n') %}"
"{% endif %}"
"{{ content }}"
"{% endif %}"
"{% if message.get('function_calls', none) is not none %}"
"{{ '' + message['function_calls'] + '' }}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|im_end|>' + '\n' }}"
"{% else %}"
"{{ eos_token }}"
"{% endif %}"
"{% elif message['role'] == 'environment' %}"
"{{ '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|im_start|>assistant\n' }}"
"{% endif %}"
"{% endfor %}"
),
"olmo_thinker_no_think_sft_tokenization": (
"{% set has_system = messages|selectattr('role', 'equalto', 'system')|list|length > 0 %}"
"{% if not has_system %}"
"{{ '<|im_start|>system\nYou are a helpful AI assistant.<|im_end|>\n' }}"
"{% endif %}"
"{% for message in messages %}"
"{% if message['role'] == 'system' %}"
"{{ '<|im_start|>system\n' + message['content'] }}"
"{% if message.get('functions', none) is not none %}"
"{{ ' ' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ ' You do not currently have access to any functions. <|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'user' %}"
"{% if message.get('functions', none) is not none %}"
"{{ '<|im_start|>user\n' + message['content'] + '\n' + '' + message['functions'] + '<|im_end|>\n' }}"
"{% else %}"
"{{ '<|im_start|>user\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% elif message['role'] == 'assistant' %}"
"{{ '<|im_start|>assistant\n' }}"
"{% if message.get('content', none) is not none %}"
"{{ message['content'] }}"
"{% endif %}"
"{% if message.get('function_calls', none) is not none %}"
"{{ '' + message['function_calls'] + '' }}"
"{% endif %}"
"{% if not loop.last %}"
"{{ '<|im_end|>' + '\n' }}"
"{% else %}"
"{{ eos_token }}"
"{% endif %}"
"{% elif message['role'] == 'environment' %}"
"{{ '<|im_start|>environment\n' + message['content'] + '<|im_end|>\n' }}"
"{% endif %}"
"{% if loop.last and add_generation_prompt %}"
"{{ '<|im_start|>assistant\n' }}"
"{% endif %}"
"{% endfor %}"
),
"olmo_thinker_rlzero": (
"Solve the following problem step by step. "
"The last line of your response should be the answer to the problem in form Answer: $Answer (without quotes) where $Answer is the answer to the problem."
"\n\n"
"{% for message in messages %}"
"{{ '\n\n' if not loop.first else '' }}"
"{{ message['content'] + '\n' }}"
"{% if loop.last and add_generation_prompt %}"
"{{ '\nRemember to put your answer on its own line after \"Answer:\"' }}"
"{% endif %}"
"{% endfor %}"
),
"olmo_thinker_code_rlzero": (
"Solve the following code problem step by step. "
"The last part of your response should be the solution to the problem in form ```\npython\nCODE\n``` where CODE is the solution for the problem."
"\n\n"
"{% for message in messages %}"
"{{ '\n\n' if not loop.first else '' }}"
"{{ message['content'] + '\n' }}"
"{% if loop.last and add_generation_prompt %}"
"\nRemember to put your solution inside the ```\npython\nCODE\n``` tags"
"{% endif %}"
"{% endfor %}"
),
# template is taken from https://arxiv.org/abs/2501.12948.
"r1_simple_chat": (
"A conversation between User and Assistant. "
"The user asks a question, and the Assistant solves it. "
"The assistant first thinks about the reasoning process in "
"the mind and then provides the user with the answer. "
"The reasoning process and answer are enclosed within "
"and tags, respectively, "
"i.e., reasoning process here "
" answer here ."
"\n\n"
"{% for message in messages %}"
"{{ '\n\n' if not loop.first else '' }}"
"{{ message['role'].capitalize() + ': ' + message['content'] + '\n' }}"
"{% if loop.last and add_generation_prompt %}"
"{{ 'Assistant:' }}"
"{% endif %}"
"{% endfor %}"
),
"r1_simple_chat_postpend_think": (
"A conversation between User and Assistant. "
"The user asks a question, and the Assistant solves it. "
"The assistant first thinks about the reasoning process in "
"the mind and then provides the user with the answer. "
"The reasoning process and answer are enclosed within "
"and tags, respectively, "
"i.e., reasoning process here "
" answer here ."
"\n\n"
"{% for message in messages %}"
"{{ '\n\n' if not loop.first else '' }}"
"{{ message['role'].capitalize() + ': ' + message['content'] + '\n' }}"
"{% if loop.last and add_generation_prompt %}"
"{{ 'Assistant: ' }}"
"{% endif %}"
"{% endfor %}"
),
"r1_simple_chat_postpend_think_orz_style": (
"A conversation between User and Assistant. "
"The user asks a question, and the Assistant solves it. "
"The assistant first thinks about the reasoning process in "
"the mind and then provides the user with the answer. "
"The reasoning process and answer are enclosed within "
"and tags, respectively, "
"i.e., reasoning process here "
" answer here ."
"\n\n"
"{% for message in messages %}"
"{{ '\n\n' if not loop.first else '' }}"
"{{ message['role'].capitalize() + ': You must put your answer inside tags, i.e., answer here . And your final answer will be extracted automatically by the \\\\boxed{} tag. This is the problem: ' + message['content'] + '\n' }}" # \\\\boxed{} is for jinja template escape
"{% if loop.last and add_generation_prompt %}"
"{{ 'Assistant: ' }}"
"{% endif %}"
"{% endfor %}"
),
"r1_simple_chat_postpend_think_tool_vllm": (
"A conversation between User and Assistant. "
"The User asks a question, and the Assistant solves it. "
"The Assistant first thinks about the reasoning process in "
"the mind and then provides the User with the answer. "
"\n\n"
"When given a question, the Assistant must conduct reasoning inside the "
"and tags. During reasoning, the Assistant may write and execute python "
"code using the tag, in order to solve the problem or verify the answer. "
"Then the Assistant will get the stdout and stderr in the tags. "
"For example, the code could be\n"
"\n"
"x, y = 1, 2\n"
"result = x + y\n"
"print(result)\n"
"\n"
"or\n"
"\n"
"import sympy as sp\n"
"from sympy import Symbol\n"
"x = Symbol('x')\n"
"y = Symbol('y')\n"
"solution = sp.solve(x**2 + y**2 - 1, (x, y))\n"
"print(solution)\n"
"\n"
"The Assistant will always `print` the result of the code execution in order to see it in the