对齐规则
本节内容介绍使用BPU的对齐限制规则。
本节是模型部署阶段的前置知识。输入数据按什么排布、内存要申请多大,都由本节介绍的 validShape、stride 与 alignedByteSize 三个属性决定。这些属性的理解对输入准备代码十分重要,建议您在开始应用开发前先完成本节的阅读。
模型输入要求
BPU不限制模型输入大小或者奇偶。既像YOLO这种416x416的输入可以支持,对于像SqueezeNet这种227x227的输入也可以支持。 对于NV12输入比较特别,要求HW都是偶数,是为了满足UV是Y的一半的要求。
对齐和有效数据
BPU对数据有对齐限制。有效数据排布和对齐数据排布用 hbDNNTensorProperties 中的 validShape 和 stride 表示。
validShape是有效数据的shape。stride表示validShape各维度的步长,描述跨越张量各个维度所需要经过的字节数。需要注意,NV12或Y类型输入的模型比较特殊,这些类型的输入只要求W方向满足固定的对齐约束即可,其获取到的stride均为-1,详细规则可参考 动态输入介绍 章节的描述。
模型输入输出张量可以通过 validShape 和 stride 获取正确的数据排布,
比如获取到的模型某输入属性 hbDNNDataType = HB_DNN_TENSOR_TYPE_U16 , validShape = [1, 3, 212, 212] , stride = [301056, 100352, 448, 2] ,
这里表示模型有效输入的大小为 1x3x212x212 。
stride[3] = 2,表示每个元素16bit大小。stride[2] = 448 = 2 * 224,表示index=3的维度按照224对齐,因此index=3的维度步长为448。stride[1] = 100352 = 448 * 224,,表示index=2的维度也按照224对齐,因此index=2的维度步长为100352。stride[0] = 301056 = 100352 * 3,表示index=1的维度按照3对齐,和有效尺寸一致,因此index=1的维度步长为301056。
在后续场景使用时,考虑到对齐要求,当 alignedByteSize > 0 时,建议按照 alignedByteSize 大小来申请内存空间。
您可以使用以下方式判断是否需要对模型的输入进行对齐,若公式不成立,您则需要额外对输入数据进行对齐操作。
,其中 n=validShape.numDimensions。
模型输入输出内存要求
BPU对模型输入输出内存首地址有对齐限制,要求输入与输出内存的首地址 32 或者 64 对齐,对应不同的计算平台。
-
J6H/P 与 S6P 要求
64对齐,J6E/M/B 要求32对齐。 -
使用 hbUCPMalloc 与 hbUCPMallocCached 接口申请的内存首地址默认
64对齐。 -
当您申请一块内存,并使用偏移地址作为模型的输入或输出时,请检查偏移后的首地址是否满足对齐要求。
本节这条对齐要求针对的是输入输出内存的首地址。平台之间还存在 NV12 输入的 stride 对齐要求、非图像张量的最小内存单元等其他输入输出差异,它们与内存首地址对齐不是同一个量,需要分别确认。如需了解本平台完整的输入输出差异,请查看 平台差异说明 章节的输入输出处理差异一节。
常见误区
stride 中出现 -1 并不代表该输入没有对齐要求。
-1 表示该维度是动态的,需要您根据实际输入自行计算并填写,而不是可以跳过对齐处理。NV12 与 Y 类型输入属于这种情况,这类输入只要求 W 方向满足固定的对齐约束,其余维度按公式逐级推导即可。具体的填写规则与计算算例请参考 动态输入介绍 章节。
下一步看哪里
-
模型输入的
validShape或stride中含有-1,需要知道动态维度怎么填:请查看 动态输入介绍 章节。 -
需要在代码中申请内存、并按
stride排布输入数据:请查看 模型推理应用开发指导 章节。 -
需要了解各计算平台在输入输出处理上的完整差异:请查看 平台差异说明 章节。
