RK3588 - RKNN(Rockchip 神经处理单元)的逆向工程

本文翻译自https://jas-hacks.blogspot.com/2024/02/rk3588-reverse-engineering-rknn.html
RK3588 NPU 的内部操作和功能主要隐藏在名为RKNPU2的闭源 SDK 中。由于对大型语言模型 (LLM) 的兴趣以及对transform模型最佳矩阵乘法的追求,想了解 RKNPU SDK 新引入的矩阵乘法 API (rknn_matmul_run) 的实现。对技术参考手册(TRM)中 RKNN NPU部分的查看,揭示了该NPU没有做矩阵乘法的原生机制(内部是通过倒一手的方法),尤其是对于向量。

为了了解发生了什么,第一步是了解 NPU 的工作原理。 TRM 提供了详细的寄存器列表以及构成 NPU 的核心单元的简要概述。它特别缺乏有关对寄存器进行编程以执行操作的基本信息。例如没有关于根据数据格式(如int8 与 float16)或输入数据或权重的大小等因素导出或计算寄存器值的具体细节。此外,没有关于如何构建 NPU 执行管道的信息,不过我从之前对V831 NPU 的逆向工程尝试中获得了一些优势。但是即使掌握了这些知识,它仍然需要几个月的反复对数据流的广泛分析、遇到一些死胡同以及无数次逆向工程尝试,最后才整明白了如何激活 NPU 并让它执行简单的操作。

RK3588 NPU 似乎是NVDLA架构的远亲,因为一些术语相似,核心单元与 NVDLA 具有相似的功能和管线,尽管它们的命名不同。其中主要区别之一是我们可以给 NPU一个要执行的任务列表(RKNN 术语),然后等待完成。例如,如果我有一个由3层的神经网络,每层由conv + bias组成,那么可以将 3 个任务(每个任务执行conv + bias)以及必要的输入、权重和偏置值提供给 NPU,随后我们只需等待 NPU 通知完成即可。
在这里插入图片描述
上面显示的图像是从 TRM 中提取的,并稍微修改了,因为 TRM 中提供的描述与它们的图表并不完全一致,更重要的是寄存器命名约定也不完全一致。这是我的解释,每个 NPU 由三个不同的单元组成:

  • CNA - 卷积网络加速器(包括 CORE 矩形),在TRM中它指的是神经网络加速引擎。
  • DPU-数据处理单元
  • PPU - 平面处理单元

基于上述,NPU 主要是为运行传统的卷积神经网络(CNN)而设计的。这是因为 CNA 核心功能是通过输入图像或特征数据以及相应的权重来执行卷积。官方提供的大多数 RKNPU2 demo(例如 YOLOX、Mobilenet 和 ResNet)都证明了对 CNN 的重视。 CNA 输出可以定向到 DPU,在 DPU 中可以执行加法、乘法和 RELU 等逐元素运算。随后,DPU 的输出可以传送到 PPU,在 PPU 中执行最小、最大和平均池化等操作。此外还可以选择直接将数据传输到 DPU 或 PPU,而无需卷积步骤。

为了有效地执行卷积,CNA 采用乘法累加 (MAC) 运算。 CNA 的性能部分取决于所使用的 MAC 单元的数量。根据 TRM,对于单个 NPU 核心,MAC 操作的计数取决于输入数据类型:

  • 每个周期 1024 个 int8 MAC 操作
  • 每个周期 512 个 float16 MAC 操作

每个 MAC 单元缓存 1x1x16 weight bytes,对于 int 8,它有 16 个值可用,而对于 fp16,它减少到 8 个。我们需要 2 个 MAC 单元来执行 fp16,因此每个周期的操作量减少。内部特征和权重数据必须符合 rk的NC1HWC2 格式,其中 C2 是weight bytes。然后,所有 MAC 单元共享一个 1x1x16 cube的特征数据,方便将其发送到累加器以计算部分和。在更高级别用法中,CNA 似乎执行块操作(block operation),如我在测试中观察到的,MAC 缓存32 channels的fp16 weight data。因此需要在每个kernel groups中layout 32 个channels的权重(不太准确,请看原文)。

