专栏算法工具链【J6】地平线J6 QAT + 板端推理全流程实操

【J6】地平线J6 QAT + 板端推理全流程实操

no_name2026-05-27
92
0

本文基于开源内容进行学习整理,如有错漏,欢迎评论交流~

背景

J6M 开发板要求量化感知训练与板端推理采用同一模型,流程连贯。本文基于 plugin_basic/run_pipeline/fx_mode.py 示例完成 QAT 量化编译,再使用 ucp_tutorial/dnn/basic_samples/code/00_quick_start/resnet_rgb/src/main.cc 示例进行板端 C++ 推理,整体流程为:

针对 J6M 开发板,需对原始示例代码做以下修改。


1. QAT 量化与编译:代码修改

1.1 目标架构设为 NASH-M

get_model_fx 函数的 march 参数改为 March.NASH_M:
common.py 中 compile 函数的 march 参数指定为 "nash-m":

1.2 量化精度配置改为 qint8

QconfigSetter 的 templates 中,将 ModuleNameTemplate({"": torch.float16}) 改为 ModuleNameTemplate({"": qint8}):

1.3 插入前处理节点

hbir 导出后、convert 之前,插入 transpose 和图像前处理节点:

节点

作用

insert_transpose(permutes=[0, 3, 1, 2])

插入 transpose 节点,将输入从 NCHW 转换为 NHWC

insert_image_preprocess()

插入图像前处理节点,并做 mean/std 归一化,适配 RGB 输入


2. QAT 量化与编译:执行命令

按顺序依次执行:

完成后在 model_path 目录下生成 model.hbm,用于下一步板端推理。

3. 板端 C++ 推理

使用 resnet_rgb/src/main.cc 示例代码加载上一步生成的 model.hbm 进行板端推理。

3.1 代码修改

模型输出类别数为 10(CIFAR-10),需将 get_topk_result 中的 tensor_len 从 1000 改为 10:

其余代码不做修改。

3.2 编译

运行 build_x86.sh 编译推理程序:

3.3 运行推理

到 runtime/script_x86/00_quick_start/ 目录下,修改 run_resnet_rgb.sh,将 --model_file 指向 QAT 编译产出的 HBM,--image_file 指向准备的dog.jpg:

执行:

输出结果:

TOP 0 结果 id 为 5,对应 CIFAR-10 中的 dog 类别,推理正确。

3.4 CIFAR-10 类别索引

索引

类别

0

airplane

1

automobile

2

bird

3

cat

4

deer

5

dog

6

frog

7

horse

8

ship

9

truck


3.5. 为什么 HBM 输入 shape 变了、图像尺寸变了,但推理代码不需改动

与原始 resnet50 示例相比,本流程中 HBM 的输入 shape 变了(CIFAR-10 的 32x32 vs resnet50 的 224x224),dog.jpg 的尺寸也与 resnet50 期望的输入不同。但推理代码只改了 tensor_len,其余无需改动,原因如下:
推理代码所有与 shape 相关的操作都是从 HBM 模型属性中动态读取的,而非硬编码

代码位置

动态读取的属性

作用

prepare_tensor

properties.alignedByteSize

根据 HBM 模型属性分配输入输出内存大小

read_image_2_tensor_as_rgb

properties.validShape.dimensionSize[1] / [2]

动态获取模型要求的 H 和 W,将任意尺寸的输入图像 resize 到该大小

add_padding

properties.validShape + properties.stride

根据 HBM 的 valid shape 和 stride 做内存对齐填充

因此,无论 HBM 的输入 shape 是 1x32x32x3 还是 1x224x224x3,推理代码都能自动适配。唯一需要手动修改的是输出类别数 tensor_len,因为它取决于模型训练时的分类数(CIFAR-10 为 10)。
算法工具链
杂谈社区征文
评论0
0/600