# 聊天模板

在我们的 GitHub 中，我们列出了 Unsloth 使用的每一种聊天模板，包括 Llama、Mistral、Phi-4 等。所以如果你需要关于格式或使用场景的任何提示，可以在这里查看： [github.com/unslothai/unsloth/blob/main/unsloth/chat\_templates.py](https://github.com/unslothai/unsloth/blob/main/unsloth/chat_templates.py)

#### Colab 聊天模板笔记本列表：

* [对话式](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_\(1B_and_3B\)-Conversational.ipynb)
* [ChatML](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3_\(8B\)-Ollama.ipynb)
* [Ollama](https://colab.research.google.com/drive/1WZDi7APtQ9VsvOrQSSC5DDtxq159j8iZ?usp=sharing)
* [文本分类](https://github.com/timothelaborie/text_classification_scripts/blob/main/unsloth_classification.ipynb) 由 Timotheeee 提供
* [多个数据集](https://colab.research.google.com/drive/1njCCbE1YVal9xC83hjdo2hiGItpY_D6t?usp=sharing) 由 Flail 提供

### 添加新 token

Unsloth 有一个名为 `add_new_tokens` 的函数，它允许你向微调中添加新的 token。例如，如果你想添加 `<CHARACTER_1>`, `<THINKING>` 以及 `<SCRATCH_PAD>` 我们可以这样做：

```python
model, tokenizer = FastLanguageModel.from_pretrained(...)
from unsloth import add_new_tokens
add_new_tokens(model, tokenizer, new_tokens = ["<CHARACTER_1>", "<THINKING>", "<SCRATCH_PAD>"])
model = FastLanguageModel.get_peft_model(...)
```

{% hint style="warning" %}
注意 - 你必须始终调用 `add_new_tokens` 之前 `FastLanguageModel.get_peft_model`!
{% endhint %}

## 多轮对话

如果你没注意到，一个问题是 Alpaca 数据集是单轮对话，而你还记得 ChatGPT 是交互式的，你可以和它进行多轮对话。例如，左边是我们想要的，而右边的 Alpaca 数据集只提供单次对话。我们希望微调后的语言模型能够以某种方式学会像 ChatGPT 一样进行多轮对话。

<figure><img src="/files/02f83b44488171e282ef1bf51fde26acb96a6a7b" alt=""><figcaption></figcaption></figure>

因此我们引入了 `conversation_extension` 参数，它本质上会在你的单轮数据集中随机选择一些行，并把它们合并成 1 段对话！例如，如果你把它设为 3，我们会随机选择 3 行并把它们合并成 1 行！设置得太长会使训练变慢，但可能会让你的聊天机器人和最终微调效果好很多！

<figure><img src="/files/4849fe401f1d094fbfcce60d2dcb75189316c9ac" alt=""><figcaption></figcaption></figure>

然后把 `output_column_name` 到预测 / 输出列。对于 Alpaca 数据集，则应为输出列。

然后我们使用 `standardize_sharegpt` 函数把数据集整理成适合微调的正确格式！一定要调用这个！

<figure><img src="/files/1e924f8e8f23e8ce40da2876066b9340c6f25e0a" alt=""><figcaption></figcaption></figure>

## 可自定义的聊天模板

现在我们可以为微调本身指定聊天模板。著名的 Alpaca 格式如下：

<figure><img src="/files/8d184b103a71fb233f5ef9220eb1ef3481088a49" alt=""><figcaption></figcaption></figure>

但还记得我们说过这是个坏主意吗？因为 ChatGPT 风格的微调只需要 1 个提示词？由于我们已经用 Unsloth 成功把所有数据集列合并成 1 列，所以我们实际上可以创建下面这种聊天模板：包含 1 个输入列（instruction）和 1 个输出：

<figure><img src="/files/c04db09684c17f35ff66b1a7f66ddbe944bdf3ca" alt=""><figcaption></figcaption></figure>

我们只要求你必须放入一个 `{INPUT}` 字段作为指令，以及一个 `{OUTPUT}` 字段作为模型输出字段。实际上我们还允许一个可选的 `{SYSTEM}` 字段，这对像 ChatGPT 那样自定义系统提示词很有用。例如，下面是一些很酷的示例，你可以把聊天模板自定义成：

<figure><img src="/files/cb48c9db509de3aa7c0e7358e9171c7f513a4de2" alt=""><figcaption></figcaption></figure>

对于 OpenAI 模型中使用的 ChatML 格式：

<figure><img src="/files/bda510272aaa6c9b37a557f137852d0f6de7f71b" alt=""><figcaption></figcaption></figure>

或者你可以直接使用 Llama-3 模板本身（它只能通过使用 Llama-3 的 instruct 版本来发挥作用）：实际上我们还允许一个可选的 `{SYSTEM}` 字段，这对像 ChatGPT 那样自定义系统提示词很有用。

<figure><img src="/files/f2654913d520ecaca3e63b3aaffa3bd697d31a26" alt=""><figcaption></figcaption></figure>

或者在 Titanic 预测任务中，你需要在这个包含 CSV 和 Excel 上传功能的 Colab 笔记本里预测乘客是死亡还是生还： <https://colab.research.google.com/drive/1VYkncZMfGFkeCEgN2IzbZIKEDkyQuJAS?usp=sharing>

<figure><img src="/files/d321b3aebceac495259213dd50100d3d3df339cf" alt=""><figcaption></figcaption></figure>

## 使用 Unsloth 应用聊天模板

对于通常遵循常见 chatml 格式的数据集，准备数据集用于训练或微调的过程只包含四个简单步骤：

* 检查 Unsloth 当前支持的聊天模板：\\

  ```
  from unsloth.chat_templates import CHAT_TEMPLATES
  print(list(CHAT_TEMPLATES.keys()))
  ```

  \
  这将打印出 Unsloth 当前支持的模板列表。下面是一个示例输出：\\

  ```
  ['unsloth', 'zephyr', 'chatml', 'mistral', 'llama', 'vicuna', 'vicuna_old', 'vicuna old', 'alpaca', 'gemma', 'gemma_chatml', 'gemma2', 'gemma2_chatml', 'llama-3', 'llama3', 'phi-3', 'phi-35', 'phi-3.5', 'llama-3.1', 'llama-31', 'llama-3.2', 'llama-3.3', 'llama-32', 'llama-33', 'qwen-2.5', 'qwen-25', 'qwen25', 'qwen2.5', 'phi-4', 'gemma-3', 'gemma3']
  ```

  \\
* 使用 `get_chat_template` 将正确的聊天模板应用到你的 tokenizer：\\

  ```
  from unsloth.chat_templates import get_chat_template

  tokenizer = get_chat_template(
      tokenizer,
      chat_template = "gemma-3", # 将其改为正确的 chat_template 名称
  )
  ```

  \\
* 定义你的格式化函数。下面是一个示例：\\

  ```
  def formatting_prompts_func(examples):
     convos = examples["conversations"]
     texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos]
     return { "text" : texts, }
  ```

  \
  \
  这个函数会遍历你的数据集，将你定义的聊天模板应用到每个样本。\\
* 最后，让我们加载数据集并对数据集应用所需的修改： \\

  ```
  # 导入并加载数据集
  from datasets import load_dataset
  dataset = load_dataset("repo_name/dataset_name", split = "train")

  # 使用 map 方法将格式化函数应用到你的数据集
  dataset = dataset.map(formatting_prompts_func, batched = True,)
  ```

  \
  如果你的数据集使用 ShareGPT 格式，并且使用的是 "from"/"value" 键，而不是 ChatML 的 "role"/"content" 格式，你可以先使用 `standardize_sharegpt` 函数将其转换。修改后的代码现在如下：\
  \\

  ```
  # 导入数据集
  from datasets import load_dataset
  dataset = load_dataset("mlabonne/FineTome-100k", split = "train")

  # 如有必要，将你的数据集转换为 "role"/"content" 格式
  from unsloth.chat_templates import standardize_sharegpt
  dataset = standardize_sharegpt(dataset)

  # 使用 map 方法将格式化函数应用到你的数据集
  dataset = dataset.map(formatting_prompts_func, batched = True,)
  ```

## 更多信息

假设你的数据集是如下所示的字典列表中的列表：

```python
[
    [{'from': 'human', 'value': 'Hi there!'},
     {'from': 'gpt', 'value': 'Hi how can I help?'},
     {'from': 'human', 'value': 'What is 2+2?'}],
    [{'from': 'human', 'value': 'What's your name?'},
     {'from': 'gpt', 'value': 'I'm Daniel!'},
     {'from': 'human', 'value': 'Ok! Nice!'},
     {'from': 'gpt', 'value': 'What can I do for you?'},
     {'from': 'human', 'value': 'Oh nothing :)'},],
]
```

你可以使用我们的 `get_chat_template` 来对其进行格式化。选择 `chat_template` 为以下任意一种： `zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, unsloth`，并使用 `mapping` 来映射字典值 `from`, `value` 等。 `map_eos_token` 允许你将 `<|im_end|>` 映射为 EOS，而无需任何训练。

```python
from unsloth.chat_templates import get_chat_template

tokenizer = get_chat_template(
    tokenizer,
    chat_template = "chatml", # 支持 zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, unsloth
    mapping = {"role" : "from", "content" : "value", "user" : "human", "assistant" : "gpt"}, # ShareGPT 风格
    map_eos_token = True, # 改为将 <|im_end|> 映射到 </s>
)

def formatting_prompts_func(examples):
    convos = examples["conversations"]
    texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False) for convo in convos]
    return { "text" : texts, }
pass

from datasets import load_dataset
dataset = load_dataset("philschmid/guanaco-sharegpt-style", split = "train")
dataset = dataset.map(formatting_prompts_func, batched = True,)
```

你也可以制作自己的自定义聊天模板！例如，我们使用的内部聊天模板如下。你必须传入一个 `元组` ，其格式为 `(custom_template, eos_token)` ，其中 `eos_token` 必须在模板中使用。

```python
unsloth_template = \
    "{{ bos_token }}"\
    "{{ '你是一个对用户有帮助的助手\n' }}"\
    "</div>"\
    "<div data-gb-custom-block data-tag="for">"\
        "<div data-gb-custom-block data-tag="if" data-0='role' data-1='role' data-2='] == ' data-3='user'>"\
            "{{ '>>> User: ' + message['content'] + '\n' }}"\
        "<div data-gb-custom-block data-tag="elif" data-0='role' data-1='role' data-2='] == ' data-3='assistant'></div>"\
            "{{ '>>> Assistant: ' + message['content'] + eos_token + '\n' }}"\
        "</div>"\
    "</div>"\
    "<div data-gb-custom-block data-tag="if">"\
        "{{ '>>> Assistant: ' }}"\
    "</div>"
unsloth_eos_token = "eos_token"

tokenizer = get_chat_template(
    tokenizer,
    chat_template = (unsloth_template, unsloth_eos_token,), # 你必须提供一个模板和 EOS token
    mapping = {"role" : "from", "content" : "value", "user" : "human", "assistant" : "gpt"}, # ShareGPT 风格
    map_eos_token = True, # 改为将 <|im_end|> 映射到 </s>
)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unsloth.ai/docs/zh/ji-chu/chat-templates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