性能还受到输入和权重数据的访问时间的影响,CNA 包含称为卷积缓冲区 (cbuf) 的二级缓存。在上图中,384KB 板载内存部分用于此目的。重要的是,MAC 单元的数量加上 CBUF 会影响一个task中可以完成的卷积size。

有些人可能已经推断出矩阵乘法 API 本质上是通过 2D 卷积执行的。例如,我们将矩阵 A 视为 [M x K],将矩阵 B 视为 [K x N]。矩阵A表示以Mx1xK(hwc)格式排列的特征数据,而矩阵B表示以1x1xNxK(hwck)格式排列的权重数据。因此,所得矩阵 C [M x N] 排列为 Mx1xN。我正在运行一个简单的demo,要求 NPU 执行矩阵乘法。我使用从 GGML 测试用例 ( test-mul-mat.cpp ) 派生的矩阵数据来验证输出是否正确。要运行测试,请查看我的github,遗憾的是我仍在 Rock-5b 上针对内核 5.10 进行测试。如果测试运行输出应如下所示和上面的屏幕截图。

rock@rock-5b:~/rk3588-npu/build$ ./matmul_4_36_16
drm name is rknpu - 20220829 - RKNPU driver
input dma is ffff8000, output dma is ffffa000, weights dma is ffff9000
Size of npu_regs 112
RKNPU_SUBMIT returned 0
=========================================================================================================1224.0 1023.0 1158.0 1259.0 1359.0 1194.0 1535.0 1247.0 1185.0 1029.0  889.0 1182.0  955.0 1179.0 1147.01216.0 1087.0 1239.0 1361.0 1392.0 1260.0 1247.0 1563.0 1167.0 1052.0  942.0 1214.0 1045.0 1134.0 1264.01125.0  966.0 1079.0 1333.0 1287.0 1101.0 1185.0 1167.0 1368.0  990.0  967.0 1121.0  971.0 1086.0 1130.0999.0  902.0 1020.0 1056.0 1076.0  929.0 1029.0 1052.0  990.0 1108.0  823.0  989.0  759.0 1041.0 1003.0
=========================================================================================================

关于逆向工程已经达到了一个阶段,了解在处理特征数据作为输入时影响卷积的大多数寄存器设置。主要的不确定性在于确定特征/权重数据的库大小,但是我希望可以推断出这一点。在投入大量时间分析 NPU 后,我们应该知道以下关键点:

  1. NPU 内的所有数据指针(例如输入、权重、输出、任务列表)均为 32 位,并且必须引用物理内存。因此,这将内存范围限制为 4GB,使得利用具有 16/32GB 内存的主板供 NPU 使用是不可能的。此外,它还可能对 NPU 上执行的模型类型施加限制。

  2. 6 TOPS 的说法有待验证。虽然每个 NPU 核心的额定速度为 2 TOPS,但有些寄存器可能可以在 3 个NPU核心之间启用卷积。但是在分析SDK生成的数据流后,似乎没有使用过该功能。此外,DPU/PPU 单元似乎没有类似的功能,这会限制其可用性。在我看来,最有效的方法是将它们视为单独的核心并在每个核心上执行模型,但是要考虑到前面提到的内存限制。

  3. SDK提供矩阵乘法API在某些方面代表了NPU的低效利用,因为他存在内存分配、内核调用以及指示 NPU 执行单个卷积的开销。理想情况下,NPU 的任务应该是执行多个操作并为这些操作提供所有提供的数据。一般来说这就是运行 CNN 模型(即 YOLOvX)时使用 NPU 的方式。这里需要注意的是,转换后的模型仅限于包含 NPU 支持操作的层。

  4. 两个 fp16 [512 x 512] 矩阵相乘的初始基准测试表明我可以在 1 毫秒左右的时间内完成。但是由于CBUF限制,这将变成2个task发送给NPU。不幸的是,当使用矢量数据作为输入时,这只是流程的一部分,耗时操作是将矩阵转换为特征和权重数据格式,如果在运行时完成,则输出反之亦然。我努力创建一个高度优化的转换例程,用于矢量到特征数据的转换。根据我的基准测试,对于 fp16 [512 x 512] 矩阵,此过程大约需要 2 毫秒。我估计需要 12-15 毫秒来执行上述矩阵的所有转换。理想情况下,应提前转换权重数据的矩阵以减少转换开销,并且如果可能的话,应保留以供重用。

  5. 我希望能够使用可编程内核来执行自定义操作。不幸的是,情况并非如此,您只能使用 OpenCL 作为替代方案。如果您需要在 OpenCL 和 NPU 之间调整数据,这就会带来挑战。

