专栏算法工具链J6算法工具链FAQ手册-v1.0

J6算法工具链FAQ手册-v1.0

芯链情报局2025-12-10
226
0

1.后量化转换(PTQ)

暂无

 

 

2. 量化感知训练(QAT)

2.1 模型尾部conv+relu结构未正确开启高精度输出

对于模型尾部的 conv+relu 结构,若发现未能按配置正确开启 int32 高精度输出,可优先检查是否存在共享算子。若 relu 是共享,则不会和其上游的 conv 发生 fuse 融合行为,relu 会单独出现,此时 conv 就不会开启高精度。

2.2 如何定位scale为nan的代码位置

可以借助如下接口定位 scale 为 nan 的代码位置:

其中,check_nan_scale 支持配置为 "forward"、"save"、"ignore" 三种:
  • "forward":会在第一次出现 nan 的位置报错:
  • "save":默认值,会在 torch.save 时做检查:
  • "ignore":即不做检查。

2.3 如何关闭POT scale

J6B/P/H 相比于 J6E/M,新增了不同程度的浮点计算能力,所以当前默认的 scale 策略为 POT(Power of Two,即2的幂次),此时 BPU 硬件能直接支持 fp16int16 的量化/反量化节点。

但若模型未使用 fp16 精度,或基于 POT scale 发现量化精度调不上去,可尝试关闭 POT,即使用浮点 scale。

  • 整体关闭:

  • 针对个别算子关闭:

2.4 Plugin旧模板配置Gemm类算子双int16

J6 工具链自 v3.2.0 版本起支持 Gemm 类算子双 int16 量化,在旧 setter 模版上使用方式如下:

  • qconfig 配上双 int16

  • hbdk4_compiler 版本 ≥ v4.3.3

  • Conv2d/Linear 无需额外配置;Matmul 在 prepare 前需配置回退逻辑为 v2 版本

注意:Gemm 类算子输入双 int16 和 int32 高精度 输出无法同时生效!

 

 

3. 模型部署

3.1 工具链与底软版本的兼容性

工具链在每轮大版本发布之前,都会在最新的底软版本上进行全量测试验证,因此我们优先建议使用对应的底软版本。在 OE-v3.2.0 版本及之后,理论上工具链和底软会尽量保持版本兼容,但由于工具链的模型推理与底软之间存在 firmware 共库开发的情况,因此有一定的耦合性。如果升级工具链(特别是UCP)后发生板上模型推理不兼容问题,可以尝试替换最新底软中的相关文件,主要涉及到的模块有:

模块

参考替换目录

Firmware

