这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【D-ROBOTICSRDKX5测评】BPU特性测试+从34模型实测到工程落地

共1条 1/1 1 跳转至页

【D-ROBOTICSRDKX5测评】BPU特性测试+从34模型实测到工程落地

助工
2026-10-21 00:10:00     打赏

一、RDK X5的 BPU

RDK X5 搭载 RK3566 八核 Cortex-A55 + 一块 BPU(Brain Processing Unit)。BPU 是地平线自研的神经网络加速器,10 TOPS 算力(INT8),X5 Module 版本对应 Bayes-e 架构。这是这个板卡能拿出来对砍树莓派的大刀。

它和 CPU/GPU 的区别:

维度CPU (A55x8)BPU

通用性什么都能跑只跑量化神经网络
精度fp32int8 量化
输入格式任意(RGB/灰度/张量)NV12 交织 YUV
输出格式float 数组int32 量化整数(需反量化)
算力3.5 FPS(YOLOv8n)99 FPS(YOLOv8n)

BPU 的价值:同一模型,推理快 27 倍。 代价是:输入输出格式和常规 YOLO 管线完全不同,必须按 BPU 的规矩来。

image.png


二、 BPU 特性专项测试

整个测试过程分三个阶段,每个阶段回答不同的问题:

阶段1: 能跑吗?
  用官方金标准 demo 验证:YOLOv8n + kite.jpg -> 7 个目标,最高 0.75
  结论:模型没问题,BPU 硬件正常。

阶段2: 跑得多快?
  分段计时(预处理 / BPU推理 / 后处理),双分辨率(320/640)
  结论:纯 BPU 推理 10ms 级,端到端 23ms,后处理是瓶颈。

阶段3: 怎么用到工程里?
  接摄像头 + Web 服务 (experience_station_v3.py), 踩出 Web 层 6 个坑
  结论:坑全在"喂对它"和"算对它",不在加速器本身。

三个阶段产出的数据就是本文的核心内容。

image.png


三、BPU 工具链特性(核心)

3.1 输入:NV12 嵌套 dict

BPU 模型的输入不是 RGB,是 NV12 格式的 YUV 交织数据,以嵌套 dict 传入:

# 错误(直接喂 RGB,能跑但结果随机):
model.run({"input0": rgb_tensor})

# 正确(NV12 嵌套 dict):
feed = {
    "input0": {
        "input0": (y_tensor, uv_tensor)  # y: (1, H*W, 1) uint8
                                                # uv: (1, H*W/2, 1) uint8
    }
}
model.run(feed)

喂 RGB 时 BPU 不报错、能出结果、能出图——但分类会随机命中(人像判成"锅",置信度还很高)。这种"看起来跑通了"的状态比直接报错更难排查。

转换路径:BGR -> YUV_I420 (cv2.cvtColor) -> 拆 Y/U/V -> U/V 交错成 UV plane -> 嵌套 dict。

3.2 输出:int32 量化整数

BPU 模型输出是 int32 量化值,不是 float。每个输出通道有自己的 scale 和 zero_point:

# 直接当 float 用 -> 数值全错
conf = outputs["output0"][0, i, j, cls]  # 这是 int32,不是 0~1 的概率

# 正确:反量化
scale, zp = model.output_quants["output0"][cls]
conf = (int_val - zp) * scale

3.3 阈值:sigmoid 逆变换

BPU 模型的 cls 输出通道是 logits(未经 sigmoid),不是概率。如果置信度阈值是 0.25:

# 错误:直接拿 logits 和 0.25 比
if logit > 0.25:  # 永远为真(logits 通常在 0 附近)

# 正确:做 sigmoid 逆变换
import numpy as np
thr_raw = -np.log(1 / 0.25 - 1)  # = -1.0986
if logit > thr_raw:  # 这才是对的

官方 demo 里这步是隐式的(封装在 dequantize_outputs 里),手写后处理时很容易漏掉。

3.4 解码:3 尺度特征层

YOLOv8 的检测头有 3 个特征层(stride 8/16/32,对应 80x80/40x40/20x20 网格)。BPU 模型把 6 个输出张量分开给:

