6.3.5. 模型推理接口说明

模型推理API接口所用头文件和lib库文件,请《交付使用说明》的 package/host/host_package/x5_aarch64/dnn文件夹获取。

6.3.5.1. 模型推理版本信息获取 API

hbDNNGetVersion()

【函数原型】

const char *hbDNNGetVersion()

【功能描述】

获取 DNN 预测版本信息。

【参数】

【返回类型】

返回版本信息。

6.3.5.2. 模型加载/释放 API

hbDNNInitializeFromFiles()

【函数原型】

int32_t hbDNNInitializeFromFiles(hbPackedDNNHandle_t *packedDNNHandle, const char **modelFileNames, int32_t modelFileCount)

【功能描述】

从文件完成packedDNNHandle创建初始化。调用可以函数、跨线程使用返回packedDNNHandle

【参数】

  • [out] packedDNNHandle Horizon DNN句柄,指向多个模型。

  • [in] modelFileNames 模型文件路径。

  • [in] modelFileCount 模型文件个数。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNInitializeFromDDR()

【函数原型】

int32_t hbDNNInitializeFromDDR(hbPackedDNNHandle_t *packedDNNHandle, const void **modelData, int32_t *modelDataLengths, int32_t modelDataCount)

【功能描述】

从文件完成packedDNNHandle创建初始化。调用可以函数、跨线程使用返回packedDNNHandle

【参数】

  • [out] packedDNNHandle Horizon DNN句柄,指向多个模型。

  • [in] modelData 模型文件指针。

  • [in] modelDataLengths 模型数据长度。

  • [in] modelDataCount 模型数据个数。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNRelease()

【函数原型】

int32_t hbDNNRelease(hbPackedDNNHandle_t packedDNNHandle)

【功能描述】

packedDNNHandle指向模型释放。

【参数】

  • [in] packedDNNHandle Horizon DNN句柄,指向多个模型。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

6.3.5.3. 模型信息获取 API

hbDNNGetModelNameList()

【函数原型】

int32_t hbDNNGetModelNameList(const char ***modelNameList, int32_t *modelNameCount, hbPackedDNNHandle_t packedDNNHandle)

【功能描述】

获取 packedDNNHandle指向模型名称列表个数。

【参数】

  • [out] modelNameList 模型名称列表。

  • [out] modelNameCount 模型名称个数。

  • [in] packedDNNHandle Horizon DNN句柄,指向多个模型。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetModelHandle()

【函数原型】

int32_t hbDNNGetModelHandle(hbDNNHandle_t *dnnHandle, hbPackedDNNHandle_t packedDNNHandle, const char *modelName)

【功能描述】

packedDNNHandle指向模型列表获取一个模型句柄。调用可以函数、跨线程使用返回dnnHandle

【参数】

  • [out] dnnHandle DNN句柄,指向一个模型。

  • [in] packedDNNHandle DNN句柄,指向多个模型。

  • [in] modelName 模型名称。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetInputCount()

【函数原型】

int32_t hbDNNGetInputCount(int32_t *inputCount, hbDNNHandle_t dnnHandle)

【功能描述】

获取 dnnHandle指向模型输入张量个数。

【参数】

  • [out] inputCount 模型输入张量个数。

  • [in] dnnHandle DNN句柄,指向一个模型。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetInputName()

【函数原型】

int32_t hbDNNGetInputName(const char **name, hbDNNHandle_t dnnHandle, int32_t inputIndex)

【功能描述】

获取 dnnHandle指向模型输入张量名称。

【参数】

  • [out] name 模型输入张量名称。

  • [in] dnnHandle DNN句柄,指向一个模型。

  • [in] inputIndex 模型输入张量编号。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetInputTensorProperties()

【函数原型】

int32_t hbDNNGetInputTensorProperties(hbDNNTensorProperties *properties, hbDNNHandle_t dnnHandle, int32_t inputIndex)

【功能描述】

获取 dnnHandle指向模型特定输入张量属性。

【参数】

  • [out] properties 输入张量信息。

  • [in] dnnHandle DNN句柄,指向一个模型。

  • [in] inputIndex 模型输入张量编号。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetOutputCount()

【函数原型】

int32_t hbDNNGetOutputCount(int32_t *outputCount, hbDNNHandle_t dnnHandle)

【功能描述】

获取 dnnHandle指向模型输出张量个数。

【参数】

  • [out] outputCount 模型输出张量个数。

  • [in] dnnHandle DNN句柄,指向一个模型。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetOutputName()

【函数原型】

int32_t hbDNNGetOutputName(const char **name, hbDNNHandle_t dnnHandle, int32_t outputIndex)

【功能描述】

获取 dnnHandle指向模型输出张量名称。

