01 hbdk-model-verifier

 

1.1 工具简介

 

hbdk-model-verifier 工具是由地平线开发,用于对指定的定点 pt 模型和 hbm 部署模型进行结果一致性验证,并输出模型预测执行时间的工具。

 

使用 hbdk-model-verifier 工具时需要注意以下两个问题:

 

  1. hbdk-model-verifier 工具的版本需要与编译 hbm 模型的 hbdk 版本一致;

  2. 如果不关注耗时信息,采用工具自动生成的随机输入数据即可,无需人工准备输入数据。

 

1.2 获取方式

  • docker 镜像

  • 地平线算法工具链的 docker 镜像中已经包含了 hbdk-model-verifier 工具,可以直接在 docker 中进行使用。

  • 本地安装

  • 如果您想要在本地安装此工具,OE 开发包的 ddk/package/host/ai_toolchain 目录下提供了本地安装的 whl 包,只需要在本地 python 环境中安装以下。whl 包即可,参考命令如下:

pip install hbdk-{version}-cp38-cp38-linux_x86_64.whl
pip install hbdk_model_verifier-{version}-py3-none-linux@

 

1.3 使用场景和方式

 

1.3.1 pyramid 输入模型一致性验证

1.3.1.1 输入数据准备

 

当模型输入是 pyramid,此时输入的数据格式是 NV12 的图片,那么可以使用 jpg,png 或者 yuv 文件作为输入数据。这里需要注意的是:

 

  1. 如果使用 jpg,png 图片作为输入,由于 hbdk-model-verifier 工具处理图片输入的时候仅做解码(例如 jpg->bgr)和颜色空间转换(bgr->yuv444),不会做图像缩放,因此需要准备和模型输入大小相同的图片;

  2. 如果使用 yuv 文件作为输入,需要通过--yuv-shape 参数给出 yuv 文件的尺寸信息 HxW。rgb/bgr 图像转 NV12 图像的代码可以参考 PTQ&QAT 方案板端验证注意事项。

     

模型的名称和输入输出信息可以通过在 x86 端或者开发板端运行 hrt_model_exec 工具获取,参考命令:

 

hrt_model_exec model_info --model_file model.hbm

 

如果仅进行模型一致性验证,采用工具自动生成的随机输入数据即可,不需要再去人工准备输入数据。

 

1.3.1.2 运行命令

 

  1. 验证 pyramid 输入模型推理、hbm 模型推理结果的一致性,命令行示例如下:

 

hbdk-model-verifier --hbm model.hbm --model-pt model.pt --model-input nv12.yuv --yuv-shape {HxW} --ip {board_ip} --times 10

 

如果没有开发板,可以用 x86 模拟器进行替代,只需要配置--skip-bpu 参数即可,命令行示例如下:

 

hbdk-model-verifier --hbm model.hbm --model-pt model.pt --model-input nv12.yuv --yuv-shape {HxW} --skip-bpu

 

参数说明:

  • --hbm(必选):地平线算法工具链编译的 hbm 模型;

  • --model-pt(必选):torchscript 定点模型 pt;

  • --model-input(可选):模型输入数据,若不配置此参数,工具会自动生成输入数据;

  • --yuv-shape:NV12 输入的 shape,用于 pyramid/resizer,配置形式为 HxW;

  • --ip :开发板 IP 地址;

  • --times:推理的帧数,默认为“1”。评估模型性能时一般需要推理多次,然后取平均时间,验证模型一致性时可不配置此参数;

  • --skip-bpu:使用 x86 模拟器代替 BPU;

  • --force-run-simulator:表示无论是否远程连接 BPU 开发板,都调用 x86 模拟器进行推理,并将模拟器结果加入对比;

     

更多参数说明可以通过运行 hbdk-model-verifier --help 获取。

 

 

1.3.2 resizer 输入模型一致性验证

 

1.3.2.1 输入数据准备

 

当模型输入是 resizer,输入的数据格式同样是 NV12 的图片,那么可以使用 jpg,png 或者 yuv 文件作为输入数据,但是需要在图片中指定 ROI 的起始坐标或者尺寸作为模型输入。

 

1.3.2.2 运行命令

 

hbdk-model-verifier --hbm model.hbm --model-pt model.pt --model-input nv12.yuv --yuv-shape {HxW} --roi-coord {YxX} --roi-size {roi_hxroi_w} --ip {board_ip}

 