output0:    (1, 80, 80, 80)  float32  cls fine  (stride 8)
318:        (1, 80, 80, 64)  int32    bbox fine (stride 8)
334:        (1, 40, 40, 64)  int32    bbox med  (stride 16)
342:        (1, 40, 40, 80)  float32  cls med   (stride 16)
350:        (1, 20, 20, 64)  int32    bbox coarse (stride 32)
358:        (1, 20, 20, 80)  float32  cls coarse (stride 32)

只用 stride=8 单尺度会怎样:只能检测近处大目标,中远景全漏。v2 版 Web 系统就栽在这里——只写了 stride=8 的解码,结果对桌面场景(鼠标/键盘/杯子都是中等距离)永远 0 检测。

正确做法:3 尺度全解码 -> 拼接 -> NMS -> letterbox 坐标回缩。

3.5 版本警告

每次加载模型会打印:

Inconsistency between hbrt library version 3.15.55.0
and model build version 3.15.49.0

实测不影响精度,但升级 SDK 后建议重新跑金标准核对。


四、主线任务实测

4.1 目标检测(YOLOv8n@640)

测试图:kite.jpg(1.4MB,海堤放风筝场景) 模型:/opt/hobot/model/x5/basic/yolov8_640x640_nv12.bin(3.5MB)

分段计时(50 次,BPU core0):

段耗时占比

预处理(RGB->NV12)3.8ms17%
BPU 推理10.1ms44%
后处理(3尺度解码+NMS)9.0ms39%
端到端22.9ms = 43.7 FPS
纯 BPU10.1ms = 99.4 FPS

双分辨率对比:

分辨率BPU 推理BPU FPS

320x3209.53ms104.9
640x64010.32ms96.9

320->640 推理时间只增加 0.8ms。BPU 算力对小模型是富余的,分辨率翻倍几乎不花额外时间。

4.2 图像分类

板上预装分类模型(224x224 NV12):

模型BPU 推理BPU FPS

MobileNetV22.4ms413
EfficientNetLite03.5ms282
MobileNetV12.2ms449
GoogLeNet3.3ms300

分类是 BPU 最富余的场景:400+ FPS,远超摄像头 30fps 的需求。

4.3 语义分割

板上 4 个分割模型全部实测(BPU 量化,1024x2048 输入):

模型BPU 推理BPU FPS大小

FastSCNN EfficientNetB018.29ms54.662.0MB
MobileNet UNet27.15ms36.841.8MB
DeepLabV3+ EfficientNetB033.91ms29.493.9MB
DeepLabV3+ EfficientNetM157.22ms17.485.4MB

分割输入分辨率大(1024x2048),BPU 推理 18~57ms 档(17~55 FPS),全部实时。FastSCNN 最稳(std 仅 0.14ms),是车道线/道路分割这类场景的首选。

4.4 大模型检测(YOLOv5x@672)

模型BPU 推理BPU FPS

YOLOv5x_672(83MB)~30ms33.3

83MB 的大模型在 BPU 上 33 FPS,3W 档位完全可用。

4.5 CPU 对照

同一 YOLOv8n 模型,CPU 管线数据:

管线推理时间FPS说明

BPU10.1ms99.4本文基准
ONNX Runtime CPU~286ms3.5fp32,8 核 A55
Ultralytics CPU 全链路~1250ms0.8含前/后处理

BPU 比纯 CPU 快 27 倍。 这就是 10 TOPS 在 nano 模型上的实际价值。

4.6 板上预装模型总览(34 个全量连跑实测)

/opt/hobot/model/x5/basic/ 下共 34 个量化模型,本次用同一套流水线逐个连跑(3 次预热 + 10 次计时推理,参考图 kite.jpg 各 resize 到模型输入尺寸),34/34 全部推理成功,0 失败。

说明:4.2 / 4.3 是单模型独立基准(预热充分、CPU 侧抖动小),4.6 是 34 个连跑数据(CPU 侧取数、转图开销摊进来)。同一模型两次的 FPS 会有百分之十以内的差异,属正常现象,BPU 纯推理时间不变。

分类(11 个,224x224 ~ 300x300 输入):

