一、课程导论与背景:为什么需要硬件加速?
各位同学好,我是这门课的主讲。今天咱们聊聊一个很现实的问题——为什么CNN非得搞硬件加速?
我2016年刚入行那会儿,在FPGA上跑一个简单的LeNet-5,帧率才十几帧。放到现在,这速度连个门禁系统都嫌慢。你想想看,一个典型的ResNet-50,在CPU上跑一张224x224的图片,大概需要200毫秒。这什么概念?一秒只能处理5张图。要是做实时视频分析,每秒25帧的要求,差了整整5倍。
为什么会这样?说白了,CNN的计算模式跟CPU的架构天生八字不合。
1.1 CNN计算瓶颈分析
我们先拆开看看,CNN到底在忙什么。
卷积层的计算量
卷积层是CNN里最耗时的部分。我给大家一个公式:
单层卷积计算量 = K × K × C_in × C_out × H_out × W_out
举个例子,VGG-16的第一个卷积层:
- 输入:224x224x3
- 卷积核:3x3x64
- 输出:224x224x64
- 计算量:3×3×3×64×224×224 ≈ 86.7M次乘加
这还只是一层。VGG-16总共16层,总计算量大约15.3G次乘加。嗯,这里要注意,这还只是前向推理,训练时还要算梯度,计算量翻三倍。
关键瓶颈:卷积操作本质上是数据重用率极低的运算。每个输出像素需要K×K×C_in次乘加,但输入数据只被用了一次就扔了。这导致内存带宽成为天花板。
池化层的访存量
池化层计算量不大,但访存压力不小。最大池化需要读取整个输入特征图,写入缩小后的输出。以2x2池化为例:
访存量 = 输入大小 + 输出大小 = H×W×C + (H/2)×(W/2)×C
我曾经在一个项目中,为了省带宽,把池化层和卷积层合并处理。结果发现,池化层的访存占到了总访存的15%左右。别小看这15%,在带宽受限的嵌入式设备上,这就是压死骆驼的最后一根稻草。
全连接层的参数爆炸
全连接层是参数量的重灾区。AlexNet的三个全连接层,参数量占了整个网络的90%以上。
| 网络层 | 参数量 | 计算量 | 访存量 |
|---|---|---|---|
| 卷积层(5层) | 2.3M | 666M | 中等 |
| 全连接层(3层) | 58.6M | 58.6M | 极高 |
你看,全连接层的参数量是卷积层的25倍,但计算量只有十分之一。这意味着什么?全连接层的瓶颈不在计算,在访存。每次推理都要从DDR里搬58.6M个权重,这带宽需求,想想都头疼。
我的经验:做硬件加速时,卷积层和全连接层要分开优化。卷积层重点优化计算单元利用率,全连接层重点优化数据搬运效率。我曾经在FPGA上把全连接层的权重做了量化压缩,从FP32降到INT8,带宽需求直接降到四分之一。
1.2 硬件加速的几种思路
既然CPU搞不定,那怎么办?目前主流方案有三个:GPU、FPGA、ASIC。我一个个说。
GPU加速
GPU是当前最成熟的方案。NVIDIA的Tensor Core,专门为矩阵乘法设计的硬件单元。一个V100 GPU有640个Tensor Core,理论算力125 TFLOPS。
优点很明显:
- 生态成熟,CUDA、cuDNN一应俱全
- 开发门槛低,调几个API就能跑
- 算力天花板高,适合训练
缺点也突出:
- 功耗高,V100满载300W
- 延迟不稳定,不适合实时系统
- 成本高,一块卡几万块
我建议,如果你做云端训练或者批量推理,GPU是首选。但要是做嵌入式或者边缘计算,就得另想办法了。
FPGA加速
FPGA的优势在于可编程性和低延迟。你可以把卷积运算流水线化,每个时钟周期出一个结果。
我在一个项目中用Xilinx的Zynq系列做过CNN加速:
- 实现了3x3卷积的脉动阵列
- 计算单元利用率达到85%以上
- 功耗只有10W左右
- 延迟控制在5ms以内
FPGA的缺点:
- 开发周期长,RTL代码调试费时
- 算力上限不如GPU
- 浮点运算效率低,一般用定点
避坑指南:我曾经在FPGA上做卷积加速时,忽略了DDR带宽的限制。结果计算单元大部分时间在空转等数据。后来加了数据预取和乒乓缓冲,才把效率提上来。记住,计算不是瓶颈,数据搬运才是。
ASIC加速
ASIC是终极方案。Google的TPU、华为的昇腾、寒武纪的MLU,都是ASIC。
ASIC的优势:
- 能效比最高,TPU v4的能效比是GPU的5倍以上
- 延迟最低,专用数据通路
- 面积最小,去掉冗余逻辑
ASIC的劣势:
- 流片成本高,一次几千万
- 灵活性差,算法变了就得重新流片
- 开发周期长,从设计到量产一年起步
说实话,ASIC适合出货量大的场景。比如手机里的NPU,一年出货几千万片,摊薄了流片成本。要是只做几百片,还是用FPGA划算。
1.3 三种方案对比
| 指标 | GPU | FPGA | ASIC |
|---|---|---|---|
| 算力 | 高 | 中 | 高 |
| 能效比 | 低 | 中 | 高 |
| 灵活性 | 高 | 中 | 低 |
| 开发周期 | 短 | 中 | 长 |
| 成本 | 高 | 中 | 极高(一次) |
| 适用场景 | 云端训练/推理 | 边缘计算/原型验证 | 大规模量产 |
我个人习惯是这么选的:
- 做研究、快速验证 → GPU
- 做产品原型、小批量 → FPGA
- 做大规模部署、追求极致能效 → ASIC
1.4 本章知识体系
下面这张图,是我梳理的本章核心逻辑。你看一眼,心里就有谱了。
这张图把本章的核心逻辑串起来了。从为什么需要加速出发,分析CNN的计算瓶颈,再对比三种硬件方案。后面的课程,我们会逐一深入每个方案的实现细节。
我的建议:学这门课之前,最好先熟悉CNN的基本原理。至少要知道卷积、池化、全连接是怎么算的。如果这些概念还不清楚,建议先补一下基础。嗯,磨刀不误砍柴工嘛。