关于其他单元(DPU/NPU)还有更多需要发现,我将花时间来做这件事。最后,TRM v1.0 包含 RKNN 的许多差距和不一致,如果有人有更新的版本,我们将不胜感激。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/830095.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动开箱机:提升包装物流效率的关键设备

随着电子商务的飞速发展,物流行业面临着重要的挑战和机遇。如何在保证服务质量的同时,提高物流效率,降低成本,成为摆在物流企业面前的重要课题。在这个背景下,自动开箱机以其高效、精准、省力的特点,正逐渐…

OpenMM——教程学习(1)

如何从零开始做一个蛋白小分子动力学模拟 AmberTools将被用来生成输入文件,OpenMM 将被用来运行模拟,模拟平台为在线百度AI Stuio, 并使用GPU加速。 First thing’s first, 到PDB 蛋白数据库下载一需要模拟的靶点晶体,备用。 1. H web server…

一文讲清:什么是供应商管理?供应商管理怎么做?

供应商管理指的是对供应商的了解、选择、开发、使用和控制等综合性管理工作的总称。其目的在于建立起一个稳定可靠的供应商队伍,为企业生产提供可靠的物资供应。但是企业在进行供应商管理往往面临以下问题: 1、招投标,信息不透明 这主要表…

R语言的基本图形

一&#xff0c;条形图 安装包 install.packages("vcd") 绘制简单的条形图 barplot(c(1,2,4,5,6,3)) 水平条形图 barplot(c(1,2,4,5,6,3),horiz TRUE) 堆砌条形图 > d1<-c("Placebo","Treated") > d2<-c("None",&qu…

你不需要总是在 React 中使用 useState

在我审查的一个拉取请求中&#xff0c;我注意到在许多拉取请求中看到的一种模式。React 组件具有多个 UI 状态&#xff0c;例如 loading、error 和 success。 作者使用了多个 useState 钩子来管理这些状态&#xff0c;这导致代码难以阅读且容易出错&#xff0c;例如&#xff1a…

hadoop命令

hadoop命令 目录 hadoop命令 1.查看文件下面有哪些文件和目录 2.获取文件信息 查看文件内容 3.创建一个文件夹 4.剪切 1&#xff09;从本地hadoop剪切到hdfs并上传到hdfs 2&#xff09;剪切 从hdfs剪切到本地hadoop目录上 5.删除 1&#xff09;递归删除 2&#xff0…

springboot权限验证学习-下

上篇讲了rbac对于菜单的权限&#xff0c;下面准备完成按钮权限以及行数据和列数据权限 权限控制(按钮权限) 权限控制 操作权限就是将操作视为资源&#xff0c;比如删除操作&#xff0c;有些人可以有些人不行。于后端来说&#xff0c;操作就是一个接口。于前端来说&#xff0…

秋招后端开发面试题 - JVM底层原理

目录 JVM底层原理前言面试题Java 对象的创建过程&#xff1f;什么是指针碰撞&#xff1f;什么是空闲列表&#xff1f;/ 内存分配的两种方式&#xff1f;JVM 里 new 对象时&#xff0c;堆会发生抢占吗&#xff1f;JVM 是怎么设计来保证线程安全的&#xff1f;/ 内存分配并发问题…

k8s pod使用sriov