【参数】

  • [out] name 模型输出张量名称。

  • [in] dnnHandle DNN句柄,指向一个模型。

  • [in] outputIndex 模型输出张量编号。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbDNNGetOutputTensorProperties()

【函数原型】

int32_t hbDNNGetOutputTensorProperties(hbDNNTensorProperties *properties, hbDNNHandle_t dnnHandle, int32_t outputIndex)

【功能描述】

获取 dnnHandle指向模型特定输出张量属性。

【参数】

  • [out] properties 输出张量信息。

  • [in] dnnHandle DNN句柄,指向一个模型。

  • [in] outputIndex 模型输出张量编号。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

6.3.5.4. 模型推理 API

hbDNNInfer()

【函数原型】

int32_t hbDNNInfer(hbDNNTaskHandle_t *taskHandle, hbDNNTensor **output, const hbDNNTensor *input, hbDNNHandle_t dnnHandle, hbDNNInferCtrlParam *inferCtrlParam)

【功能描述】

根据输入参数执行推理任务。调用可以函数、跨线程使用返回taskHandle

【参数】

  • [out] taskHandle 任务句柄指针。

  • [in/out] output 推理任务输出。

  • [in] input 推理任务输入。

  • [in] dnnHandle DNN句柄指针。

  • [in] inferCtrlParam 控制推理任务参数。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

备注:

使用接口提交任务时应提前taskHandlenullptr,除非指定 taskHandle 追加任务(即使用 inferCtrlParam::more 功能)。

支持同时存在32个模型任务。

对于batch模型,允许分开设置输入张量内存地址。例如:模型输入validShape/alignedShape为[4, 3, 224, 224], 可以申请四个hbDNNTensor, 每个hbDNNTensor的validShape/alignedShape都设置为[1, 3, 224, 224],存放每个batch的数据。当模型多个输入时, input顺序应为input0[batch0], input0[batch1], …, inputn[batch0], inputn[batch1], …。

hbDNNRoiInfer()

【函数原型】

int32_t hbDNNRoiInfer(hbDNNTaskHandle_t *taskHandle, hbDNNTensor **output, const hbDNNTensor *input, hbDNNRoi *rois, int32_t roiCount, hbDNNHandle_t dnnHandle, hbDNNInferCtrlParam *inferCtrlParam)

【功能描述】

根据输入参数执行ROI推理任务。根据输入参数执行ROI推理任务。调用可以函数、跨线程使用返回taskHandle

【参数】

  • [out] taskHandle 任务句柄指针。

  • [in/out] output 推理任务输出。

  • [in] input 推理任务输入。

  • [in] rois Roi框信息。

  • [in] roiCount Roi框数量。

  • [in] dnnHandle dnn句柄指针。

  • [in] inferCtrlParam 控制推理任务参数。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

备注:

使用 X5 ,请遵循如下规则:

  • input_count : 模型输入分支数量

  • output_count : 模型输出分支数量

  • resizer_count : 模型输入源为 resizer 的分支数量(≤input_count),模型处理一批数据时,一个 resizer 输入分支处理一个 roi

  • roiCount : roi 总数,其数值batch * resizer_count

  • data_batch : 模型需要推理数据批数,其数值roiCount / resizer_count

  • model_batch : 模型内部的 batch 数量。即模型实际推理时,输入模型的 batch_size。X5算法工具链支持模型编译为 batch model

输入/输出示例说明:

较为复杂输入模型为例,假设模型有 3 个输入分支(2个resizer输入源,1个ddr输入源)和 1 个输出分支,并batch=2 编译,模型共需处理 3 批数据共 6 个 roi(即每批数据有2个roi),那么现有如下信息:

  • input_count = 3

  • output_count = 1

  • resizer_count = 2

  • roiCount = 6

  • data_batch = 3

  • model_batch = 2

所以模型推理这 3 批数据需要准备独立地址的 input_tensor 数量input_count * data_batch = 9

假设模型输入/输出静态信息如下:

  • 模型输入(model_info):

    • tensor_0_resizer: [2, 3, 128, 128]

    • tensor_1_resizer: [2, 3, 256, 256]

    • tensor_2_ddr: [2, 80, 1, 100]

  • 模型输出(model_info):

    • tensor_out:[2, 100, 1, 56]

那么模型推理动态信息为:

  • 模型输入(input_tensors):

    • [1x3x128x128, 1x3x256x256, 1x80x1x100, 1x3x128x128, 1x3x256x256, 1x80x1x100, 1x3x128x128, 1x3x256x256, 1x80x1x100]

  • 模型输出(output_tensors):

    • [4x100x1x56]

