您好,NXP支持团队,
我们正在使用Neutron SDK v3.1.3在FRDM i.MX95平台上评估目标检测功能。并且无法生成与 NPU 兼容的模型。Neutron 变流器成功加载了模型,但报告称0 个算子映射到 Neutron NPU 。
目标板:FRDM i.MX95
Neutron SDK:3.1.3
Ultralytics:已使用 YOLO11 和 YOLOv8 进行测试
eIQ 工具包:用于 ONNX 到 TFLite 的转换
型号:定制单类钉子检测器
$ yolo detect train \ model=yolov11n.pt \ data=/visual_inspect_yolo/dataset/dataset.yaml \ imgsz=640 \ epochs=100 \ batch=16 \ project=models \ name=peg_detector_v8
$ yolo export \ model=models/peg_detector_v84/weights/best.pt \ format=tflite \ int8=True \ data=/visual_inspect_yolo/dataset/dataset.yaml
我们还测试了另一种工作流程:
导出 PyTorch → ONNX
使用 NXP eIQ 工具包将 ONNX 转换为 INT8 TFLite
使用 Neutron SDK 编译时,两种工作流程都产生了相同的结果。
〜/下载/eiq-neutron-sdk-linux-3.1.3/bin/neutron-变流器--target imx95 --input best_int8.tflite --output my_model_int8_npu.tflite
变流器报告:
导入后运算符:341
优化后的运算符数:367
已转换运算符:0
操作员转换率:0 / 367
中子图数量:0
警告:
我们观察到以下情况也存在同样的现象:
YOLO11
YOLOv8
直接 Ultralytics TFLite 导出
ONNX → eIQ 工具包 → INT8 TFLite
所有生成的 TFLite 模型都导致 Neutron 编译器映射 0 个算符。
Neutron 编译器是否正式支持 i.MX95 的 YOLOv8 或 YOLO11 目标检测模型?
对于目标平台为 i.MX95 NPU 的 YOLO 模型,是否有推荐的导出流程?
当前 Neutron SDK (v3.1.3) 是否存在任何已知限制?关于YOLO检测头?
NXP 是否提供可在 i.MX95 NPU 上成功编译的 YOLOv8/YOLO11 参考模型?
启用运算符映射是否需要额外的编译器选项或预处理步骤?
我们非常希望获得任何与 i.MX95 Neutron NPU 兼容的指导、推荐工作流程或参考模型。
谢谢!
谢谢你的回复。
我想咨询一下是否有标准程序可用于在IM X95板上进行模型的训练、导出和部署。
由于我们目前拥有ARA2 ,我们正在寻求充分利用其功能并定制我们的模型。我们将在NXP技术日上进行演示,如果您能在这方面提供帮助,我们将不胜感激。
感谢您的帮助。
在 imx95 主板上尝试了 eIQ 模型库中的 yolo8m 模型,使用了 LF 2026 Q2 版本镜像。内核版本为 6.18.20,使用 Neutron SDK 3.1.2,运行正常。
您可以先尝试以下方法:
wget https://huggingface.co/EdgeFirst/yolov8-det/resolve/main/imx95/yolov8n-det-int8-smart.imx95.tflite
root@imx95evk:/usr/bin/tensorflow-lite-2.19.0/examples# ./benchmark_model--graph=yolov8n-det-int8-smart.imx95.tflite --external_delegate_path=/usr/lib/libneutron_delegate.so
更多信息请参阅 README 文件eiq-model-zoo/tasks/vision/object-detection/yolov8 at main · NXP/eiq-model-zoo
此外,您还可以附加转换/编译的模型和详细日志。
根据变流器日志,首先要解决的问题是生成的 TFLite 模型仍然包含 FLOAT 运算符:
警告:图表中包含不受支持的浮点运算符!
对于 i.MX95 Neutron,中子变流器的输入必须是 TFLite 模型,其算符和量化格式与 Neutron 编译器兼容。具体来说,i.MX95 中子流需要量化的 TFLite 和对称的 int8 权重。如果模型在 Ultralytics 导出或 ONNX 到 TFLite 转换后仍然包含 FLOAT 运算符/张量,则变流器可能无法创建任何 Neutron 兼容的子图,这与报告的结果一致:
已转换运算符:0
中子图数量:0
YOLOv8 已在 i.MX95 上进行过一些流程的评估,但对于任意 Ultralytics 导出,不应假定完全端到端的 YOLOv8/YOLO11 卸载。根据导出的 TFLite 图,模型可能只有一部分会转换为 NeutronGraph,而不支持的操作符将保留在 CPU 上。因此,建议的下一步是检查/分析生成的 TFLite 模型并确认:
另外,请确保板上的 Neutron 变流器版本和 Neutron 运行时/固件/委托来自同一个兼容的 SDK/电路板支持包 版本。
建议采用 NXP/eIQ 转换路径:
PyTorch -> ONNX(静态输入形状) -> NXP/eIQ 量化(使用代表性校准数据) -> 量化后的 TFLite -> 中子变流器 --target imx95
如果模型具有 uint8 输入/输出张量,请同时进行以下测试:
--将输入的 uint8 转换为 int8
--convert-outputs-uint8-to-int8
如果移除浮点运算符后,转换结果仍然显示 0 个已映射运算符,请分享:
- 完整的 中子变流器 日志,如有详细/分析输出,请提供。
- TFLite 操作员列表,
- 张量数据类型和量化参数,
- FRDM i.MX95 板上确切的 电路板支持包/运行时 Neutron 代理/固件版本,
- YOLO 检测头是否包含 NMS 或 TFLite 图中的其他后处理。
在我的测试中,我没有自己训练或导出模型。我使用了 eIQ 模型库中预先生成的 YOLOv8 模型,并验证了它在 i.MX95 平台上运行。
我实际使用的唯一命令是:
./benchmark_model \
--graph=yolov8n-det-int8-smart.imx95.tflite \
--external_delegate_path=/usr/lib/libneutron_delegate.so
``
以该模型为例:
wget https://huggingface.co/EdgeFirst/yolov8-det/resolve/main/imx95/yolov8n-det-int8-smart.imx95.tflite
对于定制模型,NXP 推荐的流程如下:
PyTorch
↓
ONNX(静态输入形状)
↓
eIQ 工具包 ONNX2Quant
↓
eIQ Toolkit ONNX2TFLite
↓
量化 TFLite
↓
中子变流器 --target imx95
由于您的模型报告:
纯文本
已转换运算符:0
中子图数量:0
警告:图表中包含不支持的 FLOAT 运算符!
我怀疑您生成的 TFLite 图在结构上与 eIQ 模型库参考模型不同。我首先建议做的是比较这两个型号的以下方面:
你好
我运行的是 ubuntu 24.04,但是 eiq_toolkit 仅适用于 20.04.03 版本。
如何使用 eiqToolkit 和使用 eIQ Toolkit 进行量化
请问您是如何将 yolov8m_full_integer_quant.tflite 转换为能够在 imx95 NPU 上运行的?
以下步骤和环境设置数据(主机)将对我们非常有帮助。
推荐的端到端工作流程
使用您偏好的框架进行训练:
对于目标检测,NXP 已经在 eIQ 模型库中提供了 YOLO 参考配方,包括 YOLOv8 目标检测模型。[github.com] ,[github.com]
示例:
shell
yolo 检测训练 \
model=yolov8n.pt \
data=dataset.yaml
imgsz=640 \
epochs=100
`
NXP 通常建议在量化和部署之前使用 ONNX 作为交换格式。
yolo 导出 \
model=best.pt \
format=onnx
Neutron 启用演示文稿明确描述了基于以下流程的说明:
纯文本
PyTorch
↓
ONNX
↓
量子化
↓
TFLite
↓
中子变流器
而不是直接从训练工件中寻找部署目标。
Neutron 工作流程文档建议使用 eIQ Toolkit 量化工具:
python -m onnx2quant \
model.onnx \
-o model_quant.onnx \
-c 输入::
``
其次是:
python -m onnx2tflite \
model_quant.onnx \
-o model_int8.tflite
显示更多行
该流程在 i.MX95 Neutron 实现材料中有明确记录。
中子变流器
--target imx95 \
--输入 model_int8.tflite \
--输出 model_neutron.tflite
Neutron 变流器创建 Neutron 特有的图分区,这些分区可以卸载到 NPU 上。
NPU 部署成功后,应报告类似以下内容:
转换的操作员数量 > 0
中子图数量 > 0
如果你看到:
已转换运算符:0
中子图数量:0
那么该模型就没有被NPU加速。
你目前的问题就属于这一类。
使用 TensorFlow Lite 和 Neutron 委托运行:
./benchmark_model \
--graph=model_neutron.tflite \
--external_delegate_path=/usr/lib/libneutron_delegate.so
``
或
./label_image \
--external_delegate_path=/usr/lib/libneutron_delegate.so
i.MX 机器学习用户指南将Neutron Delegate定义为 i.MX95 TensorFlow Lite 模型的加速机制。
由于 eIQ Toolkit 已在 Ubuntu 20.04 上验证过,因此最安全的方法是:
Docker
在 Ubuntu 24.04 主机上运行 Ubuntu 20.04 容器:
docker run -it --name eiq \
ubuntu:20.04 /bin/bash
然后,在容器内安装所需的依赖项和 eIQ Toolkit。
使用 eIQ Toolkit (onnx2quant) 转换自定义 YOLOv8 ONNX 模型时,无法保留置信度输出。
NXP团队您好,
我正在尝试使用 eIQ Toolkit 在 FRDM i.MX95 上部署自定义 YOLOv8 单类目标检测模型。
整个转换流程运行成功,但在 onnx2quant 之后,置信度输出全部变为零,而边界框输出仍然有效。
- Ubuntu 24.04
- Python 3.10
- eIQ ONNX2TFLite 0.9.0
- ONNX 运行时 1.21.1
- TensorFlow 2.21
- 中子变流器 3.1.3
- 目标:FRDM i.MX95(tflite_runtime 2.19 + Neutron delegate)
1. 火车
yolo detect train model=yolov8n.pt data=dataset.yaml imgsz=640 epochs=50
2. 导出 ONNX
yolo export model=best.pt format=onnx opset=13
3. 验证 ONNX
输入:(1,3,640,640)
输出:(1,5,8400)
ONNX 运行时推理:
置信度通道最大值 = 0.773
4. 生成校准数据集
形状:(1,3,640,640)
数据类型:float32
范围:0.0 - 1.0
5. 量化
onnx2quant best.onnx -c "images;calibration/images" -o best_quant.onnx
同时测试了:
onnx2quant 最佳.onnx -u
两者产生的结果相同。
6. 验证量化的 ONNX
输出:(1,5,8400)
边界框通道仍然有效。
信心:
最小值 = 0
最大值 = 0
平均值 = 0
解码检测结果 = 0
7. 转换为 TFLite 格式
onnx2tflite best_quant.onnx -o best.tflite
8. 为 Neutron 编译
neutron-converter --target imx95 --input best.tflite --output best_neutron.tflite
编译成功。
操作员转化率:278 / 325 (85.5%)
已核实:
• PyTorch 模型有效
• ONNX 导出工作
• ONNX 运行时推理功能正常
• 校准数据集正确
• 真实校准和随机校准产生相同的结果
• TFLite 重现量化的 ONNX 输出
• Neutron 可以重现 TFLite 的输出
该问题首次出现于以下情况:
ONNX
↓
onnx2quant
↓
量化 ONNX(置信度变为零)
恩智浦参考模型:
输入:(1,640,640,3) INT8
输出:(1,84,8400) INT8
我转换后的模型:
输入:(1,3,640,640) FLOAT32
输出:(1,5,8400) FLOAT32
对于自定义 YOLOv8 模型,是否有推荐的导出或量化工作流程,能够保留置信度输出?
对于输出为 (1,5,8400) 的模型,这可能是 onnx2quant 的一个限制或错误吗?
与AE团队讨论。
Ara240 的端到端性能是否已经过评估?数据手册中提到了两个矢量核心,可以执行诸如 sigmoid 和 NMS 之类的后处理操作。编译器能否将 NMS 操作映射到向量核心?
抱歉耽搁了。我正在尝试重现转换工作流程。
现在有一个问题,为什么转换后的模型的数据类型是 FLOAT32?你试过转换成 INT8 类型吗?Neutron NPU 需要 INT8 类型作为输入数据。我在其他模型转换中也遇到过类似的错误,根本原因是数据类型错误。
由于对 YOLOv8 的输出张量应用了完全 INT8 量化( inference_output_type=tf.int8 )这一根本限制,置信度输出丢失了。
YOLOv8 将边界框坐标和置信度分数打包成形状为(1, 5, 8400)的单个输出张量。bbox 值具有较大的动态范围(~640 像素),而置信度得分在 ~0 到 1 的范围内。当整个输出张量共享一个量化尺度时,该尺度主要由较大的边界框值(~640)构成,只剩下一个整数级别的一小部分来表示整个置信范围(~1)。因此,经过 INT8 量化后,所有置信值实际上都被四舍五入为零。
推荐解决方案
而不是通过 onnx2quant,直接从您训练好的数据中导出 INT8 TFLite。 .pt 使用 Ultralytics 建模,然后将其输入到 neutron-变流器:
# 直接导出 INT8 TFLite 数据(校准使用您的训练数据集)
yolo export model=best.pt \
format=liter \
imgsz=640 \
量化=8
data=dataset.yaml
分数=0.1
#为Neutron 编译(未更改)
neutron-变流器 --target imx95 --input best_int8.tflite --output best_neutron.tflite
请确保输入和输出数据类型为 np.int8:
interp = tf.lite.Interpreter(model_path=TFLITE_INT8) interp.allocate_tensors()inp_d = interp.get_input_details()[0]out_ds = interp.get_output_details()inp_scale, inp_zp = inp_d[ "量化" ] out_d = out_ds[0] out_scale, out_zp = out_d[ "量化" ] print(f " 输入数据类型={inp_d['dtype']} 形状={inp_d['shape'].tolist()}" f " quant=(scale={inp_scale:.6f}, zp={inp_zp})" ) print(f " 输出 dtype={out_d['dtype']} shape={out_d['shape'].tolist()}" f " quant=(scale={out_scale:.6f}, zp={out_zp})" )# 根据形状确定输入格式 in_shape = inp_d[ "shape" ].tolist()# [1,3,640,640] 或 [1,640,640,3] 如果in_shape[1] == 3: # NCHW src=img_nchw 别的: # NHWC src=img_nhwcif inp_d[ "dtype" ] == np.int8: src_int8 = np.clip(np.round(src/ inp_scale + inp_zp), -128, 127).astype(np.int8) interp.set_tensor(inp_d[ “索引” ],src_int8) 别的: interp.set_tensor(inp_d[ “索引” ],src.astype(np.float32))interp.invoke()raw_out = interp.get_tensor(out_d[ "index" ])# 如果 out_d[ "dtype" ] == np.int8,则可能是 int8 或 float32: dq_out = (raw_out.astype(np.float32) - out_zp) * out_scale 别的: dq_out = raw_out.astype(np.float32)dq_out= dq_out[0] # (5, 8400) 归一化 # 将边界框重新缩放回像素坐标以便显示 BBOX_SCALE = 640.0tfl_bbox = dq_out[:4] * BBOX_SCALE # (4, 8400) tfl_conf = dq_out[4] # (8400,)
您好,我尝试了您分享的命令……
但是中子变流器无法转换模型……
请查收附件日志,供您参考,引用。
请提供日志。