浮点模型转换后上板运行报错

一、背景

自己的onnx模型,利用官方提供的工具进行转换,转换成功,但上板运行会有报错。

二、错误及初步分析

有如下错误提示,

# Fatal error in /data/zhangronghui/new-xroc/new-dev-tdt_hbdk3/2021_porject/v2.9.0/common/bpu-predict/3rdparty/horizonrt/src/plan/hbm_exec_plan.cpp, line 282

# last system error: 12

# Check failed: one_hbm_node_info ->hbm_exec_output_region_for_exceed_separate_reigon_limit_ != 0 (0 vs. 0)

==== C stack trace ===============================

./lib/libbpu_predict.so(+0x23e060) [0x7fbf4d4060]

./lib/libbpu_predict.so(+0x26b00c) [0x7fbf50100c]

./lib/libbpu_predict.so(+0x26b4c8) [0x7fbf5014c8]

./lib/libbpu_predict.so(+0x25357c) [0x7fbf4e957c]

./lib/libbpu_predict.so(+0x257dec) [0x7fbf4eddec]

./lib/libbpu_predict.so(+0x1ad140) [0x7fbf443140]

7: bpu_predict::RTProxy::riStartProxy(void**, unsigned int*, hbrt_model_handle _t, hbrt_ri_input_info_t const*, hbrt_ri_config_t const*, unsigned int, unsigne d int, int, int)

8: bpu_predict::ModelRunTask::start(int)

9: bpu_predict::BpuGroupEngine::bpu_working_proc()

/usr/lib/libstdc++.so.6(+0xb922c) [0x7fbb76c22c]

/lib/libpthread.so.0(+0x78e4) [0x7fbc1c78e4]

从错误名称来看,判断是模型分段太多,超出了官方预设的限制。我的原始模型转换之后有34个sub graph……为了验证这个结论,将模型简化到只包含一个子模块,转换之后只有3个sub graph。此时,可以正常上板运行。

三、寻求的帮助

1. sub graph的最大数量具体是多少?能不能调大?我看了一下转换报告,每个sub graph实际上都很小,耗时均在1ms以内,只是因为我模型结构的原因,在bpu算子之间会穿插很多cpu算子。所以,把sub graph的最大限制调大我觉得是个可行的思路。

2. 优化模型

只包含一个子模块的简化模型node information如下,

可以看到,bpu算子之间的cpu算子大多为Concat、Reshape之类的。那么还有一个思路,bpu有没有什么可以实现等效于reshape功能的算子,将它替换掉?有这个思路是因为官方对MatMul的支持还不是很好,但是我可以用Conv2d替换掉MatMul,实际操作下来也是可行的。

你好,我整体回复下:

1)该模型在板端的报错,其实并不是模型切段超过限制了,而是 BPU 的内存不够用了;因为模型被切了很多段,而每一段 hbm 的输出我们都需要去分配好输出 tensor 的内存,这就导致消耗了特别多的内存空间。

2)Reshape 算子在 BPU 上目前无等效替换算子,只在极个别情况下可能会被抵消优化掉,但情况很复杂,无法给出明确的描述。而且 Reshape 其实在 CPU 上运行的耗时并不大,主要的性能损耗其实是 BPU 和 CPU 之前来回切换时的量化和反量化节点,以及可能引入的 transpose,这些才是真正耗时的,所以我们的模型设计应该尽量为一整段 BPU。

3)关于 ReduceMean 算子,目前在我们的最新版本中已给出明确的支持范围:当 input_shape 为 4 维,且 axes=[2, 3] 是支持 BPU 加速的,其他情况只支持 CPU 运行

4)关于 MatMul 算子,在 onnx 中确实涉及的维度情况非常多,所以我们建议是能用 Conv2D 去替换最好

你好,问题已收到,我们今天会具体去分析一下,有结论了同步给你哈

有几个追加的问题,

1. 我已经尽可能的简化模型了,但是这个Reshape还是无法消去。实际上,这个Reshape的引入是作为要用Conv2d取代MatMul所必须的操作……我看你们的算子手册,Reshape是运行在bpu上的呀?

2. 多段hbm输出没有必要全部保存下来吧,又不需要反向传播,有什么接口可以让用过之后不用的tensor被优化掉吗?