3. 模型部署流程
模型部署不是“把权重拷到板子上”这么简单。它是一条从训练产物到端侧推理结果的完整工程链路,中间要经过模型导出、格式转换、图优化、运行时选择与部署验证五个关键环节。任何一个环节的参数不匹配,都会导致推理结果错误、性能不达标甚至根本无法加载。理解这条链路,是嵌入式 AI 工程化的第一步。
一、完整链路总览
一条典型的端侧部署链路可以抽象为:训练检查点 → 推理图导出 → 中间格式转换 → 图优化与量化 → 运行时加载 → 部署验证。下图展示了各环节的输入输出关系与关键产物。
二、模型导出:从训练图到推理图
训练框架中的模型包含大量推理不需要的信息:优化器状态、梯度计算图、Dropout 与 BatchNorm 的训练分支等。导出的目标是把模型固化为静态计算图,并固定输入输出张量形状。
以 PyTorch 为例,常用两种导出方式:
# 方式一:TorchScript 追踪导出
model.eval()
example = torch.randn(1, 3, 224, 224)
traced = torch.jit.trace(model, example)
traced.save("model_ts.pt")
# 方式二:ONNX 导出(推荐跨框架转换)
torch.onnx.export(
model, example, "model.onnx",
input_names=["input"], output_names=["output"],
opset_version=13, dynamic_axes=None
)
三、格式转换与图优化
ONNX 是中间表示,真正部署到端侧还需要转换为目标运行时支持的格式。转换器在转换过程中会执行图优化,主要包括:
- 算子融合:将 Conv + BN + ReLU 合并为单个算子,减少内存访问与调度开销。
- 常量折叠:把编译期可确定的计算提前算完,减小图规模。
- 死代码消除:移除推理不需要的分支与节点。
- 布局转换:将 NCHW 转为 NHWC 以适配某些 NPU 的数据排布偏好。
- 量化插入:在图中插入 Quantize / Dequantize 节点,或直接生成全整型图。
不同目标平台的转换命令差异较大,以下为典型示例:
# TensorFlow Lite 转换(含 INT8 量化)
tflite_convert \
--saved_model_dir=./saved_model \
--output_file=model_int8.tflite \
--quantize_weights=INT8 \
--representative_dataset=rep_data
# RKNN 转换(瑞芯微 NPU)
rknn.config(mean_values=[[127.5]], std_values=[[127.5]], target_platform='rk3588')
rknn.load_onnx(model='model.onnx')
rknn.build(do_quantization=True, dataset='calib.txt')
rknn.export_rknn('model.rknn')
四、运行时选择与部署验证
运行时是真正执行推理的引擎,选择时需综合考虑硬件加速器支持、算子覆盖率、内存占用与调度开销。下表对比了常见运行时方案。
| 运行时 | 目标硬件 | 典型格式 | 优势 | 注意事项 |
|---|---|---|---|---|
| TensorFlow Lite | ARM CPU / GPU / EdgeTPU | .tflite | 生态成熟,量化工具链完整 | 部分自定义算子需手动注册 |
| ONNX Runtime | CPU / GPU / NPU | .onnx | 跨平台,Execution Provider 丰富 | 端侧包体较大,需裁剪 |
| TensorRT | NVIDIA GPU / Jetson | .engine | 极致延迟优化,FP16/INT8 支持好 | 绑定 NVIDIA 硬件,转换耗时 |
| RKNN | 瑞芯微 NPU | .rknn | 低功耗,INT8 性能突出 | 算子支持列表有限,需查文档 |
| NCNN / MNN | 移动端 ARM CPU | .param + .bin | 轻量无依赖,启动快 | GPU 加速支持因平台而异 |
部署验证是链路的最后一道关卡,也是最重要的一环。验证至少应覆盖四个维度:
- 数值一致性:用同一组输入分别跑训练框架与端侧运行时,比较输出最大绝对误差。FP32 通常要求误差小于 1e-4,INT8 量化后允许放宽到 1e-2 量级。
- 精度指标:在完整验证集上比较 Top-1 / mAP 等指标,确认量化后精度下降在可接受范围内。
- 性能指标:测量单帧延迟、吞吐量、首帧加载时间,确认满足实时性要求。
- 资源占用:记录峰值内存、模型文件大小、NPU 占用率,避免运行时 OOM。
五、案例复盘:一次典型的部署失败
某团队将 YOLOv5s 部署到 RK3588 平台,转换成功、模型能加载,但检测框全部偏移。排查过程如下:
- 检查输入预处理:训练时使用 letterbox 填充,部署时误用了直接 resize,导致坐标映射关系改变。
- 检查输出解码:模型导出时未包含后处理,端侧自行实现时 anchor 顺序与训练代码不一致。
- 检查量化校准:校准集仅用了 20 张纯色图,导致激活值分布估计严重偏差。
最终修正预处理逻辑、对齐 anchor 顺序并补充 500 张真实场景校准图后,精度恢复至 FP32 的 98.5%。这个案例说明:部署链路的每个环节都必须与训练侧严格对齐,任何“想当然”的假设都可能成为精度损失的根源。
掌握这条完整链路后,面对任何新的硬件平台或运行时,都可以按照“导出 → 转换 → 优化 → 选择运行时 → 验证”的框架逐步推进,把不可控的部署问题转化为可定位、可复现的工程步骤。