【玩转 J6 算法工具链:模型量化实战篇】PIDNet 量化篇
整个流程如下:
本文主要关注模型转换和性能验证流程,不展开语义分割精度评测及后处理实现。
一、模型准备与 ONNX 导出
1.1 拉取源码
首先拉取 PIDNet 官方源码:
工程主要目录如下:
为了保证后续实验可复现,也可以记录当前源码版本:
1.2 下载模型权重
本文使用:
即 PIDNet-S 在 Cityscapes 验证集上的模型。
官方 README 当前说明,原有部分 Google Drive 单文件链接已经失效,建议从 README 中提供的统一权重目录下载模型。官方评测 PIDNet-S 时使用的文件名同样是:
下载后将模型放到:
后者只是 ImageNet 预训练权重。
1.3 构建推理模型
PIDNet 训练阶段默认会输出多个结果,包括主分割结果以及辅助分支输出。
而真正部署时,我们只需要最终的主分割输出。
因此,在导出 ONNX 时同样采用这一方式。
本文最终 ONNX 的输入固定为:
输入数据格式:
执行:
正常情况下输入为:
模型主输出为:
PIDNet 原始推理流程就是先得到低分辨率的 segmentation logits,再在模型外通过 bilinear interpolation 将输出恢复到原图尺寸,最后执行 ArgMax 获得类别结果。
因此本文没有将:
的 Resize 和 ArgMax 放进 ONNX,而是保留原始网络主干输出:
这样也可以避免将不必要的后处理计算加入 HBM 性能统计。
1.4 验证 ONNX
导出以后不要急着进入 PTQ,先使用 ONNX Runtime 确认模型能够正常执行:
预期结果类似:
到这里,浮点 ONNX 模型准备完成。
二、准备 Calibration 数据
PTQ 量化需要使用一批 Calibration 数据统计模型各层 Activation 的数据分布,并由此确定量化参数。
本文采用:
2.1 PIDNet 输入预处理
PIDNet 官方图片推理使用的 Normalize 参数为:
完整处理过程为:
这里和常规 RGB 输入配置最大的区别在于:
featuremap 校准数据已经是模型真正需要的 Tensor,因此不能只保存 0~255 的 RGB 图片数据。
2.2 Calibration 数据生成
下面给出一个核心版本的校准集生成脚本:
执行:
生成:
可以随机检查一个:
需要注意:
Normalize 之后 Tensor 出现负数是正常现象。
例如黑色像素经过 Normalize 后大约为:
一个很重要的原则
Calibration 数据的前处理应该和 ONNX 浮点模型实际推理使用的前处理保持一致。
也就是说:
如果两边 preprocessing 不一致,那么工具链统计得到的 Activation 分布本身就是错误的,后续再怎么调 Calibration 方法都没有意义。
三、配置 YAML 并进行 PTQ 编译
本文使用如下配置:
下面分别看一下几个关键配置。
3.1 模型配置
其中:
地平线工具链中:
最终模型会生成到:
最终 HBM 名称为:
3.2 输入配置
本文最重要的一部分是:
因为 Calibration 数据已经完成:
所以工具链不再负责输入预处理。
模型实际接收到的数据就是:
因此,这里有一个非常重要的对应关系:
千万不要出现:
否则相当于对输入做了两遍归一化。
3.3 Calibration 配置
本文采用:
校准数据目录。
官方工具链要求该目录中的校准数据与模型输入配置保持一致。
本文采用:
并设置:
其核心思想是:
不直接使用绝对最大值作为量化范围,而是通过 percentile 排除极少量异常值对量化范围的影响。
不同 OpenExplorer 版本对 Calibration 参数的 YAML 组织方式可能存在差异,本文使用的是当前实验环境中的配置方式,实际使用时建议同时参考对应版本的 OpenExplorer 文档。
3.4 编译配置
这里:
表示以降低单帧推理延迟为主要编译目标。
表示模型使用单个 BPU Core。
本文主要关注模型本身的单帧 latency,因此采用:
作为测试条件。
四、模型量化与编译
YAML 配置完成以后,就可以正式进行模型转换。
假设配置文件名称为:
执行:
也可以简写:
这是地平线 PTQ 工具链标准的模型转换方式。
整个过程并不是简单地:
而是会经历多个阶段:
官方文档中对应的主要产物包括:
本文编译完成后可以在:
看到类似:
如果最终:
正常生成,则说明整个 PTQ 量化和编译流程已经完成。
但这里需要明确:
HBM 能生成,只代表模型完成了转换,并不代表精度和性能一定满足要求。
后续仍然应该分别进行:
本文先继续进行板端性能测试。
五、J6 板端性能测试
模型最终部署性能建议直接在真实 J6 开发板上进行测试。
地平线提供:
工具,可以直接查看 HBM 信息、执行推理以及进行性能测试。官方工具定位也是直接在开发板上评估模型实际推理性能。
首先将:
拷贝到 J6 板端。
5.1 查看模型信息
可以先执行:
用于确认:
模型名称
输入节点
输入 Shape
输入数据类型
输出节点
输出 Shape
对于本文模型,重点确认:
模型信息确认正常后再进行性能测试。
5.2 测试模型 Latency
执行:
其中:
表示固定使用 Core 0。
表示单线程串行推理。
表示执行 200 帧模型推理。
在评估模型单帧 Latency 时,建议采用:
最小 latency
最大 latency
平均 latency
FPS
总推理时间
等性能信息。
5.3 查看详细 Profile
如果模型性能没有达到预期,还可以进一步增加:
例如:
工具运行完成以后会生成相应的 profiler 数据,可以继续分析:
BPU 子图执行时间
调度开销
算子执行情况
因此,如果最后模型整体 latency 偏高,不建议立即去改网络。
可以先明确:
再决定是否需要:
调整模型结构
调整量化精度
修改编译配置
优化特殊算子
减少高精度节点
重新设计部分网络结构
六、总结
至此,一个完整的 PIDNet-S J6 PTQ 部署流程就已经跑通:
整个过程中,我认为最值得注意的是三个地方。
参考资料
本文部分内容参考:
PIDNet 官方开源工程及 README。
地平线 OpenExplorer 算法工具链官方文档。