问题分析
从日志看,核心问题是 example-3 进程段错误崩溃(exit code -11),导致 WebSocket 收不到 AI 数据。
常见原因:
- 模型 bin 文件与配置文件不匹配
- 模型输入尺寸/格式与配置文件不一致
- 模型版本与 HorizonRT 不兼容
排查步骤
1. 检查配置文件关键字段
请确认你的 yolo11workconfig.json 中以下字段:
{
"model_file": "/path/to/your/model.bin",
"model_input_type": "nv12", // 必须与相机输出一致
"input_width": 640, // 必须与模型训练输入一致
"input_height": 480, // 必须与模型训练输入一致
"model_type": "yolo", // YOLO11 应设为 yolo
"label_file": "/path/to/labels.txt"
}
关键检查点:
input_width/height是否与你训练时的输入尺寸一致?(YOLO11 默认通常是 640x640)model_file路径是否正确?
2. 验证模型文件
# 检查 bin 文件是否存在且可读
ls -lh /home/sunrise/yiqiang_ws/src/origincar/models/your_model.bin
# 查看模型信息(如果有 hb_model_check 工具)
hb_model_check --model /path/to/your/model.bin
3. 查看完整错误堆栈
段错误的具体原因需要看 core dump 或更详细的日志:
# 启用核心转储
ulimit -c unlimited
# 重新运行,查看是否有更多错误信息
ros2 launch origincar_bringup usb_websocket_display.launch.py \
dnn_example_config_file:=/home/sunrise/yiqiang_ws/src/origincar/models/yolo11workconfig.json \
--log-level debug
4. 检查模型转换流程
YOLO11 模型转换到 bin 的正确流程:
# 1. ONNX 导出(确保 opset 版本兼容)
python export.py --model yolov11n.pt --imgsz 640 --format onnx --opset 11
# 2. HB 工具转换
hb_mapper --model-type yolo --model your_model.onnx --output-dir output/
社区资源
让我搜索一下社区中是否有类似的 YOLO11 部署问题:
问题分析与解决方案
根据你的报错日志,这是典型的 YOLO11 模型在 RDK X5 上部署崩溃问题(exit code -11)。结合社区已有案例,问题核心在于:
核心原因
- 模型输出格式不匹配 - YOLO11 的 ONNX 导出格式与 TROS 的
dnn_example_node期望格式不一致 - Parser 配置错误 - YOLO11 应该使用
yolov8parser,但输出头数量或顺序可能不对 - 量化校准数据问题 - 如果做了双重归一化,会导致模型输出崩塌
解决步骤
步骤 1:检查模型输出格式
首先在板子上验证你的 bin 模型输出:
# 在 RDK X5 上运行
python3 << 'EOF'
from hobot_dnn import pyeasy_dnn as dnn
import numpy as np
models = dnn.load('/home/sunrise/yiqiang_ws/src/origincar/models/yolo11n.bin')
model = models[0]
print(f"Model inputs: {len(model.inputs)}")
print(f"Model outputs: {len(model.outputs)}")
for i, out in enumerate(model.outputs):
p = out.properties
print(f"Output[{i}]: shape={p.shape}, layout={p.layout}, type={p.dtype}")
EOF
期望输出(与官方模型一致):
Output[0]: shape=(1, 64, 80, 80), layout=NCHW # bbox_P3
Output[1]: shape=(1, 1, 80, 80), layout=NCHW # cls_P3 (如果是单类别)
Output[2]: shape=(1, 64, 40, 40), layout=NCHW # bbox_P4
Output[3]: shape=(1, 1, 40, 40), layout=NCHW # cls_P4
Output[4]: shape=(1, 64, 20, 20), layout=NCHW # bbox_P5
Output[5]: shape=(1, 1, 20, 20), layout=NCHW # cls_P5
如果你的输出是 NHWC 格式 或 数量不是 6 个,说明导出有问题。
步骤 2:检查配置文件
查看你的 yolo11workconfig.json:
{
"model_file": "yolo11n.bin",
"dnn_Parser": "yolov8",
"model_output_count": 6,
"reg_max": 16,
"class_num": 1,
"cls_names_list": "config/fire.list",
"strides": [8, 16, 32],
"score_threshold": 0.25,
"nms_threshold": 0.7,
"nms_top_k": 300
}
关键检查点:
dnn_Parser必须是"yolov8"(YOLO11/12/13 都用这个)model_output_count必须是6class_num要和你的模型类别数一致
步骤 3:验证校准数据(如果量化有问题)
如果你是自己量化的模型,检查校准数据是否做了双重归一化:
# 验证校准数据
import numpy as np
import os
cal_file = "./calibration_f32/000000.f32"
data = np.fromfile(cal_file, dtype=np.float32).reshape(3, 640, 640)
print(f"Min: {data.min():.1f} (应该是 ~0)")
print(f"Max: {data.max():.1f} (应该是 ~255)")
if data.max() < 2.0:
print(" 错误:校准数据被归一化到 0~1 了!")
print("BPU 的 scale_value 会自动做 /255,校准数据必须是 0~255 范围")
步骤 4:使用官方参考模型对比
参考社区的完整教程:【保姆级教程】YOLO 自定义模型在 RDK X5 上的完整部署
关键导出代码(确保 NCHW 格式):
# export_for_rdkx5.py
import torch
import types
from ultralytics import YOLO
model = YOLO("best.pt")
head = model.model.model[-1]
# 关键:6 输出,保持 NCHW,不做 permute
def new_forward(self, x):
result = []
for i in range(self.nl):
bbox = self.cv2[i](x[i]) # (B, 64, H, W)
cls = self.cv3[i](x[i]) # (B, nc, H, W)
result.append(bbox)
result.append(cls)
return result
head.forward = types.MethodType(new_forward, head)
dummy = torch.randn(1, 3, 640, 640)
torch.onnx.export(
model.model, dummy, "yolo11n.onnx",
input_names=['images'],
output_names=['bbox_P3', 'cls_P3', 'bbox_P4', 'cls_P4', 'bbox_P5', 'cls_P5'],
opset_version=11,
do_constant_folding=True,
)
步骤 5:临时排查方案
如果还是崩溃,先用官方模型测试 TROS 是否正常:
# 使用板子自带的模型测试
ros2 launch dnn_node_example dnn_node_example.launch.py
如果官方模型能跑,说明是你的模型格式问题;如果官方模型也崩溃,说明系统环境问题。
需要补充的信息
为了更精准定位问题,请提供:
- 模型输出信息(步骤 1 的运行结果)
- 系统版本:运行
sudo rdkos_info - 量化配置 yaml(如果是自己量化的)
- ONNX 模型结构:运行
python3 -c "import onnx; m=onnx.load('your.onnx'); print([(n.name, n.op_type) for n in m.graph.node if 'Softmax' in n.op_type])"
相关资源
建议先执行步骤 1,把模型输出信息贴出来,可以更快定位问题。