其中,因为 model_batch = 2,所以底层 BPU 单次执行处理 2 批数据;又因为 data_batch = 3,所以 output_tensor 最高计算公式ceil[(data_batch) / model_batch] * model_batch,可见一定model_batch整数倍,这是 BPU 硬件指令要求,缺少输入自动忽略计算。

接口限制说明:

  • 关于 batch 数量限制:其范围应该在[1, 255]。

  • 使用接口提交任务时应提前taskHandlenullptr,除非指定 taskHandle 追加任务(即使用 inferCtrlParam::more 功能)。

  • roi 大小要求是 :math:2 <= width <= 4096, :math:2 <= height <= 4096

  • 原图尺寸要求是 :math:1 <= W <= 4096, :math:16 <= stride <= 131072stride 必须是16的倍数。

  • 输出尺寸要求是 :math:2 <= Wout, :math:2 <= Hout

  • roi缩放倍数限制 :math:0 <= step <= 262143,step计算公式 :math:step = ((src\_len - 1)*65536 + (dst\_len - 1)/2)/(dst\_len - 1),其中src_len为roi的W或H,dst_len为模型要求的W或H。

  • 支持同时存在32个模型任务。

hbDNNWaitTaskDone()

【函数原型】

int32_t hbDNNWaitTaskDone(hbDNNTaskHandle_t taskHandle, int32_t timeout)

【功能描述】

等待任务完成超时。

【参数】

  • [in] taskHandle 任务句柄指针。

  • [in] timeout 超时配置(单位:毫秒)。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

备注:

  1. timeout > 0 表示等待时间;

  2. timeout <= 0 表示一直等待,直到任务完成。

hbDNNReleaseTask()

【函数原型】

int32_t hbDNNReleaseTask(hbDNNTaskHandle_t taskHandle)

【功能描述】

释放任务,如果任务执行直接取消释放任务,如果已经执行运行某些节点取消释放任务。

【参数】

  • [in] taskHandle 任务句柄指针。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

6.3.5.5. 模型内存操作 API

hbSysAllocMem()

【函数原型】

int32_t hbSysAllocMem(hbSysMem *mem, uint32_t size)

【功能描述】

申请BPU内存。

【参数】

  • [in] size 申请内存大小。

  • [out] mem 内存指针。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysAllocCachedMem()

【函数原型】

int32_t hbSysAllocCachedMem(hbSysMem *mem, uint32_t size)

【功能描述】

申请缓存的BPU内存。

【参数】

  • [in] size 申请内存大小。

  • [out] mem 内存指针。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysFlushMem()

【函数原型】

int32_t hbSysFlushMem(hbSysMem *mem, int32_t flag)

【功能描述】

缓存的BPU内存进行刷新。

【参数】

  • [in] mem 内存指针。

  • [in] flag 刷新标志符。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysFreeMem()

【函数原型】

int32_t hbSysFreeMem(hbSysMem *mem)

【功能描述】

释放BPU内存。

【参数】

  • [in] mem 内存指针。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysWriteMem()

【函数原型】

int32_t hbSysWriteMem(hbSysMem *dest, char *src, uint32_t size)

【功能描述】

写入BPU内存。

【参数】

  • [out] dest 内存指针。

  • [in] src 数据指针。

  • [in] size 数据大小。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysReadMem()

【函数原型】

int32_t hbSysReadMem(char *dest, hbSysMem *src, uint32_t size)

【功能描述】

读取BPU内存。

【参数】

  • [out] dest 数据指针。

  • [in] src 内存指针。

  • [in] size 数据大小。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysRegisterMem()

【函数原型】

int32_t hbSysRegisterMem(hbSysMem *mem)

【功能描述】

已知物理地址内存区间注册成可被BPU使用内存标识,得到内存是cacheable的。

【参数】

  • [in/out] mem 内存指针。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

hbSysUnregisterMem()

【函数原型】

int32_t hbSysUnregisterMem(hbSysMem *mem)

【功能描述】

注销hbSysRegisterMem 注册内存标识。

【参数】

  • [in] mem 内存指针。

【返回类型】

  • 返回 0表示API成功执行,否则执行失败。

6.3.5.6. 数据类型数据结构

版本信息

HB_DNN_VERSION_MAJOR

##define HB_DNN_VERSION_MAJOR 1U

DNN主版本号信息。

HB_DNN_VERSION_MINOR

##define HB_DNN_VERSION_MINOR 1U

DNN次版本号信息。

HB_DNN_VERSION_PATCH

##define HB_DNN_VERSION_PATCH 0U

DNN补丁版本号信息。

备注:

注意,本小节版本信息类型版本号版本变化有所不同,此处版本号仅供参考,实际版本获取发布为准。

模型

