对于神经网络加速器来说,需要考虑的主要指标有:
目标:最大化计算速度,最小化资源占用。
加速器验证思路:
Python/C++
编写模块相同功能函数;testbench
,记录模拟结果;addf16
, mulf16
mulmat
softmax
, laternorm
++++
对于重叠模式下的架构:这些PE算子可跨层复用,但使用了片外DDR,由PS与PL通信控制,计算延迟受限于通信带宽。
++++
其他加速器:
gp
, hp
, ready-valid
reg_ctrl
, dma
半精度浮点数float16
:常用于实现加速器中的浮点数运算。其结构:
|S| E | M |
16| |14 10|9 0|
FP16 = (-1)^S * 1.M * 2^(E - 15)
Range: [5.96*10^-8, 6.55*10^4]
++++
待定
对卷积层进行模块分解:
ConvLayer
卷积层模块Tanh
激活函数、 Softmax
激活函数AvgPool
平均池化层mulf16
半精度浮点乘、addf16
半精度浮点加一个卷积层有多个卷积核(Filter),image输入到不同的核得到不同的特征(Feature),自顶向下先观察Multi Filter Layer
,其输入图像和六个卷积核,输出卷积结果。
网络ConvLayerMulti
层输入矩阵规模:image 32*32, filterSet 5*5
++++
模块ConvLayerMulti
层输入:
image: 1 * 32 * 32 * 16 = 16384
filters: 6 * 5 * 5 * 16 = 2400
outputConv: 1 * 28 * 28 * 16 = 12544
^ channel ^ scale ^ bitwidth
++++
对于单个卷积核(Filter),再观察Single Filter Layer
,其输入图像和单个卷积核,输出特征图(Feature Map)。
++++
模块ConvLayerSingle
层输入:
image: 1 * 32 * 32 * 16 = 16384
filters: 1 * 5 * 5 * 16 = 400
outputConv: 1 * 28 * 28 * 16 = 12544
^ channel ^ scale ^ bitwidth
一个卷积核(Filter)与一个输入图像(Image)进行卷积运算,得到特征图(Feature Map),这个过程通过ConvUnit
模块实现。
++++
CU
模块循环使用PE
模块实现一个窗口的卷积操作,并输出一个半精度浮点型(FP16)计算结果。
卷积进行的具体操作是点乘,这里本质上是浮点算子:mulf16
乘、addf16
加,这里通过PE
模块实现。
++++
元素处理(PE)模块:执行具体卷积操作,即权重与数据相乘后累加。添加result_reg
,将电路从组合逻辑转化为时序逻辑,保证数据同步。
++++
元素处理(PE)模块代码演示:
module PE(
clk, rst,
fA, fB, res
);
parameter DATA_WIDTH = 16; // 数据位宽
input clk, rst;
input [DATA_WIDTH-1:0] fA, fB;
output reg [DATA_WIDTH-1:0] res;
wire [DATA_WIDTH-1:0] mul_res;
wire [DATA_WIDTH-1:0] add_res;
// 1. 计算乘法结果
mulf16 FMUL(.fA(fA), .fB(fB), .res(mul_res));
// 2. 计算累加结果
addf16 FADD(.fA(fA), .fB(fB), .res(add_res));
always @(posedge clk or posedge rst) begin
if(rst == 1'b1) begin
res <= 0;
end else begin
res <= add_res;
end
end
endmodule
Softmax
函数将输入归一化,求得各个类概率。输入规模与输出规模相同(400)。
++++
计算过程(时序逻辑):
exponet
求指数,FloatReciprocal
计算指数模块exponent
,求解$e^x$值,输入规模与输出规模相同(32),使用泰勒展开拟合:
- 两个乘法器:分子 & 分母。
- 一个加法器:累加。
对平均池化层分解:
AvgPoolMulti
(通道平均池化)AvgPoolSingle
(单通道平均池化)AvgU
(平均池化单元)多通道平均池化层(Average Pool Multi)并行度为1,循环使用AvgPoolSingle
完成所有通道的平均池化。(时序逻辑电路)
++++
单通道平均池化(Average Pool Single):全并行度,每个窗口都有一个AvgU
运算模块。(组合逻辑电路)
平均池化单元(AvgU):每个通道的平均池化操作:求输入的四个数(位宽16 * 4)的均值,先求和,再乘以0.25得到均值(位宽16)。(组合逻辑电路)
优化:插入寄存器形成pipline。
对全连接层分解:
FCMulti
(通道全连接)FCSingle
(单通道全连接),激活函数为Tanh
PE
计算模块全连接层(Full Connection Layer):进行线性计算,矩阵向量乘,向量和。
\[y = xW^T + b\]注意:多层之间加上
Tanh
非线性激活函数。
PE
是一个乘法器和加法器实现,实现累乘和累加。
参考如下CNN
加速器目录:
.
├── vivado_project # 项目完整网络的vivado工程
├── conv_code # 不同并行度的卷积模块代码
├── final_code # 各模块以及网络顶层代码
│ ├── Part1. Convolution
│ ├── Part2. TanH Activation
│ ├── Part3. Softmax Activation
│ ├── Part4. Average Pooling
│ ├── Part5. Intergration
│ └── ...
├── test_scripts # 各个模块验证脚本
│ ├── Test1. ANN Test
│ ├── Test2. TanH Test
│ ├── Test3. Text Files Test
│ ├── Average Pooling Python Code
│ ├── Convolution Python Code
│ ├── Softmax Python Code
│ └── ...
├── results # 仿真截图,综合报告,验证数据表格
├── weights # 卷积与全连接层权重和偏置数据
├── hw_design.pdf # 项目硬件设计文档
└── README.md # 项目介绍