当前位置: 首页 > news >正文

Arm Ethos‑U65:YOLOv8n 模型准备与 Vela 编译

本文是 Arm Ethos‑U65 学习笔记的第四篇,接下来两篇将基于 U65 实现一个 YOLO v8n 目标检测实例,其中本篇完成模型准备与 Vela 编译生成命令流,下一篇将命令流导入芯片仿真环境执行推理验证,整个示例以芯片验证仿真为主线,同时对裸机环境下的软件开发也有一定参考价值。

模型选取

YOLO v8n

正常流程需要将模型按照 Tensorflow lite 格式量化,这里直接使用现成 YOLO v8n tflite 模型:

https://github.com/camthink-ai/ne302/blob/main/Model/weights/yolov8n_256_quant_pc_ui_od_coco.tflite

查看模型,可以看到输入是256x256x3 uint8,输出是1x84x1344 int8,对应80个分类1344个框。需要注意 tflite 模型是不包含后处理的,后处理需要外部实现(阈值比较、排序和 NMS),同时需要给模型提供前处理后的数据(resize 和格式转换)。

检测程序

python程序

下面完成基于 YOLO v8n tflite 实现目标检测的python程序,大体流程为:

a)将图像resize成256x256,再量化为uint8。
b)执行推理,通过tf.lite.Interpreter方法运行tfllite网络,得到输出结果。
c)将输出反量化为浮点。
d)对于每个窗,找到80个置信度中最大值,再和阈值比对,筛选出大于阈值的点。
e)进行nms,去掉重合的窗。
f)框坐标resize恢复,添加到图片中。

后面芯片仿真验证流程还需要复用程序的 c~f 也就是后处理部分。

tfile_model_run_yolov8n.py