参数说明

  • --roi-coord/--roi-size:选项后面追加一个表示 ROI 起始点坐标/大小的字符串,格式为 Y 坐标/ROI 高度 + "x" + X 坐标/ROI 宽度。resizer 模型的 ROI 和模型输入尺寸需要满足 resizer 本身的硬件限制。pyramid 模型的 ROI 大小需要与模型输入一致。

     

resizer 模型的介绍可以参考 resizer 模型使用与部署。

 

 

1.3.3 ddr 输入模型一致性验证

 

1.3.3.1 输入数据准备

 

当模型输入是 ddr,那么需要使用二进制数据 bin 文件或者 txt 格式的数据作为输入。这里需要注意的是:无论模型本身要求的输入是什么 layout,hbdk-model-verfier 工具输入的数据都必须使用 NHWC_NATIVE 进行存储。

 

  1. 如果是二进制数据,注意二进制数据的数据类型需要与模型输入一致;

  2. 如果是 txt 文本,要求通过 numpy.loadtxt 可以正确读取。

     

NHWC_Native 数据排布:指多维数组的数据排布是 NHWC,且只有维度的顺序会影响数据存储的位置。

1.3.3.2 运行命令

 

验证 ddr 输入模型推理、hbm 模型推理结果的一致性,命令行示例如下:

 

hbdk-model-verifier --hbm model.hbm --model-pt model.pt --model-input featuremap.bin --ip {board_ip} --times 100

 

如果没有开发板,可以在命令行中配置--skip-bpu 参数使用 x86 模拟器推理 hbm 模型。

 

 

1.3.4 多输入模型一致性验证

 

1.3.4.1 输入数据准备

 

当模型存在多种输入,需要根据不同的输入类型准备输入数据,参考前文 pyramid、resizer、ddr 模型的输入数据准备。需要注意的是:

 

  1. 如果模型本身有多个输入,那么输入数据用逗号进行分隔,对应的--yuv-shape/--roi-coord/--roi-size/--image-stride 等描述输入信息的参数也都用逗号分隔;

  2. 如果模型的多个输入的来源不同,有些输入没有--yuv-shape 之类的参数,那么逗号之间可以为空。

     

1.3.4.2 运行命令

 

  • 假如模型有 4 个输入,分别是 ddr, resizer, ddr, pyramid 输入;

  • resizer 输入的 HxW 为 540x960,ROI 的起始坐标为 0x0, 尺寸为 128x128;

  • pyramid 输入的 HxW 为 540x960;

  • 输入文件名分别是 input_0.bin, input_1.yuv, input_2.bin,input_3.yuv, 命令行示例如下:

 

hbdk-model-verifier --hbm model.hbm --model-pt model.pt --model-input input_0.bin,input_1.yuv,input_2.bin,input_3.yuv --yuv-shape,540x960,,540x960 
--roi-coord ,0x0,, --roi-size ,128x128,, --image-stride ,960,,960 --ip {board_ip}

 

参数说明:

--image-stride:调整 pyramid/resizer 的 W 跨距,默认情况下为“None”。在某些场景下,image-stride 可能不等于 W 维度,所以需要通过配置此参数进行调整。

 

 

1.4 输出结果

 

hbdk-model-verifier 工具的运行 log 中输出的信息包括模型在开发板端的执行时间和 verifier 结果。如下是使用 hbdk-model-verifier 工具验证 mobilenetv1 示例 pt 模型和 hbm 模型一致性的输出 log 的解读。

1.4.1 耗时信息

 

09-22-2023 14:26:35 root:INFO:Verifier Total Time on dev board with connection time (including BPU, CPU, IO, network and time to wait for lock): 9.485120 ms
09-22-2023 14:26:35 root:INFO:Verifier Total Time on dev board without connection time (including BPU, CPU, IO and network time): 8.821064 ms
09-22-2023 14:26:35 root:INFO:
#在开发板端的BPU+CPU执行时间
======> Model execution time (including BPU and CPU): 0.811332 ms
#在开发板端的BPU执行时间
======> BPU execution time (BPU function call consumed time): 0.682924 ms
#在开发板端的CPU执行时间
======> CPU execution time (including context switch and cpu operator): 0.128408 ms

注:

  1. log 中输出的为单核单线程耗时信息;

  2. 如果配置了--skip-bpu 参数,即使用 x86 模拟器推理模型,输出 log 中则不包括耗时信息;

  3. 如果采用随机输入,输出的耗时信息可能和实际情况相差较大。

 

 

1.4.2 verifier 结果

 

