1. 项目概述
在嵌入式AI开发领域,YOLOv5作为轻量级目标检测算法的代表,其部署流程一直是开发者关注的焦点。本文将详细介绍基于FMQL30TAI平台运行Icraft-ModelZoo中YOLOv5 7.0示例工程的全流程,从模型获取到最终板端部署,每个环节都包含实际验证步骤和避坑指南。
1.1 核心需求解析
YOLOv5模型在嵌入式设备上的部署主要面临三个技术挑战:
- 模型格式转换:从PyTorch训练权重到部署格式(ONNX/TorchScript)的转换
- 编译优化:通过Icraft工具链进行模型量化和编译
- 跨平台部署:实现Windows仿真与嵌入式设备的无缝衔接
2. 环境准备与工程获取
2.1 开发环境配置
对于FMQL30TAI开发,建议准备以下环境:
- Windows 10/11主机(用于模型转换和仿真)
- Ubuntu 20.04 LTS虚拟机(用于交叉编译)
- Python 3.8+环境(推荐使用Miniconda管理)
注意:Python版本过高可能导致部分依赖包兼容性问题,实测3.8.10版本最为稳定
2.2 获取YOLOv5示例工程
通过ModelScope获取工程文件:
bash复制git clone -b v3.33.1 https://www.modelscope.cn/AIBS/yolov5_7.0.git
工程目录结构说明:
code复制yolov5_7.0/
├── 1_scripts/ # 模型转换和验证脚本
├── 2_model/ # 预训练模型和配置文件
├── 3_deploy/ # 部署相关代码
├── config/ # Icraft编译配置文件
└── docs/ # 配套文档
3. 模型转换与验证
3.1 原始模型推理验证
首先验证官方预训练模型(yolov5s.pt)的推理效果:
python复制python ./1_scripts/0_infer.py --weights ./2_model/yolov5s.pt --img 640
常见问题处理:
- 若出现"ImportError: cannot import name 'COMMON_SAFE_ASCII_CHARACTERS'"错误,需降级charset-normalizer包:
bash复制
pip install charset-normalizer==2.0.12
3.2 导出TorchScript模型
使用修改后的导出脚本生成适配Icraft的模型:
python复制python ./1_scripts/1_save.py --weights ./2_model/yolov5s.pt --img-size 640
关键修改点说明:
- 输出层结构调整为DetPost模块兼容格式
- 固定输入尺寸为640x640
- 添加了后处理节点融合
3.3 导出模型验证
验证导出模型的正确性:
python复制python ./1_scripts/2_save_infer.py --weights ./2_model/yolov5s_640x640.pt
重要提示:验证时务必使用与导出时相同的图像尺寸,否则会导致精度异常
4. Icraft模型编译
4.1 编译配置解析
工程提供的ZG配置(yolov5s_int8.toml)主要参数:
toml复制[compiler]
target = "fmql30tai" # 目标平台
input_shape = [1,3,640,640] # 输入尺寸
output_layout = "NHWC" # 输出排布
[quantization]
calibration_images = "./2_model/calib/" # 校准集路径
calibration_batch_size = 1 # 校准批大小
4.2 执行模型编译
bash复制icraft compile ./config/ZG/yolov5s_int8.toml
编译产出文件:
- model.json:模型结构描述文件
- model.raw:量化后的模型参数
- report.html:编译报告(含量化精度分析)
常见编译错误处理:
- 校准集不足:至少需要100张以上代表性图像
- 内存不足:调整calibration_batch_size为1
- 算子不支持:检查模型是否包含非常规算子
5. Windows平台仿真运行
5.1 环境准备
需要安装:
- Visual Studio 2022(需包含C++开发组件)
- Icraft Windows SDK(版本需与编译时一致)
- OpenCV 4.5+(建议通过vcpkg安装)
5.2 工程构建
bash复制cd yolov5_7.0_icraft/3_deploy
mkdir build_win && cd build_win
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release
构建问题排查:
- 找不到Icraft SDK:通过-DICRAFT_SDK_PATH指定路径
- OpenCV链接错误:检查环境变量OpenCV_DIR设置
5.3 仿真配置
修改yolov5s_ZG_int8_demo.yaml关键参数:
yaml复制engine:
mode: "psin" # 仿真模式
model: "../../2_model/model.json" # 模型路径
input:
type: "image"
path: "../../2_model/test.jpg" # 测试图像
5.4 运行与调试
直接运行:
bash复制.\Release\yolov5s_psin.exe ..\cfg\yolov5s_ZG_int8_demo.yaml
VS调试技巧:
- 设置工作目录为
3_deploy文件夹 - 添加命令行参数
../cfg/yolov5s_ZG_int8_demo.yaml - 启用"原生兼容性调试"模式
6. Socket模式开发板联调
6.1 开发板环境配置
- 启动icraft-server服务:
bash复制
icraft-server --port 9000 --model ./model.json - 确认网络连接:
bash复制
ifconfig eth0 192.168.1.100 netmask 255.255.255.0
6.2 上位机配置修改
调整yaml文件:
yaml复制engine:
mode: "socket"
ip: "192.168.1.100" # 开发板IP
port: 9000
6.3 联调问题排查
常见问题及解决方案:
- 连接超时:
- 检查网线连接状态
- 确认防火墙未拦截端口
- 推理失败:
- 对比开发板与编译环境的Icraft版本
- 检查模型文件是否完整传输
7. 板端PSIN模式部署
7.1 交叉编译环境搭建
使用官方提供的Docker镜像:
bash复制docker pull icraft/fmql30tai:2.4.0
docker run -it --name fmql_build -v $(pwd):/workspace icraft/fmql30tai:2.4.0
7.2 工程交叉编译
bash复制mkdir build_arm && cd build_arm
cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchains/fmql30tai.cmake
make -j4
编译产物优化:
- 使用strip减小可执行文件体积:
bash复制
arm-linux-gnueabihf-strip yolov5s_psin - 压缩模型文件:
bash复制
gzip -k model.json model.raw
7.3 板端运行
- 文件传输:
bash复制
scp -r build_arm root@192.168.1.100:/userdata - 运行程序:
bash复制cd /userdata/build_arm ./yolov5s_psin ../cfg/yolov5s_ZG_int8_demo.yaml
性能优化建议:
- 设置CPU频率为性能模式:
bash复制echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor - 使用ION内存分配器减少内存拷贝
8. 常见问题与解决方案
8.1 模型转换问题
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| ONNX导出失败 | PyTorch版本不兼容 | 使用torch==1.8.0 |
| 输出节点缺失 | 导出脚本未适配 | 使用工程提供的1_save.py |
| 推理精度下降 | 动态尺寸问题 | 固定输入尺寸为640x640 |
8.2 编译问题
| 错误类型 | 排查方法 | 修复方案 |
|---|---|---|
| 量化误差大 | 检查校准集 | 增加校准图像数量 |
| 算子不支持 | 查看report.html | 修改模型结构 |
| 内存不足 | 监控系统资源 | 减小校准batch size |
8.3 部署问题
| 平台 | 典型问题 | 调试技巧 |
|---|---|---|
| Windows仿真 | 依赖库缺失 | 使用Dependency Walker检查 |
| Socket模式 | 网络延迟 | 使用ping测试基础延迟 |
| 板端运行 | 内存不足 | 优化模型分片加载 |
9. 性能优化实践
9.1 模型层面优化
- 通道剪枝:
python复制# 在export前添加剪枝处理 from torch.nn.utils import prune prune.l1_unstructured(module, name='weight', amount=0.2) - 量化策略调整:
- 对敏感层使用FP16量化
- 调整校准算法为KL散度
9.2 运行时优化
- 内存池配置:
yaml复制# 在yaml中添加 memory: pool_size: 256 # MB allocator: "ion" - 多线程推理:
cpp复制icraft::set_option(ICRAFT_OPTION_NUM_THREADS, 4);
9.3 实测性能数据
在FMQL30TAI平台上的典型性能:
| 模式 | 分辨率 | 帧率(FPS) | 内存占用 |
|---|---|---|---|
| INT8 | 640x640 | 32.5 | 180MB |
| FP16 | 640x640 | 18.7 | 210MB |
| FP32 | 640x640 | 6.2 | 320MB |
10. 扩展开发建议
10.1 自定义模型集成
对于非YOLO系列模型,需要:
- 确保导出ONNX包含完整计算图
- 实现对应的后处理插件
- 调整toml文件中的输入输出配置
10.2 多模型流水线
通过Icraft的Pipeline功能实现:
toml复制[pipeline]
stages = [
{ model = "detection.json", input = "camera" },
{ model = "classification.json", input = "detection.crops" }
]
10.3 视频流处理优化
- 使用零拷贝内存传递:
cpp复制icraft::Tensor input = icraft::wrap_memory(ptr, {1,3,640,640}); - 异步推理接口:
cpp复制icraft::run_async(input, [](Result result){ // 回调处理 });
在实际部署过程中,我发现模型量化校准集的质量对最终推理精度影响极大。建议使用实际场景数据作为校准集,而非单纯使用训练数据。另外,对于边缘设备,合理设置内存池大小可以显著减少动态内存分配带来的性能波动。