HB_DNN_TENSOR_MAX_DIMENSIONS

##define HB_DNN_TENSOR_MAX_DIMENSIONS 8

张量最大维度设置8

HB_DNN_INITIALIZE_INFER_CTRL_PARAM

##define HB_DNN_INITIALIZE_INFER_CTRL_PARAM(param) \
{                                                 \
    (param)->bpuCoreId = HB_BPU_CORE_ANY;         \
    (param)->dspCoreId = HB_DSP_CORE_ANY;         \
    (param)->priority = HB_DNN_PRIORITY_LOWEST;   \
    (param)->more = false;                        \
    (param)->customId = 0;                        \
    (param)->reserved1 = 0;                       \
    (param)->reserved2 = 0;                       \
}

初始化控制参数。

hbPackedDNNHandle_t

typedef void *hbPackedDNNHandle_t;

DNN句柄,指向打包多个模型。

hbDNNHandle_t

typedef void *hbDNNHandle_t;

DNN句柄,指向单一模型。

hbDNNTaskHandle_t

typedef void *hbDNNTaskHandle_t;

任务句柄,指向一个任务。

hbDNNTensorLayout

typedef enum {
  HB_DNN_LAYOUT_NHWC = 0,
  HB_DNN_LAYOUT_NCHW = 2,
  HB_DNN_LAYOUT_NONE = 255,
} hbDNNTensorLayout;

张量排布形式。 NHWC 分别代表Number、Height、Width和Channel。

  • 成员

成员名称 描述
HB_DNN_LAYOUT_NONE 没有定义排布形式。
HB_DNN_LAYOUT_NHWC 排布形式NHWC
HB_DNN_LAYOUT_NCHW 排布形式NCHW

hbDNNDataType

typedef enum {
  HB_DNN_IMG_TYPE_Y,
  HB_DNN_IMG_TYPE_NV12,
  HB_DNN_IMG_TYPE_NV12_SEPARATE,
  HB_DNN_IMG_TYPE_YUV444,
  HB_DNN_IMG_TYPE_RGB,
  HB_DNN_IMG_TYPE_BGR,
  HB_DNN_TENSOR_TYPE_S4,
  HB_DNN_TENSOR_TYPE_U4,
  HB_DNN_TENSOR_TYPE_S8,
  HB_DNN_TENSOR_TYPE_U8,
  HB_DNN_TENSOR_TYPE_F16,
  HB_DNN_TENSOR_TYPE_S16,
  HB_DNN_TENSOR_TYPE_U16,
  HB_DNN_TENSOR_TYPE_F32,
  HB_DNN_TENSOR_TYPE_S32,
  HB_DNN_TENSOR_TYPE_U32,
  HB_DNN_TENSOR_TYPE_F64,
  HB_DNN_TENSOR_TYPE_S64,
  HB_DNN_TENSOR_TYPE_U64,
  HB_DNN_TENSOR_TYPE_MAX
} hbDNNDataType;

张量类型。 S 代表符号, U 代表符号, F 代表浮点型,后面数字代表bit数。

HB_DNN_IMG_TYPE_NV12HB_DNN_IMG_TYPE_NV12_SEPARATE代表NV12的数据,只是存储差异。

推理NV12输入模型时,用户根据实际情况更改张量tensorType 属性HB_DNN_IMG_TYPE_NV12HB_DNN_IMG_TYPE_NV12_SEPARATE

  • 成员

成员名称 描述
HB_DNN_IMG_TYPE_Y 张量类型有Y通道图片。
HB_DNN_IMG_TYPE_NV12 张量类型一张NV12的图片。
HB_DNN_IMG_TYPE_NV12_SEPARATE 张量类型为Y通道及UV通道输入图片。
HB_DNN_IMG_TYPE_YUV444 张量类型为YUV444为输入图片。
HB_DNN_IMG_TYPE_RGB 张量类型为RGB为输入图片。
HB_DNN_IMG_TYPE_BGR 张量类型为BGR为输入图片。
HB_DNN_TENSOR_TYPE_S4 张量类型符号4bit。
HB_DNN_TENSOR_TYPE_U4 张量类型符号4bit。
HB_DNN_TENSOR_TYPE_S8 张量类型符号8bit。
HB_DNN_TENSOR_TYPE_U8 张量类型符号8bit。
HB_DNN_TENSOR_TYPE_F16 张量类型浮点型16bit。
HB_DNN_TENSOR_TYPE_S16 张量类型符号16bit。
HB_DNN_TENSOR_TYPE_U16 张量类型符号16bit。
HB_DNN_TENSOR_TYPE_F32 张量类型浮点型32bit。
HB_DNN_TENSOR_TYPE_S32 张量类型符号32bit。
HB_DNN_TENSOR_TYPE_U32 张量类型符号32bit。
HB_DNN_TENSOR_TYPE_F64 张量类型浮点型64bit。
HB_DNN_TENSOR_TYPE_S64 张量类型符号64bit。
HB_DNN_TENSOR_TYPE_U64 张量类型符号64bit。
HB_DNN_TENSOR_TYPE_MAX 代表最大张量类型编号。

