模型交付后为什么表现变了:模板、量化与行为回归

成长演进

具备清晰骨架、初步数学推导或工程验证,持续补充论据与实测。

ℹ数字花园

🌿 什么是数字花园与思想演进?

遵循 Maggie Appleton 与 Andy Matuschak 的常青笔记理念:这里不是按时间沉底的流水账,而是持续修剪打磨的知识生态。文章按成熟度经历:

  • 🌱 萌芽 (Seedling): 发散灵感、读书摘录、开放猜想
  • 🌿 演进 (Budding): 结构渐明、初步代码推导、积极修正
  • 🌳 常青 (Evergreen): 逻辑闭环、持久经得起检验的基石
  • 🔬 实验待证 (Speculative): 结合沙盒与仿真探针的理论探索
浏览全站数字花园与笔记全景 →

训练结束后,验证脚本里的模型能够正确调用库存查询工具。换成推理服务,却开始输出普通文字,偶尔还会给出半截 JSON。权重文件明明相同,为什么表现不一样?

先不要急着重新训练。用户消息需要经过模板变成 token,模型输出还要经过采样、停止判断和解析,才成为用户看到的回答。交付改变了其中任何一步,都可能改变结果。

本文沿用库存查询这个任务:用户要 3 件 A17 商品,先查杭州,不足再查深圳,查询不等于预订。实际执行的检查只有自定义 token 协议、十进制舍入和回归计数,没有加载语言模型,没有进行真实量化或服务性能测试。下面的交付流程是待应用到真实模型的实验设计。

先确定要保持哪一种行为#

行为回归是拿新版本重新做旧版本已经能做的事,检查是否出现退步。这里的“版本”不只指权重,也包括服务配置。

对于库存任务,至少有三种不同要求:调用内容能否解析、参数是否正确、整个任务是否完成。输出是合法 JSON,不代表商品编号正确;编号正确,也不代表模型遵守了先杭州后深圳的顺序。

因此,交付目标不应该只写“回答和训练时一样”。训练时通常在已有答案前缀上预测下一个 token,部署时则使用自己刚生成的内容继续回答,两者运行方式本来就不同。更合理的目标是:在固定任务、输入协议和预算下,保持已验证的能力与约束。

把原始验证环境保留为参考实现,把待交付版本称为候选实现。后续每次只改变一个环节,才能解释差异来自哪里。

从用户消息一直检查到 token#

同一份 messages,在不同模板下不一定是相同输入。角色标记、消息结束标记、工具定义位置,都会进入模型看到的序列。

下面是自定义教学协议,不对应任何真实模型的词表:

BOS=1, USER=2, END=3, ASSISTANT=4
“查询 A17 库存”这个完整占位内容=10
参考输入:[1, 2, 10, 3, 4]
重复起始:[1, 1, 2, 10, 3, 4]
缺少角色:[1, 2, 10, 3]

这三组数字的中文内容看起来一样,但模型接收的序列不同。教学检查只能发现序列变了,不能证明真实模型会因此下降多少分。

Transformers 的模板文档提醒:模板通常已经包含所需特殊 token;先渲染为文本再分词时,应避免再次添加特殊 token。是否需要生成用的 assistant 前缀,也由具体模型模板决定。Transformers 4.57.1 对话模板

真实交付时,选几条可以公开保存的固定请求,同时记录原始消息、渲染文本、token ID、attention mask 和截断位置。文本一致而 token 不一致,应先检查分词器与特殊 token 配置;token 一致而输出不同,才继续向模型计算与生成过程排查。

输入一致性还包括服务有没有偷偷加入系统提示、有没有把工具说明改写成另一种格式,以及长请求超出限制时删掉了哪一段。接口字段名相同,不等于这些行为相同。

批量推理也要单独检查:一条请求独立运行,与混在不同长度请求里运行,是否仍正确处理填充、位置和掩码。不要凭经验强行统一所有模型的填充方向,应核对实际后端要求和最终张量。

权重交付要说明基座、适配器与转换关系#

如果训练的是 LoRA,交付目录里可能只有适配器,并没有完整基座。PEFT 文档说明,适配器检查点需要配合原始模型与适配器配置加载。PEFT 0.17.0 检查点格式

因此要保存基座版本、适配器版本、目标模块与缩放配置。只写一个可能继续更新的模型名称,不足以锁定当时的计算。分词器或词表如果也改过,同样需要与模型配套;新增 token 的编号和相关参数不能丢失。

