跳到主要内容

NPU 系统介绍

V853 芯片内置一颗 NPU,其处理性能为最大 1 TOPS 并有 128KB 内部高速缓存用于高速数据交换,支持 VIPLite 调用接口,并支持导入大量常用的深度学习模型进行运算,同时支持常用的深度学习框架导入,例如 TensorFlow,Caffe,TFLite,Keras,Pytorch,Onnx等

NPU 系统架构​

NPU 的系统架构如下图所示:

image-20220712100607889

上层的应用程序可以通过加载模型与数据到 NPU 进行计算,也可以使用 NPU 提供的软件 API 操作 NPU 执行计算。

NPU包括三个部分:可编程引擎(Programmable Engines,PPU)、神经网络引擎(Neural Network Engine,NN)和各级缓存。

可编程引擎可以使用 EVIS 硬件加速指令与 Shader 语言进行编程,也可以实现激活函数等操作。

神经网络引擎包含 NN 核心与 Tensor Process Fabric(TPF,图中简写为 Fabric) 两个部分。NN核心一般计算卷积操作, Tensor Process Fabric 则是作为 NN 核心中的高速数据交换的通路。算子是由可编程引擎与神经网络引擎共同实现的。

NPU 支持 UINT8,INT8,INT16 三种数据格式。

NPU 模型转换​

NPU 使用的模型是 NPU 自定义的一类模型结构,不能直接将网络训练出的模型直接导入 NPU 进行计算。这就需要将网络训练出的转换模型到 NPU 的模型上。

NPU 的模型转换步骤如下图所示:

image-20220712113105463

NPU 模型转换包括准备阶段、量化阶段与验证阶段。

准备阶段​

首先我们把准备好模型使用工具导入,并创建配置文件。

这时候工具会把模型导入并转换为 NPU 所使用的网络模型、权重模型与配置文件。

配置文件用于对网络的输入和输出的参数进行描述以及配置。这些参数包括输入/输出 tensor 的形状、归一化系数 (均值/零点)、图像格式、tensor 的输出格式、后处理方式等等。

量化阶段​

由于训练好的神经网络对数据精度以及噪声的不敏感,因此可以通过量化将参数从浮点数转换为定点数。这样做有两个优点:

(1)减少了数据量,进而可以使用容量更小的存储设备,节省了成本;

(2)由于数据量减少,浮点转化为定点数也大大降低了系统的计算量,也提高了计算的速度。

但是量化也有一个致命缺陷——会导致精度的丢失。

由于浮点数转换为定点数时会大大降低数据量,导致实际的权重参数准确度降低。在简单的网络里这不是什么大问题,但是如果是复杂的多层多模型的网络,每一层微小的误差都会导致最终数据的错误。

那么,可以不量化直接使用原来的数据吗?当然是可以的。

但是由于使用的是浮点数,无法将数据导入到只支持定点运算的 NN 核心进行计算,这就需要可编程引擎来代替 NN 核进行计算,这样可以大大降低运算效率。

另外,在进行量化过程时,不仅对参数进行了量化,也会对输入输出的数据进行量化。如果模型没有输入数据,就不知道输入输出的数据范围。这时候我们就需要准备一些具有代表性的输入来参与量化。这些输入数据一般从训练模型的数据集里获得,例如图片数据集里的图片。

另外选择的数据集不一定要把所有训练数据全部加入量化,通常我们选择几百张能够代表所有场景的输入数据就即可。理论上说,量化数据放入得越多,量化后精度可能更好,但是到达一定阈值后效果增长将会非常缓慢甚至不再增长。

这里是一个因为错误的量化导致精度丢失并识别失败的案例:

yolo_v3_abnormal

而正常情况应该是这样的:

yolo_v3_output

验证阶段​

由于上一阶段对模型进行了量化导致了精度的丢失,就需要对每个阶段的模型进行验证,对比结果是否一致。

首先我们需要使用非量化情况下的模型运行生成每一层的 tensor 作为 Golden tensor。输入的数据可以是数据集中的任意一个数据。然后量化后使用预推理相同的数据再次输出一次 tensor,对比这一次输出的每一层的 tensor 与 Golden tensor 的差别。

如果差别较大可以尝试更换量化模型和量化方式。差别不大即可使用 IDE 进行仿真。也可以直接部署到 V853 上进行测试。

此时测试同样会输出 tensor 数据,对比这一次输出的每一层的 tensor 与 Golden tensor 的差别,差别不大即可集成到 APP 中了。

模型转换实操​

详见:NPU 转换 YOLO V3 模型

NPU 模型的部署​

NPU 系统的模型部署流程一般包括以下四个部分:

image-20220712110126757

数据预处理​

数据预处理即将数据处理到适合模型使用的过程。

这里就以一个图像主体识别案例来举例:摄像头捕获到了图像数据,其数据格式是YUV的,而我们的模型使用的输入数据是RGB的数据,所以需要使用前处理将 YUV 数据转换到 RGB。

模型部署实操​

接下来是将模型加载到 NPU 内,初始化 NPU 的环境与分配内存,然后将之前预处理的数据交给 NPU 进行计算。计算后 NPU 会输出一个 tensor 数据,这时候就需要数据后处理,将 tensor 数据转换为具体的坐标与类型,就可以反馈到上层应用程序做应用的处理了。

部署实操详见:NPU 模型的部署

FAQ​

(1)NPU 支持调用算子级别的运算吗?支持哪些算子?

NPU 默认使用的是网络级别的调用,但是 NPU 同时也支持算子级别的调用。不过由于直接调用算子导致数据需要到内存里交换,不能通过 NPU 内置的SRAM交换,大大降低了效率,不推荐这样的做法。

NPU 使用的是双算子结构,其中的神经网络引擎使用的是硬算子,其性能很高,速度很快;而可编程引擎属于软算子,可以覆盖硬件算子没有支持的一些算子结构。硬算子覆盖了大部分的卷积操作。而软算子可以通过编程实现算子。具体的算子支持表格可以到文档《Operation Mapping and Support》查询。

(2)NPU 是否支持 FP16,FP32?

不支持。

(3)NPU 支持多模型运行吗?

支持多模型运行

(4)是否可以使用自己的量化函数量化?

可以的,只需要输出的量化表符合格式即可。

(5)NPU 支持的模型

V853 支持的常用深度学习框架模型有:

  • TensorFlow
  • Caffe
  • TFLite
  • Keras
  • Pytorch
  • Onnx NN
  • Darknet
  • and so on...