hbDNNTensorShape

typedef struct {
  int32_t dimensionSize[HB_DNN_TENSOR_MAX_DIMENSIONS];
  int32_t numDimensions;
} hbDNNTensorShape;

张量形状。例如一张224x224的bgr彩色空间图片 numDimensions=4,若排布形式为NHWC, 则 dimensionSize 数组顺序存储图片 Number=1Height=224Width=224Channel=3

  • 成员

成员名称 描述
dimensionSize 张量每个维度大小。
numDimensions 张量维度。

hbDNNQuantiShift

typedef struct {
  int32_t shiftLen;
  uint8_t *shiftData;
} hbDNNQuantiShift;

量化/反量化移位数据。

对于输入:采集浮点数据 data[i], 对应移位数据shift[i], 则送入模型推理数据为: :math:data[i] * (1 << shift[i]) 取整;

对于输出:推理结果 data[i], 对应移位数据shift[i], 则最终推理结果为: :math:data[i] / (1 << shift[i])

注意:

其中 shiftLen数据 data 按照 per-axisper-tensor (反)量化方式决定。 当数据 dataper-tensor (反)量化时, shiftLen 等于 1,此时需要关注 quantizeAxis 数值;否则等于数据 dataquantizeAxis 维度大小。

  • 成员

成员名称 描述
shiftLen 移位数据长度。
shiftData 移位数据地址。

hbDNNQuantiScale

typedef struct {
  int32_t scaleLen;
  float *scaleData;
  int32_t zeroPointLen;
  int8_t *zeroPointData;
} hbDNNQuantiScale;

量化/反量化缩放数据。

对于输入:采集浮点数据 data[i], 对应缩放数据scale[i], 零点偏移数据zeroPoint[i],则送入模型推理数据为: :math:g((data[i] / scale[i]) + zeroPoint[i]) , 其中: :math:g(x) = clip(nearbyint(x)), 使用fesetround(FE_TONEAREST)舍入方法, 截断到:U8: :math:g(x)∈[0, 255], S8: :math:g(x)∈[-128, 127];

对于输出:推理结果 data[i], 对应缩放数据scale[i], 零点偏移数据zeroPoint[i],则最终推理结果为: :math:(data[i] - zeroPoint[i])* scale[i]

注意:

其中 scaleLen数据 data 按照 per-axisper-tensor (反)量化方式决定。 当数据 dataper-tensor (反)量化时, scaleLen 等于 1,此时需要关注 quantizeAxis 数值; 否则等于数据 dataquantizeAxis 维度大小。 zeroPointLenscaleLen 保持一致。

  • 成员

成员名称 描述
scaleLen 缩放数据长度。
scaleData 缩放数据地址。
zeropointLen 零点偏移数据长度。
zeropointData 零点偏移数据地址。

hbDNNQuantiType

typedef enum {
  NONE, 
  SHIFT,
  SCALE,
} hbDNNQuantiType;

定点浮点转换量化/反量化类型。 NONE 代表需要数据任何处理; SHIFT 类型对应量化/反量化参数存储hbDNNQuantiShift 结构体中, SCALE 对应量化/反量化参数存储hbDNNQuantiScale 结构体中。

  • 成员

成员名称 描述
NONE 没有量化。
SHIFT 量化类型SHIFT
SCALE 量化类型SCALE

hbDNNTensorProperties

typedef struct {
  hbDNNTensorShape validShape;
  hbDNNTensorShape alignedShape;
  int32_t tensorLayout;
  int32_t tensorType;
  hbDNNQuantiShift shift;
  hbDNNQuantiScale scale;
  hbDNNQuantiType quantiType;
  int32_t quantizeAxis;
  int32_t alignedByteSize;
  int32_t stride[HB_DNN_TENSOR_MAX_DIMENSIONS];
} hbDNNTensorProperties;

张量信息。

其中 alignedShape模型信息获取时,为张量对齐形状; 在准备输入数据之后, alignedShape 需要张量真实输入形状保持一致。

  • 成员

成员名称 描述
validShape 张量有效内容形状。
alignedShape 张量对齐内容形状。
tensorLayout 张量排布形式。
tensorType 张量类型。
shift 量化偏移量。
scale 量化放量。
quantiType 量化类型。
quantizeAxis 量化通道,仅按per-axis量化生效。
alignedByteSize 张量对齐内容内存大小。
stride 张量中validShape各维度步长

