国内目前关于hailo的资料过少,我自己也在这个问题卡了许久,所以决定把我完整的部署流程发布。
CSDN上有少量关于Hailo部署的教程,但是略有缺陷,不是完整的部署使用流程。先说使用,再说编译模型。
一、在树莓派用CPP部署模型
1)为什么用CPP?
我是做视觉的,更偏偏向于用CPP榨取性能,所以我的探索使用CPP代码。虽然我知道大部分使用树莓派的人是更习惯用Python,但很抱歉,这片文章帮不了你(因为我也不会)。
2)环境部署
你也可以在我的GitHub的readme看
步骤一:更新系统与固件
更新软件包列表和所有软件:
sudo apt update && sudo apt full-upgrade -y
重启系统:
sudo reboot
步骤二:启用 PCIe Gen 3.0 模式
运行树莓派配置工具:
sudo raspi-config
依次选择:
Advanced Options>PCIe Speed。系统询问是否启用 PCIe Gen 3.0 模式,选择Yes。
选择
Finish退出。当系统询问是否重启时,选择Yes。
步骤三:安装 Hailo 软件包
安装所有必需的驱动、固件和库:
sudo apt install hailo-all
安装完成后,再次重启系统。
步骤四:验证安装
1. 检查 NPU 状态
运行以下命令,识别并显示 Hailo 芯片信息:
hailortcli fw-control identify
示例输出:
Executing on device: 0001:01:00.0 Identifying board Control Protocol Version: 2 Firmware Version: 4.23.0 (release,app,extended context switch buffer) Logger Version: 0 Board Name: Hailo-8 Device Architecture: HAILO8L # 这里是关键:8L 还是 8 Serial Number: HLDDLBB243502526 Part Number: HM21LB1C2LAE Product Name: HAILO-8L AI ACC M.2 B+M KEY MODULE EXT TMP- 命令执行后,可能会在当前目录生成一个
hailo.log文件,这是保存返回信息的日志文件,可以忽略。 - 重要:通过输出中的
Device Architecture字段可以确认你的设备是Hailo-8还是Hailo-8L。lspci命令无法区分这两者。
2. 检查 PCIe 硬件连接(可选)
lspci | grep Hailo
示例输出:
0001:01:00.0 Co-processor: Hailo Technologies Ltd. Hailo-8 AI Processor (rev 01)实际上,第一步的
hailortcli fw-control identify已经足够验证硬件连接。
补充:模型相关说明
硬件和系统配置到这里就基本完成了。
- 树莓派系统中通常自带 C++ 开发环境,以及一些已经编译好的.hef格式模型(Hailo NPU 必须使用此格式)。
- 自带模型一般位于:
/usr/share/hailo-models - 选择模型时注意:
- 如果你是Hailo-8L型号,请选择
h8l模型 - 如果你是Hailo-8型号,请选择
h8模型
- 如果你是Hailo-8L型号,请选择
查看模型信息
使用以下命令查看.hef模型文件的信息:
hailortcli parse-hef your_model.hef
示例(以yolov8s.hef为例):
hailortcli parse-hef yolov8s.hef
示例输出及说明:
Architecture HEF was compiled for: HAILO8L # 模型是为 8 还是 8L 编译的 Network group name: yolov8s, Multi Context - Number of contexts: 4 Network name: yolov8s/yolov8s VStream infos: Input yolov8s/input_layer1 UINT8, NHWC(640x640x3) # 输入数据格式 Output yolov8s/yolov8_nms_postprocess FLOAT32, HAILO NMS BY CLASS(number of classes: 80, maximum bounding boxes per class: 100, maximum frame size: 160320) # 输出格式 Operation: Op YOLOV8 Name: YOLOV8-Post-Process Score threshold: 0.200 # 置信度阈值 IoU threshold: 0.70 Classes: 80 # 类别数 Max bboxes per class: 100 Image height: 640 Image width: 640一个需要注意的点
大部分模型(如 YOLO 系列)的输入尺寸是640×640,但很多常见摄像头的输出是640×480。
请不要直接将画面拉伸到 640×640 再送入模型,这样会导致图像失真,严重影响检测效果。
正确做法:将 640×480 的画面放置到一个640×640 的黑色画布上(上下填充黑边),再进行推理。
3)代码讲解
源代码地址:https://github.com/CHNsevecl/Hailo ;这是我自己练习的仓库,下载下来后请删除build文件夹自己重构一下。在build文件夹运行train文件即可。
关于函数的hpp文件:
const std::string hef_path = "/usr/share/hailo-models/yolov8s_h8l.hef";
指向了模型地址,这里我指向了官方模型地址,前提是你的系统是树莓派官方的树莓派5 最新系统。
const std::vector<std::string> class_names
为数据集的名称,务必与训练时的顺序一致。
其他的你不必动用。
关于函数的cpp文件:
我不太想赘述太多,如果你想阅读可以试试看。如果你只想部署请跳过下一步。
返回的数据:(可跳过)
这个核心问题,困扰了我大概一周,虽然github有官方实例但是易读性不足。接下来用 最简单的方式向你说明数据的格式。
我在Myhailo.cpp中加了这个函数:SaveOutputToFile(const hailort::Buffer& buffer),他的作用是把Hailo绑定的输出内存的数据以float的格式保存为文本文件(保存在build文件夹下的hailo_debug_output.txt),不过我把他注释了,如果你要看的话请把103行的注释取消。
假设第一类检测到两个物体,没有其他类,那么数组的数据结构是:
2(第一类的数量) ,ymin1 ,xmin1 ,ymax1 ,xmax1 ,score1 ,ymin2 ,xmin2 ,ymax2 ,xmax2 ,score2 ,0(第二类的数量),0(第三类的数量),0(...),...
假设第一类检测到0个物体,第二类检测到1个物体,没有其他类,那么数组的数据结构是:
0(第一类的数量),1(第二类的数量),ymin1 ,xmin1 ,ymax1 ,xmax1 ,score1 ,0(第三类的数量),0(...),...
以此类推,大致是这个意思。注意:这些坐标是浮点小数,实际使用还要乘上你的图像的尺寸
二、编译环境
强调:Hailo官方的编译套件必须是基于 x86! x86! x86! 架构的 Linux系统。ARM架构不行!
显卡问题:如果你是在WSL下部署,那么无论如何都是不能使用GPU加速,只能使用CPU,即使GPU可以与Docker连接。如果你是在独立Linux系统,那么50系以下的显卡可以正常使用,因为50系使用的是最新的BlackWheel架构,Hailo官方还没适配。
Linux系统有很多教程,我就不多说了。
1、Docker下载
官网下载地址:https://hailo.ai/developer-zone/
需要注册账号登陆。,登陆后点击下载(DownLoads):
选择套件:
Device选择你手上的
Package选择第一个,最完整
网页下拉,选择Docker(第一个下载):Hailo AI Software Suite – Docker
Log In • Hailo
部署docker的细节自行查阅
三、编译指令
1、文件准备
在编译开始前,请将你的onnx模型,以及含有64张(至少)的图片放入验证集文件夹dataset(需要自行创建)中,例:
其中yolo_ls是我自建的文件夹,编译后的文件也会保存在这里。
2、编译指令
hailomz compile yolov8s --hw-arch hailo8l --ckpt=best.onnx --calib-path dataset --classes 1 --performance --end-node-names /model.22/cv2.0/cv2.0.2/Conv /model.22/cv3.0/cv3.0.2/Conv /model.22/cv2.1/cv2.1.2/Conv /model.22/cv3.1/cv3.1.2/Conv /model.22/cv2.2/cv2.2.2/Conv /model.22/cv3.2/cv3.2.2/Conv
--ckpt=best.onnx指向模型,--calib-path dataset为交验集, classes 类别数量
重点:--end-node-names为模型输出Conv层,我的实例是yolov8s模型,如果是别的或是修改过的yolo需要自行确定并指定Conv。
编译大约耗时2h(纯CPU)。
文件夹最后内容:
其中的hef文件就是所需的模型。
解语
这些写的不能说是教程,更像是我的经验,有些仓促,见谅