/usr/lib/firmware/*.bin

libbpu.so (BPU驱动)

/usr/lib/aarch64-linux-gnu/libbpu.so.2.0.X (请注意此目录下的软连接)

BPU ARM 侧驱动 ko 文件

/usr/lib/modules/6.1.94-rt33/hobot-drivers/bpu/

libhbmem 库

/usr/hobot/lib/libhbmem.so.1 (请注意此目录下的软连接)

UCP 推理库系列 so

 

以上模块替换后,请重启硬件,为了保证替换再重启后生效,可将 cp 命令写在 /app/init.sh 启动脚本中。

3.2 查看bpu firmware版本号

bpu0 对于 J6 多核计算平台支持修改为不同的 BPU 核。

3.3 UCP侧如何降低CPU负载

  1. 关闭不需要的UCP调度线程

UCP 作为统一异构调度框架,会默认开启一些后端的调度线程(部分线程说明如下)。如果这些后端在业务中没有使用,那么可以使用环境变量减少或关闭对应的后端线程,配置到 0 为彻底关闭,用户手册请见:这里
  • BPU-LB-Schedule:该线程主要负责 BPU 负载均衡,对于 J6EMB 等单 BPU 芯片,还会复用这个线程去做 BPU 任务的生成和下发,所以其负载主要和 BPU 调用次数有关,即主要和对应时间内提交和完成的 BPU 任务的数量正相关
  • CPU-OP-Process:该线程用于处理模型中的 CPU 算子
  • DSP-Recv:该线程用于等待 DSP 任务处理完成并返回信息
  • Sync-Scheduler:该线程负责 DSP/GDC/PYM 后端的调度
  • Codec-Scheduler:该线程负责图像/视频编解码后端的调度
  1. 小模型复用 task handle

对于推理速度较快的小模型,可尝试复用 task handle,即一起下发一起返回,这样也可以减少 CPU 负载,用户手册请见:这里
  1. 尝试使用内存LRU缓存

用户手册请见:这里。但 LRU 功能使用也需要关注其限制:
  • 对于模型的输入输出不是实时申请和释放的,会在一开始就申请好并进行循环复用。所以如果在模型推理结束后就立刻执行内存释放操作,实际不会立刻释放,UCP 会等一段时间(默认至少1s)后才执行,所以可能会有内存泄漏的风险,建议是模型推理的内存块不要释放,且模型每次输入输出的虚拟地址是复用的;

  • 单进程内 hbmem 的虚拟地址是不变的,可以直接复用,没有影响;跨进程场景暂不适用。

3.4 包含CPU算子模型的一致性未对齐

对于包含 CPU 算子的模型,其 quantized.bc 和 hbm 的推理结果确实无法保障 bit 一致,因为不同架构的浮点计算本身即会存在计算误差。例如相同的浮点计算,在 x86 和 aarch64 平台分别计算就可能存在微小误差,但该误差通常对模型精度指标无影响,可忽略。

若 quantized.bc 和 hbm 均在 x86 平台推理也存在一致性误差,那么请提供相关模型文件给地平线进行进一步分析。

3.5 x86推理hbm报错Model march incompatible!

该报错是因为当前 X86 平台默认的 march 架构为 nash-e,使用 hrt_model_exec 推理其他架构编译的 hbm 时,就可能触发如下报错:
可通过 HB_UCP_SIM_PLATFORM_TYPE 环境变量修改成对应的 march,用户手册请见:这里

3.6 如何修改hbm文件中的model name

3.7 基于输入/输出名称移除节点

J6 工具链支持在 quantized.bc 上使用 remove_io_op 接口移除模型首尾部的部分算子,用户手册可见:这里

其中:

  • 可移除算子类型包括:["Dequantize", "Quantize", "Transpose", "Cast", "Reshape", "Softmax"]

  • op_types:支持指定以上的算子类型进行模型首尾部的统一遍历和移除;

  • op_names:也支持指定算子名称进行移除,主要用于 PTQ 链路生成的模型,QAT 链路由于当前算子名称过长,所以实际并不实用。

以下脚本可用于指定模型的输入/输出节点名称,并移除其链接的第一个节点,可以更精准地进行模型修改。脚本使用根据模型 export 导出时配置的 native_pytree 不同而略有差异:
  • native_pytree=True(默认值):
  • native_pytree=False

 

 

4. 参考算法

暂无

 

 

5. DSP

5.1 自定义DSP算子后发现UCP VP接口未注册

在自定义新的 DSP 算子后,需重新编译 DSP 镜像,若使用时调用 UCP 已实现的 VP 算子返回未注册错误,请优先从以下两处进行排查:

  1. 是否调用 HB_DSP_REGISTER_CV_ALL 宏注册官方已实现的 VP 算子,该宏定义位于 samples/ucp_tutorial/deps_xxx/ucp/plugin/dsp_plugin/hobot/include/cv/core.h
  1. 确保 CMake 中是否链接了算子库

5.2 DSP代码unmap、writeback接口的调用顺序是否有影响

在当前 OE 包提供的 DSP 基础示例代码中,可以看见对于算子的输出内存,既会调用 cadence 的 dsp 接口 xthal_dcache_region_writeback 进行缓存刷新,还会调用 ucp 接口 hb_dsp_mem_unmap 进行地址解映射。不过这两个接口因为使用场景不一样,所以其调用顺序并不会对代码行为产生影响:
  • 板端运行时:需要调用 ucp 的 map 接口和 xthal 的 invalid 和 writeback 接口,无需调用 ucp 的 unmap 接口;
  • 仿真运行时:因为使用的都是 Acore 内存,无需做不同核间的 ddr 同步,所以仅需使用 ucp 的 map/unmap 接口,无需调用 xthal 的 invalid 和 writeback 接口。
算法工具链
社区征文征程6官方教程
评论0
0/1000