importcv2importnumpyasnpimporttensorflowastf# ---------- 配置 ----------MODEL_PATH="./tfile_model/yolov8n_256_quant_pc_ui_od_coco.tflite"IMAGE_PATH="bike.jpg"CONFIDENCE_THRESHOLD=0.5# 置信度阈值IOU_THRESHOLD=0.45# NMS 的 IOU 阈值INPUT_SIZE=256# 模型输入尺寸 (256x256)# 只关心这些类别的索引 (COCO: person=0, bicycle=1, car=2)TARGET_CLASS_IDS = [0, 1, 2]TARGET_CLASS_NAMES=["person","bicycle","car"]# ---------- 加载模型 ----------interpreter=tf.lite.Interpreter(model_path=MODEL_PATH)interpreter.allocate_tensors()input_details=interpreter.get_input_details()output_details=interpreter.get_output_details()# 获取输入类型(应为 uint8)input_dtype=input_details[0]['dtype']input_shape=input_details[0]['shape']# [1, 256, 256, 3]# ---------- 后处理函数 ----------defsigmoid(x):return1/(1+np.exp(-x))defdecode_yolov8_output(output,input_width,input_height,conf_threshold):# 去除 batch 维度preds=np.transpose(output,(0,2,1))[0]# preds shape: (num_anchors, 84)boxes=[]scores=[]class_ids=[]forpredinpreds:# 前4个是 bbox (cx, cy, w, h) 归一化到 0~1 cx, cy, w, h = pred[:4]# 后80个是类别得分class_scores=pred[4:]# 最大得分及其类别class_id=np.argmax(class_scores)score=class_scores[class_id]# 过滤低置信度ifscore<conf_threshold:continue# 只关心指定类别ifclass_idnotinTARGET_CLASS_IDS:continue# 将中心坐标和宽高转换为左上角和右下角 (x1,y1,x2,y2) 归一化到 0~1 x1=cx-w/2y1=cy-h/2x2=cx+w/2y2=cy+h/2# 限制在 [0,1] 范围内x1=max(0,min(1,x1))y1=max(0,min(1,y1))x2=max(0,min(1,x2))y2=max(0,min(1,y2))boxes.append([x1,y1,x2,y2])scores.append(float(score))class_ids.append(class_id)returnboxes,scores,class_idsdefnms(boxes,scores,iou_threshold):""" 非极大值抑制,返回保留的索引列表 """iflen(boxes)==0:return[]boxes=np.array(boxes)# 计算每个框的面积areas=(boxes[:,2]-boxes[:,0])*(boxes[:,3]-boxes[:,1])# 按置信度降序排序indices=np.argsort(scores)[::-1]keep=[]whilelen(indices)>0:current=indices[0]keep.append(current)iflen(indices)==1:break# 计算当前框与其余框的IOUother=indices[1:]xx1=np.maximum(boxes[current,0],boxes[other,0])yy1=np.maximum(boxes[current,1],boxes[other,1])xx2=np.minimum(boxes[current,2],boxes[other,2])yy2=np.minimum(boxes[current,3],boxes[other,3])w=np.maximum(0,xx2-xx1)h=np.maximum(0,yy2-yy1)intersection=w*h iou=intersection/(areas[current]+areas[other]-intersection)# 保留IOU低于阈值的框indices=indices[1:][iou<iou_threshold]returnkeep# ---------- 主程序 ----------if__name__=="__main__":# 读取图像img=cv2.imread(IMAGE_PATH)orig_h,orig_w=img.shape[:2]# 预处理:调整大小并转换为 uint8 (模型期望)img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)resized=cv2.resize(img_rgb,(INPUT_SIZE,INPUT_SIZE))input_tensor=np.expand_dims(resized,axis=0).astype(np.uint8)# 推理interpreter.set_tensor(input_details[0]['index'],input_tensor)interpreter.invoke()# 获取输出# 可能模型有多个输出,但通常只有一个,先取第一个output=interpreter.get_tensor(output_details[0]['index'])# 处理量化输出:需要反量化scale,zero_point=output_details[0]['quantization']# 反量化:float_val = (quant_val - zero_point) * scaleoutput=(output.astype(np.float32)-zero_point)*scaleprint(f"原始输出形状:{output.shape}")# 解码输出boxes,scores,class_ids=decode_yolov8_output(output,INPUT_SIZE,INPUT_SIZE,CONFIDENCE_THRESHOLD)# 执行 NMS (对所有类别一起做)keep_indices=nms(boxes,scores,IOU_THRESHOLD)final_boxes=[boxes[i]foriinkeep_indices]final_scores=[scores[i]foriinkeep_indices]final_class_ids=[class_ids[i]foriinkeep_indices]# 绘制检测结果for(x1,y1,x2,y2),score,cls_idinzip(final_boxes,final_scores,final_class_ids):# 将归一化坐标转换为原图尺寸x1=int(x1*orig_w)y1=int(y1*orig_h)x2=int(x2*orig_w)y2=int(y2*orig_h)# 绘制矩形和标签label=f"{TARGET_CLASS_NAMES[TARGET_CLASS_IDS.index(cls_id)]}{score:.2f}"cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0),2)cv2.putText(img,label,(x1,y1-5),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,255,0),2)# 显示图像cv2.imshow("Result",img)cv2.waitKey(0)cv2.destroyAllWindows()

运行程序,对人、汽车、自行车进行了识别。

Vela编译

Vela 安装和执行

Vela 是 ARM 开发的一款编译器工具,可以将 TensorFlow Lite 模型(.tflite文件)编译为Ethos U65 可以执行的命令流,编译同时会对模型会进行权重压缩、内存分配等优化,这个优化过程不会有精度损失。

Vela 以 python 软件包形式使用,首先通过 pip 安装。

pip install ethos-u-vela

安装后可以直接在端口执行,指定模型、NPU版本和输出路径。

vela ./tfile_model/yolov8n_256_quant_pc_ui_od_coco.tflite --accelerator-config ethos-u65-512 --output-dir ./output

运行后会生成带 _vela 后缀的 tflite 格式文件,生成文件并不是网络,只是借用了 .tflite 格式,文件实际内容是命令流+权重(下图中的1<>和2<>),命令流可以通过hex格式打开查看,权重因为经过压缩直接看会对不上。

