本帖最后由 abner_ma 于 2020-11-28 19:55 编辑

   最近做了CNN的卷积层和LS-SVM在ZYNQ7020上的实现。除了输入是由ARM通过AXI总线传输,算法的主要部分都是由PL部分(FPGA)实现的。当然这只是入门的尝试,对于一个深度学习算法,如何在硬件上实现效率最高,还需要进一步的验证(在SOC架构中对算法进行划分还是直接采用高端FPGA实现)。

       最开始做的是卷积层的实现,通过学习的例程,使我对整个开发流程有了初步的认识。随着自己在自己板子上的实现,对于其中存在的很多没有明说的关键细节,有了更多的积累。最后,开发的流程和思想由这些细节串联成一个整体。而后来的LS-SVM的实现,让我对论文中的算法复现体验了一番。接下来,我将以上述两个算法为例,总结一下深度学习算法在FPGA上的开发思想。

       首先,在做实现之前,最重要的是算法是在硬件上是做训练,还是做检测,这两者之间差别较大。我认为FPGA对于训练任务的适用性一定是体现在需要一边检测一边学习的工程中,而不是为了减少训练时间的单纯训练任务。训练算法一般有两类情况,一类是需要不断地迭代(BP算法,SMO算法等),一类是通过矩阵求逆等环节直接求解。这两种在硬件上实现都对维数和层数提出了限制(多层迭代存在小数位数过大,难以定点化的问题;直接求解存在大型矩阵求逆的问题)。所以想在硬件上实现,需要对原先的算法进一步的优化,用一些理论技巧去避免这些问题。对于检测任务来说,把训练好的算法在FPGA上实现要更容易,但是同样地,当浮点数实现算法达不到要求(资源开销,速度等),需要定点化时,检测的准确率是会受影响的,这也是需要解决的问题。

       当我们明确了能满足上述要求的具体的算法后,就要用硬件思想去理解算法本身的结构,这是很必要的,即便我们是要用C或C++在HLS上实现(否则即便算法在C/C++层面是通的,也很难综合成RTL)。在LS-SVM中我们要实现的是:


转换成硬件结构描述就是:

1.png


    硬件思想的对于HLS也很重要,就是因为HLS中对C/  C++的一些限制就是硬件思想的体现:不支持动态分配内存,不支持长度不定的数组(数组都被综合成ROM/RAM),不支持递归(内存分配问题)。所以当我们有了硬件思想,就能避免这些问题的出错,不仅如此,硬件思想对于C/C++代码的进一步优化也有很大作用:使用FIFO,开辟缓存,数组的分割,数组被综合成ROM还是RAM(双端口还是单端口)。有了这些认识使得我们对代码的结构优化变成可能。例如实现卷积时,窗口缓冲和行缓冲,减少了从DDR中取数据的等待时间,保证数据的流水取出并计算:

2.png




现状和问题的总结

一、工程中如果需要边训练边检测,由于数据维度和算法层数,对于需要不断地迭代(BP算法,SMO算法等),存在小数位数过大,难以定点化的问题;对于通过矩阵求逆等环节直接求解的算法(ELM,LS-SVM)存在大型矩阵求逆的问题。因而算法的维度和层数有所限制。

二、浮点数计算的误差及复杂度,和定点数精度的损失,对于算法的效果也有所影响,这需要在具体的工程中评估,并提出解决方法。

三、已经实现的CNN和LS-SVM都只是单纯的算法实现,过于理想,没有与实际的工程相关,可能在实际问题上的FPGA实现还有很多没有考虑到的细节

四、ZYNQ的ARM+FPGA(对算法不同部分划分到ARM和FPGA中)架构与高端的FPGA-V-7相比对于深度学习的实现各自的性能还不可知,这也需要成熟具体的工程实现进行验证对比。