Page 383 - 《软件学报》2025年第10期
P. 383
4780 软件学报 2025 年第 36 卷第 10 期
附录 B); 这可以视作一次脉冲传播计算, 也是 BIVM 要优化适配的主体.
ReRAM 交叉开关结构具有低功耗、高密度、计算速度快等特点, 避免了传统神经网络加速器在突触发放计
算时的权重数据移动所带来的内存墙问题.
● ReRAM 方言
针对 ReRAM 后端设计的第 3 层 IR, 我们提出了 ReRAM 方言, 以描述 ReRAM 交叉开关阵列加速脉冲传播
操作的过程. 第 2 层 IR 中脉冲传播操作使用粗粒度描述表示, 递降到第 3 层 IR 后会转变为如下 ReRAM 方言以
符合交叉开关阵列的计算方式: rram.Crossbar 类型代表初始化完成的 ReRAM 交叉开关阵列, 在 IR 中这个类型的
实例通过 rram.init_crossbar(weights) 操作基于给定的权值生成, 对应硬件的初始化; 之后, 可以使用 rram.run_
crossbar 操作使用交叉开关阵列实例进行矩阵-向量乘法计算 (图 3(d2)). ReRAM 方言的形式化描述请见附录 A 中
的表 A2.
● 基于权重微调的精度优化
由于 ReRAM 本身的物理局限, 进行计算时从权值矩阵获取的实际权重数值是围绕特定值 (初始化值) 的一个
分布. 因此在基于精确的突触权重 (如经过软件训练得到的网络模型权重) 进行 ReRAM crossbar 初始化之前, 需要
进行网络权重微调 (fine-tuning), 以保证在使用较低精度的计算时也能保持其所执行的应用任务结果的高精度 (如
后续测试中的 MNIS 神经网络分类任务). BIVM 框架集成了这一功能——当基于 BIVM 的编译器为 ReRAM 类
脑芯片进行编译时, 如果使用者输入了目标 ReRAM 的权重分布情况, 就可自动进行权重微调优化过程, 在精度受
限的情况下提升计算结果的准确度. 需指出的是, 这类微调方法适用于面向 AI 任务的深度脉冲神经网络 (即 D-SNN):
这类任务有明确的数据集, 可以利用神经网络强大的泛化能力, 基于已有网络拓扑与初始参数进行受限条件下的
权重调整 [15] ; 而对于侧重生物脉冲神经网络模拟的仿真计算应用是否适用, 还需要进一步研究.
● 硬件执行
需要指出的是, 从 ReRAM 方言进一步递降为可以在目标硬件上运行的程序可以采用两种方式, 一是直接调
用目标硬件的运行时库, 本工作示例就是采用这一形式: ReRAM 方言中在运行时通过链接外部函数来完成与硬
件相关的操作, 这类形式在 DNN 编译框架 (如 TVM [42] ) 中也广泛使用, 比如直接链接英伟达 GPGPU 的深度学习
库而不是直接生成底层 CUDA 代码. 外部函数@initRRAMCrossbar 和@runRRAMCrossbar 分别对应方言中初始
化和使用 ReRAM 交叉开关阵列进行计算的过程. 目前我们使用了 ReRAM 模拟器来模拟交叉开关阵列的运行.
对于其他的 ReRAM 的硬件实现, 动态链接库的设计保证了 ReRAM 后端的灵活性, 实现时只需要改写外部函数,
而不用更改 IR 以及编译器的具体实现; 这一方式也可使得交叉开关阵列的某些物理约束 (如尺寸等) 对编译框架
透明. 图 3(d2) 展示了 Brunel 神经网络递降后的 IR.
另一种则是调用目标硬件的底层原生编译器方式, 如 OCC [30] 就是一个基于 MLIR 的存算一体编译器, 支持基
于交叉开关阵列的矩阵乘法算子的优化调度; 与此类工作的融合将作为下一步工作之一.
3.4.3 GaBAN 后端
GaBAN 是一个针对类脑计算应用所设计的基于 FPGA 的向量处理器, 包含一个 RISC-V 控制核心和数个计
算内核, 计算核心中采用自定义指令集以及基于 Buffets [43] 的异步访存机制.
● GaBAN 方言
GaBAN 后端第 3 层 IR 由第 2 层 IR 的细粒度描述递降得到. 一方面, 需要将神经网络模拟过程中的具体计算
操作转变为计算核心上执行的 GaBAN 指令序列, 另一方面, 需要生成控制核心上的硬件配置、驱动过程. 其中,
由于 GaBAN 指令集采用硬件驱动的隐式循环, 因此为计算核心生成的代码对应一次循环内的计算逻辑. 本研究
针对 GaBAN 后端第 3 层 IR 提出了专属的 GaBAN 方言, 包含一种数据类型与两种类型操作: gaban.tensor 对应
了 GaBAN 后端中声明的向量数据类型, 它是存储与计算的基本单元; 其中一类操作是向量运算操作, 对应了
GaBAN 中的向量指令, 例如浮点加法操作 gaban.addf 以及减法操作 gaban.subf; 另一类则是控制计算核心相关的
功能性操作, 例如写入代码段基地址和循环上下界等配置参数的 gaban.configure 操作以及与计算核心同步的
gaban.wait 操作. GaBAN 方言的形式化描述请见附录 A 中的表 A3.