对标准加性 LoRA,理想实数运算下,可以把基座与增量写成:

W′=W+ΔW.W'=W+\Delta W.

但“分开计算再相加”和“先合并再计算”在有限精度下未必逐位一致。某些适配器方法或量化组合也不支持相同的合并方式,不能把这条式子当作任意格式转换都安全的保证。

保留未经转换的参考版本。依次比较“基座加适配器”“合并后”“量化后”,每次都记录转换工具、版本和配置。否则最终结果变差时,很难判断是哪一次转换造成的。

量化误差小,不代表任务一定不变#

量化可以理解为:用更有限的一组数表示原来的数。它能减少某些存储需求,但实际速度还取决于硬件、算子与任务形状,不能仅凭位数宣布加速。

为了看清转换顺序,定义一个非常简单的函数 Q:四舍五入到最近的 0.1,遇到正数正中间时向上取。取权重 w=0.14,增量 d=0.04:

Q(w+d)=0.2,Q(w)+d=0.14,Q(Q(w)+d)=0.1.\begin{aligned} Q(w+d)&=0.2,\\ Q(w)+d&=0.14,\\ Q\bigl(Q(w)+d\bigr)&=0.1. \end{aligned}

这是实际复算过的十进制反例:先合并再量化,与先量化再合并、再次量化,可以得到不同结果。它不是 NF4、GPTQ 或某种实际量化器的模拟,也不说明哪条路径在真实任务上更好。

还要区分数值偏差和决策变化。假设两个候选 token 的原始分数是 1.001 和 1.000,变换后变成 0.999 和 1.000;每个分数变化都很小,但贪心选择已经翻转。接下来的生成以这个不同 token 为条件,整段文字可能进一步分开。

所以量化验收至少看两层:固定输入下的数值差异,以及实际任务上的变化。平均误差可以帮助定位问题,却不能替代 JSON 完整率、工具参数正确率或任务成功率。也不能从一个教学反例推断所有量化模型都会严重退化。

把生成与停止规则当作交付配置#

生成策略决定模型怎样从分数中选下一个 token。贪心选择与随机采样不是同一项测试;官方文档分别描述了这两种机制。Transformers 4.57.1 生成策略

比较参考版本和候选版本时,要显式记录实际生效的采样开关、温度、候选截断设置、最大新增 token 数、停止 token 或停止字符串。不同服务同名参数的默认值与实现语义可能不同,应检查最终配置,而不只保存客户端传过去的字段。

即使使用贪心生成,也不意味着跨设备、跨实现必然逐字一致;数值差异可能改变接近的候选排名。上一文的复现边界同样适用。

对于半截 JSON,先检查停止原因:是模型主动输出结束标记,还是达到长度上限、超时、服务取消,或解析器误截断?这些原因不应都记成模型“不懂格式”。

自定义协议可以把完整回答表示成三个 token:JSON_START, JSON_BODY, JSON_END。如果最大新增数只有 2,输出一定不完整;如果错误地把 JSON_BODY 配成停止 token,也会提前结束。本文脚本实际检查了这两种情况,但没有模拟模型生成概率。

不要为了提高解析率而静默修复答案,再把修复后的成绩算给原始模型。若服务确实使用补全括号、重试或二次解析,应把它们作为系统的一部分,同时报告原始失败率、修复后的成功率和额外成本。

分层回归,比只对比最终字符串更容易定位#

推荐按下面顺序比较,每层失败时先停在该层排查:

层次固定什么检查什么
输入协议原始消息、工具定义渲染文本、ID、掩码、截断
模型前向相同输入张量指定位置分数、候选排名、数值容差
生成过程输入与解码规则输出 token、停止原因、长度
结果解析同一段原始输出格式、字段、类型、错误处理
完整任务相同初始环境与预算正确性、约束、调用次数与耗时

前向比较最好使用相同的固定前缀。若两个版本已经生成了不同内容,再比较后面位置的分数,会把输入变化和计算变化混在一起。

逐字匹配适合固定格式的回归样例,但不是全部质量标准。例如两个自然语言答案措辞不同,却都明确说明“深圳有货,但尚未预订”,可以都算完成任务。相反,两段文字看起来很像,也可能在 reserved 字段上有关键区别。

做一张能看见退步的配对表#

假设有 100 个独立任务,下面是人为构造、已复算的计数,不是模型实测:

