1 概述
为了应对复杂的智能机器人场景,地平线于2024年推出了10Tops高算力的旭日5计算平台(以下简称X5)。 作为一款端侧SOC,X5的BPU中包含多种专用硬件计算单元,各硬件单元在设计时为了更高的性能可能牺牲了部分灵活性,因此需要各位开发者们在了解BPU的特性后,针对性地对模型做出一些更贴合硬件特点的优化,以尽可能发挥出BPU的计算优势。 下文将具体阐述在X5计算平台上设计高效模型的建议。 文本给出的优化思路,仅做指导建议,所列举案例并不保证对所有场景都适用,请根据实际情况多做尝试。
2 通用建议
2.1 使用BPU算子搭建模型
BPU算子本身性能远高于CPU算子,且CPU和BPU之间的异构调度还会引入量化、反量化节点,其计算因为需要遍历数据,所以耗时也与shape大小成正比。 对于模型尾部输出的反量化,和featuremap模型输入的量化节点,我们建议通过 hb_model_modifier 工具手动摘除, 并将相关操作合入前、后处理代码中,从而节省一次数据遍历的冗余耗时。同时在模型后处理中还可考虑先完成筛选过滤的操作,仅对剩下的数据做反量化,还可进一步压缩耗时。
2.2 选择BPU高效实现的Backbone
在X5计算平台上,BPU针对GroupConv,DepthwiseConv做了针对性的优化,所以我们更推荐采用Depthwise+Pointwise结构的 MobileNetv2、EfficientNet_lite, 以及地平线基于GroupConv手工设计自研的 VarGNet 作为模型的Backbone, 以获得更高的性能收益。需要注意的是:
- 地平线的EfficientNet_lite示例模型来源于 EfficientNet-lite Github地址 , 相比于官方原版实现去除了包含sigmoid查表算子的SE结构,Swish激活替换为ReLU。
- 相较于XJ3处理器,Depthwise Conv算子在X5上的加速比有所下降,因此,对于同样的网络结构,将DepthwiseConv替换成Groupconv(保证每个group内channel 8对齐),可获得精度的提高且不损耗性能。 此外,建议尽量避免使用stride>1时的DepthwiseConv,效率较低。
- GroupConv每个组内C方向8对齐,否则无效的padding会造成算力浪费。
2.3 尽量提高模型的计算/访存比
由于X5算力的显著增加,所以要更多地考虑其带宽压力。地平线常用的提高模型计算/访存比的优化思路包括:
- 使用GroupConv降低模型深层的weight加载 。当模型channel比较小时,我们可以利用普通的稠密卷积(如3x3)去发挥处理器的强大算力。 而随着模型加深,下采样次数变多,channel会急剧变大,此时建议使用GroupConv来缓解带宽压力。
- Block间采用更小的featuremap ,这样可以减少DDR与SRAM之间的数据搬运。
- 避免使用过大的kernel_size 。过大的kernel_size(>9)一方面会增加weight的参数量, 另一方面会使当前计算依赖过多的前层数据,导致数据搬运更加频繁。
- Shortcut不宜过长 。过长的shortcut会导致featuremap在SRAM里驻存的时间过长,甚至会导致数据dump到DDR上。
- 小图多Batch 。对于小模型(分辨率 <= 256),则建议使用batch模式进行推理,从而降低模型weight的加载次数, 更有效地平衡计算/访存比。
2.4 遵循硬件对齐规则
2.4.1 硬件对齐规则介绍
X5计算平台运算的时候有最小的对齐单位,若不满足对齐规则,会对Tensor自动进行padding,造成无效的算力浪费。 不同的算子对齐规则有所差异,以下为一些常见计算在X5上的对齐规则:
**注解:**2H16W4C,表示计算的时候H方向对齐到2,W方向对齐到16,C方向对齐到4。假如原始tensor shape为 (1, 1, 20, 10) (layout: NHWC),实际运行时的tensor shape将被padding至 (1, 2, 32, 12)。
2.4.2参考advice参数建议
PTQ 可以在编译参数组(compiler_parameters)中配置advice参数,具体描述如下: 参数作用:用于提示模型编译后预估的耗时增加的情况,单位是微秒。 取值范围:自然数。 默认配置:无,不设置或设置为0则表示不开启。 参数说明:模型在编译过程中,工具链内部会进行耗时分析。而实际过程中, 如算子做数据对齐等操作时会导致耗时有所增加,设置该参数后, 当某个OP的实际计算耗时与理论计算耗时的偏差大于您指定的值时,会打印相关log, 包括耗时变化的信息、数据对齐前后的shape以及padding比例等信息。 若编译模型时指定advice为1,则表示开销额外增加超过1微秒时打印提示,打印信息如下:
advice: Layer "/conv1/Conv" becomes slow (0.002ms -> 0.007ms). Output is aligned from 1x226x226x3 to 1x226x232x8 (+173%).
QAT 可在调用horizon_plugin_pytorch.quantization.check_model接口时配置advice参数,该接口用于检查模型是否能够被编译,具体说明如下:
horizon_plugin_pytorch.quantization.check_model(module: Union[torch.jit._script.ScriptModule, torch.nn.modules.module.Module], example_inputs: tuple, march: Optional[str] = None, input_source: Union[Sequence[str], str] = 'ddr', advice: Optional[int] = None, check_quanti_param: bool = True)
Check if nn.Module or jit.ScriptModule can be compiled by HBDK.
Dump advices for improving performance on BPU.
参数
module (nn.Module or jit.ScriptModule.) –
example_inputs (A tuple of example inputs, in torch.tensor format.) – For jit.trace and shape inference.
march (Specify the target march of bpu.) – Valid options are bayes and bernoulli2. If not provided, use horizon plugin global march.
input_source (Specify input features' sources(ddr/resizer/pyramid)) –
advice (Print HBDK compiler advices for improving the utilization of the) – model on bpu if layers of the model become slow by more than the specified time (in microseconds)
check_quanti_param (Check quanti param) –
返回
flag – 0 if pass, otherwise not.
返回类型
int
3 特殊结构优化建议及示例
3.1 大数放在W维度
根据硬件对其规则表,对于Conv、Elementwise等常见计算,W的对齐要求通常都高于H和C,因此,在模型设计时我们可以考虑尽量将数据放在W维度上,其次是C,最后才是H。例如:
可见将大数放到w维度之后,对模型性能的增益效果是非常明显的,由于transpose又会引入额外的耗时,因此参考优化方式2直接改写模型输入尺寸会是最高效的做法。
3.2 减少数据transform操作
X5 BPU是张量运算处理器,数据排布是多维表示,而Reshape、Transpose的表达语义是基于CPU/GPU的线性排布,因此在BPU上进行数据transform操作是会引入部分耗时的。
3.2.1 减少使用reshape、transpose等操作
地平线转换工具会将部分matmul、gemm等op等价转换为conv2d计算,或多或少会引入额外的data transform操作以及add无法被吸收等问题, 因此建议设计模型时将nn.Linear、nn.MultiheadAttention等原生非四维的计算重新改写为四维计算,并尽可能用conv2d等价替代一些操作。例如:
板端实测单帧延时:左图1.21ms,右图0.87ms
3.2.2 reshape时减少改动的维度
使用reshape操作时,改动的维度越多,计算效率越低。在这个已知特性的前提下,可见如下例子:
由于地平线工具链支持matmul两个输入矩阵的batch维度(指除最低两维外的其他维度)广播,因此依据计算逻辑,通过减少reshape改动的维度可明显降低延时。
另外,对于使用Reshape算子把(a, b, c, d)展开成一维的场景,如果Reshape成(1, n, 1, 1),会比把n放在其他维度有快得多的运行效率。