如果 log 中输出[SUCCESS] output file [{output_node_name}。txt] is same,则说明一致性验证通过,否则验证失败。log 中的一致性验证通过的结果如下所示:

 

09-22-2023 14:26:42 root:INFO:======> Compare Results on BPU Board vs. Framework
09-22-2023 14:26:42 root:INFO: [SUCCESS] output file [hbdk_output__backbone_output_1_0_hz_conv2d.txt] is same.

 

 

02 hbdk-sim

 

2.1 工具简介

 

hbdk-sim 工具是由地平线开发,用于在 x86 环境下模拟 BPU 对 hbm 模型推理的工具。

 

2.2 获取方式

 

地平线算法工具链的 docker 镜像中已经包含了 hbdk-sim 工具,可以直接在 docker 中进行使用。

 

2.3 使用场景和方式

 

2.3.1 输入数据准备

 

参考 1.3.1,1.3.2,1.3.3 节进行不同类型输入数据的准备。

 

 

2.3.2 运行命令

 

  1. 模拟推理 pyramid 输入模型,命令行示例如下:

 

hbdk-sim --model-name {model_name} --hbm model.hbm --input-binary nv12.yuv --yuv-size {HxW} --output ./result

 

1.模拟推理 resizer 输入模型,命令行示例如下:

 

hbdk-sim --model-name {model_name} --hbm model.hbm --input-binary nv12.yuv --yuv-shape {HxW} --roi-coord {YxX}  --roi-size {roi_hxroi_w} --output ./result

resizer 模型的 ROI 和模型输入尺寸需要满足 resizer 本身的硬件限制。

 

1.模拟推理 ddr 输入模型,命令行示例如下:

hbdk-sim --model-name {model_name} --hbm model.hbm --input-binary featuremap.bin --output ./result

 

1.模拟推理复杂输入模型,命令行示例如下:

2.假如模型有 4 个输入,

    • 分别是 ddr, resizer, ddr, pyramid 输入;

    • resizer 输入的 HxW 为 540x960,ROI 的起始坐标为 0x0,尺寸为 128x128;

    • pyramid 输入的 HxW 为 540x960;

    • 输入文件名分别是 input_0.bin, input_1.yuv, input_2.bin,input_3.yuv, 命令行示例如下:

 

hbdk-sim --hbm model.hbm --input-binary input_0.bin,input_1.yuv,input_2.bin,input_3.yuv --yuv-shape,540x960,,540x960 --roi-coord ,0x0,, --roi-size ,128x128,, --image-stride ,960,,960

 

参数说明:

  • --model-name(必选):hbm 模型的名称;

  • --hbm(必选):地平线算法工具链编译的 hbm 模型;

  • --input-binary(必选):模型输入数据;

  • --output(必选):输出结果保存路径;

  • --yuv-size:NV12 输入的 shape,用于 pyramid/resizer,配置形式为 HxW;

  • --yuv-roi-coord/--yuv-roi-size:resizer 输入的 ROI 起始坐标和尺寸,配置形式为格式为 Y 坐标/ROI 高度 + "x" + X 坐标/ROI 宽度;

  • 更多参数说明可以通过运行 hbdk-sim --help 获取。

 

 

2.4 输出结果

 

hbdk-sim 的输出包括耗时信息、带宽占用信息、内存占用信息和推理结果。推理结果以。txt 文件的形式保存在配置的--output 路径下;其他信息则显示在终端的 log 中,如下所示:

 

****************************************************
#推理耗时信息                     
                     Latency Info                   
* Estimated model latency: 567 us

#带宽占用信息
                  DDR Bandwidth Info                
* Total DDR bandwidth: 4156608 bytes
* Bpu read           : 4140608 bytes
* Bpu write          : 16000 bytes

#内存占用信息
                  Memory Usage Info                 
* Bpu side memory usage peak value: 5.191 MB
* Input memory                    : 75264 Bytes
* Output memory                   : 16000 Bytes

 

 

03 hbdk-hbm-attach

 

3.1 工具简介

 

hbdk-hbm-attach 工具是由地平线开发的 hbm 文件辅助工具,用于更新或读取 hbm 文件里面的 desc(description)信息,它具有以下功能:

 

  1. 更新/提取 hbm 文件中的 desc(tag)信息,模型的 desc 信息,以及模型输入输出 feature 的 desc 信息;

  2. 修改模型的输入输出 feature name。

desc 信息是描述模型属性(如版本、任务类型、开发人员等)的信息,由用户自行添加。

 

