对话模板与特殊 token
前置知识点
- 微调是什么:定义与全景 入门
一句话定义
对话模板(chat template)用特殊标记把多轮对话序列化成模型实际看到的字符串,训练与推理必须用同一套模板,否则训得再好也会答非所问。
为什么重要
这是新手翻车率最高的单点:模型学不会停止(无限续写)、多轮对话答非所问、上线后输出带 <|im_start|> 之类残留标记,九成是模板问题。基座模型是纯文本续写器,「角色」「轮次」「结束」这些概念完全由模板的标记约定出来。
前置知识
kp-001 中基座模型与指令模型的区别;知道 tokenizer 把文本切成 token。
核心概念
- 角色标记:
<|im_start|>user / assistant / system与<|im_end|>(ChatML 风格),或各家私有标记。 - eos(序列结束符):模型学会在回答末尾生成 eos 才会「闭嘴」。
- generation prompt:推理时模板末尾保留的
assistant起始标记,引导模型接着说话。 - 特殊 token 注册:新增 token 要加入 tokenizer 词表,且其 embedding 需要可训练(或复用已有 token)。
原理与机制
训练样本的构造规则:把 {system, messages} 经 apply_chat_template 渲染成字符串,标签(label)只对 assistant 回答段 + 末尾 eos 计算 loss,指令部分置为 -100(不计算损失)——这叫 loss masking,否则模型会浪费容量去学「如何生成用户的问题」。
eos 是本节最重要的机制细节:训练数据中每条 assistant 回答的结尾必须跟 eos token 并参与 loss,模型才能学会停止。分词细节上, eos 前通常需要一个换行符约定(模板里写死),训练与推理不一致就会出现「差一个换行导致停不下来」。
各家族模板不同:ChatML(Qwen 系)、Llama-3 的 <|begin_of_text|>/<|eot_id|>、Yi/GLM 各有私有标记。训练哪个模型就用哪个模型的官方模板,不要自创。
图示
<|im_start|>system
你是客服助手<|im_end|>
<|im_start|>user
退货流程?<|im_end|>
<|im_start|>assistant
第一步……<|im_end|> ← eos 参与loss, 模型由此学会停止直观类比
模板是剧场的舞台提示系统:观众(模型)只看得到剧本文本,靠「幕布标记」分清谁在说话、什么时候该自己上台(generation prompt)、什么时候谢幕(eos)。训练和演出必须用同一套幕布暗号。
实例或案例
「模型停不下来」案例:自建数据训练后回答结尾无限重复。排查发现训练脚本用自定义模板,assistant 段末尾忘了拼接 eos,模型从没学过「结束」这个动作。补上 eos 并确认其进入 label 后重训,问题消失。第二个案例:推理时用错另一家族的模板,输出质量骤降且夹带标记残留,换回官方模板即恢复。
操作步骤
- 确认所用模型的官方模板(读
tokenizer.chat_template的 jinja 源码)。 - 构造消息列表
messages=[{role, content}, ...],用tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True/False)渲染——训练时 False(要补 eos),推理时 True。 - 训练框架里确认两点:assistant 段外 label 为 -100;eos 在 label 中。
- 抽一条样本 decode 打印,肉眼核对字符串与标记。
- 上线服务用同一模板渲染(vLLM/OpenAI 兼容层默认读模型自带模板,见 kp-029)。
排错清单
- 无限生成不停:eos 未进 label 或训练数据末尾缺 eos。
- 输出夹杂模板标记:推理模板与训练模板不一致。
- 多轮对话记不住上文:拼接时历史轮次被截断或 system 重复插入。
- 新增领域 token 后效果差:新 token 的 embedding 未训练或样本量不足以学到它,尽量复用已有 token。
- 首个 token 表现异常:漏掉 BOS(
<|begin_of_text|>等)。
常见误区
- 所有模型模板通用:标记体系是各家私有的,混用必然出错。
- 对全序列计算 loss:不 mask 用户侧文本,模型分心学习生成指令,回答质量下降。
- eos 只是「一个普通词」:它是控制信号,必须作为 token 注册并出现在训练 label 末尾。
与其他知识点的关系
训练数据如何装进模板见 kp-010 与 kp-021;模板错误引发的线上症状见 kp-030;服务端模板一致性见 kp-029。
延伸阅读
本节不适用:模板是各家模型的工程约定,权威依据是所用模型的官方文档与 tokenizer 配置。
自测题
- 训练后模型无限续写,最可能的原因?
答:assistant 回答末尾的 eos 没有拼接或未纳入 loss label,模型从未学会停止。
- loss masking 的作用是什么?
答:只在 assistant 回答段(含 eos)计算损失,避免模型浪费容量学习生成指令与上文。
- 推理时 add_generation_prompt 的作用?
答:在渲染结果末尾保留 assistant 角色的起始标记,引导模型以助手身份续写而非继续用户发言。