你好!看到 wzm1809434 也遇到了同样的问题。这个问题确实很典型,我来总结一下最终解决方案:
核心问题
YOLOv8 部署到 RDK X5 时,hb_mapper PTQ 流程默认不量化输出层,导致:
- 所有输出都是
F32 + NONE - 但 TROS 的
yolov8parser 期望 bbox 分支是S32 + SCALE
正确解决方案
步骤 1:使用 rdk_model_zoo 官方的 YOLOv8 导出脚本
不要自己修改导出脚本,直接使用社区验证过的:
# 1. 克隆 rdk_model_zoo
git clone -b rdk_x5 https://github.com/D-Robotics/rdk_model_zoo.git
cd rdk_model_zoo/samples/vision/ultralytics_yolo/conversion
# 2. 查看导出脚本
ls -la
# 找到 export_yolo26_detect_bpu.py 或类似脚本
关键:YOLOv8 在 Ultralytics 框架中也被称为 YOLOv26,所以要用 ultralytics_yolo 相关的导出脚本,而不是 yolov5 的。
步骤 2:正确的导出流程
# 1. 训练你的 YOLOv8 模型(5 分类)
yolo task=detect mode=train model=yolov8n.pt data=your_data.yaml epochs=100 imgsz=640
# 2. 使用官方导出脚本(关键!)
cd rdk_model_zoo/samples/vision/ultralytics_yolo/conversion/onnx_export
python export_yolo26_detect_bpu.py \
--weights /path/to/your/best.pt \
--imgsz 640 \
--opset 11
# 3. 验证 ONNX 输出(应该全是 F32,这是正常的)
python3 -c "
import onnx
model = onnx.load('yolo26_det_bpu.onnx')
for output in model.graph.output:
shape = [d.dim_value for d in output.type.tensor_type.shape.dim]
print(f'{output.name}: shape={shape}')
"
步骤 3:正确的 hb_mapper YAML 配置
model_parameters:
onnx_model: './yolo26_det_bpu.onnx'
march: "bayes-e"
layer_out_dump: False
working_dir: 'model_output'
output_model_file_prefix: 'yolov8_cow'
input_parameters:
input_name: "images"
input_type_rt: 'nv12'
input_type_train: 'rgb'
input_layout_train: 'NCHW'
norm_type: 'data_scale'
scale_value: 0.003921568627451
calibration_parameters:
cal_data_dir: './cal_bin'
cal_data_type: 'float32'
calibration_type: 'default'
compiler_parameters:
compile_mode: 'latency'
debug: False
optimize_level: 'O3'
注意:
layer_out_dump: False(不要输出中间层)- 不要添加
optimization_parameters(1.24.3 版本不支持)
步骤 4:编译并验证
# 1. 编译
hb_mapper makertbin --model-type onnx --config yolov8.yaml
# 2. 验证模型输出
hrt_model_exec model_info --model_file=./model_output/yolov8_cow.bin
# 期望输出(6 个输出,bbox 应该是 S32):
# output[0]: shape=(1,80,80,5), type=F32 # cls_P3
# output[1]: shape=(1,80,80,64), type=S32 # bbox_P3 ✓
# output[2]: shape=(1,40,40,5), type=F32 # cls_P4
# output[3]: shape=(1,40,40,64), type=S32 # bbox_P4 ✓
# output[4]: shape=(1,20,20,5), type=F32 # cls_P5
# output[5]: shape=(1,20,20,64), type=S32 # bbox_P5 ✓
步骤 5:TROS 配置
{
"model_file": "/home/sunrise/yolov8/yolov8_cow.bin",
"task_num": 4,
"dnn_parser": "yolov8",
"model_output_count": 6,
"reg_max": 16,
"class_num": 5,
"cls_names_list": "my_config/cow.list",
"strides": [8, 16, 32],
"score_threshold": 0.25,
"nms_threshold": 0.7,
"nms_top_k": 300,
"output_order": [0, 1, 2, 3, 4, 5]
}
如果还是不行
备选方案:使用 Python 推理
如果 TROS parser 始终无法兼容,可以直接用 Python 推理:
from hobot_dnn import pyeasy_dnn as dnn
import numpy as np
# 加载模型
models = dnn.load('/home/sunrise/yolov8/yolov8_cow.bin')
model = models[0]
# 推理
outputs = model.inference(input_image)
# 手动后处理
# 1. 解码 bbox(output[1], [3], [5])
# 2. 获取 cls(output[0], [2], [4])
# 3. NMS
关键差异总结
| 操作 | 错误做法 | 正确做法 |
|---|---|---|
| 导出脚本 | 自己修改 Detect_forward |
用 rdk_model_zoo 官方脚本 |
| 输出量化 | 在 PyTorch 中转 int32 | 让 hb_mapper 自动处理 |
| YAML 配置 | 添加 cal_data_count 等无效参数 |
只用标准参数 |
| layer_out_dump | True(导致 69 个输出) |
False(只有 6 个输出) |
相关资源
给 wzm1809434 的建议
你的问题和 huajinxhr 完全一样,直接按上述步骤操作即可。最关键的是使用 rdk_model_zoo 官方的导出脚本,不要自己修改 Detect_forward 函数。
如果还有问题,建议:
- 把
hrt_model_exec model_info的输出发出来 - 确认输出数量是 6 个(不是 69 个)
- 确认 bbox 分支是 S32(不是 F32)
祝顺利!![]()