跳到主要内容

推理

开始使用 SyNAP 最简单的方法是使用预装在开发板上的示例预编译模型和应用程序。

important

在 Android 上,示例模型位于 /vendor/firmware/models/,而在 Yocto Linux 上位于 /usr/share/synap/models/。 在本文档中,我们将此目录称为 $MODELS

模型根据其输入数据类型和输出信息类型进行广泛分类。在每个类别中,模型按主题组织(例如"imagenet"),每个主题都提供一组模型和示例输入数据。

每个类别都提供相应的命令行测试应用程序。

模型分类

类别输入输出测试应用
image_classification图像概率(每个类别一个)synap_cli_ic
object_detection图像检测结果(边界框+类别+概率)synap_cli_od
image_processing图像图像synap_cli_ip

除了上述特定应用程序外,synap_cli 可用于执行所有类别的模型。此应用程序的目的不是提供高级输出,而是测量推理时间。这是唯一可用于需要安全输入或输出的模型的示例应用程序。

synap_cli_ic 应用程序

此命令行应用程序允许轻松执行图像分类模型。

输入:

  • 转换后的 synap 模型(.synap 扩展名)
  • 一个或多个图像(jpeg 或 png 格式)

输出:

  • 每个输入图像的前 5 个最可能的类别
备注

jpeg/png 输入图像在软件中调整大小到网络输入张量的大小。这不包括在显示的分类时间中。

示例:

$ cd $MODELS/image_classification/imagenet/model/mobilenet_v2_1.0_224_quant
$ synap_cli_ic -m model.synap ../../sample/goldfish_224x224.jpg
Loading network: model.synap
Input image: ../../sample/goldfish_224x224.jpg
Classification time: 3.00 ms
Class Confidence Description
1 18.99 goldfish, Carassius auratus
112 9.30 conch
927 8.70 trifle
29 8.21 axolotl, mud puppy, Ambystoma mexicanum
122 7.71 American lobster, Northern lobster, Maine lobster, Homarus americanus

synap_cli_od 应用程序

此命令行应用程序允许轻松执行目标检测模型。

输入:

  • 转换后的 synap 模型(.synap 扩展名)
  • 可选的目标检测置信度阈值
  • 一个或多个图像(jpeg 或 png 格式)

输出:

  • 每个输入图像检测到的目标列表,每个目标包含以下信息:
    • 边界框
    • 类别索引
    • 置信度
备注

jpeg/png 输入图像在软件中调整大小到网络输入张量的大小。

示例:

$ cd $MODELS/object_detection/people/model/mobilenet224_full1/
$ synap_cli_od -m model.synap ../../sample/sample001_640x480.jpg
Input image: ../../sample/sample001_640x480.jpg (w = 640, h = 480, c = 3)
Detection time: 26.94 ms
# Score Class Position Size Description
0 0.95 0 94,193 62,143 person
important

目标检测模型的输出没有标准化,存在多种不同的格式。输出格式必须在模型转换时指定,请参见模型转换教程。如果缺少此信息或格式未知,synap_cli_od 不知道如何解释结果,因此会失败并显示错误消息:"Failed to initialize detector"

synap_cli_ip 应用程序

此命令行应用程序允许执行图像处理模型。最常见的情况是执行超分辨率模型,它接收低分辨率图像作为输入并生成高分辨率图像作为输出。

输入:

  • 转换后的 synap 模型(.synap 扩展名)
  • 可选的图像感兴趣区域(如果模型支持)
  • 一个或多个原始图像,具有以下扩展名之一:nv12nv21rgbbgrbgragraybin

输出:

  • 每个输入文件的处理后图像文件。输出文件名为 outimage[i](i)_[W](W)x[H](H).[ext](ext),其中 [i](i) 是相应输入文件的索引,[W](W)[H](H) 是图像的尺寸,[ext](ext) 取决于输出图像的类型,例如 nv12rgb。默认情况下,输出文件在当前目录中创建,可以使用 --out-dir 选项更改。
备注

输入图像会自动调整大小到网络输入张量的大小。这不支持 nv12:如果网络接收 nv12 图像作为输入,提供的输入文件必须具有相同的格式,且图像的 WxH 尺寸必须与网络输入张量的尺寸相对应。

备注

任何 pngjpeg 图像都可以使用 SyNAP 工具包中的 image_to_raw 命令转换为 nv12 并缩放到所需大小(更多信息请参见安装 Docker)。同样,生成的原始 nv12rgb 图像可以使用 image_from_raw 命令转换为 pngjpeg 格式。

示例:

$ cd $MODELS/image_processing/super_resolution/model/sr_qdeo_y_uv_1920x1080_3840x2160
$ synap_cli_ip -m model.synap ../../sample/ref_1920x1080.nv12
Input buffer: input_0 size: 1036800
Input buffer: input_1 size: 2073600
Output buffer: output_13 size: 4147200
Output buffer: output_14 size: 8294400

Input image: ../../sample/ref_1920x1080.nv12
Inference time: 30.91 ms
Writing output to file: outimage0_3840x2160.nv12

synap_cli_ic2 应用程序

此应用程序按顺序执行两个模型,输入图像首先输入到第一个模型,然后将其输出输入到第二个模型,第二个模型用于执行分类,如 synap_cli_ic 中所示。它提供了一种简单的方法来实验两阶段推理,其中例如第一个模型是用于降尺度和/或格式转换的预处理模型(请参见模型转换),第二个是图像分类模型。

输入:

  • 转换后的 synap 预处理模型(.synap 扩展名)
  • 转换后的 synap 分类模型(.synap 扩展名)
  • 一个或多个图像(jpegpng 格式)

输出:

  • 每个输入图像的前 5 个最可能的类别
备注

第一个模型的输出张量形状必须与第二个模型的输入相匹配。

作为示例,我们可以使用预处理模型将 NV12 图像转换并缩放到 RGB,以便可以由标准的 mobilenet_v2_1.0_224_quant 模型处理:

$ pp=$MODELS/image_processing/preprocess/model/convert_nv12@1920x1080_rgb@224x224
$ cd $MODELS/image_classification/imagenet/model/mobilenet_v2_1.0_224_quant
$ synap_cli_ic2 -m $pp/model.synap -m2 model.synap ../../sample/goldfish_1920x1080.nv12

Inference time: 4.34 ms
Class Confidence Description
1 19.48 goldfish, Carassius auratus
122 10.68 American lobster, Northern lobster, Maine lobster, Homarus americanus
927 9.69 trifle
124 9.69 crayfish, crawfish, crawdad, crawdaddy
314 9.10 cockroach, roach

分类输出与我们在 synap_cli_ic 中得到的结果非常接近,细微的差异是由于从 NV12 缩放的图像差异造成的。整体推理时间较长是由于需要对输入的 1920x1080 图像进行缩放和转换处理。

synap_cli 应用程序

此命令行应用程序可用于运行所有类别的模型。synap_cli 的目的不是显示推理结果,而是对网络执行时间进行基准测试。因此,它提供了额外的选项,允许多次运行推理以收集统计信息。

一个额外的功能是 synap_cli 可以自动生成具有随机内容的输入图像。这使得即使没有合适的输入文件,也可以轻松测试任何模型。

示例:

$ cd $MODELS/image_classification/imagenet/model/mobilenet_v2_1.0_224_quant
$ synap_cli -m model.synap -r 50 random
Flush/invalidate: yes
Loop period (ms): 0
Network inputs: 1
Network outputs: 1
Input buffer: input_0 size: 150528 : random
Output buffer: output_66 size: 1001

Predict #0: 2.68 ms
Predict #1: 1.81 ms
Predict #2: 1.79 ms
Predict #3: 1.79 ms
.....
Inference timings (ms): load: 55.91 init: 3.84 min: 1.78 median: 1.82 max: 2.68 stddev: 0.13 mean: 1.85
备注

指定 random 输入是执行需要安全输入的模型的唯一方法。

synap_init 应用程序

此应用程序的目的不是执行模型,而只是初始化和锁定 NPU。它可用于模拟一个进程锁定 NPU 以供其独占使用。

锁定 NPU 访问的示例:

$ synap_init -i --lock

当程序退出或终止时,锁定被释放。

备注

这阻止了任何进程通过 NNAPI 和直接 SyNAP API 访问 NPU。请参阅下一节以仅禁用 NNAPI 的 NPU 访问。

备注

当 NPU 被锁定时,仍然可以从另一个进程创建网络,但任何尝试进行推理的操作都会失败。发生这种情况时,适当的错误消息会添加到系统日志中:

$ synap_cli_ic
Loading network: /vendor/firmware/models/image_classification/imagenet/model/mobilenet_v2_1.0_224_quant/model.synap
Inference failed
$ dmesg | grep NPU
[ 1211.651] SyNAP: cannot execute model because the NPU is reserved by another user

故障排除

SyNAP 库和命令行应用程序生成日志消息以帮助在出现问题时进行故障排除。在 Android 上,这些消息出现在 logcat 中,而在 Linux 上,它们直接发送到控制台。

有 4 个日志级别:

  • 0: verbose
  • 1: info
  • 2: warning
  • 3: error

The default level is 3, so that only error logs are generated. It is possible to select a different level by setting the SYNAP_NB_LOG_LEVEL environment variable before starting the application, for example to enable logs up to info:

export SYNAP_NB_LOG_LEVEL=1
logcat -c; synap_cli_ic; logcat -d | grep SyNAP
Input image: /vendor/firmware/models/image_classification/imagenet/sample/space_shuttle_224x224.jpg
Classification time: 3.16 ms
Class Confidence Description
812 19.48 space shuttle
...
1-08 15:10:57.185 830 830 I SyNAP : get_network_attrs():70: Parsing network metadata
1-08 15:10:57.185 830 830 I SyNAP : load_model():252: Network inputs: 1
1-08 15:10:57.185 830 830 I SyNAP : load_model():253: Network outputs: 1
1-08 15:10:57.191 830 830 I SyNAP : resume_cpu_access():65: Resuming cpu access on dmabuf: 5
1-08 15:10:57.193 830 830 I SyNAP : set_buffer():208: Buffer set for tensor: input_0
1-08 15:10:57.193 830 830 I SyNAP : resume_cpu_access():65: Resuming cpu access on dmabuf: 6
1-08 15:10:57.193 830 830 I SyNAP : set_buffer():208: Buffer set for tensor: output_66
1-08 15:10:57.193 830 830 I SyNAP : do_predict():83: Start inference
1-08 15:10:57.193 830 830 I SyNAP : suspend_cpu_access():54: Suspending cpu access on dmabuf: 5
1-08 15:10:57.195 830 830 I SyNAP : do_predict():95: Inference time: 2.33 ms
1-08 15:10:57.195 830 830 I SyNAP : resume_cpu_access():65: Resuming cpu access on dmabuf: 6
1-08 15:10:57.196 830 830 I SyNAP : unregister_buffer():144: Detaching buffer from input tensor input_0
1-08 15:10:57.196 830 830 I SyNAP : set_buffer():177: Unset buffer for: input_0
1-08 15:10:57.196 830 830 I SyNAP : unregister_buffer():150: Detaching buffer from output tensor output_66
1-08 15:10:57.196 830 830 I SyNAP : set_buffer():177: Unset buffer for: output_66