备注:

通过接口获取张量信息模型要求的,您可以根据实际输入修改对应张量信息,目前允许修改 alignedShapetensorType信息,而且必须符合要求。

alignedShape

  1. 根据 alignedShape 准备输入,则无需更改 alignedShape

  2. 根据 validShape 准备输入,则更改 alignedShapevalidShape ,推理内部数据进行padding操作。

tensorType

推理NV12输入模型时,您根据实际情况更改张量tensorType 属性HB_DNN_IMG_TYPE_NV12HB_DNN_IMG_TYPE_NV12_SEPARATE

hbDNNTaskPriority

typedef enum {
  HB_DNN_PRIORITY_LOWEST = 0,
  HB_DNN_PRIORITY_HIGHEST = 255,
  HB_DNN_PRIORITY_PREEMP = HB_DNN_PRIORITY_HIGHEST,
} hbDNNTaskPriority;

Task优先级配置,提供默认参数。

hbDNNTensor

typedef struct {
  hbSysMem sysMem[4];
  hbDNNTensorProperties properties;
} hbDNNTensor;

张量。用于存放输入输出信息。其中 NV12_SEPARATE 类型张量需要用2个 hbSysMem,其余为1个。

  • 成员

|成员名称 |描述 | |———–|—————-| |sysMem | 存放张量内存。| |properties | 张量信息。|

hbDNNRoi

typedef struct {
  int32_t left;
  int32_t top;
  int32_t right;
  int32_t bottom;
} hbDNNRoi;

矩形感兴趣区域。:math:W∈[left, right], H∈[top, bottom]

  • 成员

成员名称 描述
left 感兴趣区域宽度像素点。
top 感兴趣区域高度像素点。
right 感兴趣区域右下点宽度像素点。
bottom 感兴趣区域右下点高度像素点。

hbDNNInferCtrlParam

typedef struct {
  int32_t bpuCoreId;
  int32_t dspCoreId;
  int32_t priority;
  int32_t more;
  int64_t customId;
  int32_t reserved1;
  int32_t reserved2;
} hbDNNInferCtrlParam;

模型推理控制参数。 bpuCoreIddspCoreId 用于控制推理模型BPU和DSP节点使用核;X3不支持DSP推理,dspCoreId作为占位使用。 其中 more 参数用于模型批量处理场景,当希望所有任务执行完再获得输出时,除最后一个任务设置 more0 外, 之前任务 more设置1,最支持255个模型推理,小模型为resizer模型时,每一个roi都可能算作一个模型。 customId 参数用于用户自定义优先级,定义task的优先级大小,例如:时间戳、frame id等,数值越小优先级越高。优先级:priority > customId。

  • 成员

成员名称 描述
bpuCoreId BPU核ID。
dspCoreId DSP核ID。
priority 任务优先级。
more 任务后续是否跟随任务。
customId 自定义优先级。
reserved1 保留字段1。
Reserved2 保留字段2。

系统

hbBPUCore

typedef enum {
  HB_BPU_CORE_ANY = 0,
  HB_BPU_CORE_0 = (1 << 0),
  HB_BPU_CORE_1 = (1 << 1)
} hbBPUCore;

BPU核枚举,X5系统一个BPU核,仅支持指定HB_BPU_CORE_ANY或HB_BPU_CORE_0。

  • 成员

成员名称 描述
HB_BPU_CORE_ANY 任意的BPU核。
HB_BPU_CORE_0 BPU核0。
HB_BPU_CORE_1 BPU核1。

hbDSPCore

typedef enum {
  HB_DSP_CORE_ANY = 0,
  HB_DSP_CORE_0 = (1 << 0),
  HB_DSP_CORE_1 = (1 << 1)
} hbDSPCore;

DSP核枚举。

  • 成员

成员名称 描述
HB_DSP_CORE_ANY 任意的DSP核。
HB_DSP_CORE_0 DSP核0。
HB_DSP_CORE_1 DSP核1。

hbSysMem

typedef struct {
  uint64_t phyAddr;
  void *virAddr;
  uint32_t memSize;
} hbSysMem;

系统内存结构体,用于申请系统内存。

  • 成员

成员名称 描述
phyAddr 物理地址。
virAddr 虚拟地址。
memSize 内存大小。

hbSysMemFlushFlag

typedef enum {
  HB_SYS_MEM_CACHE_INVALIDATE = 1,
  HB_SYS_MEM_CACHE_CLEAN = 2
} hbSysMemFlushFlag;

