DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

apply_chat_template 报 chat_template is not set

apply_chat_template 找不到模板时,核对基础模型与对话 checkpoint、本地保存文件及模型角色格式。只用匹配训练格式的模板,避免重复添加特殊标记。

把 role、content 组成的消息列表交给 tokenizer.apply_chat_template(),还没开始生成,就遇到:

tokenizer.chat_template is not set and no template argument was passed!

tokenizer 没有可用的对话模板。消息列表本身不包含模型需要的完整分隔符、角色标记和结束标记;模板负责把它转换成模型训练时使用的 token 序列。下面以 Transformers 4.57.1 的文本对话接口为例,其他版本的报错开头可能不同。

基础模型和对话模型要一起核对

先看当前实际加载的对象:

print(tokenizer.name_or_path)
print(tokenizer.chat_template)

同一家族的基础模型与 Instruct 模型可能共用相近的 tokenizer 词表,但不一定提供相同的对话配置。基础模型没有对话模板,并不表示下载坏了。若本来要调用对话微调模型,确认模型权重与 tokenizer 都来自那个具体 checkpoint,而不是一边加载基础模型、一边加载 Instruct tokenizer。

不要只给基础模型套一个随手找来的模板,让报错消失。能渲染消息,不能证明该模型经过这种角色格式的训练。若任务本来就是文本续写,可以直接编码符合任务要求的字符串,无需调用 apply_chat_template()。

对话 checkpoint 的本地副本也可能漏文件

如果已经确认是对话模型,检查本地保存或打包时是否保留了 tokenizer 的全部文件。在 4.57.1 中,模板可能来自 chat_template.jinja,也可能保存在 tokenizer 配置中;不能仅看到 tokenizer.json 就认定对话配置齐全。

优先从同一 checkpoint 的完整 tokenizer 配置恢复。需要手动加载模板时,应使用这个模型确认过的模板,保留原文件,别覆盖仍可恢复的模型目录:

from pathlib import Path

# 路径示例:这里必须是与当前模型匹配的已核对模板。
verified_template = Path("./verified-chat-template.jinja")
tokenizer.chat_template = verified_template.read_text(encoding="utf-8")

如果 chat_template 是包含多个模板的字典,并且没有 default,调用时将 chat_template 参数设为字典中实际存在的模板名称。它和模板完全不存在是两个分支。

渲染成功后,还要看角色格式

下面只检查 tokenizer 格式,不加载或运行模型。checkpoint 是你实际使用、已确认附带对话模板的模型仓库标识或本地目录:

from transformers import AutoTokenizer

checkpoint = "./my-chat-checkpoint"  # 替换为实际完整目录。
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
messages = [{"role": "user", "content": "Explain what a tokenizer does."}]

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

inputs = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_dict=True,
    return_tensors="pt",
)

核对渲染文本的角色分隔符、结束标记和 assistant 起始位置是否符合当前模型的格式。add_generation_prompt=True 的作用取决于模板;并不是所有模板都添加相同的 assistant 标记。示例只使用 user,因为有些模型不接受单独的 system 消息。遇到角色交替或 system 不支持的报错,应该按模型支持的角色格式调整消息,而不是把所有角色名硬改成 user。

若先得到 formatted 再自行编码,应按模板要求避免重复添加特殊标记;常见用法是 tokenizer(formatted, add_special_tokens=False)。直接让 apply_chat_template(tokenize=True) 完成编码,可以少一层重复处理。

模板缺失的验收是:同一个 checkpoint 重新加载后仍能正确渲染预期消息,不靠进程里临时遗留的赋值。生成成功却把输入对话一起显示出来,则属于另一个问题,见 generate 输出中保留提示词的处理方法。