yolov11seg模型部署帧率极低

你好!针对你提出的 YOLOv11seg 模型在 RDK X5 上部署帧率极低 的问题,结合社区已有案例(特别是 YOLOv11 检测模型的优化经验),核心原因通常集中在 算子未完全下沉 BPU 和 数据流传输瓶颈 两点。

以下是针对 Segmentation(分割)模型的排查路径和优化方案:

:bullseye: 核心结论

YOLOv11seg 帧率低(如 <10 FPS)的常见原因:

  1. 关键算子(如 Softmax/Sigmoid/Resize)回退到 CPU 运行,导致频繁的 CPU-BPU 数据拷贝。
  2. 模型输出头未适配,后处理在 CPU 上耗时过长。
  3. 输入预处理格式不匹配(如使用了 RGB 而非 NV12),增加了额外转换开销。
  4. 量化配置缺失 node_info,导致注意力模块中的 Softmax 未被指定到 BPU。

:magnifying_glass_tilted_left: 排查步骤(按优先级)

1. 检查算子分布(最关键)

使用 hb_mapper checker 确认所有算子是否都在 BPU 上运行,重点检查 Softmax、Sigmoid、Resize 等算子。

# 在 Docker 或开发机执行
hb_mapper checker --model-type onnx --march bayes-e --model your_yolov11seg.onnx > checker.log

# 查看是否有算子被分配到 CPU
grep "CPU" checker.log

# 特别关注分割模型特有的算子
grep -i "softmax\|sigmoid\|resize\|upsample" checker.log

:white_check_mark: 正常情况:所有算子显示 BPU,且只有 1 个 BPU subgraph。
:cross_mark: 异常情况:

  • 看到 Softmax 或 Sigmoid 在 CPU 运行(分割模型解码常用)。
  • 出现多个 BPU subgraph(说明模型被切分,中间有数据拷贝)。

:wrench: 解决方案:在量化配置 YAML 中添加 node_info,强制关键算子上 BPU:

model_parameters:
  onnx_model: './yolov11seg.onnx'
  march: 'bayes-e'
  # 【关键】强制 Softmax/Sigmoid 在 BPU 运行(使用 int16 精度)
  node_info: {
    "/model.10/m/m.0/attn/Softmax": {'ON': 'BPU', 'InputType': 'int16', 'OutputType': 'int16'},
    "/model.22/Sigmoid": {'ON': 'BPU', 'InputType': 'int16', 'OutputType': 'int16'} 
    # 注意:具体节点名称需用 checker 日志确认
  }

2. 验证 BPU 子图数量

编译完成后,使用 hrt_model_exec 检查模型结构:

hrt_model_exec model_info --model_file your_yolov11seg.bin | grep -i "subgraph"
  • :white_check_mark: 理想状态:Model has 1 BPU subgraph
  • :cross_mark: 问题状态:Model has 2+ BPU subgraphs(说明有算子在 CPU,导致数据来回拷贝)

3. 检查输入数据格式

RDK X5 的 BPU 原生支持 NV12 格式输入。如果你使用 RGB/BGR 输入,会触发额外的格式转换开销。

:wrench: 优化配置:

input_parameters:
  input_type_rt: 'nv12'  # 板端推理使用 NV12
  input_type_train: 'rgb'  # 训练时是 RGB
  input_layout_train: 'NCHW'
  norm_type: 'data_scale'
  scale_value: 0.003921568627451  # 1/255

代码侧调整(Python 示例):

# ❌ 错误:使用 RGB 输入,增加转换开销
input_data = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).transpose(2,0,1)

# ✅ 正确:使用 NV12 输入,BPU 硬件加速预处理
def bgr_to_nv12(img):
    yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV_I420)
    h, w = img.shape[:2]
    uv = np.concatenate([yuv[h:h+h//4], yuv[h+h//4:]], axis=1)
    return np.concatenate([yuv[:h], uv], axis=0)

nv12_data = bgr_to_nv12(img)
outputs = model.forward(nv12_data)

4. 分割模型后处理优化

YOLOv11seg 的输出包含 Detection Head 和 Mask Head,后处理比检测模型更复杂。

常见问题:

  • Mask 解码在 CPU 上进行,耗时过长。
  • 未使用 NMS 或 NMS 实现效率低。

:wrench: 优化建议:

  • 参考社区 YOLOv11 检测模型的输出头修改方案,将输出拆分为多个 Tensor,简化后处理逻辑。
  • 使用 C++ 实现后处理(Python 后处理通常有 5-10ms 开销)。
  • 检查 Mask 分支是否也需要 node_info 优化(如 Sigmoid 算子)。

:bar_chart: 性能对比参考

根据社区 YOLOv11n 检测模型的优化案例:

优化阶段 BPU 延迟 端到端 FPS 关键操作
初始部署 126ms 7 FPS Softmax 在 CPU,2 个子图
添加 node_info 10.8ms 47 FPS Softmax 强制 BPU,1 个子图
C++ 后处理 ~8ms 60+ FPS 后处理优化

:light_bulb: 注意:分割模型由于多了 Mask 分支,FPS 通常会比检测模型低 20-30%,这是正常的。


:hammer_and_wrench: 快速行动清单

  1. 运行 hb_mapper checker,确认 Softmax/Sigmoid 是否在 BPU。
  2. 检查 node_info 配置,参考 YOLOv11 部署实战帖 添加强制 BPU 配置。
  3. 验证输入格式,确保使用 NV12 而非 RGB。
  4. 查看编译日志,确认只有 1 个 BPU subgraph。
  5. 参考社区资源:

如果以上步骤仍无法解决,请提供:

  • hb_mapper checker 日志中关于 Softmax/Sigmoid 的输出
  • hrt_model_exec model_info 显示的 subgraph 数量
  • 当前量化配置 YAML 文件

这样可以更精准定位问题!:rocket: