RDKX5的TROS部署自己的yolov8输出结构全是F32,该怎么调整?

你好!你的问题定位非常精准,核心问题在于 YOLOv8 的 bbox 分支缺少正确的量化信息(quanti type),导致 TROS 的 parser 无法正确解析。

问题结论

你的猜测 2 是正确的:在 export_yolo26_detect_bpu.py 中提前将 bbox 转换为 int32,导致 hb_mapper 无法识别这是需要量化的浮点输出,最终 quanti type 显示为 NONE

关键错误点

  1. ONNX 导出时不应手动转 int32:量化应该在 hb_mapper 阶段完成,而不是在 PyTorch 导出时
  2. 输出顺序错误:TROS 的 YOLOv8 parser 期望 先 cls 后 bbox(与你当前代码相反)
  3. 缺少量化配置:yaml 中需要正确配置输出节点的量化策略

正确解决方案

步骤 1:修正 ONNX 导出脚本

关键修改

  • 不要在 PyTorch 中手动转 int32
  • 保持 bbox 和 cls 都是 float32
  • 调整输出顺序为 先 cls 后 bbox(匹配官方模型)
  • 添加 permute 将 NCHW 转为 NHWC(BPU 要求)
def bpu_detect_forward(self, x):
    result = []
    for i in range(self.nl):
        # bbox 分支:保持 float32,不要转 int32!
        bbox = self.cv2[i](x[i])  # (B, 4*reg_max, H, W)
        
        # cls 分支:保持 float32
        cls = self.cv3[i](x[i])  # (B, nc, H, W)
        
        # 关键:先 permute 再调整顺序
        # 1. NCHW -> NHWC
        bbox = bbox.permute(0, 2, 3, 1).contiguous()  # (B, H, W, 4*reg_max)
        cls = cls.permute(0, 2, 3, 1).contiguous()    # (B, H, W, nc)
        
        # 2. 输出顺序:先 cls 后 bbox(匹配官方)
        result.append(cls)
        result.append(bbox)
    return result

重新导出 ONNX

cd /path/to/export_script
python export_yolo26_detect_bpu.py --pt your_model.pt --imgsz 640 640 --opset 11

验证 ONNX 输出(应该全是 float32):

python3 -c "
import onnx
model = onnx.load('best.onnx')
for output in model.graph.output:
    elem_type = output.type.tensor_type.elem_type
    shape = [d.dim_value for d in output.type.tensor_type.shape.dim]
    type_name = 'float32' if elem_type == 1 else 'int32' if elem_type == 7 else f'unknown({elem_type})'
    print(f'{output.name}: shape={shape}, type={type_name}')
"

期望输出(全是 float32):

output0: shape=[1, 80, 80, 5], type=float32    # cls_P3
output1: shape=[1, 80, 80, 64], type=float32  # bbox_P3
output2: shape=[1, 40, 40, 5], type=float32   # cls_P4
output3: shape=[1, 40, 40, 64], type=float32  # bbox_P4
output4: shape=[1, 20, 20, 5], type=float32   # cls_P5
output5: shape=[1, 20, 20, 64], type=float32  # bbox_P5

步骤 2:修正 hb_mapper YAML 配置

关键修改

  • 移除错误的 set_node_output_int32 配置(这个语法不支持)
  • 添加正确的量化策略配置
  • 确保校准数据充足(至少 100 张)
model_parameters:
  onnx_model: './best.onnx'
  march: "bayes-e"
  layer_out_dump: False
  working_dir: 'model_output'
  output_model_file_prefix: 'yolov8_cow'

input_parameters:
  input_name: "images"
  input_shape: '1x3x640x640'
  input_type_rt: 'nv12'
  input_layout_rt: 'NHWC'
  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'  # 或 'max'
  # 关键:确保校准数据充足
  cal_data_count: 100

compiler_parameters:
  compile_mode: 'latency'
  debug: False
  optimize_level: 'O3'
  
# 关键:添加输出量化配置(如果 hb_mapper 版本支持)
optimization_parameters:
  # 不要手动指定 int32,让 hb_mapper 自动处理
  # 某些版本支持以下配置(尝试)
  quantize_output_nodes: True

重新编译模型

hb_mapper makertbin --model-type onnx --config yolov8.yaml

步骤 3:验证 bin 模型输出

编译完成后,检查输出类型和 quanti type:

hrt_model_exec model_info --model_file=./yolov8_cow.bin

期望输出(注意 quanti type 应该有值):

output[0]:
  valid shape: (1,80,80,5,)
  tensor type: HB_DNN_TENSOR_TYPE_F32
  tensor layout: HB_DNN_LAYOUT_NHWC
  quanti type: SCALE  # 或 SHIFT,不应该是 NONE

output[1]:
  valid shape: (1,80,80,64,)
  tensor type: HB_DNN_TENSOR_TYPE_S32  # bbox 应该是 int32
  tensor layout: HB_DNN_LAYOUT_NHWC
  quanti type: SCALE  # 关键:这里有量化信息

如果 quanti type 仍然是 NONE,说明量化失败,可能是:

  1. 校准数据不足或质量差
  2. ONNX 模型结构有问题
  3. hb_mapper 版本不支持自动输出量化

步骤 4:检查 TROS 配置文件

确保 yolov8workconfig.json 配置正确:

{
  "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]
}

步骤 5:OE 版本问题

你提到的 OE 1.2.8 版本问题:

  • RDK X5 最新 OE 版本:截至 2024 年底,最新版本是 1.2.8(你当前使用的)
  • 建议:检查是否有更新版本,访问 地瓜开发者社区 下载中心
  • 版本兼容性:你的 hb_mapper 版本 1.24.3 与运行时 1.24.5 接近,一般没问题

快速排查清单

检查项 期望结果 当前状态
ONNX 输出类型 全是 float32 :cross_mark: 你改成了 int32
输出顺序 先 cls 后 bbox :cross_mark: 你是先 bbox 后 cls
输出布局 NHWC :white_check_mark: 已修正
bin 模型 quanti type SCALE/SHIFT :cross_mark: 显示 NONE
校准数据数量 ≥100 张 需确认

参考资源


总结

  1. 回退 ONNX 导出脚本:不要手动转 int32,保持 float32
  2. 调整输出顺序:先 cls 后 bbox
  3. 确保校准数据充足:至少 100 张代表性图片
  4. 让 hb_mapper 自动处理量化:不要手动指定 int32

按照上述步骤重新导出 → 量化 → 部署,应该能解决 quanti type: NONE 的问题!如果还有问题,可以把新的 hrt_model_exec model_info 输出发出来继续分析。