hrt_model_exec工具介绍

工具简介

hrt_model_exec 是一个模型执行工具,可直接在开发板上评测模型的推理性能、获取模型信息。 一方面可以让您拿到模型时实际了解模型真实性能; 另一方面也可以帮助您了解模型可以做到的速度极限,对于应用调优的目标极限具有指导意义。

hrt_model_exec 工具源码位于 horizon_j6_open_explorer 发布物的 samples/ucp_tutorial/tools/hrt_model_exec 路径下。结构如下所示:

├── include               # 头文件
├── src                   # 工具源码
├── build.sh              # 编译脚本
├── build_x86.sh          # 编译产生x86工具
├── build_aarch64.sh      # 编译产生aarch64工具
├── CMakeLists.txt        
├── README.md
├── script                       
│   └── run_hrt_model_exec.sh    # aarch64工具运行脚本原件,编译后会下载至output_shared_J6_aarch64/script目录
└── script_x86                   
    └── run_hrt_model_exec.sh    # x86工具运行脚本原件,编译后会下载至output_shared_J6_x86/script_x86目录

hrt_model_exec 工具分别提供了模型推理 infer、模型性能分析 perf 和查看模型信息 model_info 三类功能,如下表:

编号子命令说明
1model_info获取模型信息,如:模型的输入输出信息等。
2infer执行模型推理,获取模型推理结果。
3perf执行模型性能分析,获取性能分析结果。

工具可以通过 -v 或者 --version 命令,查看工具的 dnn 预测库版本号。

hrt_model_exec -v
hrt_model_exec --version

参数描述

