# Efficient Hardware Acceleration of Sparsely Active Convolutional Spiking Neural Networks

# 摘要

翻译自 ChatGPT:

脉冲神经网络(SNNs)以事件驱动方式进行计算,以实现比标准神经网络更高效的计算。在 SNNs 中,神经元的输出不是编码为实值激活,而是编码为二进制脉冲序列。使用 SNNs 而不是传统神经网络的动机根植于脉冲处理的特殊计算方面,尤其是高度稀疏的脉冲。已经建立良好的卷积神经网络(CNNs)实现具有大型的处理元素(PEs)空间阵列,但在面对激活稀疏性时,它们的利用率仍然很低。我们提出了一种针对高度稀疏的卷积脉冲神经网络(CSNNs)进行优化的新型架构。所提出的架构包括一个与卷积内核大小相同的 PE 阵列以及一个智能脉冲队列,提供了高 PE 利用率。通过将特征图压缩成可以逐个脉冲处理的队列,确保了脉冲的持续流动。这种压缩是在运行时执行的,导致了一种自时序调度。这使得处理时间可以随着脉冲数量的增加而扩展。此外,引入了一种新颖的内存组织方案,用于使用多个小型并行的片上 RAM 高效存储和检索各个神经元的膜电位。每个 RAM 都与其 PE 硬连线,减少了开关电路。我们在 FPGA 上实现了所提出的架构,并与以前提出的 SNN 实现相比实现了显著的加速(约 10 倍),同时需要更少的硬件资源并保持更高的能源效率(约 15 倍)。

# 相关工作

  1. 使用 m-TTFS coding,比 rate coding 时间步更短,相较于 TTFS 的只发射一次脉冲变成持续发送脉冲,虽然脉冲稀疏性降低了,但是不需要再积累膜电势了,仍然比 rate coding 更加高效。但是后面在讲 Thresholding Unit 的时候,又提到说 m-TTFS coding 只发射一次脉冲,前后矛盾!!暂且认为是笔误了,Threshoding Unit 对于膜电势做两个判断,一是是否超过阈值,二是特定的 bit 有没有 set,set 说明发射过脉冲,而在最后一个时间步时会 reset.

# 硬件架构

  1. 卷积和全连接分成了两个部分硬件实现,不够优雅(你猜为什么测试用例在做 FC 之前卷积核个数锐减到 10 个?),系统框图如图:
  2. 输出通道作为循环最外层,先对某一通道做所有时间步的推理,然后将这些通道的 Spike 存入 AER 的表中。一层一层做,没有层间流水化:

# 硬件实现

  1. 所谓的 Memory Interlacing,就是只做 3×3 卷积(这篇文章对于 3×3 卷积做了很多特定的设计,非常之不通用,详见后文),且这 9 个格的 Spike 可以并行写入到 9 个 RAM 里作为 AER 表格(深度未知,需要 fmapSize / 9 × ChannelOut?) 。他的分块方式是这样的:对特征图 FMap 直接做 3×3 的分块,然后将分块内的 9 个元素编号后分别存在各自的 RAM 中,膜电势和权重也是分成 9 个部分,AER 表格存储方式如图:

  2. 卷积单元流程可以分为:计算地址 S1 → 读膜电势 S2 → 更新电势 S3 → 写膜电势 S4

    • 计算 Spike 所产生的 Active 邻域地址的时候,作者对于 9 个输出地址与输入地址都做了相应的映射(对于 3×3 卷积设计非常的特质化!!或许有些情况可以合并,懒得深究了),如图为输入地址为 (0, 0)[5](sin=5s_{in}=5)到邻域 sin=1s_{in}=1 的映射公式与示例:

      除此之外,由于这 9 个卷积核到 9 个 PE 的映射取决于输入脉冲地址(比如从蓝框到紫框,最左上角从序号 1 变成了序号 6,但权重位置其实没有变),所以它还需要 9 个 9 选 1 的 Mux 来做膜电势更新。

    • 更新电势的过程中考虑了上溢下溢的情况做了饱和操作,饱和操作对于 m-TTFS 而言影响不大,通过 check 符号位的变化可以实现上下溢的判断,好评。

    • 卷积会遇到 S2 - S4,S3 - S4 的 Data Hazard,为了避免这样的数据冒险,作者对 S2 - S4 的数据冒险(S4 写的膜电势地址与 S2 读的膜电势地址一致)做了 Bypass(意味着 9 个 2 选 1 的 Mux),因为 S4 计算完的膜电势刚好可以对 S2 用,而对于 S3 - S4 的数据冒险则是采用了对 S2,S1 做了阻塞,从而使得转换成 S2 - S4 的数据冒险类型,但这样其实是会空一拍。不过作者也说明了由于他是 0 - 9 的顺序去做的,所以其实也很难有同样地址的 S3 - S4 数据冒险。

  3. 只支持 3×3 的 MaxPooling,垃圾。

# 实验与总结

  1. 给出了不同并行度时的吞吐速率和功耗,进一步计算能效比,这样可以选择出合适的并行度,不错的思路。

  2. 8 bits 量化大概用了 60 个 36K BRAM,16 bits 量化大概用了 111 个 36K BRAM(网络本身很小,28×28-32C3-32C3-P3-10C3-F10,对于 8 bits 量化而言按道理权重需要 10 个 18K 而已,膜电势就算所有都全存储起来也只需要 50 个 18K,你在这用了 60 个 36 K 在干啥啊??),时钟频率跑到 333 MHz,但用的是 UltraScale+ ZU7EV,这个器件比 ZU5EV 大了一倍多,只能说还可以吧。

  3. 作者统计了下自己 PE 阵列的使用率,第二、三层都只有 50+ 的使用率,这依然不妨碍作者夸自己的 PE 使用率高。

  4. 性能对比:

# 结论

  1. 结论部分说自己的 neuron multiplexing 是为了降低膜电势的存储占用问题的???

  2. 通信作者是 IEEE Fellow,以及

    dddd,哈哈。