参考版本候选版本任务数
成功成功70
失败成功5
成功失败5
失败失败20

两个版本都是 75% 成功,但候选版本丢掉了原来能完成的 5 个任务。只看总分,会错过这 5 个退步。它们可能集中在工具调用、长输入或某个语言子集,不能只用另外 5 个修复抵消后就宣布等价。

真实验收前,明确哪些错误不可接受、哪些指标允许多大变化,以及用多少任务和重复采样来估计不确定性。阈值应由使用要求决定,不在看到结果后临时放宽。小样本没有发现退步,也不是已经证明两个系统等价。

对采样输出,不要只比较一个随机种子。保留同一组任务、多次运行和配对统计;对于工具任务,沿用环境重置与轨迹重放中的隔离方法,否则任务差异可能来自环境而非模型。

一次最小交付实验应该留下什么#

先用少量固定样例排除协议错误,再在预先保留的任务集上比较参考与候选。依次加入合并、量化、服务批处理等变化,记录每一步的输入与输出,不把所有优化一次打开。

最终交付包至少能回答五个问题:权重从哪个不可变版本来;用哪份分词器和模板;服务实际采用什么计算与生成配置;在哪份回归集上接受了哪些差异;发现问题时怎样恢复到参考版本。

可以用文件哈希识别内容,用配置和工具版本解释生成过程,用逐任务结果支持验收结论。哈希只能帮助确认文件身份,不能证明模型正确;一份通过的回归报告也只支持它实际覆盖的条件。

这一步的研究结论应当具体到:“在这份任务集、这个预算和这些约束下,该交付版本满足预设标准。”保留失败样例和未覆盖条件,下一次换后端、改模板或压缩权重时,才有可靠的比较起点。

文章概念网络

从章节进入正文概念。实线表示所属层级,虚线连接跨章节重复出现的概念,不代表因果关系。

55 / 55 个节点 · 正文标记术语与关键词概念

模型交付后为什么表现变了:模板、量化与行为回归同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept模型交付后为什么表现变了:模板、量化与行为回归模型交付后为什么表现变了:模板、量化与行为回归先确定要保持哪一种行为先确定要保持哪一种行为行为回归行为回归参考实现参考实现候选实现候选实现从用户消息一直检查到 token从用户消息一直检查到 tokenTransformers 4.57.1 对话模板Transformers 4.57.1 对话模板输入一致性输入一致性权重交付要说明基座、适配器与转换关系权重交付要说明基座、适配器与转换关系PEFT 0.17.0 检查点格式PEFT 0.17.0 检查点格式基座版本基座版本量化误差小,不代表任务一定不变量化误差小,不代表任务一定不变量化量化数值偏差数值偏差决策变化决策变化把生成与停止规则当作交付配置把生成与停止规则当作交付配置生成策略生成策略Transformers 4.57.1 生成策略Transformers 4.57.1 生成策略上一文的复现边界上一文的复现边界停止原因停止原因JSONSTART, JSONBODY, JSONENDJSONSTART, JSONBODY, JSONENDJSONBODYJSONBODY分层回归,比只对比最终字符串更容易定位分层回归,比只对比最终字符串更容易定位reservedreserved做一张能看见退步的配对表做一张能看见退步的配对表环境重置与轨迹重放环境重置与轨迹重放一次最小交付实验应该留下什么一次最小交付实验应该留下什么tokentoken采样采样推理推理实验实验tokentoken环境环境tokentoken分词分词AttentionAttention推理推理LoRALoRAtokentoken分词分词tokentoken选择选择tokentoken采样采样策略策略语义语义选择选择tokentoken环境环境采样采样环境环境工具调用工具调用实验实验分词分词优化优化
模型交付后为什么表现变了:模板、量化与行为回归

模型交付后为什么表现变了:模板、量化与行为回归

回到原文 ↗
BIBTEX

引用本文

@article{2026-10-23-llm-training-eval-05-delivery,
  author  = {枫语},
  title   = {模型交付后为什么表现变了:模板、量化与行为回归},
  journal = {枫语},
  year    = {2026},
  month   = {oct},
  url     = {https://meiluosi.github.io/posts/2026-10-23-llm-training-eval-05-delivery/}
}
🌐

本篇知识星丛与滑动侧栈

模型交付后为什么表现变了:模板、量化与行为回归 当前主轴

搜索

正在载入索引…