参数类型说明
model_filestring模型文件路径,多个路径可通过逗号分隔。
model_namestring指定某个模型的名称。
core_idint指定运行核。0:任意核,1:core0;默认为 0。
input_filestring模型输入信息。 输入后缀必须为 PNG/JPG/JPEG/png/jpg/jpeg/bin/txt 中的一种。每个输入之间需要用英文字符的逗号隔开,,如:xxx.jpg,input.txt
input_img_propertiesstring模型图像输入的色彩空间信息,参数范围[Y, UV]。 input_file 中每一个图片类型输入都需要指定一个 Y/UV 类型,每个输入色彩空间之间需要用英文字符的逗号隔开,,如:Y,UV
input_valid_shapestring模型动态 validShape 输入信息。 若模型输入属性 validShape 中含有 -1,则需要将 -1 的部分进行补全,多个 validShape 间通过英文分号间隔。如:--input_valid_shape="1,376,376,1;1,188,188,2"
input_stridestring模型动态 stride 输入信息。 若模型输入属性 stride 中含有 -1,则需要将 -1 的部分进行补全,多个 stride 间通过英文分号间隔。如:--input_stride="144384,384,1,1;72192,384,2,1"
frame_countint执行模型运行帧数。子命令为 infer 时,默认为 1。子命令为 perf 时,默认为 200,没有设置 perf_time 时生效。
dump_intermediatestringdump模型每一层输入和输出,参数范围[0, 3]。
  • dump_intermediate=0 时,默认dump功能关闭。
  • dump_intermediate=1 时,模型中每一层节点输入数据输出数据以 bin 方式保存, 其中节点输入输出为 stride 数据。
  • dump_intermediate=2 时,模型中每一层节点输入数据和输出数据以 bintxt 两种方式保存,其中节点输入输出为 stride 数据。
  • dump_intermediate=3 时,型中每一层节点输入数据和输出数据以 bintxt 两种方式保存,其中节点输入输出为 valid 数据。
  • enable_dumpbool使能dump模型输入和输出,默认为 false
    dump_precisionint控制txt格式输出float型数据的小数点位数,默认为 9
    dequantize_processbool对模型输出进行反量化处理,在 enable_dumptrue 时生效,默认为 false
    remove_padding_processbool对模型输出进行去padding处理,在 enable_dumptrue 时生效,默认为 false
    dump_formatstringdump模型输入和输出的格式,参数范围[bin, txt]。默认为 bin
    dump_txt_axisint控制txt格式输入输出的换行规则。若输出维度为n,则参数范围为[0, n], 默认为 -1,一行一个数据。
    enable_cls_post_processbool使能分类后处理,默认为 false。 子命令为 infer 时配合使用,目前只支持ptq分类模型的后处理,打印分类结果。
    perf_timeint设置 perf 运行时间,单位:分钟,默认为 0
    thread_numint设置程序运行线程数(并行度),数值可以表示最多有多少个任务在并行处理,范围[1, 8], 默认为 1, 设置大于8时按照8个线程处理。
    测试延时,数值需要设置为1,没有资源抢占发生,延时测试更准确。
    测试吞吐,建议设置>2 (BPU核心个数),调整线程数使BPU利用率尽量高,吞吐测试更准确。
    profile_pathstring统计工具日志产生路径,运行产生profiler.log和profiler.csv,分析op耗时和调度耗时。一般设置 --profile_path="." 即可,代表在当前目录下生成日志文件。
    dump_pathstringdump模型输入输出的路径,设置 enable_dumpdump_intermediate 时生效。

    设置profile_path参数且工具正常运行后会产生profiler.log和profiler.csv文件,文件中包括如下参数:

    • ucp_version:UCP及HBRT版本号。

    • perf_result:记录perf结果。

    参数说明
    FPS每秒处理的帧数。
    average_latency指定模型中某个模型平均一帧运行所花费的时间。
    • running_condition:运行环境信息。
    参数说明
    core_id程序运行设置的bpu核。
    frame_count程序运行的总帧数。
    model_name评测模型的名字。
    run_time程序运行时间。
    thread_num程序运行的线程数。
    • model_latency:模型节点耗时统计。
    参数说明
    Node-pad模型输入padding耗时。
    Node-NodeIdx-NodeType-NodeName模型节点耗时信息。注:NodeIdx为模型节点拓扑排序的序号,NodeType为具体的节点类型,如Dequantize,NodeName为具体的节点名称。
    • processor_latency:模型处理器耗时统计。
    参数说明
    BPU_inference_time_cost每帧推理BPU处理器耗时。
    CPU_inference_time_cost每帧推理CPU处理器耗时。
    • task_latency:模型任务耗时统计。
    参数说明
    TaskRunningTime任务实际运行耗时,耗时时间包括UCP框架耗时。

    使用说明

    工具提供三类功能:模型信息获取、单帧推理功能、多帧性能评测。

    运行 hrt_model_exechrt_model_exec -hhrt_model_exec --help 获取工具使用详情。

    model_info

    概述

    该参数用于获取模型信息,模型支持范围:qat模型,ptq模型。该参数与 model_file 一起使用,用于获取模型的详细信息,信息包括模型输入输出信息 hbDNNTensorProperties

    不指定 model_name 输出模型中所有模型信息,指定 model_name 则只输出对应模型的信息。

    示例

    1. 单模型
    hrt_model_exec model_info --model_file=xxx.hbm
    
    ../aarch64/bin/hrt_model_exec model_info --model_file=resnet50_224x224_nv12.hbm
    
    Load model to DDR cost 1965.57ms.
    This model file has 1 model:
    [resnet50_224x224_nv12]
    ---------------------------------------------------------------------
    [model name]: resnet50_224x224_nv12
    
    input[0]:
    name: input_y
    valid shape: (1,224,224,1,)
    aligned byte size: -1
    tensor type: HB_DNN_TENSOR_TYPE_U8
    quanti type: NONE
    stride: (-1,-1,1,1,)
    
    input[1]:
    name: input_uv
    valid shape: (1,112,112,2,)
    aligned byte size: -1
    tensor type: HB_DNN_TENSOR_TYPE_U8
    quanti type: NONE
    stride: (-1,-1,2,1,)
    
    output[0]:
    name: output
    valid shape: (1,1000,)
    aligned byte size: 4096
    tensor type: HB_DNN_TENSOR_TYPE_F32
    quanti type: NONE
    stride: (4000,4,)
    
    ---------------------------------------------------------------------
    1. 多模型(输出所有模型信息)
    hrt_model_exec model_info --model_file=xxx.hbm,xxx.hbm  
    1. 多模型--pack模型(输出指定模型信息)
    hrt_model_exec model_info --model_file=xxx.hbm --model_name=xx

    infer

    概述

    该参数用于模型推理,用户自定义输入图片,推理一帧。该参数需要与 input_file 一起使用,指定输入图片路径,工具根据模型信息resize图片,整理模型输入信息。

    程序单线程运行单帧数据,输出模型运行的时间。

    示例

    1. 单模型
    hrt_model_exec infer --model_file=xxx.hbm --input_file=xxx.bin
    
    ../aarch64/bin/hrt_model_exec infer --model_file=resnet50_224x224_nv12.hbm --input_file=zebra_cls.jpeg,zebra_cls.jpeg --input_img_properties=Y,UV --input_stride=50176,224,1,1;25088,224,2,1
    Load model to DDR cost 1965.03ms.
    [I][35143][06-28][10:39:51:373][file_util.cpp:527][hrt_model_exec][HRT_MODEL_EXEC] The input valid shape is (1,224,224,1), and the image [zebra_cls.jpeg] will be scaled to 224x224
    [I][35143][06-28][10:39:51:377][file_util.cpp:527][hrt_model_exec][HRT_MODEL_EXEC] The input valid shape is (1,112,112,2), and the image [zebra_cls.jpeg] will be scaled to 224x224
    
    ---------------------Frame 0 begin---------------------
    Infer time: 1.464 ms
    ---------------------Frame 0 end---------------------
    1. 多模型
    hrt_model_exec infer --model_file=xxx.hbm,xxx.hbm --model_name=xx --input_file=xxx.jpg

    可选参数

    您可以根据场景选择使用以下参数:

    core_idinput_img_propertiesinput_valid_shapeinput_strideframe_countdump_intermediateenable_dumpdump_precisiondequantize_processremove_padding_processdump_formatdump_txt_axisenable_cls_post_processdump_path

    参数使用说明请参考 参数描述 章节。

    perf

    概述

    该参数用于测试模型性能。 该模式下,您无需输入数据,程序根据模型信息自动构造输入tensor,tensor数据为随机数。 程序默认单线程运行200帧数据,当指定perf_time参数时,frame_count参数失效,程序会执行指定时间后退出。 输出模型运行的latency、以及帧率信息。程序每200帧打印一次性能信息: latency的最大、最小、平均值,不足200帧程序运行结束打印一次。

    程序最后输出running相关数据, 包括:程序线程数、帧数、模型推理总时间,模型推理平均latency,帧率信息。

    示例

    1. 单模型
    hrt_model_exec perf --model_file=xxx.hbm
    
    ../aarch64/bin/hrt_model_exec perf --model_file=resnet50_224x224_nv12.hbm --input_stride=50176,224,1,1;25088,224,2,1 --frame_count=200 --thread_num=8
    [BPU][[BPU_MONITOR]][INFO]BPULib verison(2, 0, 1)[]!
    Load model to DDR cost 1965.34ms.
    Frame count: 200,  Thread Average: 5.262160 ms,  thread max latency: 5.498000 ms,  thread min latency: 1.636000 ms,  FPS: 1467.383789
    
    Running condition:
      Thread number is: 8
      Frame count   is: 200
      Program run time: 136.440000 ms
    Perf result:
      Frame totally latency is: 1052.432007 ms
      Average    latency    is: 5.262160 ms
      Frame      rate       is: 1465.845793 FPS
    1. 多模型
    hrt_model_exec perf --model_file=xxx.hbm,xxx.hbm --model_name=xxx

    可选参数

    您可以根据场景选择使用以下参数:

    core_idinput_fileinput_img_propertiesinput_valid_shapeinput_strideframe_countdump_intermediateperf_timethread_numprofile_path

    参数使用说明请参考 参数描述 章节。

    多输入模型说明

    工具 infer 推理功能支持多输入模型的推理,支持图片输入、二进制文件输入以及文本文件输入,输入数据用逗号隔开。 模型的输入信息可以通过 model_info 进行查看。

    示例:

    hrt_model_exec infer --model_file=xxx.hbm --input_file=xxx.jpg,input.txt

    动态输入说明

    若模型的输入是动态的,您需要根据输入实际情况使用 input_valid_shapeinput_stride 参数来补全动态信息。您可以选择以下两种方式指定参数:

    • 只给定动态输入的 validShapestride 信息。

    • 给定所有输入的 validShapestride 信息,非动态输入的信息必须与模型信息保持一致。

    注解

    工具内部会对于动态输入的信息会进行最大限度的自动补全,方便您更简单的进行性能评测,您可以根据实际情况选择是否交由工具内部进行自动补全。

    • 若输入 stride 为动态的,validShape 为固定的,您可以不指定 input_stride 参数,工具会自动按照最小对齐规则进行补齐并打印对齐信息。

    • 若输入 validShapestride 都是动态的:

      • 若指定输入为图片类型,您需要指定图片的色彩空间信息 input_img_properties,其余参数可不指定,工具内部按照图片的大小补全 input_valid_shapeinput_stride 信息。

      • 若指定输入为图片之外的类型或不指定输入,您需要设置 input_valid_shape 信息,内部会自动补全 input_stride 信息并打印。

    动态输入介绍 章节中的模型为例,您可以通过以下命令运行模型:

    # 只给定动态输入的信息
    hrt_model_exec infer --model_file=xxx.hbm --input_file="input_y.bin,input_uv.bin,input_roi.bin" --input_valid_shape="1,220,220,1;1,110,110,2" --input_stride="49280,224,1,1;24640,224,2,1"
    
    # 给定所有输入的信息
    hrt_model_exec infer --model_file=xxx.hbm --input_file="input_y.bin,input_uv.bin,input_roi.bin" --input_valid_shape="1,220,220,1;1,110,110,2;1,4" --input_stride="49280,224,1,1;24640,224,2,1;16,4"

    图像类型输入说明

    input_file 给定图像输入时,需要使用 input_img_properties 参数来指定您想使用该图片的哪个色彩空间当做模型的输入,目前只支持 YUV 两种色彩空间。

    hrt_model_exec infer --model_file=xxx.hbm --input_file="img.jpg,img.jpg,input_roi.bin" --input_img_properties="Y,UV"

    工具运行说明

    构建

    ucp_tutorial/tools/hrt_model_exec 目录下有预先配置好的编译脚本 build.sh,选项 -a x86-a aarch64 分别支持两种编译方式,您可以使用该脚本并指定编译选项进行编译。 此外,目录中也包含了 build_aarch64.shbuild_x86.sh 两个编译脚本,分别对应了两个编译选项,使用这两个脚本进行编译与使用 build.sh 脚本并指定编译选项等效。

    # 构建板端运行工具
    bash -ex build_aarch64.sh
    # 构建x86端运行工具
    bash -ex build_x86.sh

    运行

    构建板端运行工具后,将生成 output_shared_J6_aarch64 文件夹。 您可以将文件夹复制到板端环境中并执行 output_shared_J6_aarch64/script/run_hrt_model_exec.sh 来使用该工具。

    构建x86端运行工具后,将生成 output_shared_J6_x86 文件夹。 您可以在x86端直接执行 output_shared_J6_x86/script_x86/run_hrt_model_exec.sh 来使用该工具。

    run_hrt_model_exec.sh 脚本分为设置环境变量和获取模型信息并推理模型两部分。

    # 设置环境变量
    # arch代表架构类型,aarch64或x86
    arch=aarch64
    bin=../$arch/bin/hrt_model_exec
    lib=../$arch/lib/
    export LD_LIBRARY_PATH=${lib}:${LD_LIBRARY_PATH}
    
    # 获取模型信息、推理模型、获取模型性能
    ${bin} model_info --model_file=xxx.hbm
    
    ${bin} infer --model_file=xxx.hbm --input_file=xxx.bin
    
    ${bin} perf --model_file=xxx.hbm --frame_count=200
    注解

    运行前需要修改 run_hrt_model_exec.sh 相应参数,以确保模型和输入文件正确。您还可以灵活使用其他参数来使用更多功能。

    常见问题

    Latency、FPS数据是如何统计的?

    Latency是指单流程推理模型所耗费的平均时间,重在表示在资源充足的情况下推理一帧的平均耗时,体现在上板运行是单核单线程统计;统计方法伪代码如下:

    // Load model and prepare input and output tensor
      ...
    
      // Loop run inference and get latency
      {
        int32_t const loop_num{1000};
        start = std::chrono::steady_clock::now();
        for(int32_t i = 0; i < loop_num; i++){
            hbUCPSchedParam sched_param{};
            HB_UCP_INITIALIZE_SCHED_PARAM(&sched_param);
            // create task
            hbDNNInferV2(&task_handle, output_tensor, input_tensor, dnn_handle);
            // submit task
            hbUCPSubmitTask(task_handle, &sched_param);
            // wait task done
            hbUCPWaitTaskDone(task_handle, 0);
            // release task handle
            hbUCPReleaseTask(task_handle);
            task_handle = nullptr;
        }
        end = std::chrono::steady_clock::now();
        latency = (end - start) / loop_num;
      }
    
      // release tensor and model
      ...

    FPS是指多流程同时进行模型推理平均一秒推理的帧数,重在表示充分使用资源情况下模型的吞吐,体现在上板运行为单核多线程;统计方法是同时起多个线程进行模型推理,计算平均1s推理的总帧数。

    通过Latency推算FPS与工具测出的FPS为什么不一致?

    Latency与FPS的统计情景不同,Latency为单流程(单核单线程)推理,FPS为多流程(单核多线程)推理,因此推算不一致;若统计FPS时将流程(线程)数量设置为 1 ,则通过Latency推算FPS和测出的一致。

    Perf时出现内存不足如何处理?

    当提示内存不足时,可以通过以下方式解决:

    • 减少 thread_num 的值,以减少并行度,降低内存占用。

    • 优化模型,减少模型的内存占用。