模型BPU 推理BPU FPS

MobileNetV11.72ms582
MobileNetV21.94ms515
EfficientNetLite01.96ms510
EfficientNetLite12.10ms476
GoogLeNet2.53ms396
EfficientNetLite22.73ms367
EfficientNetLite33.82ms262
ResNet183.85ms260
EfficientNetLite44.72ms212
EfficientNASNet-S (280)2.39ms419
EfficientNASNet-M (300)4.84ms206

检测(17 个,300x300 ~ 896x896 输入):

模型BPU 推理BPU FPS

SSD-MobileNetV1 (300)4.03ms248
VarGConvNet (224)4.65ms215
FCOS (512)6.94ms144
YOLOv8n (640)10.93ms91.5
YOLOv3 (416)22.45ms44.6
YOLOv5s-v7 (640)22.68ms44.1
YOLOv5s-v6 (640)23.10ms43.3
YOLOv3-DarkNet53 (416)35.84ms27.9
YOLOv10 (640)37.92ms26.4
YOLOv5s (672)28.02ms35.7
YOLOv12n (640)27.10ms36.9
YOLOv2-DarkNet19 (608)29.96ms33.4
YOLO11m (640)41.81ms23.9
CenterNet-ResNet101 (512)41.11ms24.3
FCOS-EfficientNetB2 (768)20.21ms49.5
FCOS-EfficientNetB3 (896)34.51ms29.0
YOLOv5x (672)101.52ms9.85

分割(6 个):

模型输入BPU 推理BPU FPS

YOLOv8-seg640x64012.91ms77.5
FastSCNN-EfficientNetB01024x204819.30ms51.8
STDC (19 类)512x102419.71ms50.8
MobileNet-UNet1024x204831.82ms31.4
DeepLabV3+-EfficientNetB01024x204833.26ms30.1
DeepLabV3+-EfficientNetM11024x204857.66ms17.3

FPS 总览(34 模型横向对比):

image.png

几个直接结论:

  • 分类最快:MobileNetV1(224x224)1.72ms,582 FPS;分类全线 206~582 FPS,富余

  • 检测最实用:SSD-MobileNetV1 248 FPS 但类别少;YOLOv8n 91.5 FPS 是速度/精度平衡点;YOLOv5x(672)压到 9.85 FPS,大模型上 BPU 也救不回来

  • 分割可用:YOLOv8-seg 77.5 FPS 实时;1024x2048 的大分辨率分割 17~52 FPS,DeepLabV3+(M1) 17.3 FPS 只能算准实时

  • 常见任务开箱就有量化模型,不需要自己转

4.7 全部 34 个模型的真实运行窗口截图

每个模型一个真实 tkinter 窗口:左侧输入图叠加模型输出特征,右侧状态面板(MODEL / TASK / FPS / LATENCY / INPUT / OUT 张量形状),底部 infer 10/10 + [PASS] 时间戳。

分类 11 张:

image.pngimage.pngimage.png

检测 17 张:

image.pngimage.png

image.pngimage.pngimage.pngimage.png


五、BPU 格式注意事项

#坑现象根因修复

1喂 RGB 不报错分类随机命中(人像判成锅)BPU 吃 NV12,RGB 张量被当 YUV 解RGB->YUV_I420->NV12 交错
2输出不反量化置信度数值全错int32 量化值直接当 float 用(q-zp)*scale 逐通道
3阈值空间错永远检出 0 或永远全检出logits 直接和 0.25 比sigmoid 逆变换 thr_raw
4只用单尺度中远景目标全漏只解码 stride=8 的 80x80 网格3 尺度(8/16/32)全解码
5box 解码比例猜错框位置全偏用了常数 /100.0 而非 output_quants用模型自带量化参数

核心教训:性能数字(FPS)健康不代表功能正确。 110 FPS 的系统可以一直检出 0 个物体——后处理错了,推理再快也白搭。验证方法:拿官方金标准 demo 跑同一张图,对比结果数量。


六、Web 实时目标检测系统(工程落地)

