2372640_zh-CN

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2372640_zh-CN

2372640_zh-CN

当空间内核 dim>= 16 时,i.MX 8M Plus VX 委托程序上的 Conv2D 会产生不正确的输出。

摘要

在 i.MX 8M Plus EVK 上,空间内核维度(H 或 W)为>= 16 的 Conv2D 操作在 VX 委托 (libvx_delegate.so) 下会产生不正确的输出。模型加载完毕,Conv2D 通过 vsi_nn_kernel_selector 绑定到 OPENVX 内核,error_during_init/prepare/invoke 均为 0,推理延迟正常,但在不同输入的每个位置,int8 输出都饱和为单一值(int8 = 127)。

沿任一空间轴,K=15 和 K=16 之间的边界都很明显。这与记录的跨度> 15 限制的阈值相符(https://community.nxp.com/t5/i-MX-Processors/Conv2D-not-working-with-stride-16-for-NPU-Kernel-crash...

两个问题

  1. 内核-dim ≥ 16 悬崖是否是一个已知限制,如果是,能否将其添加到《i.MX 机器学习用户指南》(UG10166)的 Conv2D 约束部分?

  2. 在图形编译时,vsi_nn_op_conv2d::op_check(或 VX 委托的分区逻辑)是否应该拒绝这种情况,以便操作返回 CPU?当前"accept, run, return constant int8=127, no diagnostic" 行为是不安全的--已部署的具有大型内核的模型似乎可以正常加载和运行。


环境

元器件价值

电路板i.MX 8M Plus EVK
BSP恩智浦 i.MX 发行版 6.18-whinlatter(version_id=6.18-whinLatter)
内核Linux 6.18.2-1.0.0-gf49f45233f7bSMP PREEMPT (aarch64)
libvx_delegate.so md52f88ec0871d18298bfa357ddaaea4d6d
libGAL.so md5af4806f617b23363b3be69c4dad2dc05
libOpenVX.so{,.1,.1.3.0}md592f85c32746d4d0b38800e21503d13d0 (三处相同)
imx-gpu-viv 软件包1:6.4.11.p4.4-aarch64-r0
tim-vx 软件包1.2.2-r0
OVxlib(运行时报告)OVXLIB_VERSION==1.2.14
TFLite 运行时TFLite 2.19.0 (/usr/bin/tensorflow-lite-2.19.0/examples/benchmark_model)

复制器

随附的 conv_1x17_broken.tflite(2,136 字节)是单 conv2D 神器:内核(1、17)、输入 1×1×1000×5 int8、输出 1×1×1000×8 int8、每通道 int8 权重量化、padding=Same、stride= (1,1)、无融合激活。

# On the i.MX 8M Plus board:
python3 reproduce.py conv_1x17_broken.tflite        # exits 1: BROKEN, saturated to int8=127
python3 reproduce.py conv_1x15_torch_control.tflite # exits 0: OK (K<16, same pipeline)

reproduce.py(附后,仅依赖于 tflite_runtime 和 numpy)通过普通解释器和 VX 委托解释器输入 6 个种子随机 int8 输入值,并报告平均值|Δ|、最大值|Δ|,以及来自 VX 路径的唯一 int8 输出值的计数。


内核大小扫描

INT8 PTQ 单例二维单元测试模型。在相同的 int8 输入字节上均值 VX 与板 CPU 的对比;uniq_VX = 6 个输入(总共 256 个)上的 int8 输出值是唯一的 int8 输出值。

核 (H, W) 平均值 |Δ| uniq_VX 结果

(1, 11)0.03256OK
(1, 15)0.02256OK
(1, 16)134.91破损(常量 int8=127)
(1, 17)136.91破损(常量 int8=127)
(1, 23)130.51破损(常量 int8=127)
(15, 1)0.11256OK
(17, 1)136.91破损(常量 int8=127)
(23, 1)129.31破损(常量 int8=127)
(3, 3), (5, 5), (7, 7)< 0.2256OK
(15,15)(区域 225)0.41256OK
(3, 23)123.41破损(常量 int8=127)
(5, 15)0.24256OK

阈值独立适用于 H 和 W。在每种破碎情况下,VX 输出在每个位置都饱和到 int8 = 127 - 饱和到 int8 的正极端值(而不是 output_zp 或 0)表明,要么是乘法器移位在最终钳位前溢出,要么是一个固定值被写入输出磁贴以代替 MAC 结果。这个问题似乎与内核面积无关(例如,15x15 的内核可以正常工作)

阈值是必要的,但还不够 — 某些 int8 权重值模式在 K ≥ 16 时会触发错误,而另一些则不会。我们已经进行了字节级隔离实验(在损坏和未损坏的伪影之间移植单个 TfLite 张量场),将值模式触发范围缩小到特定的张量场。如果有用,我很乐意分享隔离结果和工具。


冗长日志摘录(VSI_NN_LOG_LEVEL=5,破例)

INFO: Vx delegate: error_during_init    set to 0.
INFO: Vx delegate: error_during_prepare set to 0.
INFO: Vx delegate: error_during_invoke  set to 0.
I [vsi_nn_CreateGraph:1327] OVXLIB_VERSION==1.2.14
D [setup_node:535] Setup node id[3] uid[30000] op[DATACONVERT]
D [setup_node:535] Setup node id[0] uid[1]     op[PERMUTE]
D [setup_node:535] Setup node id[1] uid[2]     op[CONV2D]
D [setup_node:535] Setup node id[2] uid[3]     op[PERMUTE]
D [setup_node:535] Setup node id[4] uid[30001] op[DATACONVERT]
D [vsi_nn_kernel_selector:1286] Instance OPENVX node with kernel "conv2d"

完整日志作为 vsi_nn_log_level_5_conv_1x17.txt 附后。


附件

捆绑为 bug_report_artifacts.tar.gz

  • conv_1x17_broken.tflite — 2,136 字节损坏的神器。
  • conv_1x15_torch_control.tflite — 2,056 字节的亚阈值控制,相同的管道。
  • reproduce.py — 板端复制器(仅限 tflite_runtime + numpy)。
  • vsi_nn_log_level_5_conv_1x17.txt - 完整的详细日志。

其他工件可根据要求提供:字节级隔离工具、用于增量分析的结构相同的工作工件(1、17)、完全符合条件的移植结果。

i.MX 8M | i.MX 8M Mini | i.MX 8M NanoLinux疑似软件缺陷Re: Conv2D on i.MX 8M Plus VX delegate produces incorrect output when either spatial kernel dim >

你好@themis_stewart

感谢您提供的信息,我正在与内部团队核实您提出的两个问题。

致敬,
Zhiming

Re: Conv2D on i.MX 8M Plus VX delegate produces incorrect output when either spatial kernel dim >

您好@themis_stewart

请尝试使用以下基于 L6.18.2 的补丁,以便在内核大小为> 16 时,将操作回退到 CPU

,谢谢
Zhiming

Re: Conv2D on i.MX 8M Plus VX delegate produces incorrect output when either spatial kernel dim >

非常感谢你们如此迅速地处理此事——我们已经应用并测试了该保护补丁,并确认它解决了我们这边的问题。

我们使用您的 op_map.cc 更改,从 lf-6.18.2_1.0.0 委托源代码构建了打过补丁的 libvx_delegate.so,并在我们的 i.MX 8M Plus EVK 上针对原始报告中的最小复现步骤进行了验证。安装补丁后:

  • 受影响的 INT8 Conv2D(空间内核 ≥ 16)现在已被委托人干净利落地拒绝,并回退到 TFLite CPU,日志消息明确地表明了回退——不再静默饱和到 int8 = 127。输出结果与CPU参考值完全一致。
  • 我们的生产模型(内核≤15)不受影响——仍然完全委托给NPU,因此保护机制不会过度触发。

在实践中,CPU 回退路径对我们来说表现良好,尽管回退速度自然比完全在 NPU 上运行的模型要慢。如果详细的前后对比基准测试结果对您的回归测试有所帮助,我们很乐意私下分享。

再次感谢,非常感激。

Tags (1)
No ratings
Version history
Last update:
Tuesday
Updated by: