社区首页
技术讨论创新帖
全部新帖
资料区
社区活动
联系管理员
★ 社区积分制度
★ 新手必读
★ 申请版主★
请
登录
后使用快捷导航
没有帐号?
注册
首页
|
电子技术
|
嵌入式
模拟电子
单片机
电源管理
传感器
半导体
电子应用
|
工业控制
物联网
汽车电子
网络通信
医疗电子
手机便携
测试测量
安防电子
家用电子
机器人
新能源
电子头条
|
社区
|
论坛
测评
博客
大学堂
|
下载
|
下载中心
电路图
精品文集
电路图
|
参考设计
|
Datasheet
|
活动
|
直播
datasheet
datasheet
文章
搜索
登录
注册
中文
En
论坛
切换旧版
电子工程世界-论坛
»
论坛
›
电子技术交流
›
国产芯片交流
›
玄铁RISC-V活动专区
›
【玄铁杯第三届RISC-V应用创新大赛】LicheePi 4A HHB工 ...
返回列表
发新帖
回复
阅
788
|
回
0
DDZZ669
当前离线
纯净的硅(中级)
最后登录
2025-1-11
在线时间
137 小时
威望
1122分
芯积分
1921分
(兑换)
E金币
0枚
(兑换)
(兑换)
好友
2
DDZZ669
291
帖子
5
TA的资源
纯净的硅(中级)
+ 好友
私信
楼主
发表于2023-10-28 16:34
只看该作者
【玄铁杯第三届RISC-V应用创新大赛】LicheePi 4A HHB工具使用基础与MobilenertV2测试
[复制链接]
在LicheePi4A板子上运行AI模型,需要使用HHB工具进行模型部署,上篇文章测试Yolov5n中已经用到了HHB工具。 由于对HHB工具的使用还比较陌生,本篇参考HHB 用户手册:
,进行HHB工具的实操使用测试,然后再测试MobilenertV2使用HHB编译后,在板子中的运行效果,并分析Demo代码的程序逻辑。 # 1 HHB快速上手 HHB (Heterogeneous Honey Badger tools collection) 是 T-HEAD 提供的一套针对无剑 SoC 平台的神经网络模型部署工具集。 包括了编译优化,性能分析,过程调试,结果模拟等一系列部署时所需的工具。 ![](https://xxpcb-1259761082.cos.ap-shanghai.myqcloud.com/pic2/LiPi4A/9/1.png) ## 1.1 HHB工具确认 HHB 已经默认安装在docker中的 /tools 目录,进入docker后,可以用 hhb --version 命令确认 ```sh xxpcb@xxpcb-ubuntu20:~/Desktop$ sudo docker restart your.hhb2.4 [sudo] password for xxpcb: your.hhb2.4 xxpcb@xxpcb-ubuntu20:~/Desktop$ sudo docker exec -it your.hhb2.4 /bin/bash root@9b266aa1e9ac:/# hhb --version HHB version: 2.4.5, build 20230703 root@9b266aa1e9ac:/# ``` ## 1.2 运行脚本查看 以在玄铁 c906 上部署 mobilenet 为例,在 /home/example/basic/c906/onnx_mobilenetv2/ 中,已经有完整的 run.sh 描述了整个过程。 ```sh root@9b266aa1e9ac:~# ls root@9b266aa1e9ac:~# cd /home/example/basic/c906/onnx_mobilenetv2/ root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls deploy.py persian_cat.jpg run.sh ``` run.sh中的内容 ```sh #!/bin/bash -x hhb -S --model-file ../../model/mobilenetv2-12.onnx --data-scale 0.017 --data-mean "124 117 104" --board c906 --input-name "input" --output-name "output" --input-shape "1 3 224 224" --postprocess save_and_top5 --simulate-data persian_cat.jpg ``` ## 1.3 参数含义 hhb后面的第一个参数-S是流程控制参数,其所有可取值的含义如下 ### 1.3.1 流程控制参数 | 流程控制参数 | 对应的英文全称 | 含义 | | ------------ | -------------- | ------------------------------------ | | -E | import | 执行到 import 阶段为止 | | -Q | quantize | 执行到 quantize 阶段为止 | | -C | codegen | 执行到 codegen 阶段为止 | | -D | deploy | 执行到编译出目标平台的可执行文件为止 | | -S | simulate | 执行到使用模拟器执行出结果为止 | 后续的参数是常规参数 ### 1.3.2 常规选项 | 参数 | 值 | 含义 | | --------------- | ------------------------------- | ------------------------------------------------------------ | | --model-file | ../../model/mobilenetv2-12.onnx | 指定模型文件所在位置,此例是mobilenetv2-12.onnx | | --data-scale | 0.017 | 输入数值的缩放,默认是1,此例是0.017 | | --data-mean | "124 117 104" | 输入的均值,不同数值之间按空格(或者分号)分开 | | --board | c906 | 设置目标平台(可选th1520,c906,c908,c920,c920v2, x86_ref) | | --input-name | "input" | 指定模型的输入节点名字 | | --output-name | "output" | 指定模型的输出节点名字 | | --input-shape | "1 3 224 224" | 指定模型的输入节点的形状 | | --postprocess | save_and_top5 | 设置后处理的类型,此例是保存到文件,并且打印输出中数值最大的5项 | | --simulate-data | persian_cat.jpg | 指定模拟执行的数据集路径 | ## 1.4 运行脚本 ### 1.4.1 运行中的打印 运行该脚本,输出结果如下: ```sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ./run.sh + hhb -S --model-file ../../model/mobilenetv2-12.onnx --data-scale 0.017 --data-mean '124 117 104' --board c906 --input-name input --output-name output --input-shape '1 3 224 224' --postprocess save_and_top5 --simulate-data persian_cat.jpg [2023-10-28 01:45:25] (HHB LOG): Start import model. [2023-10-28 01:45:31] (HHB LOG): Model import completed! [2023-10-28 01:45:31] (HHB LOG): Start quantization. [2023-10-28 01:45:31] (HHB LOG): Start optimization. [2023-10-28 01:45:31] (HHB LOG): Optimization completed! [2023-10-28 01:45:31] (HHB LOG): Start conversion to csinn. [2023-10-28 01:45:32] (HHB LOG): Conversion completed! [2023-10-28 01:45:32] (HHB LOG): Start operator fusion. [2023-10-28 01:45:32] (HHB LOG): Operator fusion completed! [2023-10-28 01:45:32] (HHB LOG): Start operator split. [2023-10-28 01:45:32] (HHB LOG): Operator split completed! [2023-10-28 01:45:32] (HHB LOG): Start layout convert. [2023-10-28 01:45:32] (HHB LOG): Layout convert completed! [2023-10-28 01:45:32] (HHB LOG): Quantization completed! [2023-10-28 01:45:46] (HHB LOG): cd hhb_out; qemu-riscv64 -cpu c906fdv hhb_runtime ./hhb.bm persian_cat.jpg.0.bin Run graph execution time: 10309.05469ms, FPS=0.10 === tensor info === shape: 1 3 224 224 data pointer: 0x25ec40 === tensor info === shape: 1 1000 data pointer: 0x1cace0 The max_value of output: 16.000000 The min_value of output: -7.933594 The mean_value of output: 0.001621 The std_value of output: 8.914919 ============ top5: =========== 283: 16.000000 281: 13.976562 287: 12.195312 282: 11.421875 285: 11.335938 root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ``` ### 1.4.2 运行后的输出文件 命令会在当前目录的子目录 hhb_out 中生成示例程序,并且展现示例图片的参考结果: ```sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls deploy.py hhb_out persian_cat.jpg run.sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls hhb_out/ hhb.bm hhb_runtime io.c io.h main.c main.o model.c model.o model.params persian_cat.jpg.0.bin persian_cat.jpg.0.bin_output0_1_1000.txt process.c process.h root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ``` hhb_out 中生成文件含义如下。 板子中运行需要用的文件: - hhb_runtime:生成的可执行文件 - hhb.bm:示例程序使用的模型权重 - persian_cat.jpg.0.bin:经过的预处理的输入数据 其它文件: - main.c:示例程序的参考入口 - model.c:模型结构文件,与模型结构相关 - model.params:模型权重数据 - io.c:读写文件的辅助函数 - io.h:读写文件的辅助函数声明 - process.c:图像预处理函数 - process.h:图像预处理函数声明 ### 1.4.3 板子中运行 将这些复制到 c906 Linux 操作系统的开发板的任意目录中,然后执行如下命令,即可展现 mobilenet v2 的分类结果: ```sh ./hhb_runtime hhb.bm persian_cat.jpg.0.bin ``` 没有c906的板子,这里就不演示了。 ## 1.5 性能分析 profiler 子命令是 HHB 集成的一个性能分析工具,负责分析网络模型的算力和内存读写等性能相关的热点,为特定平台上的模型优化提供量化数据。 可以使用如下命令,即可统计 mobilenetv2 的理论算力: ```sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# hhb profiler --model-file ../../model/mobilenetv2-12.onnx --indicator all -in "input" -on "output" -is "1 3 224 224" Toal profiler information as follows: Total calculation amount: macc=300774272, flops=601827648 Total memory(float): params=13947264 bytes, output=54308672 bytes. Total ddr: accum_ddr=0 bytes, coeff_ddr=0 bytes, input_ddr=0 bytes, output_ddr=0 bytes. root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ``` 参数说明: | 参数 | 值 | 含义 | | ----------------- | ------------------------------- | ---------------------------------------------- | | --model-file | ../../model/mobilenetv2-12.onnx | 指定统计所用的源文件 | | --indicator | all | 指定需要统计的信息,cal 表示只统计计算量 | | -in/--input-name | "input" | 指定模型的输入节点形状,多个输入用分号分隔 | | -on/--output-name | "output" | 指定模型的输出节点名字,多个输出用分号分隔 | | -is/--input-shape | "1 3 224 224" | 选项指定模型的输入节点形状,多个输入用分号分隔 | # 2 HHB其它知识点 ## 2.1 模型与平台 HHB 支持将多种训练框架导出的模型部署到多种目标平台上: ![](https://xxpcb-1259761082.cos.ap-shanghai.myqcloud.com/pic2/LiPi4A/9/2.png) 目前支持的模型类型:caffemodel、pb、onnx、tflite - ONNX 对应的 .onnx 后缀的格式 - Caffe 框架导出的模型分两个文件,分别以.caffemodel和.prototxt作为文件后缀 - pb 格式的模是 TensorFlow 框架导出的模型 - tflite 模型是 .tflite 后缀的格式的模型,通常由 tensorflow 框架训练出来的模型转换而来 目前支持的目标平台:C906、C908、C920、TH1520、x86_ref - c906 是玄铁 9 系列中高能耗比的矢量计算 CPU,D1主要使用 C906 的RISC-V 矢量计算指令集作为模型推理的加速方式 - TH1520 是首款基于无剑600 SoC平台设计的量产多模态AI处理器SoC原型 ## 2.2 各种量化方式 模型通常是用 float32 而来,而玄铁平台侧重嵌入式和边缘计算方向,所以一般需要通过量化才能在玄铁平台正确执行。 | 量化方式 | 参数名称 | 其它说明 | | -------------------------------------------------- | --------------- | -------------------------------------------------------- | | int8 对称量化 | int8_sym | 一般不推荐,相比其他量化方式精度损失较大 | | int8 非对称量化 | int8_asym | | | uint8 非对称量化 | uint8_asym | | | int16 量化 | int16_sym | | | int16_sym | float16 | 通常是精度表现最好的方案,也是 RISC-V CPU 的推荐量化方式 | | 输入和输出 int8 非对称量化权重 int8 对称量化 | int8_asym_w_sym | 常见于 TFLite 格式的量化模型 | | 输入和输出 float16 量化权重 int8 对称量化 | float16_w_int8 | HHB 定制的一种量化方式,兼顾精度和权重大小 | ## 2.3 CPU模拟器 RISC-V CPU 模拟器可以执行模拟已经编译完成的玄铁 CPU 可执行文件。 ![](https://xxpcb-1259761082.cos.ap-shanghai.myqcloud.com/pic2/LiPi4A/9/3.png) - QEMU:用CPU指令做推理的玄铁平台,可以直接使用QEMU模拟器模拟执行 - 开发板执行:将模型编译成可执行文件,执行在各种玄铁平台实体开发板 以c906平台的MobileNet 为例,使用如下命令,将模型转换为 CPU 执行所需的可执行文件: ```sh hhb -D --model-file ../../model/mobilenetv2-12.onnx --data-scale 0.017 --data-mean "124 117 104" --board c906 --input-name "input" --output-name "output" --input-shape "1 3 224 224" --postprocess save_and_top5 ``` 测试前可将之前的hhb_out目录先删掉,执行结果如下: ```sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls deploy.py hhb_out persian_cat.jpg run.sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# rm -rf hhb_out/ root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls deploy.py persian_cat.jpg run.sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# hhb -D --model-file ../../model/mobilenetv2-12.onnx --data-scale 0.017 --data-mean "124 117 104" --board c906 --input-name "input" --output-name "output" --input-shape "1 3 224 224" --postprocess save_and_top5 [2023-10-28 06:33:36] (HHB LOG): Start import model. [2023-10-28 06:33:37] (HHB LOG): Model import completed! [2023-10-28 06:33:37] (HHB LOG): Start quantization. [2023-10-28 06:33:37] (HHB LOG): Start optimization. [2023-10-28 06:33:37] (HHB LOG): Optimization completed! [2023-10-28 06:33:37] (HHB LOG): Start conversion to csinn. [2023-10-28 06:33:38] (HHB LOG): Conversion completed! [2023-10-28 06:33:38] (HHB LOG): Start operator fusion. [2023-10-28 06:33:38] (HHB LOG): Operator fusion completed! [2023-10-28 06:33:38] (HHB LOG): Start operator split. [2023-10-28 06:33:38] (HHB LOG): Operator split completed! [2023-10-28 06:33:38] (HHB LOG): Start layout convert. [2023-10-28 06:33:38] (HHB LOG): Layout convert completed! [2023-10-28 06:33:38] (HHB LOG): Quantization completed! root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls deploy.py hhb_out persian_cat.jpg run.sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls hhb_out/ hhb.bm hhb_runtime io.c io.h main.c main.o model.c model.o model.params process.c process.h root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ``` 调用 RISC-V CPU 模拟器模拟 c906 CPU 的执行结果: ```sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# qemu-riscv64 -cpu c906fdv hhb_out/hhb_runtime hhb_out/hhb.bm persian_cat.jpg Run graph execution time: 10032.33398ms, FPS=0.10 === tensor info === shape: 1 3 224 224 data pointer: 0x1cace0 === tensor info === shape: 1 1000 data pointer: 0x25a7c0 The max_value of output: 16.046875 The min_value of output: -7.957031 The mean_value of output: 0.001386 The std_value of output: 8.905679 ============ top5: =========== 283: 16.046875 281: 13.945312 287: 12.203125 282: 11.437500 285: 11.296875 root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ls deploy.py hhb_out persian_cat.jpg persian_cat.jpg_output0_1_1000.txt run.sh root@9b266aa1e9ac:/home/example/basic/c906/onnx_mobilenetv2# ``` # 3 MobilenertV2在板子中测试 前面介绍的hhb的操作,都是是Ubuntu虚拟机的Docker中测试的,模拟使用的是C906平台。 本小节在LicheePi4A板子(TH1520平台)中实际测试MobilenertV2的效果。 ## 3.1 准备工作 首先将mobilenetv2-12.onnx模型下载到示例目录 /home/example/th1520_npu/onnx_mobilenetv2_c++下。 方法一:可以去github下载: ![](https://xxpcb-1259761082.cos.ap-shanghai.myqcloud.com/pic2/LiPi4A/9/4.png) 方法二:此模型在 /home/example/basic/model目录下已经有了,可以拷贝过来。 然后在 /home/example/th1520_npu目录,从github下载优化版本 opencv 所需的库文件 ```sh git clone https://github.com/zhangwm-pt/prebuilt_opencv.git ``` 实测记录: ```sh root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# ls main.cpp persian_cat.jpg synset.txt root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# cp /home/example/basic/model/mobilenetv2-12.onnx ./ root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# ls main.cpp mobilenetv2-12.onnx persian_cat.jpg synset.txt root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# cd .. root@9b266aa1e9ac:/home/example/th1520_npu# ls onnx_mobilenetv2_c++ yolov5n root@9b266aa1e9ac:/home/example/th1520_npu# git clone https://github.com/zhangwm-pt/prebuilt_opencv.git Cloning into 'prebuilt_opencv'... remote: Enumerating objects: 461, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (3/3), done. remote: Total 461 (delta 0), reused 4 (delta 0), pack-reused 457 Receiving objects: 100% (461/461), 47.56 MiB | 81.00 KiB/s, done. Resolving deltas: 100% (78/78), done. Updating files: 100% (395/395), done. root@9b266aa1e9ac:/home/example/th1520_npu# ls onnx_mobilenetv2_c++ prebuilt_opencv yolov5n root@9b266aa1e9ac:/home/example/th1520_npu# ``` ## 3.2 HHB编译 将 ONNX 模型交叉编译成 NPU 上可执行的程序,NPU 上仅支持8位或者16位定点运算,本示例中指定为 int8 非对称量化,指令如下: ```sh cd /home/example/th1520_npu/onnx_mobilenetv2_c++ hhb -D --model-file mobilenetv2-12.onnx --data-scale 0.017 --data-mean "124 117 104" --board th1520 --postprocess save_and_top5 --input-name "input" --output-name "output" --input-shape "1 3 224 224" --calibrate-dataset persian_cat.jpg --quantization-scheme "int8_asym" ``` 如果要编译为CPU类型的,指令为: ```sh hhb -D --model-file mobilenetv2-12.onnx --data-scale 0.017 --data-mean "124 117 104" --board c920 --postprocess save_and_top5 --input-name "input" --output-name "output" --input-shape "1 3 224 224" ``` 实测记录: ```sh root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# hhb -D --model-file mobilenetv2-12.onnx --data-scale 0.017 --data-mean "124 117 104" --board th1520 --postprocess save_and_top5 --input-name "input" --output-name "output" --input-shape "1 3 224 224" --calibrate-dataset persian_cat.jpg --quantization-scheme "int8_asym" [2023-10-28 07:12:08] (HHB LOG): Start import model. [2023-10-28 07:12:09] (HHB LOG): Model import completed! [2023-10-28 07:12:09] (HHB LOG): Start quantization. [2023-10-28 07:12:09] (HHB LOG): get calibrate dataset from persian_cat.jpg [2023-10-28 07:12:09] (HHB LOG): Start optimization. [2023-10-28 07:12:10] (HHB LOG): Optimization completed! Calibrating: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 153/153 [00:20<00:00, 7.52it/s] [2023-10-28 07:12:30] (HHB LOG): Start conversion to csinn. [2023-10-28 07:12:30] (HHB LOG): Conversion completed! [2023-10-28 07:12:30] (HHB LOG): Start operator fusion. [2023-10-28 07:12:31] (HHB LOG): Operator fusion completed! [2023-10-28 07:12:31] (HHB LOG): Start operator split. [2023-10-28 07:12:31] (HHB LOG): Operator split completed! [2023-10-28 07:12:31] (HHB LOG): Start layout convert. [2023-10-28 07:12:31] (HHB LOG): Layout convert completed! [2023-10-28 07:12:31] (HHB LOG): Quantization completed! root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# ls hhb_out main.cpp mobilenetv2-12.onnx persian_cat.jpg synset.txt root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# ``` 命令执行完成后,会在当前目录生成 hhb_out 子目录。 ## 3.3 g++编译 然后使用g++编译指令: ```sh root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# riscv64-unknown-linux-gnu-g++ main.cpp -I../prebuilt_opencv/include/opencv4 -L../prebuilt_opencv/lib -lopencv_imgproc -lopencv_imgcodecs -L../prebuilt_opencv/lib/opencv4/3rdparty/ -llibjpeg-turbo -llibwebp -llibpng -llibtiff -llibopenjp2 -lopencv_core -ldl -lpthread -lrt -lzlib -lcsi_cv -latomic -static -o mobilenetv2_example /tools/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.1-light.1/bin/../lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../prebuilt_opencv/lib/libopencv_core.a(filesystem.cpp.o): in function `.L0 ': filesystem.cpp:(.text._ZN2cv6plugin4impl10DynamicLib11libraryLoadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x4e): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# ls hhb_out main.cpp mobilenetv2-12.onnx mobilenetv2_example persian_cat.jpg synset.txt root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# file mobilenetv2_example mobilenetv2_example: ELF 64-bit LSB executable, UCB RISC-V, version 1 (GNU/Linux), statically linked, for GNU/Linux 4.15.0, with debug_info, not stripped root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# ``` 编译完成后会生成mobilenetv2_example可执行文件 ## 3.4 在板子中运行 与上一篇测试Yolov5n类似,将整个目录复制到开发板的目录中。可以使用 scp 命令,例如我的指令是: ```sh root@9b266aa1e9ac:/home/example/th1520_npu/onnx_mobilenetv2_c++# cd .. root@9b266aa1e9ac:/home/example/th1520_npu# ls onnx_mobilenetv2_c++ prebuilt_opencv yolov5n root@9b266aa1e9ac:/home/example/th1520_npu# scp -r onnx_mobilenetv2_c++/ sipeed@192.168.5.110:~/Desktop/tfcard sipeed@192.168.5.110's password: synset.txt 100% 31KB 530.0KB/s 00:00 main.cpp 100% 3705 311.8KB/s 00:00 persian_cat.jpg 100% 351KB 3.4MB/s 00:00 mobilenetv2-12.onnx 100% 13MB 3.6MB/s 00:03 mobilenetv2_example 100% 12MB 3.3MB/s 00:03 io.c 100% 4945 428.1KB/s 00:00 hhb_jit 100% 322KB 3.4MB/s 00:00 jit.o 100% 13KB 1.1MB/s 00:00 graph_info.bin 100% 361 46.6KB/s 00:00 process.h 100% 2039 246.7KB/s 00:00 hhb_th1520_x86_jit 100% 157KB 3.5MB/s 00:00 model.o 100% 194KB 3.8MB/s 00:00 hhb.bm 100% 3472KB 4.0MB/s 00:00 main.o 100% 47KB 1.8MB/s 00:00 input.0.bin 100% 588KB 3.7MB/s 00:00 main.c 100% 7404 859.9KB/s 00:00 model.c 100% 138KB 3.4MB/s 00:00 process.c 100% 20KB 2.3MB/s 00:00 hhb_runtime 100% 732KB 3.7MB/s 00:00 model.params 100% 3464KB 3.8MB/s 00:00 hhb_th1520_x86_runtime 100% 712KB 3.9MB/s 00:00 jit.c 100% 1942 214.5KB/s 00:00 io.h 100% 1538 177.2KB/s 00:00 input.0.tensor 100% 2794KB 3.9MB/s 00:00 root@9b266aa1e9ac:/home/example/th1520_npu# ``` 然后在板子中进入之前配置的Python虚拟环境在,执行那个可执行文件即可,实测记录: ![](https://xxpcb-1259761082.cos.ap-shanghai.myqcloud.com/pic2/LiPi4A/9/5.png) # 4 MobilenertV2代码分析 ## 4.1 主程序 main.c中的主程序如下,主要是三部分: - load_image_and_preprocess加载图片,进行预处理,得到input_img.bin - 调用hhb_runtime,传入参数hhb.bm和input_img.bin - load_result_and_postprocess进行图片后处理 ```c++ int main() { std::cout << " ********** preprocess image **********" << std::endl; load_image_and_preprocess(); std::cout << " ********** run mobilenetv2 **********" << std::endl; system("./hhb_out/hhb_runtime ./hhb_out/hhb.bm input_img.bin"); std::cout << " ********** postprocess result **********" << std::endl; load_result_and_postprocess(); return 0; } ``` ## 4.2 图片预处理 图片预处理主要的逻辑包括: - opencv读取jpg读取 - 图片尺寸转换 - 转为float图片 - bgr到rgb的转换 - mean与scale处理 - 保存为input_img.bin文件 ```c++ void load_image_and_preprocess() { // load image Mat origin_img = imread("persian_cat.jpg"); int image_width = 224; int image_height = 224; int image_channel = 3; // resize image to 224 * ? or ? * 224 cv::Mat resized_img; float ratio = 224 / fmin(origin_img.size().width, origin_img.size().height); cv::resize(origin_img, resized_img, cv::Size(), ratio, ratio); // Crop image center 224 * 224 int start_x = resized_img.size().width / 2 - image_width / 2; int start_y = resized_img.size().height / 2 - image_height / 2; cv::Rect crop_region(start_x, start_y, image_width, image_height); cv::Mat cropped_image = resized_img(crop_region); // convert to float cv::Mat float_img; cropped_image.convertTo(float_img, CV_32F); // bgr to rgb cv::cvtColor(float_img, float_img, cv::COLOR_BGR2RGB); // mean float_img -= Scalar(124, 117, 104); // scale float_img *= 0.017; // save to file FILE* fp = fopen("input_img.tensor", "w"); FILE* bfp = fopen("input_img.bin", "w"); float *f32_ptr = float_img.ptr
(0); float float_data[image_channel * image_width * image_height]; // layout to be CHW for (int k = 0; k < image_channel ; k++) { for (int i = 0; i < image_width * image_height; i++) { float point = f32_ptr[k + i * image_channel]; fprintf(fp, "%f\n", point); float_data[k * image_width * image_height + i] = point; } } fwrite(float_data, sizeof(float), image_channel * image_width * image_height, bfp); fclose(fp); fclose(bfp); } ``` ## 4.3 运行mobilenetv2 代码里对应这一句: ```c++ system("./hhb_out/hhb_runtime ./hhb_out/hhb.bm input_img.bin"); ``` hhb_runtime是hhb编译时生成的文件: - hhb_runtime:生成的可执行文件 - hhb.bm:示例程序使用的模型权重 - input_img.bin:第一步预处理得到的输入数据 执行后,应该会输出input_img.bin_output0_1_1000.txt识别结果文件。 ## 4.4 图片后处理 图片后处理主要的逻辑包括: ```c static void get_top5(float *buf, uint32_t size, float *prob, uint32_t *cls); static float* get_data_from_file(const char* filename, uint32_t size); void load_result_and_postprocess() { uint32_t i = 0, size = 1000; uint32_t cls[5]; float prob[5]; float* output_data = get_data_from_file("input_img.bin_output0_1_1000.txt", 1000); //读取文件 get_top5(output_data, size, prob, cls); //top5识别率 std::ifstream infile; infile.open("synset.txt"); std::vector
labels; std::string line; while (getline(infile, line)) { labels.push_back(line); } std::cout << " ********** probability top5: ********** " << std::endl; //打印识别率 size = size > 5 ? 5 : size; for (i = 0; i < size; i++) { std::cout << labels[cls[i]] << std::endl; } } ``` # 5 总结 本篇介绍了HHB工具的一些基础知识,通过实操记录测试过程,然后测试了HHB编译MobilenertV2,并在板子中的运行查看效果,最后分析Demo代码的程序逻辑。
LicheePi
此帖出自
玄铁RISC-V活动专区论坛
点赞
关注
(0)
回复
分享
扫一扫,分享给好友
复制链接分享
链接复制成功,分享给好友
举报
提升卡
变色卡
千斤顶
返回列表
发新帖
回复
您需要登录后才可以回帖
登录
|
注册
发表回复
回帖后跳转到最后一页
活动
更多>>
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
安世半导体智能工业应用探索站,闯关赢好礼!
PI 电源小课堂:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
Microchip喊你探索dsPIC33A 芯片,70份好礼等你赢!
【瓜分2500元红包】票选2024 DigiKey “感知万物,乐享生活”创意大赛人气作品TOP3!
DigiKey应用探索站重磅上线!潮流应用,硬核技术探秘,N多干货,一站get!
验证并选择心仪MOSFET,探寻选型奥秘!注册、体验双重好礼等你拿~
免费申请测评 | 泰坦触觉 TITAN Core开发套件
开源项目
更多>>
AM6TW-2412SZ 12V 6 瓦单路输出 DC-DC 转换器的典型应用
LT1172CT、5V/1.25A 反激式转换器的典型应用
CBM2199 open source -UD
AI红外语音助手
使用 ROHM Semiconductor 的 BD4843 的参考设计
TWR-S08UNIV,通用 8 位 S08/RS08 MCU 塔式系统模块
[DCDC]RT8251核心,5A可调降压模块
使用 Analog Devices 的 LTC1771ES8 的参考设计
使用具有引脚可配置模拟输入范围的 LTC2389IUK-18、18 位、2.5Msps SAR ADC 的典型应用
使用具有 USB On-The-Go、过压和反向电压保护功能的 LTC4160EUDC-1 高效开关电池充电器的典型应用
随便看看
请问 MSP430离线编程器 有哪些,原先力杰的那款买不到了
请问MSP430离线编程器有哪些,原先力杰的那款买不到了,新买的那款有些难用。
今天进行签到
买一个逻辑分析仪,对写代码很有帮助
急寻11位有缘人,拼团免费搭车去上海电子展
串口通信问题
推荐长焦相机
关于代码在RAM执行的疑问
自愉自乐之C8051F020与80C51的区别
查找数据手册?
搜索
EEWorld Datasheet 技术支持
热门标签
源代码
单片机
放大器
TI
ST
电源
分立器件
传感器
测试测量
模拟
串联型稳压电源
声表谐振器
固定电容器
blinker-nodejs
激光雷达
共模增益
摩尔定律
差分码
协议栈
太赫兹
相关文章
更多>>
苹果M4 Mac mini曝出USB-C接口问题!随机间歇性断开连接
1月17日消息,苹果M4 Mac mini自2024年底发布以来,收获了不少好评,然而近期一些用户在使用过程中发现,该设备的USB-C接口似乎存在连接性问题,给使用带来了不便。 有用户反映M4 Ma
消息称 SK 海力士有望 2 月启动业界最先进 1c nm 制程 DRAM 内存量产
1 月 17 日消息,韩媒 MT(IT之家注:全称 MoneyToday)当地时间今日报道称,SK 海力士近日已成功完成内存业界最先进 1c 纳米制程 DRAM 的批量产品认证,连续多个以 25 块
未经同意出售用户数据,通用汽车遭美国 FTC 处罚
1 月 17 日消息,当地时间周四,美国联邦贸易委员会(FTC)宣布通用汽车及其子公司 OnStar 因未经用户同意出售用户位置和驾驶行为数据,因此将对其进行处罚,包括在五年内禁止向消费者报告机构披
日本三井住友银行推出半导体设备抵押贷款,铠侠已率先获益
联想宣布收购Infinidat,扩充高端企业存储业务
台积电董事长:我们不是美积电 最先进制程不会搬到美国
曝台积电拒绝代工三星Exynos处理器:理由是怕泄密
SK 海力士被曝上半年削减 10% NAND 闪存产量
苹果加入UALink联盟 成员含AMD、英特尔、谷歌等公司
英特尔宣布将逐渐停产第 12 代 Alder Lake 移动处理器,覆盖酷睿、奔腾及赛扬
新帖速递
STM32和无源蜂鸣器播放声音的问题
车规级AECQ200介绍,混合铝电解电容器的选择
嵌入式教程_DSP技术_DSP实验箱操作教程:2-28 搭建轻量级WEB服务器实验
OPA847IDBVR运放器国产替代
AG32VF407测试UART
【得捷电子Follow Me第二期】第一章 收到货物的分享
请问这个红外接收头是什么型号?能用哪个型号代替?谢谢
出售全新未拆封ZYNQ 7Z020 FPGA核心板
用在锂电池供电的水表设置上的LORA模块,当有100块水表集中安装在一个楼道内时,节能
请问一下,当某个端口被设置为 RX0后,这个端口的输入输出方向还有必要设置吗
今年怎么这么难,比疫情时还难,三十了面临失业好迷茫
请教稳压管测试问题
【小华HC32F448测评】关于小华半导体的UART中断发送和PRINTF构造和重定向
【BIGTREETECH PI开发板】 HDMI输出测试
【BIGTREETECH PI开发板】+08.音频测试(zmj)
安世半导体智能工业应用探索站,闯关赢好礼!
点击页面内“开始探索”按钮,填写并提交表单;
请根据序号依次完成3个安世半导体智能工业应用的探索,并根据给出的资料完成共计9题(每个应用3题),答对5题以上的玩家即可获得抽奖资格;
每人仅有一次参与答题的机会,请慎重作答,活动结束后,我们将抽取30位玩家赠送礼品。
查看 »
Microchip 直播|多相降压电源控制技术的发展与探讨 报名中!
直播主题:多相降压电源控制技术的发展与探讨
直播时间:2025年2月25日(星期二)上午10:30-11:30
快来报名!
查看 »
回帖赢好礼 | 关于无线技术的那些事儿
【活动时间】即日起—2025年1月31日
【活动好礼】50元京东卡
查看 »
答题赢好礼,PI电源小课堂第3期来啦!
本期内容:集成式半桥驱动IC BridgeSwitch 2, 助力高效永磁同步电机逆变器的设计
活动时间:即日起-2月28日
看视频答题即可赢取京东卡!
查看 »
Microchip喊你探索 dsPIC33A 芯片,70份好礼等你赢!
活动时间:即日起-1月26日
活动奖励:随身Wi-Fi、家用多功能电烤箱、20000mAh充电宝、50元京东卡
查看 »
DigiKey应用探索站重磅上线!潮流应用,硬核技术探秘,N多干货,一站get!
当月好物、热门技术资源、潮流应用技术、特色活动、DigiKey在线实用工具,干货多多~
查看 »
本周精选下载推荐:电源管理基础Dummies
本周小编给大家带来一本超简单、超干货的电子书——《电源管理基础Dummies》!内容深入浅出,排版舒服简洁,分分钟能get到电源管理最核心的知识内容。
查看 »
下载资料赢好礼!看Vicor模块化电源解决方案如何推动创新
活动时间:即日起-2024年12月31日
如何参与:点击活动页内您想了解的模块,找到资料下载即可参与抽奖,活动结束后统一发奖!
查看 »
验证并选择心仪MOSFET,探寻选型奥秘!注册、体验双重好礼等你拿~
MOSFET 选型有点难
选N沟道MOSFET?还是选P沟道MOSFET?
封装如何选:不同封装尺寸有不同的热阻和耗散功率。
瞬态散热更严苛,热设计需要如何处理?
用东芝在线电路仿真器,一键解锁MOSFET选型的秘密!
查看 »
关闭
站长推荐
1
/9
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
电信业务审批[2006]字第258号函
京公网安备 11010802033920号
Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复
返回顶部
返回列表
论坛首页
版块列表
专业技术中心
TI技术论坛
ST传感器与低功耗无线技术论坛
ADI参考电路
DigiKey得捷技术专区
ADI · 世健工业技术
电子技术交流
嵌入式系统
单片机
国产芯片交流
电机驱动控制
FPGA/CPLD
模拟电子
电源技术
PCB技术
RF/无线
传感器
综合技术交流
下载中心专版
大学堂专版
测评中心专版
创意与实践
电子竞赛
DIY/开源硬件专区
淘e淘
创意市集
行业应用
汽车电子
移动便携
医疗电子
工控电子
安防电子
休息一下
聊聊、笑笑、闹闹
工作这点儿事
为我们提意见&公告
EEWorld颁奖专区
信息发布
最新帖子
最新帖子
最新回复
精华
消灭零回复
测评中心
活动中心
积分兑换
E金币兑换
芯积分
厂商专区
TI技术论坛
ST传感器与低功耗无线技术论坛