1. 关于 tokenizer.apply_chat_template 的使用

apply_chat_template 是 Hugging Face Transformers 库中 tokenizer 的一个方法,用于将对话格式的聊天数据转换为模型可以处理的输入格式

1.1 基本用法

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("模型名称")

# 对话格式示例
messages = [
    {"role": "system", "content": "你是一个有帮助的助手。"},
    {"role": "user", "content": "你好!"},
    {"role": "assistant", "content": "你好!有什么我可以帮助你的吗?"},
    {"role": "user", "content": "你能解释一下量子计算吗?"}
]

# 应用聊天模板
tokenized_chat = tokenizer.apply_chat_template(messages, tokenize=False)
print(tokenized_chat)

1.2 参数说明

  • messages: 对话列表,每个元素是一个字典,包含 role (system/user/assistant) 和 content (文本内容)
  • tokenize: 是否直接进行tokenize (默认True,返回token IDs;False则返回格式化后的字符串)
  • add_generation_prompt: 是否添加提示词表示需要模型生成回复 (默认False)
  • return_tensors: 返回的张量格式 (“pt” for PyTorch, “tf” for TensorFlow)
  • **kwargs: 其他传递给tokenizer的参数

1.3 示例输出

对于不同的模型,输出格式会有所不同:

  1. ChatML格式 (如Mistral)

    <|im_start|>system\n你是一个有帮助的助手。<|im_end|>\n<|im_start|>user\n你好!<|im_end|>\n<|im_start|>assistant\n你好!有什么我可以帮助你的吗?<|im_end|>\n<|im_start|>user\n你能解释一下量子计算吗?<|im_end|>\n<|im_start|>assistant\n
    
  2. LLAMA2格式

    [INST] <<SYS>>\n你是一个有帮助的助手。\n<</SYS>>\n\n你好! [/INST]你好!有什么我可以帮助你的吗? </s><s>[INST] 你能解释一下量子计算吗? [/INST]
    

1.4 实际应用示例

# 完整的使用示例,包括模型推理
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_id = "mistralai/Mistral-7B-Instruct-v0.1"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)

messages = [
    {"role": "user", "content": "你好!"},
    {"role": "assistant", "content": "你好!有什么我可以帮助你的吗?"},
    {"role": "user", "content": "你能解释一下量子计算吗?"}
]

inputs = tokenizer.apply_chat_template(messages, return_tensors="pt").to("cuda")
outputs = model.generate(inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))

1.5 注意事项

  1. 不同模型的聊天模板可能不同,确保使用与模型匹配的tokenizer
  2. 对于没有内置聊天模板的模型,可能需要手动定义对话格式
  3. 在流式传输或交互式应用中,需要正确处理对话历史

2. 上面的应用示例,如果apply_chat_template的输入参数是:inputs = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True),那么其输出inputs会是什么样子

如果需要为特定模型自定义聊天模板,可以修改tokenizer的chat_template属性。

如果使用 tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True),输出会是格式化后的对话字符串,并在末尾添加了提示模型生成回复的标记(具体格式取决于模型使用的模板)。

mistralai/Mistral-7B-Instruct-v0.1 模型为例:

输入对话

messages = [
    {"role": "user", "content": "你好!"},
    {"role": "assistant", "content": "你好!有什么我可以帮助你的吗?"},
    {"role": "user", "content": "你能解释一下量子计算吗?"}
]

应用模板后的输出

inputs = tokenizer.apply_chat_template(
    messages, 
    tokenize=False, 
    add_generation_prompt=True
)

输出内容 (Mistral的ChatML格式)

<|im_start|>user\n你好!<|im_end|>\n<|im_start|>assistant\n你好!有什么我可以帮助你的吗?<|im_end|>\n<|im_start|>user\n你能解释一下量子计算吗?<|im_end|>\n<|im_start|>assistant\n

关键变化:

  1. add_generation_prompt=True 在末尾添加了 \n<|im_start|>assistant\n,这是提示模型开始生成回复的位置标记
  2. 没有进行 tokenize(tokenize=False),所以返回的是纯文本字符串
  3. 保留了 ChatML 格式的特殊标记(<|im_start|><|im_end|>

对比说明:

  • 没有 add_generation_prompt 时,输出会停在最后一个用户消息的结束标记 <|im_end|>
  • 添加 add_generation_prompt 后,会额外加上助理的开始标记,等待模型生成内容

不同模型的差异:

  1. LLAMA2 格式 会添加 [/INST] 标记
  2. Zephyr 格式 会添加 <|assistant|> 标记
  3. 其他模型可能有自己的特殊标记

这个功能在交互式对话中特别有用,因为它自动处理了"轮到模型说话了"的上下文提示。

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