LLM 课程文档
聊天模板
并获得增强的文档体验
开始使用
聊天模板
介绍
聊天模板对于构建语言模型与用户之间的交互至关重要。无论是构建简单的聊天机器人还是复杂的 AI 代理,了解如何正确格式化对话对于从模型中获得最佳结果都至关重要。在本指南中,我们将探讨聊天模板是什么、为什么它们很重要以及如何有效地使用它们。
模型类型和模板
基础模型与指令模型
基础模型通过原始文本数据训练来预测下一个词元,而指令模型则经过专门微调以遵循指令并进行对话。例如,SmolLM2-135M
是一个基础模型,而 SmolLM2-135M-Instruct
是其经过指令微调的变体。
指令微调模型经过训练以遵循特定的对话结构,使其更适合聊天机器人应用。此外,指令模型可以处理复杂的交互,包括工具使用、多模态输入和函数调用。
要使基础模型表现得像指令模型,我们需要以模型能够理解的一致方式格式化我们的提示。这就是聊天模板的作用。ChatML 是一种这样的模板格式,它通过明确的角色指示器(系统、用户、助手)来组织对话。这里是关于 ChatML 的指南。
常见模板格式
在深入特定实现之前,了解不同模型期望的对话格式非常重要。让我们通过一个简单的对话示例来探讨一些常见的模板格式。
我们将使用以下对话结构作为所有示例的基础:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"},
{"role": "assistant", "content": "Hi! How can I help you today?"},
{"role": "user", "content": "What's the weather?"},
]
这是 SmolLM2 和 Qwen 2 等模型中使用的 ChatML 模板。
<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
Hello!<|im_end|>
<|im_start|>assistant
Hi! How can I help you today?<|im_end|>
<|im_start|>user
What's the weather?<|im_start|>assistant
这是使用 mistral
模板格式。
<s>[INST] You are a helpful assistant. [/INST]
Hi! How can I help you today?</s>
[INST] Hello! [/INST]
这些格式之间的主要区别包括:
系统消息处理:
- Llama 2 将系统消息包含在
<<SYS>>
标签中。 - Llama 3 使用
<|system|>
标签,并以</s>
结尾。 - Mistral 将系统消息包含在第一个指令中。
- Qwen 使用带有
<|im_start|>
标签的显式system
角色。 - ChatGPT 使用
SYSTEM:
前缀。
- Llama 2 将系统消息包含在
消息边界:
- Llama 2 使用
[INST]
和[/INST]
标签。 - Llama 3 使用角色特定标签(
<|system|>
、<|user|>
、<|assistant|>
),并以</s>
结尾。 - Mistral 使用
[INST]
和[/INST]
,以及<s>
和</s>
。 - Qwen 使用角色特定的开始/结束标记。
- Llama 2 使用
特殊标记:
- Llama 2 使用
<s>
和</s>
作为对话边界。 - Llama 3 使用
</s>
结束每条消息。 - Mistral 使用
<s>
和</s>
作为轮次边界。 - Qwen 使用角色特定的开始/结束标记。
- Llama 2 使用
理解这些差异是使用各种模型的关键。让我们看看 transformers 库如何帮助我们自动处理这些变化。
from transformers import AutoTokenizer
# These will use different templates automatically
mistral_tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1")
qwen_tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B-Chat")
smol_tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-135M-Instruct")
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"},
]
# Each will format according to its model's template
mistral_chat = mistral_tokenizer.apply_chat_template(messages, tokenize=False)
qwen_chat = qwen_tokenizer.apply_chat_template(messages, tokenize=False)
smol_chat = smol_tokenizer.apply_chat_template(messages, tokenize=False)
点击查看模板示例
Qwen 2 和 SmolLM2 ChatML 模板
<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
Hello!<|im_end|>
<|im_start|>assistant
Hi! How can I help you today?<|im_end|>
<|im_start|>user
What's the weather?<|im_start|>assistant
Mistral 模板
<s>[INST] You are a helpful assistant. [/INST]
Hi! How can I help you today?</s>
[INST] Hello! [/INST]
高级功能
聊天模板可以处理比仅仅对话交互更复杂的场景,包括:
- 工具使用:当模型需要与外部工具或 API 交互时
- 多模态输入:用于处理图像、音频或其他媒体类型
- 函数调用:用于结构化函数执行
- 多轮上下文:用于维护对话历史
对于多模态对话,聊天模板可以包含图像引用或 Base64 编码的图像。
messages = [
{
"role": "system",
"content": "You are a helpful vision assistant that can analyze images.",
},
{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image", "image_url": "https://example.com/image.jpg"},
],
},
]
这是一个带有工具使用的聊天模板示例:
messages = [
{
"role": "system",
"content": "You are an AI assistant that can use tools. Available tools: calculator, weather_api",
},
{"role": "user", "content": "What's 123 * 456 and is it raining in Paris?"},
{
"role": "assistant",
"content": "Let me help you with that.",
"tool_calls": [
{
"tool": "calculator",
"parameters": {"operation": "multiply", "x": 123, "y": 456},
},
{"tool": "weather_api", "parameters": {"city": "Paris", "country": "France"}},
],
},
{"role": "tool", "tool_name": "calculator", "content": "56088"},
{
"role": "tool",
"tool_name": "weather_api",
"content": "{'condition': 'rain', 'temperature': 15}",
},
]
最佳实践
一般准则
在使用聊天模板时,请遵循以下关键实践:
- 一致的格式:在整个应用程序中始终使用相同的模板格式。
- 明确的角色定义:清晰指定每条消息的角色(系统、用户、助手、工具)。
- 上下文管理:在维护对话历史时注意词元限制。
- 错误处理:对工具调用和多模态输入进行适当的错误处理。
- 验证:在发送到模型之前验证消息结构。
动手练习
让我们通过一个真实世界的例子来练习实现聊天模板。
- 加载数据集
from datasets import load_dataset
dataset = load_dataset("HuggingFaceTB/smoltalk")
- 创建处理函数
def convert_to_chatml(example):
return {
"messages": [
{"role": "user", "content": example["input"]},
{"role": "assistant", "content": example["output"]},
]
}
- 使用您选择的模型的分词器应用聊天模板。
请记住验证您的输出格式是否符合目标模型的要求!