3.2 使用流程

 

hbdk-hbm-attach 工具更新 hbm 模型的 description 信息可以分为以下 3 个步骤:

 

  1. 提取用于更新 description 信息的 json 模板;

  2. 修改 json 文件中的 description 信息;

  3. 运行 description 信息更新命令;

  4. 结果验证。

     

本文将以 mobilenetv1 的 hbm 模型为例,对更新模型 desc 信息的流程进行讲解。

 

 

3.2.1 提取用于更新 description 信息的 json 模板

 

在更新 hbm 模型的 description 信息之前,我们需要提取 hbm 模型 description 信息的 json 模板,参考命令如下:

hbdk-hbm-attach model.hbm

 

运行后会生成记录 desc 信息的 model_desc.json 文件,json 文件格式如下所示:

 

{
    "models": {
        "mobilenetv1_cls": {
            "desc": "",
            "desc_type": "string",
            "input_features": {
                "arg0[img]": {
                    "desc": "",
                    "desc_type": "string"
                }
            },
            "output_features": {
                "_backbone_output_1_0_hz_conv2d": {
                    "desc": "",
                    "desc_type": "string"
                }
            }
        }
    },
    "tag": ""
}

上述流程中提取的 model.json 可能会因权限问题不支持修改,可以使用 chmod 777 model.json 修改文件权限。

 

3.2.2 修改 json 文件

 

提取到模型 desc 信息的 json 模板后,可以通过以下方式修改 desc 信息和 feature 名称:

 

  • 如果想要修改某个 feature 的 desc 信息;可以直接编辑"desc"字段的值;

  • 如果想要修改某个 feature 的名称,只需要在这个 feature 名称对应的字典中增加修改输入/输出节点名称的保留关键字"new_name"即可。

如果不想修改某个 feature 的 desc 信息,对应的字典中请不要出现"new_name"这个 key;

 

比如,我们对步骤 1 中提取的 json 模板进行如下修改:

 

{
    "models": {
        "mobilenetv1_cls": {
            #修改模型desc
            "desc": "This is mobilenetv1 hbm",
            "desc_type": "string",
            "input_features": {
                "arg0[img]": {
                    #修改"input_features"的desc信息
                    "desc": "shape of input is 1x3x224x224",
                    "desc_type": "string",
                    #把输入名称改成"horizon_input"
                    "new_name" :"horizon_input"

                }
            },
            "output_features": {
                "_backbone_output_1_0_hz_conv2d": {
                    #修改"output_features"的desc信息
                    "desc": "shape of output is 1x1000x1x1",
                    "desc_type": "string",
                    #把输入名称改成"horizon_output"
                    "new_name" :"horizon_output"
                }
            }
        }
    },
    #修改模型tag
    "tag": "Journey to AD"
}

 

3.2.3 运行 description 信息更新命令

 

当更新 hbm 模型的 desc 信息时,json 文件是工具的输入,该文件需要放在待更新 hbm 文件的同一级目录,且文件名满足一定的规则,比如:xxx.hbm 文件对应的 desc 文件名为 xxx_desc.json。

 

json 文件修改完成后,使用以下命令更新 hbm 的 desc 信息:

hbdk-hbm-attach model.hbm --update

 

命令运行完成后,会在终端输出以下信息:

 

INFO: Will update hbm
INFO: Update feature name from "arg0[img]" to "horizon_input"
INFO: Update feature name from "_backbone_output_1_0_hz_conv2d" to "horizon_output"

 

 

3.2.4 结果验证

 

hbm 模型的 desc 信息更新完成后,我们可以再次运行以下命令来验证是否成功修改 desc 信息:

 

hbdk-hbm-attach model.hbm

 

命令运行后,生成的 model.json 文件如下所示:

 

{
    "models": {
        "mobilenetv1_cls": {
            "desc": "This is mobilenetv1 hbm",
            "desc_type": "string",
            "input_features": {
                "horizon_input": {
                    "desc": "shape of input is 1x3x224x224",
                    "desc_type": "string"
                }
            },
            "output_features": {
                "horizon_output": {
                    "desc": "shape of output is 1x1000x1x1",
                    "desc_type": "string"
                }
            }
        }
    },
    "tag": "Journey to AD"
}

 

从提取到的 model.json 文件可以看到,input_features 和 output_features 的 desc 信息和名称、模型 tag 已经成功实现了更新。

Logo

加入社区

更多推荐