训练与推理
把可学习状态冻结为可移植、可验证的模型产物
建议阅读:约 20 分钟
学习目标
本章关键词
| 关键词 | 解释 | ESP32 工程类比 |
|---|---|---|
| eval 模式 | 让 Dropout、BatchNorm 使用推理语义的模式。 | 像从调试配置切换到量产配置。 |
| 优化器 | 依据梯度更新参数的算法及其状态。 | 像自动调参器;部署后不应留在固件里。 |
| 计算图 | 以节点和边描述张量如何经过算子得到输出。 | 像固件的数据流图或任务依赖图。 |
| ONNX opset | 模型声明的算子语义版本。 | 像通信协议版本;收发两端必须兼容。 |
承上:回顾与定位
上一章解释了张量、梯度和一次权重更新;本章追踪这些训练状态如何被冻结、转换并交付给不执行反向传播的设备 runtime。
历史发展脉络
模型交付链由训练算法、运行模式、图表示与互操作标准共同形成。它把“一个实验能复现”推进为“一个产物能在另一套 runtime 上保持语义”。
感知机学习规则形成最小训练循环
感知机依据预测错误修改连接权重,把样本、预测、误差、更新连接成闭环。虽然模型简单,它已经区分了“正在被样本改变的参数”和“使用当前参数给出判断”这两个时刻。
Rosenblatt 感知机原始论文 ↗Dropout 明确展示同一模块的两套运行语义
Dropout 在训练时随机丢弃单元,以降低共适应;测试时则使用完整网络的确定性近似。它使工程师必须显式切换模式,否则同一输入会因训练期随机行为而得到不稳定输出。
Dropout 原始论文 ↗轻量 runtime 把设备端职责收束为低延迟前向执行
TensorFlow Lite 的开发者预览面向移动和嵌入式设备,强调轻量、快速初始化与硬件加速。模型从训练框架转换为受限部署格式,训练状态、调试便利性与设备运行约束开始由工具链明确分工。
TensorFlow Lite 官方发布说明 ↗Caffe 用声明式网络与权重文件推动模型复用
Caffe 将网络结构、训练配置与学习到的参数组织为可交换产物,并以层为扩展单元。它展示了模型可以脱离单个研究脚本被分享和部署,也暴露了框架专属层与格式绑定的问题。
Caffe 原始论文 ↗ONNX v1 将互操作写成公开的图与算子契约
ONNX v1 面向多个框架发布生产就绪版本,以开放图格式和算子集推动模型转移。导出器、转换器和 runtime 从此可以围绕共同 IR 协作,但每一方仍必须支持模型声明的域与 opset。
ONNX v1 官方发布说明 ↗GGUF 强化单文件、可扩展与快速加载
GGUF 作为 GGML 系执行器的模型格式,把张量与键值 metadata 放入可扩展的二进制容器,并取代早期 GGML、GGMF、GGJT 格式。它说明 LLM 部署不仅要保存权重,还要可靠携带架构和 tokenizer 等解释信息。
GGUF 官方规范 ↗类比图解
从风洞试飞到封装进无人机的飞控程序
训练像在风洞中反复试飞:工程师改变参数,注入扰动,记录每次偏航并调整控制律。推理像量产无人机起飞,机上只带定型的控制表、传感器接口和必要状态,不会把整座风洞、试验日志与调参团队一同装进去。导出则是把试验配置审定为可烧录版本。
类比的边界: 飞控通常由明确物理模型和安全论证构成,而神经网络是统计模型,不能因“已定型”就视为覆盖所有现场条件。类比也不代表导出后图永远不变:常量折叠、量化与后端分区仍会改变数值和资源行为。
本章讲解
训练循环同时推进参数状态与优化器状态
一次 step 不只是执行 forward 与减去梯度:Adam 等优化器还维护每个参数的历史统计,学习率调度器也有自己的步数。若只恢复权重却遗漏优化器和 epoch,续训轨迹会改变;而这些状态对纯推理毫无用途。工程上应把“可续训 checkpoint”和“可部署权重”作为两种产物命名、校验和归档。
模式切换必须逐模块验证,不能只相信一个布尔值
eval 会递归切换 Dropout、BatchNorm 等模块的行为,但自定义层可能仍读取 training 标志或随机数。BatchNorm 的 running mean/variance 还可能因小批次、数据漂移而失真。导出前应对同一输入连续运行多次确认输出确定,并逐项检查随机算子、统计 buffer 和 requires-grad 状态是否符合预期。
部署图是经变换后的新产物,不是 checkpoint 的复印件
导出器可能内联函数、删除反向节点、折叠常量,把 Conv 与 BatchNorm 的参数合并,或依据 example input 固化控制流。这样能降低调度和内存开销,却也可能只捕获示例走过的分支。若模型包含依赖数据的循环、动态 shape 或自定义算子,应明确导出策略,不能假设源程序的所有路径都被保存。
把格式拆成语法、语义与随附资产三层
schema 只回答字段如何编码,算子规范才回答节点应算什么,tokenizer、标签表或归一化参数则可能存在 metadata 或外部文件中。解析成功只证明语法有效;缺少算子语义会导致 runtime 拒绝,缺少资产则可能运行却解释错输出。交付清单应逐层列出校验方式,而不是只记录一个模型文件哈希。
IR、opset 与 runtime 版本是三把不同的锁
IR version 约束模型容器与图结构,opset 约束特定域中算子的签名和语义,runtime 版本决定实现覆盖。降 opset 不是改一个整数:若旧集合没有等价表达,转换器必须分解节点或直接失败。自定义 domain 还要求随部署提供实现。兼容表应记录三者组合及目标芯片,而非笼统写“支持 ONNX”。
转换器会重写表达,必须审计差异清单
转换可能把一个高层算子展开为子图、把常量计算提前、把 NCHW 换成 NHWC,或将权重存为不同 dtype。数学上等价的重写仍可能改变舍入、workspace 和 backend 分区。应在转换日志中保存新增、删除、替换的节点统计,并对关键中间张量建立名称映射,避免最终输出异常时只能盲猜。
建立模型 ABI 测试包,而不只保存模型本体
为每个模型版本附上输入名称、shape 范围、dtype、量纲、前后处理版本和数个 golden 样本;样本应包含正常值、边界 shape 与非法输入。CI 先做 schema/checker 校验,再由目标 runtime 加载并比较输出容差。若模型使用外部权重或 tokenizer 文件,还要校验相对路径与哈希,防止“主文件没变、配套资产已漂移”。
动态过程演示
模型穿越五道格式闸门
同一组测试数据伴随模型从训练框架走到目标 backend;每道闸门检查一种契约,任何红灯都会停在最接近根因的位置。
框架对象 · modules + parameters + control flow
展开实际执行过的模块与参数引用
源程序可以包含无法直接序列化的动态行为
循环 / 返回条件: 当 runtime、opset、转换器或配套资产升级时,从受影响的闸门重新播放;golden 输入始终随模型同行,形成可回归的格式护照。
查看静态全景图
data + labels → train state → checkpoint
│ eval/freeze/export
▼
input contract → graph + weights + metadata → runtime/backend代码或命令示例
model.eval()
export(model, example_input, opset_version=...)
assert_close(reference_output, runtime_output)
# 同时保存 tokenizer/labels/preprocess/version动手实验
实验记录与导出
工程陷阱
核心测试
完成 3 道单选题后提交;提交前不会显示答案。
在 GitHub 上讨论本章
登录 GitHub 后提问、补充实测或分享你的实现;评论会保存在本课程的 GitHub Discussions 中。
评论区需要 JavaScript;也可以直接打开 GitHub 讨论区: 打开 GitHub 讨论区 ↗
延伸阅读
启下:下一章如何使用本章能力
下一章研究量化:在明确模型 ABI 后,用校准与误差证据把浮点表示映射到低比特整数。
下一天: Day 3 · 模型量化