Vela指令

运行 Vela 指令的同时会打印 log 信息,能看到存储和带宽使用情况,还可以通过添加指令后缀调整存储使用和优化策略、查看更多信息项。vela -h 可以显示所有命令后缀,更推荐的是直接查看 Vela 官方文档。

https://gitlab.arm.com/artificial-intelligence/ethos-u/ethos-u-vela


通过 --memory-mode 可以指定存储使用模式,支持 Shared_Sram 和 Dedicated Sram;通过 --config 可以指定配置文件;通过 --system-config 可以指定系统配置。后两者可以在vela安装目录找到参考 (…\Lib\site-packages\ethosu\config_files\Arm\vela.ini)。

--memory-mode Shared_Sram --config Arm/vela.ini --system-config Ethos_U55_High_End_Embedded

调试信息

有2条比较有用的调试指令后缀。

--verbose-high-level-command-stream > high-level-command.log --verbose-register-command-stream > register-command.log

通过high-level-command可以看到优化后的网络结构,可以看到原尺寸已经被拆分成 Block 尺寸。

通过register-command可以直接看到带注释的命令行。

http://www.jsqmd.com/news/1213515/

相关文章:

  • AI多智能体协作框架agency-swarm实战指南
  • R3nzSkin国服特供版:英雄联盟换肤终极完整教程
  • 2026沧州铝合金不锈钢废铝回收公司TOP5盘点 - LYL仔仔
  • 终极抖音无水印下载方案:3种方法快速获取高清原片
  • 如何快速配置阴阳师百鬼夜行自动化脚本:终极效率提升指南
  • 2026年电钢琴避坑核心指南:选购误区全解析,10款实测好琴推荐
  • Mac终极NTFS读写解决方案:3分钟实现跨平台文件自由
  • NS-USBLoader移动版:Android手机直连Switch游戏传输终极指南
  • 亨得利青岛区售后资质核验报告|权威收录正规维修网点信息(2026年7月最新) - 亨得利客户服务中心
  • 如何实现Windows与Office的智能激活:KMS_VL_ALL_AIO完整指南
  • 高并发内存池设计:从三级缓存架构到性能优化实战
  • 3步打造你的专属Windows键盘:SharpKeys键位重映射完全指南
  • Unity多点触控交互开发:实现多人点击拖动互不干扰的解决方案
  • ARM ETMv4 核心寄存器深度解析:从硬件能力评估到复杂触发逻辑配置
  • Windows HEIC缩略图插件:让iPhone照片在资源管理器里“活“起来
  • Steam游戏清单3分钟搞定!Onekey终极解决方案让游戏管理如此简单
  • 断电导致文件丢失的应急恢复与防护方案
  • 【Coze扣子2024最新版深度测评】:对比Dify/Minimax/飞书多维Bot平台,性能、成本与扩展性硬核数据曝光
  • 真力时全国腕表官方售后服务中心|原厂配件更换网点完整披露(2026 年 7 月最新) - 亨得利客户服务中心
  • Java学习心得
  • STM32到GD32移植实战:三步法实现低成本切换
  • C++项目集成ZXing-C++:高性能二维码识别与生成实战指南
  • 中山透明黄金回收,全程称重录像公开无隐瞒 - 新芸鼎珠宝首饰
  • openEuler Native-Turbo-kernel未来路线图:AI加速与异构计算支持
  • 从理论到实践:构建视觉-语言-动作模型,让机器人听懂指令并执行任务
  • 亨得利宁波区售后网络核验|权威公告正规维修服务网点(2026年7月最新) - 亨得利客户服务中心
  • 2026电钢琴选购五大核心标准,绝不翻车的电钢琴选购指南
  • AI办公时间黑洞大扫除:5个被90%职场人忽略的自动化捷径,立即生效
  • 小红书内容获取终极指南:XHS-Downloader一键搞定无水印素材批量下载
  • Windows 11系统资源优化与内存管理实践