NPU架构总览:从宏观到微观

各位同学,今天我们来聊聊NPU的宏观架构。说实话,我第一次接触NPU设计时,也被各种术语搞得头晕。但后来我发现,只要抓住三个核心——计算、存储、控制,整个架构就清晰了。

一、宏观架构三要素

NPU说白了就是为神经网络量身定做的处理器。它不像CPU那样什么都能干,但干起矩阵乘法来,效率高得吓人。

1. 计算单元

这是NPU的心脏。我习惯把它想象成一个「乘法累加器阵列」。在项目中,我们通常用MAC(乘累加单元)来衡量算力。

  • PE(处理单元):最基本的计算单元,负责一次乘法和一次加法
  • MAC阵列:多个PE排列成矩阵,比如16x16、32x32
  • SIMD扩展:单指令多数据,一条指令处理多个数据

关键点:MAC阵列的大小直接决定了NPU的峰值算力。但别一味追求大,我见过一个项目把阵列做到128x128,结果布线绕得飞起,频率死活上不去。

2. 存储单元

存储是NPU的命门。你想想看,计算再快,数据喂不进去也是白搭。

存储层级容量带宽用途
寄存器文件KB级最高临时变量
片上SRAMMB级权重、特征图
片外DRAMGB级模型参数、数据集

嗯,这里要注意:片上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的数据流动:

TPU数据流架构 片外DRAM 权重/输入 统一缓冲区 (24MB) 数据广播 矩阵乘法单元 (256x256 MAC) 每次处理256x256矩阵乘法 部分和 累加器 (4MB) 激活单元 结果写回

从图上你能看到,数据从DRAM加载到统一缓冲区,然后广播到MAC阵列。计算完的部分和暂存在累加器中,最后经过激活单元处理,写回DRAM。

TPU的设计哲学:用大块SRAM换带宽,用大规模MAC阵列换算力。说白了,就是「大力出奇迹」。

TPU的指令集

TPU的指令集非常精简,只有几条核心指令:

// TPU核心指令示例
CWM: 将权重从DRAM加载到统一缓冲区
MMU: 执行矩阵乘法
ACT: 执行激活函数
STORE: 将结果写回DRAM

嗯,你没看错,就这么几条。我当年第一次看到时也震惊了——这么简单的指令集,居然能跑出那么高的性能?后来我明白了,专用芯片的精髓就在于「少即是多」

四、小结

今天的内容,说白了就是三件事:

  1. 宏观架构:计算单元、存储单元、控制单元,三者缺一不可
  2. 数据流架构:行固定、列固定、输出固定,选对模式事半功倍
  3. TPU案例:简单粗暴的设计,但效果拔群

我个人觉得,理解NPU架构最好的方法,就是动手画一画数据流图。你想想看,数据从哪来,到哪去,中间经过哪些处理——画明白了,架构也就懂了。

一点建议:如果你刚开始学NPU设计,别急着看那些复杂的论文。先把TPU的架构吃透,它虽然简单,但包含了NPU设计的核心思想。


公众号:蓝海资料掘金营,微信deep3321