NPU架构总览:从宏观到微观
各位同学,今天我们来聊聊NPU的宏观架构。说实话,我第一次接触NPU设计时,也被各种术语搞得头晕。但后来我发现,只要抓住三个核心——计算、存储、控制,整个架构就清晰了。
一、宏观架构三要素
NPU说白了就是为神经网络量身定做的处理器。它不像CPU那样什么都能干,但干起矩阵乘法来,效率高得吓人。
1. 计算单元
这是NPU的心脏。我习惯把它想象成一个「乘法累加器阵列」。在项目中,我们通常用MAC(乘累加单元)来衡量算力。
- PE(处理单元):最基本的计算单元,负责一次乘法和一次加法
- MAC阵列:多个PE排列成矩阵,比如16x16、32x32
- SIMD扩展:单指令多数据,一条指令处理多个数据
关键点:MAC阵列的大小直接决定了NPU的峰值算力。但别一味追求大,我见过一个项目把阵列做到128x128,结果布线绕得飞起,频率死活上不去。
2. 存储单元
存储是NPU的命门。你想想看,计算再快,数据喂不进去也是白搭。
| 存储层级 | 容量 | 带宽 | 用途 |
|---|---|---|---|
| 寄存器文件 | KB级 | 最高 | 临时变量 |
| 片上SRAM | MB级 | 高 | 权重、特征图 |
| 片外DRAM | GB级 | 低 | 模型参数、数据集 |
嗯,这里要注意:片上SRAM的大小直接决定了你能跑多大的模型。我做过一个边缘端NPU,SRAM只有256KB,跑个MobileNet都得拆成好几块,那叫一个痛苦。
3. 控制单元
控制单元负责调度。它告诉计算单元「该算哪块数据了」,告诉存储单元「把数据搬到哪」。我个人习惯把控制单元分成两级:
- 全局控制器:负责指令解析、任务调度
- 本地控制器:负责PE阵列内部的微操作
避坑指南:我曾经在一个项目中,全局控制器和本地控制器的握手信号没处理好,导致PE阵列空转了30%的周期。后来加了个FIFO缓冲,问题才解决。
二、数据流架构:三种固定模式
数据流架构是NPU设计的精髓。说白了,就是决定「谁不动、谁在动」。常见的三种模式:
1. 行固定(Row-Stationary)
权重行固定不动,输入特征图滑动。这种模式适合权重复用率高的场景。
// 伪代码示意
for (row = 0; row < R; row++) {
weight_row[row] 固定不动
for (col = 0; col < C; col++) {
input_col[col] 滑动
output[row][col] = MAC(weight_row[row], input_col[col])
}
}
2. 列固定(Column-Stationary)
输入特征图固定,权重列滑动。我一般在处理大输入特征图时用这个。
3. 输出固定(Output-Stationary)
输出结果固定,权重和输入都滑动。这种模式可以减少中间结果的写回次数。
| 模式 | 固定对象 | 适用场景 | 优缺点 |
|---|---|---|---|
| 行固定 | 权重行 | 权重复用高 | 存储友好,但控制复杂 |
| 列固定 | 输入列 | 输入特征图大 | 带宽友好,但PE利用率低 |
| 输出固定 | 输出结果 | 输出通道多 | 减少写回,但控制开销大 |
注意:别以为选了一种模式就万事大吉。实际项目中,我经常需要根据不同的层动态切换数据流模式。比如卷积层用行固定,全连接层用输出固定。
三、典型NPU拆解:以TPU为例
Google的TPU是NPU设计的经典案例。我当年研究TPU架构时,最大的感受就是:简单粗暴,但有效。
TPU的核心架构
- 矩阵乘法单元:256x256的MAC阵列,一次处理256x256的矩阵乘法
- 统一缓冲区:24MB的片上SRAM,用于存储权重和中间结果
- 累加器:4MB的累加器,专门存放部分和
- 激活单元:处理ReLU、池化等非线性操作
这里有个有意思的点:TPU没有复杂的缓存层级,而是用了一个大块统一缓冲区。为什么?因为神经网络的数据访问模式很规律,不需要CPU那种复杂的缓存一致性协议。
TPU的数据流
我画了一张图,帮你理解TPU的数据流动:
从图上你能看到,数据从DRAM加载到统一缓冲区,然后广播到MAC阵列。计算完的部分和暂存在累加器中,最后经过激活单元处理,写回DRAM。
TPU的设计哲学:用大块SRAM换带宽,用大规模MAC阵列换算力。说白了,就是「大力出奇迹」。
TPU的指令集
TPU的指令集非常精简,只有几条核心指令:
// TPU核心指令示例
CWM: 将权重从DRAM加载到统一缓冲区
MMU: 执行矩阵乘法
ACT: 执行激活函数
STORE: 将结果写回DRAM
嗯,你没看错,就这么几条。我当年第一次看到时也震惊了——这么简单的指令集,居然能跑出那么高的性能?后来我明白了,专用芯片的精髓就在于「少即是多」。
四、小结
今天的内容,说白了就是三件事:
- 宏观架构:计算单元、存储单元、控制单元,三者缺一不可
- 数据流架构:行固定、列固定、输出固定,选对模式事半功倍
- TPU案例:简单粗暴的设计,但效果拔群
我个人觉得,理解NPU架构最好的方法,就是动手画一画数据流图。你想想看,数据从哪来,到哪去,中间经过哪些处理——画明白了,架构也就懂了。
一点建议:如果你刚开始学NPU设计,别急着看那些复杂的论文。先把TPU的架构吃透,它虽然简单,但包含了NPU设计的核心思想。
公众号:蓝海资料掘金营,微信deep3321