我正试图在 IMX95 的内部 NPU 上运行 PyTorch 模型。我按照以下步骤进行了操作:
所有步骤运行无误,我还创建了一个 PowerShell 脚本,用于运行第 2-4 步。可在此处下载:
script.ps1
ONNX 文件(输出步骤 1)可在此处下载:
model.onnx
我遇到的问题是:
当我在 IMX95 的 NPU 上运行模型时,尽管提供了不同的输入图像,但输出总是相同的。但是,当我在 IMX95 的 CPU 上运行 TFLite 模型(步骤 3 的输出)时,每幅图像的输出都是正确的。这表明,转换和量化步骤工作正常,但最后一步出现了问题。
我成功进行了转换(使用中子变流器)并运行了恩智浦提供的示例模型(mobilenet_v1_1.0_224_quant.tflite)在 IMX95 的 NPU 上。因此,推理代码并不是问题所在。
我怀疑要么模型中使用的层有问题,要么在导出或转换过程中出现问题。
感谢您就如何解决这个问题提出任何意见或建议。
eIQ 1.17 与 LF 6.12.34 兼容。
eIQ 1.16 与 LF 6.12.20 兼容。
您可以尝试使用正确的版本,然后再试一次吗?
你好 @danielchen
电路板支持包 版本为 6.12.20。
我在 /proc/version 中进行了检查:
Linux 版本 6.12.20-lts-next-gdfaf2136deb2 (oe-user @OE-host) (aarch64-参考发行版、系统开发套件。-linux-gcc (GCC) 14.2.0,GNU ld (GNU Binutils) 2.44)#1 SMP PREEMPT Wed Jun 4 10:15:09 UTC 2025
我使用的是 IMX.95 EVK。
我使用同样的工具转换了 mobilenet.tflite 锉刀使用 MCU_SDK_25.09.00+Linux_6.12.34_2.1.0 转换模型时 变流器即使输出与 CPU 型号不同,输出看起来也更有用。不过,当我使用 Linux_6.6.3_1.0.0 时,也会出现与自定义模型相同的问题。输出变化
NPU (Linux_6.6.3_1.0.0):
- 推理结果 -
推理时间(平均):0.50 ms
模型输出:(1, 1001)
[[0 0 0 ... 0 0 0]]
非零类得分:
所有类得分均为零!
NPU (MCU_SDK_25.09.00+Linux_6.12.34_2.1.0):
- 推理结果 -
推理时间(平均):2.00 ms
模型输出:(1, 1001)
[[0 6 0 ... 0 0 0]]
非零类得分:
Class ID:1 得分:6
Class ID:114 Score: 6
Class ID:117 Score: 6
Class ID:118 Score: 6
Class ID:123 Score: 6
Class ID:125 Score: 6
Class ID:242 Score: 6
Class ID:245 Score: 6
Class ID:246 Score: 6
Class ID:250 Score: 6
Class ID:251 Score: 6
Class ID:253 Score: 6
Class ID:256 Score: 6
Class ID:257 Score: 6
Class ID:370 Score: 6
Class ID:373 Score: 6
Class ID:374 Score: 6
Class ID:379 Score: 6
Class ID:381 Score: 6
Class ID:457 Score: 6
Class ID:498 Score: 6
Class ID:501 Score: 6
Class ID:502 Score: 6
Class ID:507 Score: 6
Class ID:508 Score: 5
Class ID:509 Score: 6
Class ID:513 Score: 6
Class ID:514 Score: 6
Class ID:626 Score: 6
Class ID:629 Score: 6
Class ID:630 Score: 6
Class ID:635 Score: 6
Class ID:637 Score: 6
Class ID:709 Score: 3
Class ID:754 Score: 6
Class ID:757 Score: 6
Class ID:758 Score: 6
Class ID:763 Score: 6
Class ID:765 Score: 6
Class ID:882 Score: 6
Class ID:885 Score: 6
Class ID:886 Score: 6
Class ID:890 Score: 6
Class ID:891 Score: 6
Class ID:893 分数: 2预测等级 ID:1
预测等级得分:6
最低得分:0 最高得分:6
CPU:
- 推理结果 -
推理时间(平均):116.31 ms
模型输出:(1, 1001)
[[0 0 0 ... 0 0 0]]
非零类得分:
Class ID:439 分数:18
Class ID:441 Score: 1
Class ID:454 Score: 1
Class ID:496 Score: 1
Class ID:505 Score: 3
Class ID:506 Score: 7
Class ID:527 Score: 2
Class ID:528 Score: 1
Class ID:544 Score: 1
Class ID:549 Score: 1
Class ID:551 Score: 1
Class ID:554 Score: 1
Class ID:573 Score: 15
Class ID:599 Score: 2
Class ID:605 Score: 112
Class ID:620 Score: 11
Class ID:627 Score: 1
Class ID:630 Score: 1
Class ID:645 Score: 1
Class ID:665 Score: 2
Class ID:697 Score: 6
Class ID:712 Score: 13
Class ID:726 Score: 1
Class ID:738 Score: 2
Class ID:744 Score: 1
Class ID:774 Score: 3
Class ID:783 Score: 8
Class ID:800 Score: 1
Class ID:805 Score: 2
Class ID:847 Score: 5
Class ID:852 Score: 3
Class ID:895 Score: 1
Class ID:899 Score: 3
Class ID:900 Score: 5
Class ID:906 Score: 3
Class ID:908 Score: 1
Class ID:967 分数: 3预测等级 ID:605
预测等级得分:112
最低得分:0 最高得分:112
Python 代码推理
import time
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from tensorflow.lite.python.interpreter import Interpreter
from tensorflow.lite.python.interpreter import load_delegate
from tqdm import tqdm
MODEL_PATH_NPU = ‘./mobilenet_v1_1.0_224_quant_IMX_95.tflite’
MODEL_PATH_CPU = ‘./mobilenet_v1_1.0_224_quant.tflite’
IMAGE_PATH = ‘./train.jpg’
USE_NPU_DELEGATE = True
NPU_DELEGATE_PATH = ‘/usr/lib/liblitert_neutron_delegate.so’
INFERENCE_WARMUP_STEPS = 10
INFERENCE_STEPS = 10
class TFLiteModel:
def __init__(self, model_path, use_npu_delegate, npu_delegate_path):
if use_npu_delegate:
ext_delegate = [load_delegate(npu_delegate_path)]
self.interpreter = Interpreter(model_path=model_path, experimental_delegates=ext_delegate)
else:
self.interpreter = Interpreter(model_path=model_path)
self.interpreter.allocate_tensors()
self.input_details = self.interpreter.get_input_details()
self.output_details = self.interpreter.get_output_details()
def load_image(self, image_path, input_mean, input_std):
image_height = self.input_details[0]['shape'][1]
image_width = self.input_details[0]['shape'][2]
img = Image.open(image_path).resize((image_width, image_height))
img_array = np.array(img)
input_data = np.expand_dims(img_array, axis=0)
return input_data
def infer(self, input_tensor):
self.interpreter.set_tensor(self.input_details[0]['index'], input_tensor)
self.interpreter.invoke()
output_data = self.interpreter.get_tensor(self.output_details[0]['index'])
return output_data
if __name__ == ‘__main__':
if not USE_NPU_DELEGATE:
MODEL_PATH = MODEL_PATH_CPU
else:
MODEL_PATH = MODEL_PATH_NPU
tf_lite_model = TFLiteModel(MODEL_PATH, USE_NPU_DELEGATE, NPU_DELEGATE_PATH)
input_tensor = tf_lite_model.load_image(IMAGE_PATH, input_mean=[0.485, 0.456, 0.406], input_std=[0.229, 0.224, 0.225])
#Warm up
for _ in tqdm(range(INFERENCE_WARMUP_STEPS), desc="Warming up",total=INFERENCE_WARMUP_STEPS):
tf_lite_model.infer(input_tensor)
# Actual inference
average_inference_time = 0
for _ in tqdm(range(INFERENCE_STEPS), desc="Inference", total=INFERENCE_STEPS):
start_time = time.time()
output_data = tf_lite_model.infer(input_tensor)
stop_time = time.time()
average_inference_time += (stop_time - start_time) * 1000
average_inference_time /= INFERENCE_STEPS
print('\n--- Inference Results ---')
print(f'Inference Time (average): {average_inference_time:.2f} ms')
print(f'Model Output: {output_data.shape} \n {output_data}')
# List all None-zero class scores
print('Non-zero class scores:')
number_of_zero_scores = 0
for class_id, score in enumerate(output_data[0]):
if np.abs(score) > 1e-6:
print(f' Class ID: {class_id} Score: {score}')
else:
number_of_zero_scores += 1
if number_of_zero_scores == len(output_data[0]):
print(' All class scores are zero!')
else:
id = np.argmax(output_data)
print(f'\nPredicted class ID: {id}')
print(f'Predicted class score: {output_data[0][id]}')
print(f'Min score: {np.min(output_data)} Max score: {np.max(output_data)}')
print('-------------------------\n')
# Plot a heat map with the logits for each class
class_width_pixels = 100
plt.figure(figsize=(20, 4))
plt.imshow(output_data, aspect='auto', cmap='viridis', extent=[0, output_data.shape[1]*class_width_pixels, 0, 1])
plt.colorbar()
plt.xlabel('Class ID')
plt.title('Model Output Scores per Class')
plt.savefig(f'model_output_scores_{"NPU" if USE_NPU_DELEGATE else "CPU"}.png')
plt.close()```你使用的是哪个电路板支持包 版本?
@danielchen感谢您的建议。
我用 eIQ 1.17 和 LF 6.12.34(Linux 版本 6.12.34-lts-next-gbe78e49cb433)进行了重试。
我也没有使用自定义代码,而是使用了 /usr/bin/tensorflow-lite-2.19.0/examples 中的label_image.py文件。
1.使用所提供的模型进行测试
python3 label_image.py --ext_delegate /usr/lib/libneutron_delegate.so
INFO:NeutronDelegate 委托:31 个节点中有 0 个节点被委托,0 个分区。
INFO:
预热时间:57.4 ms推理时间: 54.8 毫秒
0.878431: 军装
0.027451:温莎领带
0.011765: 按揭板
0.011765: 防弹背心
0.007843: 萨克斯
查看结果 NPU 上执行了 0 个节点
2.使用 MCU_SDK_25.09.00+Linux_6.12.34_2.1.0
python3 label_image.py --ext_delegate /usr/lib/libneutron_delegate.so --model_file /root/mobilenet_v1_1.0_224_quant_imx95_MCU-SDK-25-09-00-Linux-6-12-34-2-1-0.tflite
INFO:NeutronDelegate 委托:4 个节点中委托了 1 个节点,有 1 个分区。
INFO:Neutron 委托版本:v1.0.0-be8bf399,已启用 zerocp。
INFO:
预热时间:0.6 毫秒推理时间:0.4 毫秒
0.000000: 卫生纸
0.000000: 海星
0.000000: 斑马
0.000000: 苏木
0.000000: 天竺鼠
结果显示,在 NPU 上执行了一个节点,但输出全为零,是错误的。
使用的 .tflite 文件附在帖子后面。
我还用自定义模型进行了实验,结果也显示了同样的问题,即所有零或所有对数的值都完全相同,与输入图像无关。