首页/AI/大模型部署与运维速查/chat template:消息到 prompt 的渲染
推理参数与优化50 条

chat template:消息到 prompt 的渲染

Chat 模型要求把消息列表按模板渲染成带角色标记的 prompt:标准做法是用 tokenizer 自带 chat template(Jinja)渲染;模板与模型训练格式不一致是输出异常的常见根因。

chat template 是什么

chat template 是把结构化的消息列表渲染成模型训练时见过的带角色标记纯文本的模板:模型不认识 JSON 消息,只认识训练格式的字符串。标准做法是用 tokenizer 自带的 Jinja 模板渲染,而不是手工拼字符串。模板与训练格式不一致时,典型表现是答非所问、输出里带角色标记、或者回复刚开始就结束。

基本信息

载体tokenizer 的 chat_template 字段(Jinja 模板)
渲染入口tokenizer.apply_chat_template,推理服务端按模型自带模板渲染
关键开关add_generation_prompt=True 追加助手起手标记
常见缺失部分模型仓库未提供模板,需要显式配置
适用平台HF transformers、vLLM/TGI 等 OpenAI 兼容服务

典型使用场景

  • 采集与处理多轮对话数据:轮次必须渲染成训练时的角色格式,否则微调效果无从保证
  • 自查输出异常:把渲染结果打印出来核对标记与分隔符,比猜测推理服务更直接
  • 跨模型迁移:不同模型的标记体系不同,切换模型前先对比两个模板的差异
  • 自建推理服务:确认服务端确实用了模型自带模板,而不是框架兜底的通用格式
  • 构造评测集:prompt 渲染方式与线上一致,评测结论才对线上有意义

本地渲染自查

本地渲染自查
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("<模型路径>")
text = tok.apply_chat_template(
    [{"role": "system", "content": "你是运维助手"},
     {"role": "user", "content": "你好"}],
    tokenize=False,
    add_generation_prompt=True,
)
print(repr(text))   # 用 repr 看空格、换行与特殊标记是否与模型卡示例一致

模板不匹配的表现

现象可能原因核对动作
答非所问、答完就停角色标记与训练格式不一致对比 repr 输出与模型卡示例
输出里出现标记文本模型把标记当正文,通常是模板缺失确认仓库是否提供模板,必要时显式配置
回复立刻结束或突然截断结束标记处理不一致检查模板里的结束标记与生成结束条件
多轮里角色错位历史轮次渲染不全确认历史消息都进了渲染输入
渲染时优先让模板与 tokenizer 自己处理特殊标记:自定义角色标记如果不是词表里的特殊 token,会被拆成普通子词,与训练时的分词结果不同。
模板属于模型资产的一部分,建议与 revision 一起记录进部署清单:换仓库版本后模板可能同步变化,输出风格随之改变。

易错点

  • 手拼 prompt 替代模板:特殊标记与格式对不上,表现为答非所问或输出角色标记,改提示词前先对比渲染结果
  • 推理服务端使用框架的通用兜底模板:与模型训练格式不符,模型能力发挥不出来
  • 只渲染当前一轮、丢掉历史轮次:多轮上下文断裂,模型反复追问已经说过的信息
  • 忽略 add_generation_prompt:缺少助手起手标记,模型可能接着用户的话继续编,而不是回答

数据来源与参考

  • Hugging Face:Chat templates 文档(huggingface.co/docs/transformers)
  • vLLM 官方文档:OpenAI 兼容服务器(docs.vllm.ai)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