BPU 特性测试的终点是一个完整跑通的 Web 实时目标检测项目:USB 摄像头接 RDK X5,BPU 跑 YOLOv8n,检测结果叠加后通过 HTTP 推到浏览器,任意电脑/手机打开 http://你的ip:8080 直接看实时画面。

主程序 experience_station_v3.py。git里其他的项目也可以尝试效果。

6.1 系统组成

USB 摄像头 (V4L2, 640x480)
  -> 读帧 -> flip -> resize -> BGR->NV12 (3.8ms)
  -> BPU 推理 YOLOv8n@640 (10.1ms)
  -> 3 尺度解码 + int32 反量化 + NMS (9.0ms)
  -> 画框 -> 共享帧缓冲 (加锁)
  -> HTTP 服务 :8080 (/frame 出帧 + /info 出数据)
  -> 浏览器 66ms 定时拉取, 实时画面

三个组成部分:

  1. 视频流服务:板上起 HTTP 服务,/frame 返回当前帧 JPEG(已叠加检测框),/info 返回 {fps, count, time, model}

  2. 推理引擎:BPU 官方模型 yolov8_640x640_nv12.bin(3.5MB),通过 hbm_runtime 调用

  3. Web 界面:静态 HTML + JS 定时器,每 66ms 拉一次帧图和数据(图片加随机参数防缓存)

    4ba52630b0fd03fad1e977cc29f683f6.png

6.2 双线程架构

线程1: 摄像头循环
  读帧 -> 预处理 -> BPU 推理 -> 后处理 -> 画框
  -> 更新 frame_buffer / detection_data (threading.Lock 保护)

线程2: HTTP 服务 (ThreadingMixIn, 8080)
  GET /      -> 静态 HTML
  GET /frame -> 当前帧 JPEG (带检测框)
  GET /info  -> JSON

浏览器 (每 66ms 拉一次 /frame + /info)

两个关键取舍:

  • 帧缓冲而不是 MJPEG 流:浏览器每次拉一张完整 JPEG,不用手写 multipart 流协议;640 分辨率千兆内网延迟可接受

  • 推理线程和 HTTP 线程分离:推理持续跑,HTTP 请求只读共享缓冲,访问频率不影响推理

6.3 NV12 预处理(完整代码)

RDK X5 的 BPU 模型只吃 NV12 张量(3.1 节),构造方式:

