yolov11seg模型部署帧率极低,可能问题有哪些,包括每个算子是否都用了bpu,数据流传输有没有优化等
你好!针对你提出的 YOLOv11seg 模型在 RDK X5 上部署帧率极低 的问题,结合社区已有案例(特别是 YOLOv11 检测模型的优化经验),核心原因通常集中在 算子未完全下沉 BPU 和 数据流传输瓶颈 两点。
以下是针对 Segmentation(分割)模型的排查路径和优化方案:
核心结论
YOLOv11seg 帧率低(如 <10 FPS)的常见原因:
- 关键算子(如 Softmax/Sigmoid/Resize)回退到 CPU 运行,导致频繁的 CPU-BPU 数据拷贝。
- 模型输出头未适配,后处理在 CPU 上耗时过长。
- 输入预处理格式不匹配(如使用了 RGB 而非 NV12),增加了额外转换开销。
- 量化配置缺失
node_info,导致注意力模块中的 Softmax 未被指定到 BPU。
排查步骤(按优先级)
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
正常情况:所有算子显示 BPU,且只有 1 个 BPU subgraph。
异常情况:
- 看到
Softmax或Sigmoid在 CPU 运行(分割模型解码常用)。 - 出现多个
BPU subgraph(说明模型被切分,中间有数据拷贝)。
解决方案:在量化配置 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"
理想状态:Model has 1 BPU subgraph
问题状态:Model has 2+ BPU subgraphs(说明有算子在 CPU,导致数据来回拷贝)
3. 检查输入数据格式
RDK X5 的 BPU 原生支持 NV12 格式输入。如果你使用 RGB/BGR 输入,会触发额外的格式转换开销。
优化配置:
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 实现效率低。
优化建议:
- 参考社区 YOLOv11 检测模型的输出头修改方案,将输出拆分为多个 Tensor,简化后处理逻辑。
- 使用 C++ 实现后处理(Python 后处理通常有 5-10ms 开销)。
- 检查 Mask 分支是否也需要
node_info优化(如 Sigmoid 算子)。
性能对比参考
根据社区 YOLOv11n 检测模型的优化案例:
| 优化阶段 | BPU 延迟 | 端到端 FPS | 关键操作 |
|---|---|---|---|
| 初始部署 | 126ms | 7 FPS | Softmax 在 CPU,2 个子图 |
添加 node_info |
10.8ms | 47 FPS | Softmax 强制 BPU,1 个子图 |
| C++ 后处理 | ~8ms | 60+ FPS | 后处理优化 |
注意:分割模型由于多了 Mask 分支,FPS 通常会比检测模型低 20-30%,这是正常的。
快速行动清单
- 运行
hb_mapper checker,确认 Softmax/Sigmoid 是否在 BPU。 - 检查
node_info配置,参考 YOLOv11 部署实战帖 添加强制 BPU 配置。 - 验证输入格式,确保使用 NV12 而非 RGB。
- 查看编译日志,确认只有 1 个 BPU subgraph。
- 参考社区资源:
如果以上步骤仍无法解决,请提供:
hb_mapper checker日志中关于Softmax/Sigmoid的输出hrt_model_exec model_info显示的 subgraph 数量- 当前量化配置 YAML 文件
这样可以更精准定位问题!![]()
我的叫best.onnx
好的!请执行以下命令来诊断你的 best.onnx 模型:
# 在 Docker 或开发机执行
hb_mapper checker --model-type onnx --march bayes-e --model best.onnx > checker.log
# 查看关键信息
grep -i "softmax\|sigmoid\|cpu" checker.log
然后把 checker.log 中的以下内容发给我:
- 是否有算子显示
CPU(特别是 Softmax/Sigmoid/Resize) - 日志末尾的 subgraph 信息(类似
Model has X BPU subgraphs) - 分割模型特有的算子分布(Mask 分支相关)
快速自检清单
执行完 checker 后,先自己看一眼:
| 检查项 | 正常 | 异常 |
|---|---|---|
| Softmax/Sigmoid 位置 | BPU |
CPU |
| BPU subgraph 数量 | 1 个 |
2+ 个 |
| Resize/Upsample | BPU |
CPU |
如果看到 任何算子在 CPU 或 subgraph > 1,就是帧率低的根本原因。
提前准备修复方案
如果确认有算子回退 CPU,需要在量化配置中添加 node_info。先告诉我 checker 的结果,我帮你定位具体需要配置的节点名称!
Usage: hb_mapper checker [OPTIONS]
Error: Invalid value for ‘–model’: Path ‘best.onnx’ does not exist.
root@0f773d5694e5:/open_explorer#
root@0f773d5694e5:/open_explorer# # 查看关键信息
root@0f773d5694e5:/open_explorer# grep -i “softmax|sigmoid|cpu” checker.log
root@0f773d5694e5:/open_explorer# # 在 Docker 或开发机执行
root@0f773d5694e5:/open_explorer# hb_mapper checker --model-type onnx --march bayes-e --model best.onnx > checker.log
Usage: hb_mapper checker [OPTIONS]
Error: Invalid value for ‘–model’: Path ‘best.onnx’ does not exist.
root@0f773d5694e5:/open_explorer#
root@0f773d5694e5:/open_explorer# # 查看关键信息
root@0f773d5694e5:/open_explorer# grep -i “softmax|sigmoid|cpu” checker.log
看到问题了!best.onnx 文件在 Docker 容器中找不到,这是路径挂载问题。
先定位文件位置
在 Docker 容器内执行:
# 1. 查看当前目录
pwd
# 2. 查找 onnx 文件
find / -name "*.onnx" 2>/dev/null
# 3. 或者查看挂载的目录(通常是 /data)
ls -lh /data/
ls -lh /app/
常见路径对照
| 宿主机路径 | Docker 容器内路径 |
|---|---|
~/rdk_x5_deploy/ |
/data/ |
~/rdk_x5_deploy/models/ |
/data/models/ |
当前目录 . |
/open_explorer/ |
正确执行步骤
# 步骤1:找到你的 onnx 文件
ls -lh /data/*.onnx /data/models/*.onnx 2>/dev/null
# 步骤2:使用完整路径执行 checker
# 假设文件在 /data/models/best.onnx
hb_mapper checker --model-type onnx --march bayes-e --model /data/models/best.onnx > /data/checker.log
# 步骤3:查看结果
cat /data/checker.log | grep -i "softmax\|sigmoid\|cpu\|subgraph"
如果文件确实没挂载
退出 Docker,在宿主机确认文件位置:
# 退出 Docker
exit
# 在宿主机查找
find ~/rdk_x5_deploy -name "best.onnx"
# 确认文件存在后,重新启动 Docker(确保挂载正确)
cd ~/rdk_x5_deploy
docker run -it --rm -v $(pwd):/data --name oe_toolchain openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8-py310 /bin/bash
下一步
请告诉我:
find / -name "*.onnx"的输出结果(文件实际在哪里)- 你启动 Docker 时用的挂载命令
找到文件后,我们重新执行 hb_mapper checker 获取有效的诊断日志!![]()
usr/local/lib/python3.10/dist-packages/onnx/backend/test/data/pytorch-converted/test_Softmax/model.onnx
/usr/local/lib/python3.10/dist-packages/onnx/backend/test/data/pytorch-converted/test_Conv1d_pad1size1/model.onnx
/usr/local/lib/python3.10/dist-packages/onnx/backend/test/data/simple/test_shrink/model.onnx
/usr/local/lib/python3.10/dist-packages/onnx/backend/test/data/simple/test_strnorm_model_monday_insensintive_upper_twodim/model.onnx
/usr/local/lib/python3.10/dist-packages/onnx/backend/test/data/simple/test_strnorm_model_monday_casesensintive_nochangecase/model.onnX
为什么有那么多onnx
这些 ONNX 文件是 ONNX 库自带的测试模型,不是你的模型!它们是安装 onnx 包时自带的单元测试文件。
你的模型在哪里?
需要在宿主机(Ubuntu 虚拟机或你的电脑)上找到 best.onnx,然后正确挂载到 Docker。
步骤 1:退出 Docker,在宿主机查找
# 先退出 Docker
exit
# 在宿主机查找你的模型
find ~ -name "best.onnx" 2>/dev/null
# 或者常见位置
ls -lh ~/rdk_x5_deploy/models/
ls -lh ~/yolo11seg/
ls -lh ./*.onnx
正确挂载流程
找到文件后,按以下步骤操作:
# 1. 假设找到文件在 ~/yolo11seg/best.onnx
cd ~/yolo11seg
# 2. 确认文件存在
ls -lh best.onnx
# 3. 启动 Docker 时挂载当前目录
docker run -it --rm \
-v $(pwd):/data \
--name oe_toolchain \
openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8-py310 \
/bin/bash
# 4. 在 Docker 内验证文件已挂载
ls -lh /data/best.onnx
# 5. 执行 checker
hb_mapper checker --model-type onnx --march bayes-e --model /data/best.onnx > /data/checker.log
# 6. 查看结果
grep -i "softmax\|sigmoid\|cpu\|subgraph" /data/checker.log
常见问题
| 问题 | 解决方案 |
|---|---|
找不到 best.onnx |
检查导出脚本是否成功运行 |
| Docker 内看不到文件 | 确认 -v $(pwd):/data 挂载正确 |
| 路径不对 | 使用 pwd 确认当前目录 |
请先执行
exit
find ~ -name "best.onnx" 2>/dev/null
把找到的完整路径发给我,我帮你确认挂载命令!![]()
/home/cairuiqian/rdk_work/
看到路径了!你的模型应该在 /home/cairuiqian/rdk_work/ 目录下。
下一步操作
步骤 1:确认文件存在
# 在宿主机执行(先退出 Docker)
exit
# 确认 best.onnx 在这个目录下
ls -lh /home/cairuiqian/rdk_work/best.onnx
如果文件存在,继续步骤 2。
步骤 2:正确挂载并执行 checker
# 进入模型所在目录
cd /home/cairuiqian/rdk_work/
# 启动 Docker,挂载当前目录到 /data
docker run -it --rm \
-v $(pwd):/data \
--name oe_toolchain \
openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8-py310 \
/bin/bash
# === 以下在 Docker 内执行 ===
# 验证文件已挂载
ls -lh /data/best.onnx
# 执行 checker 诊断
hb_mapper checker --model-type onnx --march bayes-e --model /data/best.onnx > /data/checker.log
# 查看关键信息
grep -i "softmax\|sigmoid\|cpu\|subgraph" /data/checker.log
步骤 3:发送诊断结果
请把以下信息发给我:
grep命令的输出(看是否有算子在 CPU)- 日志末尾的 subgraph 数量(类似
Model has X BPU subgraphs) - 如果有 Softmax/Sigmoid,显示的运行位置(BPU 还是 CPU)
预期结果对照
| 检查结果 | 含义 | 下一步 |
|---|---|---|
Softmax/Sigmoid 显示 CPU |
算子回退,性能瓶颈 | 添加 node_info 配置 |
Model has 2+ BPU subgraphs |
模型被切分 | 需要优化算子分布 |
全部显示 BPU 且 1 subgraph |
模型正常 | 排查其他问题(后处理/输入格式) |
提前准备
如果确认有算子在 CPU,修复方案是修改量化配置 YAML:
model_parameters:
onnx_model: '/data/best.onnx'
march: 'bayes-e'
# 强制关键算子到 BPU(节点名称从 checker 日志获取)
node_info: {
"你的节点名称": {'ON': 'BPU', 'InputType': 'int16', 'OutputType': 'int16'}
}
先执行上面的诊断命令,把结果发给我,我帮你定位具体需要配置的节点!![]()
grep -i “softmax\|sigmoid\|cpu\|subgraph” /data/checker.log可以单独发吗,为什么单独发没反应
单独执行 grep 没反应,通常是因为 checker.log 文件是空的(hb_mapper checker 命令实际没成功执行)。
先确认文件是否有内容
在 Docker 内依次执行:
# 1. 确认 checker.log 是否存在
ls -lh /data/checker.log
# 2. 查看文件大小(如果是 0 或很小,说明没生成成功)
wc -l /data/checker.log
# 3. 直接查看文件内容
cat /data/checker.log
如果文件是空的(0 行)
说明 hb_mapper checker 命令执行失败了。请重新执行完整的 checker 命令:
# 在 Docker 内执行
hb_mapper checker --model-type onnx --march bayes-e --model /data/best.onnx 2>&1 | tee /data/checker.log
注意:
2>&1会把错误信息也输出到文件,tee可以同时显示和保存。
如果文件有内容(>100 行)
再执行 grep:
# 方式1:直接 grep
grep -i "softmax\|sigmoid\|cpu\|subgraph" /data/checker.log
# 方式2:分步 grep(更清晰)
echo "=== CPU 算子 ===" && grep "CPU" /data/checker.log
echo "=== Softmax ===" && grep -i "softmax" /data/checker.log
echo "=== Sigmoid ===" && grep -i "sigmoid" /data/checker.log
echo "=== Subgraph ===" && grep -i "subgraph" /data/checker.log
快速排查表
| 现象 | 原因 | 解决 |
|---|---|---|
ls 显示文件不存在 |
checker 没执行 | 重新执行 hb_mapper checker |
wc -l 显示 0 行 |
命令执行失败 | 加 2>&1 捕获错误信息 |
| grep 无输出 | 日志中没有这些关键词 | 直接 cat 查看完整日志 |
| grep 有输出 | 把输出发给我分析 |
请先执行
ls -lh /data/checker.log && wc -l /data/checker.log
把输出结果发给我,我帮你判断下一步!如果文件是空的,我们重新执行完整的 checker 命令。
文件有啊,oot@fecf37072655:/open_explorer# grep -i “softmax|sigmoid|cpu|subgraph” /data/checker.log
root@fecf37072655:/open_explorer# grep -i “softmax|sigmoid|cpu|subgraph” /data/checker.log但是一直这样
grep 没输出说明日志中没有这些关键词,或者格式不同。让我们直接查看文件内容来确认实际格式!
直接查看日志内容
在 Docker 内依次执行:
# 1. 查看文件末尾(subgraph 信息通常在末尾)
tail -50 /data/checker.log
# 2. 或者查看完整内容(如果文件不大)
cat /data/checker.log
如果 tail 输出类似这样…
正常情况(全 BPU):
/model.0/conv/Conv BPU id(0) HzSQuantizedConv
/model.1/conv/Conv BPU id(0) HzSQuantizedConv
...
Compile submodel: main_graph_subgraph_0
Model has 1 BPU subgraphs
→ 说明模型正常,帧率低可能是后处理或输入格式问题
异常情况(有 CPU 算子):
/model.10/m/m.0/attn/Softmax CPU -- Softmax
/model.22/Sigmoid CPU -- Sigmoid
Compile submodel: main_graph_subgraph_0
Compile submodel: main_graph_subgraph_1
Model has 2 BPU subgraphs
→ 说明有算子回退 CPU,需要添加 node_info 配置
如果 tail 也没看到有用信息
请执行以下命令,把完整输出发给我:
# 查看文件行数
wc -l /data/checker.log
# 查看文件前 100 行
head -100 /data/checker.log
# 查看文件后 100 行
tail -100 /data/checker.log
另一种可能:grep 语法问题
试试这个更简单的 grep:
# 分开搜索
grep "CPU" /data/checker.log
grep "BPU" /data/checker.log | head -20
grep "subgraph" /data/checker.log
请把以下信息发给我
tail -50 /data/checker.log的完整输出wc -l /data/checker.log的行数
这样我就能帮你准确判断模型是否存在算子回退问题!![]()
/model.22/cv2.2/cv2.2.0/act/Mul BPU id(0) HzLut – 1.0 int8这种
看到日志了!算子显示 BPU 是好消息,说明没有算子回退到 CPU。
但还需要确认一个最关键的信息——BPU subgraph 数量!
请继续执行以下命令
# 1. 查看日志末尾(subgraph 信息在这里)
tail -30 /data/checker.log
# 2. 搜索 subgraph 关键词
grep -i "subgraph" /data/checker.log
# 3. 确认文件总行数
wc -l /data/checker.log
判断标准
| Subgraph 数量 | 含义 | 帧率预期 |
|---|---|---|
| 1 个 | 应该高 | |
| 2+ 个 | 会很低 |
如果 Subgraph = 1(模型正常)
帧率低的原因可能是:
1. 输入数据格式问题
# ❌ 错误:使用 RGB 输入,CPU 做格式转换
input_data = rgb_data.transpose(2,0,1)
# ✅ 正确:使用 NV12 输入,BPU 硬件加速
input_data = nv12_data # BPU 内部自动转 RGB + 归一化
2. 后处理耗时过长(分割模型特有)
YOLOv11seg 比检测模型多了 Mask 解码 步骤:
- Proto 网络输出
- Mask 系数计算
- Mask 还原(CPU 上可能耗时 20-50ms)
3. 板端 CPU 频率未设置
# 在 RDK X5 板端执行
sudo bash -c "echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor"
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq # 应该是 1800000
请把以下信息发给我
grep -i "subgraph" /data/checker.log的输出tail -30 /data/checker.log的完整内容- 当前板端测试的实际 FPS 是多少?
- 测试代码中输入数据格式是 NV12 还是 RGB?
这样我能帮你精准定位是模型编译问题还是代码实现问题!![]()
没有任何cpu的,这个没问题,那应该是数据流传输不好
好的!既然算子都在 BPU 上,那帧率低确实很可能是数据流传输瓶颈。根据社区 YOLOv11 优化案例,数据流问题通常占性能损耗的 50% 以上。
数据流传输优化排查清单
1. 输入数据格式(最关键!)
RDK X5 的 BPU 原生支持 NV12 格式,使用 RGB 会触发额外的 CPU 转换开销。
错误方式(RGB 输入):
# CPU 做 BGR→RGB 转换 + 归一化 + HWC→CHW
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_float = img_rgb.astype(np.float32) / 255.0
input_data = img_float.transpose(2, 0, 1) # 耗时约 3-5ms
正确方式(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) # 耗时约 1-2ms
outputs = model.forward(nv12_data)
量化配置确认:
input_parameters:
input_type_rt: 'nv12' # 板端推理格式
input_type_train: 'rgb' # 训练时格式
norm_type: 'data_scale'
scale_value: 0.003921568627451
2. 板端 CPU 性能模式
CPU 频率未设置会导致后处理变慢:
# 在 RDK X5 板端执行
sudo bash -c "echo 1 > /sys/devices/system/cpu/cpufreq/boost"
sudo bash -c "echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor"
# 验证
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq # 应该是 1800000
3. 分层性能测试(定位瓶颈)
在你的测试代码中加入计时:
import time
# 1. 预处理耗时
start = time.time()
nv12_data = bgr_to_nv12(img)
preprocess_time = (time.time() - start) * 1000
# 2. BPU 推理耗时
start = time.time()
outputs = model.forward(nv12_data)
inference_time = (time.time() - start) * 1000
# 3. 后处理耗时(分割模型特有:Mask 解码)
start = time.time()
boxes, masks = postprocess(outputs)
postprocess_time = (time.time() - start) * 1000
print(f"预处理: {preprocess_time:.2f}ms")
print(f"BPU 推理: {inference_time:.2f}ms")
print(f"后处理: {postprocess_time:.2f}ms")
print(f"总计: {preprocess_time + inference_time + postprocess_time:.2f}ms")
预期参考值(RDK X5):
| 环节 | 正常值 | 异常值 |
|---|---|---|
| 预处理(NV12) | 1-3ms | >5ms |
| BPU 推理 | 8-15ms | >30ms |
| 后处理(分割) | 5-15ms | >30ms |
| 总计 | 15-30ms | >50ms |
4. 分割模型后处理优化
YOLOv11seg 比检测模型多了 Mask 分支,后处理更复杂:
常见瓶颈:
- Mask 系数与 Proto 特征图相乘在 CPU 上进行
- 未使用向量化计算(NumPy 循环慢)
优化建议:
- 使用 NumPy 向量化操作代替循环
- 考虑用 C++ 实现后处理(可提速 3-5 倍)
- 参考社区 YOLOv11 检测模型的后处理代码
请提供以下信息
- 当前测试代码中输入数据格式(NV12 还是 RGB?)
- 分层性能测试结果(预处理/BPU/后处理各耗时多少)
- 当前实际 FPS 是多少?
- 量化配置 YAML 中的
input_type_rt设置
这样我能帮你精准定位是哪个环节拖慢了速度!![]()
参考资源
model_parameters:
onnx_model: “best.onnx”
march: “bayes-e”
working_dir: “model_output”
output_model_file_prefix: “yolov5_best_quant”
input_parameters:
input_name: “images”
input_shape: “1x3x480x480”
input_type_rt: “nv12”
input_type_train: “rgb”
input_layout_train: “NCHW”
norm_type: “data_scale”
scale_value: 0.003921568627
mean_value: “”
calibration_parameters:
cal_data_dir: “./calibration_images”
cal_data_type: “float32”
calibration_type: “kl”
preprocess_on: true
compiler_parameters:
compile_mode: “latency”
debug: false
optimize_level: “O3”
看到你的量化配置了!配置整体没问题,input_type_rt: "nv12" 已正确设置。但还有几个关键点需要排查:
配置分析
| 配置项 | 当前值 | 状态 |
|---|---|---|
input_type_rt |
nv12 |
|
optimize_level |
O3 |
|
compile_mode |
latency |
|
node_info |
缺失 | |
input_shape |
1x3x480x480 |
数据流传输优化排查步骤
步骤 1:确认板端 CPU 性能模式
在 RDK X5 板端执行:
# 设置 CPU 为性能模式
sudo bash -c "echo 1 > /sys/devices/system/cpu/cpufreq/boost"
sudo bash -c "echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor"
# 验证频率(应该是 1800000)
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq
如果频率是 1200000 或更低,CPU 后处理会慢 30-50%!
步骤 2:分层性能测试
在你的测试代码中加入计时,定位具体瓶颈:
import time
import cv2
import numpy as np
from hobot_dnn import pyeasy_dnn as dnn
def bgr_to_nv12(img):
"""BGR 转 NV12"""
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)
# 加载模型
models = dnn.load('yolov5_best_quant.bin')
model = models[0]
# 测试图片
img = cv2.imread('test.jpg')
# === 分层计时 ===
times = {'preprocess': [], 'inference': [], 'postprocess': []}
for i in range(50):
# 1. 预处理
start = time.time()
nv12_data = bgr_to_nv12(img)
times['preprocess'].append((time.time() - start) * 1000)
# 2. BPU 推理
start = time.time()
outputs = model.forward(nv12_data)
times['inference'].append((time.time() - start) * 1000)
# 3. 后处理(你的分割解码逻辑)
start = time.time()
# TODO: 你的后处理代码
# boxes, masks = postprocess(outputs)
times['postprocess'].append((time.time() - start) * 1000)
# 打印结果
print(f"预处理平均: {np.mean(times['preprocess']):.2f}ms")
print(f"BPU 推理平均: {np.mean(times['inference']):.2f}ms")
print(f"后处理平均: {np.mean(times['postprocess']):.2f}ms")
print(f"总耗时: {np.mean([sum(x) for x in zip(*times.values())]):.2f}ms")
print(f"预估 FPS: {1000 / np.mean([sum(x) for x in zip(*times.values())]):.1f}")
预期参考值(RDK X5):
| 环节 | 正常值 | 异常值 | 可能原因 |
|---|---|---|---|
| 预处理(NV12) | 1-3ms | >5ms | 图片尺寸过大/转换方式不对 |
| BPU 推理 | 8-15ms | >30ms | 模型未优化/输入尺寸不对 |
| 后处理(分割) | 5-15ms | >30ms | CPU 未设性能模式/代码效率低 |
步骤 3:检查输入尺寸匹配
你的配置是 480x480,确认 ONNX 模型输入也是这个尺寸:
# 在 Docker 内检查 ONNX 输入 shape
python3 -c "
import onnx
model = onnx.load('/data/best.onnx')
print('输入名称:', model.graph.input[0].name)
print('输入 shape:', [d.dim_value for d in model.graph.input[0].type.tensor_type.shape.dim])
"
如果 ONNX 是 640x640 但配置是 480x480,会导致额外缩放开销!
步骤 4:添加 node_info(可选优化)
虽然 checker 显示没有 CPU 算子,但分割模型的 Sigmoid/Resize 有时需要显式指定:
model_parameters:
onnx_model: "best.onnx"
march: "bayes-e"
working_dir: "model_output"
output_model_file_prefix: "yolov11seg_best_quant" # 建议改个名字
# 【建议添加】强制关键算子到 BPU
node_info: {
"/model.22/Sigmoid": {'ON': 'BPU', 'InputType': 'int16', 'OutputType': 'int16'}
}
input_parameters:
input_name: "images"
input_shape: "1x3x480x480"
input_type_rt: "nv12"
input_type_train: "rgb"
input_layout_train: "NCHW"
norm_type: "data_scale"
scale_value: 0.003921568627
calibration_parameters:
cal_data_dir: "./calibration_images"
cal_data_type: "float32"
calibration_type: "kl"
preprocess_on: true
compiler_parameters:
compile_mode: "latency"
debug: false
optimize_level: "O3"
注意:
node_info中的节点名称需要用hb_mapper checker日志中的实际名称替换
请提供以下信息
执行完上面的分层测试后,告诉我:
- 预处理/BPU/后处理各耗时多少?
- 当前实际 FPS 是多少?
- CPU 频率是否为 1800000?
- ONNX 模型输入尺寸是多少?
这样我能帮你精准定位是哪个环节拖慢了速度!![]()