切换深色模式
自回归生成与推理基础
输入如何构造 → 回答如何生成 → 下一个 Token 如何选择 → 推理如何执行 → 长度、随机性与成本
一、从对话输入到生成回答:整体流程
一次语言模型调用,可以理解为:把本次需要的指令和对话内容转换成 Token 序列,再让模型根据这个序列逐步生成新的 Token,最后转换成文本。
1.1 输入:系统指令、多轮历史与当前用户消息
大模型的推理接口是无状态的(stateless):每次调用都是一次独立的计算,模型不会自动“记得”上一轮聊过什么。因此,多轮历史必须由调用方(应用程序或服务端会话机制)显式地拼进本次请求中。
模型接收的输入由三部分组成,首先,它们被拼接成一个完整的消息列表:
| 输入部分 | 作用 | 举例 |
|---|---|---|
| 系统指令(System Prompt) | 设定模型的角色、回答方式和总体要求 | 数学助教、用中文解释 |
| 多轮历史(Conversation History) | 之前所有轮次的对话,包括用户的提问和模型的回复 | 已经讨论过最大似然估计 |
| 当前用户消息(Current User Message) | 本轮用户最新说的话 | 比较最大似然估计与最大后验估计 |
python
messages = [
{"role": "system", "content": "你是一名数学助教,请用中文解释概念。"},
{"role": "user", "content": "什么是最大似然估计?"},
{"role": "assistant", "content": "最大似然估计是选择使观测数据出现的似然最大的参数……"},
{"role": "user", "content": "那它与最大后验估计有什么区别?"}
]对于通常的文本模型调用,模型不会自动读取此前所有聊天内容。 应用需要把相关历史放入本次上下文,或者由服务端的会话机制将其组织进去。
记:第
其中
1.2 一次回答的完整流程
第
第一步:使用 Chat Template 组织对话格式,如 1.1所示
第二步:使用 Tokenizer 转换为整数序列
分词器将格式化后的内容转换为 Token ID。记第
第三步:自回归生成 :从下一 Token 的概率分布 + 解码策略
整个生成过程在逻辑上表现为:
第四步:将生成的 Token 序列转换为回答文本
生成结束后,我们得到的是一串 Token ID:
分词器将它们解码为文本,并根据规则处理不需要展示的特殊标记:
1.3 进入下一轮对话
第
从执行顺序来看:
- 应用组织系统指令、历史消息和当前用户消息。
- 使用 Chat Template 和 Tokenizer 构造输入 Token 序列。
- 模型计算下一 Token 的分布。
- 解码策略选出一个 Token,将其追加到生成序列。
- 若未满足停止条件,则继续预测下一个 Token。
- 将生成的 Token 转换为文本,得到本轮助手回复。
回答结束后,应用将本轮的用户消息和助手回复加入历史:
其中
当下一轮用户消息
这样,**上一轮生成的输出,就成为了下一轮输入的一部分。**因此,改变一个回复会改变后续对话分布。
二. 对话如何进入模型:Chat Template 与多轮历史
上一节把本轮对话输入记为:
其中
这一节要进一步解释:这些带有角色和轮次的信息,如何被编码进一个连续的 Token 序列,以及模型如何知道应该从哪里开始回复。
2.1 消息列表与角色
system、user、assistant的作用。- 消息角色与消息正文的区别。
2.2 Chat Template:将结构化消息转换为序列
- 角色标记、消息边界与特殊 Token。
- 不同模型可能使用不同模板。
- 模板与模型训练格式保持一致的意义。
2.3 多轮历史的拼接
- 按时间顺序排列历史消息。
- 先前的 Assistant 回答如何成为新的输入。
- 当前用户消息与待生成回答的位置。
2.4 Assistant 生成前缀
- 如何提示模型开始生成 Assistant 回答。
add_generation_prompt的含义。- 开始一条新回复与续写已有回复的区别。
2.5 模型的“记忆”来自哪里
- 单次模型调用与应用保存的对话状态。
- 历史未进入输入时,模型通常无法直接访问它。
- 历史截断、摘要与选择性保留的基本概念。