yuv420 = cv2.cvtColor(resize_img, cv2.COLOR_BGR2YUV_I420).reshape(-1)
area = INPUT_SIZE * INPUT_SIZE
y_plane = yuv420[:area]
u_plane = yuv420[area:area + area // 4]
v_plane = yuv420[area + area // 4:]
uv_interleaved = np.zeros(area // 2, dtype=np.uint8)
for i in range(area // 4):
    uv_interleaved[2 * i]   = u_plane[i]
    uv_interleaved[2 * i+1] = v_plane[i]
nv12 = np.concatenate([y_plane, uv_interleaved])
nv12 = nv12.reshape(1, INPUT_SIZE * 3 // 2, INPUT_SIZE, 1)

注意 I420 的 U/V 平面是分开的,NV12 的 UV 是交错的,最后一段循环就是做这个转换。

6.4 BPU 推理调用

runtime = hbm_runtime.HB_HBMRuntime()
runtime.create_runtime(model_path)
runtime.set_input(0, input_name, (1, INPUT_SIZE * 3 // 2, INPUT_SIZE, 1))
# 喂 nv12 张量, 输出取 6 个尺度张量 (3.4 节), 3 次预热后每帧约 10ms

后处理走 3.2 / 3.3 / 3.4 节的三步:int32 逐通道反量化 -> sigmoid 逆变换阈值 -> 3 尺度全解码 + NMS + letterbox 坐标回缩。

6.5 Web 接口

# 当前帧 (JPEG, 已叠加检测框)
curl -o frame.jpg http://192.168.199.129:8080/frame

# 检测信息
curl http://192.168.199.129:8080/info
# {"fps": 96, "count": 2, "time": "18:35:02", "model": "YOLOv8n", "type": "detection"}

6.6 Web 部署注意事项

前文第五节是 BPU 格式类的 5 个坑,这一节是 Web 系统层的 6 个坑。前 3 个都是「RDK X5 的 BPU 模型和标准 YOLOv8 格式不一致」——照着 Ultralytics 文档做会处处碰壁;后 3 个是常规嵌入式 Web 服务的坑。

#坑现象根因修复

1Web 路径 404/frame?_=xxx 返回 404路由写 self.path == '/frame' 精确匹配,JS 防缓存参数导致匹配失败self.path.split('?')[0] 先去掉查询参数
2输出格式非标按官方 [1,84,8400] 取张量对不上RDK X5 是 6 个独立张量(3 尺度 x 2),bbox 是 int32 量化值手写 3 尺度解码 + 逐通道反量化(3.4 节)
3官方 decode_boxes 崩IndexError: 1600 out of bounds官方代码 anchor 索引越界,叠加非标输出放弃官方后处理,手写解码(单尺度起步 -> 3 尺度)
4画面倒置上下颠倒摄像头物理安装方向cv2.flip(frame, 0)
5视频流卡住画面偶尔不动推理线程写、HTTP 线程读,共享状态没加锁threading.Lock() 保护 frame_buffer / detection_data
6喂 RGB 随机结果人像判成 wokBPU 吃 NV12,RGB 被当 YUV 解金标准用例先验证(zebra conf 约 0.885)

关键排查经验:检测不出目标时,先抓 /frame 确认画面正常,再降阈值到 0.1 看候选框数量,区分是「没检出」还是「NMS 全滤掉了」。

6.7 性能数据

项实测值

BPU 单帧推理(640x640)10.1ms = 99.4 FPS
预处理(BGR->NV12)3.8ms
后处理(3 尺度解码 + NMS)9.0ms
单帧全链路22.9ms = 43.7 FPS
系统吞吐(帧循环口径,含 JPEG 编码 + 网络)110 FPS
实测检出(桌面场景)mouse 0.435 / keyboard 0.409 / cup 0.538 / remote 0.472
对照:ONNX Runtime CPU 同模型3.5 FPS(BPU 快 27 倍)

系统瓶颈不在 BPU 而在 CPU 侧的 JPEG 编码和网络传输——BPU 还有很大余量。

6.8 使用方法

# 1. 启动
cd /home/sunrise/project/web_detection
/usr/bin/python3.10 experience_station_v3.py

# 2. 浏览器打开
http://192.168.199.129:8080

# 3. 命令行验证
curl http://localhost:8080/info
curl -o test.jpg http://localhost:8080/frame

摄像头打不开时:ls -l /dev/video0 && sudo chmod 666 /dev/video0。

53ac067165b8a0c4c7c946eed4041c82.png


6.9 优化方向

  1. 预处理硬件化:V4L2 直接出 NV12,省 3.8ms

  2. 跳帧推理:隔帧推 1 次,吞吐翻倍(YOLO26 ONNX 版已验证 +248%,框沿用上一帧不消失)

  3. 后处理并行:NMS 与下一帧推理重叠

  4. 模型替换:同一套 NV12 预处理 + 3 尺度解码框架,可直接换 4.6 节表里任意检测模型(FCOS / CenterNet / YOLOv10)


七、结论

特性实测结论

34 模型全量分类 206~582 FPS / 检测 9.85~248 FPS / 分割 17~77.5 FPS,34/34 跑通
对比 CPU快 27 倍(同一 nano 模型)
Web 系统摄像头 -> BPU YOLOv8n -> 3 尺度解码 -> HTTP 8080,浏览器实时画面,110 FPS
坑全在哪BPU 格式 5 个(NV12 嵌套 dict / int32 反量化 / sigmoid / 3 尺度)+ Web 层 6 个
验证方法金标准 demo 同图对比 + 每模型真实界面截图留证
仓库状态主程序 v3(commit 716e063)+ bpu_sweep 34 模型测试子项目(commit cc0fd49)

BPU 算力在这类小模型上是富余的,真正的工程难度在"喂对它"和"算对它"——输入输出格式和后处理决定了能不能出框,不是加速器本身。


我的测试过程:https://gitee.com/genvex/web_detection





关键词: D-ROBOTICSRDKX5     测评     特性     PBU    

共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]