系统内存缓存同步参数。CPU与内存之间一个缓存区,导致缓存内容内存内容出现同步情况,为了每次能够拿到最新数据, 我们需要在CPU读前、写后进行数据更新。CPU读前,将内存数据更新缓存中。CPU写后,将缓存数据更新内存中。

hbSysMemFlushFlag

  • 成员

成员名称 描述
HB_SYS_MEM_CACHE_INVALIDATE 内存同步缓存中,CPU读前使用。
HB_SYS_MEM_CACHE_CLEAN 缓存数据同步内存中,CPU写后使用。

处理

HB_DNN_INITIALIZE_RESIZE_CTRL_PARAM

##define HB_DNN_INITIALIZE_RESIZE_CTRL_PARAM(param)     \
  {                                                     \
    (param)->bpuCoreId = HB_BPU_CORE_ANY;              \
    (param)->resizeType = HB_DNN_RESIZE_TYPE_BILINEAR; \
    (param)->priority = HB_DNN_PRIORITY_LOWEST;        \
    (param)->reserved1 = 0;                             \
    (param)->reserved2 = 0;                             \
    (param)->reserved3 = 0;                             \
    (param)->reserved4 = 0;                             \
  }

初始化控制参数。

hbDNNResizeType

typedef enum {
  HB_DNN_RESIZE_TYPE_BILINEAR = 0,
} hbDNNResizeType;

Resize 类型。

  • 成员

成员名称 描述
HB_DNN_RESIZE_TYPE_BILINEAR Resize类型线性插值。

hbDNNResizeCtrlParam

typedef struct {
  int32_t bpuCoreId;
  int32_t priority;
  hbDNNResizeType resizeType;
  int32_t reserved1;
  int32_t reserved2;
  int32_t reserved3;
  int32_t reserved4;
} hbDNNResizeCtrlParam;

Resize控制参数。

  • 成员

成员名称 描述
bpuCoreId BPU核ID。
priority 任务优先级。
resizeType Resize类型。
reserved1 保留字段1。
Reserved2 保留字段2。
Reserved3 保留字段3。
Reserved4 保留字段4。

6.3.5.7. 数据排布对齐规则

数据排布

硬件内部为了提高计算效率,其数据使用特殊排布方式使得卷积运算同一批次乘加用到的feature map和kernel在内存相邻排放。 下面简要介绍X5处理器数据排布(layout)的概念。

神经网络模型变量可以一个4维张量表示,每个数字这个张量元素,我们称之为自然排布。 将不同维度不同元素一定规则紧密排列一起,形成一个独立块(block),然后这些看成元素,组成的4维张量, 我们称之为带有数据排布张量。

输入输出数据用到不同的layout数据排布,用户通过API获取layout描述信息,不同的layout数据可以直接比较。

备注:

需要注意是,在进行数据排布转换时,如果需要padding,则padding的建议设置零。

此处介绍两种数据排布: NHWC_NATIVENCHW_NATIVE ,以 NHWC_NATIVE 为例,其数据排布如下:

N0H0W0C0 N0H0W0C1 ……
N0H0W1C0 N0H0W1C1 ……
…… …… ……
N0H1W0C0 N0H1W0C1 ……
…… …… ……
N1H0W0C0 N1H0W0C1 ……
…… …… ……

一个NHW*C大小张量可用如下4重循环表示:

for (int32_t n = 0; n < N; n++) {
    for (int32_t h = 0; h < H; h++) {
        for (int32_t w = 0; w < W; w++) {
            for (int32_t c = 0; c < C; c++) {
                int32_t native_offset = n*H*W*C + h*W*C + w*C + c;
            }
        }
    }
}

其中 NCHW_NATIVENHWC_NATIVE 相比,只是排布循环顺序一样,此处不再单独列出。

caution 下文提到的native都特指该layout。

BPU对齐限制规则

内容介绍使用BPU的对齐限制规则。

模型输入要求

BPU不限制模型输入大小或者奇偶。既像YOLO这种416x416的输入可以支持,对于像SqueezeNet这种227x227的输入可以支持。 对于NV12输入比较特别,要求HW都偶数,是为了满足UV是Y的一半要求。

对齐有效数据

BPU对数据对齐限制。对齐要求真实数据排布hbDNNTensorPropertiesvalidShape , alignedShapestride 表示。

  • validShape有效的shape;

  • alignedShape满足对齐要求的shape, 由于硬件特性, alignedShape四维数据表示;

  • stride 表示 validShape维度步长,其中,NV12输入模型比较特殊,其 stride为0,因为NV12输入模型要求W 16对齐。

目前四维模型张量可以通过 validShapealignedShape 获取正确数据排布,若使用 X5 模型大于四维模型张量可以通过 validShapestride 获取正确数据排布。

NV12介绍

YUV格式