之前的文章中讲了k8s multus的使用&#xff0c;本章节来讲述下如何使用multus来实现sriov的使用。 一、sriov 简介 SR-IOV在2010年左右由Intel提出&#xff0c;但是随着容器技术的推广&#xff0c;intel官方也给出了SR-IOV技术在容器中使用的开源组件&#xff0c;例如&#…

3MF体积设计扩展

3MF 联盟最近宣布了他们最新的体积设计扩展&#xff08;volumetric design extension&#xff09;&#xff0c;用于通过基于体积的描述来编码几何形状和空间多样性属性。 该组织致力于推进 3D 打印的通用规范&#xff0c;目前正在新扩展达到 1.0 之前征求公众反馈。 NSDT工具推…

OpenCV 实现重新映射

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV 实现霍夫圆变换 下一篇 :OpenCV实现仿射变换 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 一个。使用 OpenCV 函数 cv&#xff1a;&#xff1a;remap 实现简单的重新…

20240428如何利用IDM下载磁链视频

缘起&#xff1a; https://weibo.com/tv/show/1034:4864336909500449 中国获奖独立纪录片《阿辉》揭秘红灯区“教父”的生存法则 5,751次观看 1年前 发布于 陕西 身为里中横 67.7万粉丝 互联网科技博主 微博原创视频博主 头条文章作者 https://weibo.com/tv/show/1034:4864…

数据通信-A

数据通信 一、数据通信网络基础二、VRP系统三、eNSP配置命令 不是从零开始&#xff0c;有一些基础&#xff0c;主要记录配置命令。一、数据通信网络基础 图标&#xff1a;主要是认识第一行。 常见术语&#xff1a;数据通信网络最基本的功能是实现数据互通。 数据载荷&#…

解决IDEA下springboot项目打包没有主清单属性

1.问题出现在SpringBoot学习中 , 运行maven打包后无法运行 报错为spring_boot01_Demo-0.0.1-SNAPSHOT.jar中没有主清单属性 SpringBoot版本为 2.6.13 Java 版本用的8 解决方法 1.执行clean 删除之前的打包 2.进行打包规范设置 2.1 3.进行问题解决 (借鉴了阿里开发社区) 使用…

[嵌入式系统-53]:嵌入式系统集成开发环境大全

目录 一、嵌入式系统集成开发环境分类 二、由MCU芯片厂家提供的集成开发工具 三、由嵌入式操作提供的集成开发工具 四、由第三方工具厂家提供的集成开发工具 一、嵌入式系统集成开发环境分类 嵌入式系统集成开发工具和集成开发环境可以按照不同的分类方式进行划分&#xff…

【LAMMPS学习】八、基础知识(5.2)粒度模型

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

将针孔模型相机 应用到3DGS

Motivation 3DGS 的 投影采用的是 CG系的投影矩阵 P P P, 默认相机的 principal point (相机光心) 位于图像的中点处。但是 实际应用的 绝大多数的 相机 并不满足这样一个设定&#xff0c; 因此我们 需要根据 f , c x , c y {f,c_x, c_y} f,cx​,cy​ 这几个参数重新构建3D …

centos 7 yum install -y nagios

centos 7 systemctl disable firewalld --now vi /etc/selinux/config SELINUXdisabled yum install -y epel-release httpd nagios yum install -y httpd nagios systemctl enable httpd --now systemctl enable nagios --now 浏览器 IP/nagios 用户名&#xff1a;…

vue学习的预备知识为学好vue打好基础

目录 Vue是什么 &#xff1f;如何使用Vue &#xff1f;Vue ApiVue入口apiVue实例apiVue函数api 无构建过程的渐进式增强静态HTMLVue模块化构建工具npmyarnWebpackvue-cliVite Vue是什么 &#xff1f; 文章基于Vue3叙述。 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于…

十大USDT交易平台大全XEX交易所

USDT是一种基于比特币区块链网络的加密代币&#xff0c;主要运用于数字货币交易平台&#xff0c;以稳定币为主。USDT的核心价值在于其与真实货币的固定兑换比率1:1&#xff0c;所以被称为Tether。随着加密货币市场的不断壮大&#xff0c;越来越多的交易平台开始支持USDT&#x…