YUV格式主要用于优化彩色视频信号传输。 YUV分为三个分量:Y表示明亮度,也就是灰度值;而U和V表示色度,作用描述影像色彩饱和度,用于指定像素颜色。

NV12排布

NV12图像格式属于YUV颜色空间的YUV420SP格式,每四个Y分量共用一组U分量和V分量,Y连续排序,U与V交叉排序。

排列方式如下:

nv12_layout

6.3.5.8. 模型推理DEBUG方法

错误码

HB_DNN_SUCCESS = 0                              // 执行成功
HB_DNN_INVALID_ARGUMENT = -6000001              // 非法参数
HB_DNN_INVALID_MODEL = -6000002                 // 非法模型
HB_DNN_MODEL_NUMBER_EXCEED_LIMIT = -6000003     // 模型个数超过限制
HB_DNN_INVALID_PACKED_DNN_HANDLE = -6000004     // 非法packed handle
HB_DNN_INVALID_DNN_HANDLE = -6000005            // 非法handle
HB_DNN_CAN_NOT_OPEN_FILE = -6000006             // 文件不存在
HB_DNN_OUT_OF_MEMORY = -6000007                 // 没有足够的内存
HB_DNN_TIMEOUT = -6000008                       // 超时
HB_DNN_TASK_NUM_EXCEED_LIMIT = -6000009         // 任务数量超限制
HB_DNN_TASK_BATCH_SIZE_EXCEED_LIMIT = -6000010  // 多任务处理数量超限制
HB_DNN_INVALID_TASK_HANDLE = -6000011           // 非法task handle
HB_DNN_RUN_TASK_FAILED = -6000012               // 任务执行失败
HB_DNN_MODEL_IS_RUNNING = -6000013              // 任务执行中
HB_DNN_INCOMPATIBLE_MODEL = -6000014            // 不兼容的模型
HB_DNN_API_USE_ERROR = -6000015                 // 接口使用错误
HB_DNN_MULTI_PROGRESS_USE_ERROR = -6000016      // 多进程使用错误

HB_SYS_SUCCESS = 0                              // 执行成功
HB_SYS_INVALID_ARGUMENT = -6000129              // 非法参数
HB_SYS_OUT_OF_MEMORY = -6000130                 // 没有足够的内存
HB_SYS_REGISTER_MEM_FAILED = -6000131           // 注册内存失败

配置信息

  1. 日志等级。 dnn日志主要分为4个等级,:

    • HB_DNN_LOG_NONE = 0,不输出日志;

    • HB_DNN_LOG_WARNING = 3,该等级主要用来输出代码告警信息;

    • HB_DNN_LOG_ERROR = 4,该等级主要用来输出代码报错信息;

    • HB_DNN_LOG_FATAL = 5,该等级主要用来输出代码导致退出错误信息。

  2. 日志等级设置规则:

    发生的LOG等级 >= 设置等级,则该LOG可以打印,反之屏蔽;设置的LOG等级越小,打印信息多(等级0除外,0不输出日志)。 例如:设置LOG等级为3,即WARNING 级别,则3,4,5等级的LOG均可以打印; 预测默认LOG等级HB_DNN_LOG_WARNING ,则以下LOG级别信息可以打印: WARNINGERRORFATAL

  3. 日志等级设置方式: 可通过环境变量 HB_DNN_LOG_LEVEL 设置日志等级。 比如: export HB_DNN_LOG_LEVEL=3,则输出 WARNING以上级别日志。

  4. 常用环境变量

     HB_DNN_LOG_LEVEL                // 设置日志等级。
     HB_DNN_PLUGIN_PATH              // 自定义CPU算子动态链接库所在目录。
     HB_DNN_PROFILER_LOG_PATH        // 模型运行各阶段耗时统计信息dump路径。
     HB_DNN_SIM_PLATFORM             // x86模拟器模拟平台设置,可设置为BERNOULLI、BERNOULLI2、BAYES、BAYESE。
     HB_DNN_SIM_BPU_MEM_SIZE         // x86模拟器设置BPU内存大小,单位MB。
    

开发模拟器使用注意事项

  1. 开发模拟器使用时,可以通过设置环境变量 HB_DNN_SIM_PLATFORM指定需要模拟处理器架构,可执行如下命令:

    • export HB_DNN_SIM_PLATFORM=BAYESE ,表示模拟 x5 平台;

  2. 如果设置 HB_DNN_SIM_PLATFORM 环境变量,会根据第一次加载模型架构设置模拟器平台,例如:第一次加载模型BAYESE 架构,则程序默认设置平台x5

  3. 开发模拟器执行 resize 相关操作之前,需要通过 HB_DNN_SIM_PLATFORM 环境变量指定平台。