第一章:NPU架构概览——从CPU到NPU的演进、核心计算单元与存储层次

大家好,我是你们的老朋友。今天咱们正式开讲NPU算子映射与缓存优化这门课。第一章,我想先带大家把NPU的底子摸清楚。说白了,你得知道NPU长什么样、怎么干活、跟编译器又是啥关系,后面那些优化技巧才能用得上。

我刚开始接触NPU时,其实挺懵的。CPU、GPU我都熟,但NPU这玩意儿,看着像GPU,用起来又像CPU,调试起来还特别“个性”。后来踩了不少坑,才慢慢摸清它的脾气。今天就把这些经验分享给你们。

1.1 从CPU到NPU:为什么非要有NPU?

先问个问题:CPU那么万能,为什么还要搞NPU?

你想想看,CPU的设计哲学是“通用”。它要处理操作系统、数据库、游戏、办公软件……啥活都得干。所以它花了大把晶体管在分支预测、乱序执行、缓存一致性上。但神经网络计算呢?说白了就是一堆矩阵乘法和激活函数。CPU去算这个,就像用瑞士军刀砍树——能砍,但效率感人。

GPU呢?它本来是做图形渲染的,擅长并行计算。但GPU的架构是为“吞吐”设计的,延迟高、控制逻辑弱。跑神经网络时,很多小算子(比如reshape、slice)在GPU上反而跑不快。

所以NPU诞生了。它的设计思路很纯粹:只做神经网络计算,做到极致。

核心差异一句话总结:

  • CPU:通用、低延迟、强控制——但算力密度低。
  • GPU:高吞吐、大并行——但控制弱、小算子效率低。
  • NPU:专为神经网络设计——算力密度高、能效比好、控制灵活。

我个人习惯把NPU比作“专用流水线”。CPU是万能工具箱,GPU是大型工厂,NPU就是一条专门生产“矩阵乘法”的自动化产线。产线一旦搭好,效率是前两者的几十倍。

1.2 NPU核心计算单元:MAC阵列

NPU的心脏,就是MAC阵列。MAC是Multiply-Accumulate(乘累加)的缩写。一个MAC单元做一次 a * b + c 的操作。神经网络里,一个卷积层可能有几百万次这样的操作。

MAC阵列就是把成千上万个MAC单元排成矩阵。比如一个16x16的阵列,就有256个MAC单元。它们可以同时工作,一次完成256次乘累加。

嗯,这里要注意:MAC阵列的规模直接决定了NPU的算力。但规模不是越大越好。我见过一些芯片,MAC阵列做得特别大,结果带宽跟不上,MAC单元经常“饿着肚子等数据”。这就是典型的“算力虚胖”。

避坑指南:

我曾经在一个项目里,把MAC阵列从8x8扩到16x16,以为算力能翻4倍。结果实际性能只提升了1.8倍。为什么?因为数据搬运成了瓶颈。后来我学乖了:算力要和带宽匹配,否则就是浪费硅片面积。

MAC阵列的工作模式也值得一说。它通常支持多种数据精度:INT8、INT4、甚至二进制。精度越低,算力越高(因为单位面积能塞更多MAC单元)。但精度低,模型准确率可能下降。所以实际部署时,需要权衡。

我个人习惯的做法是:先用FP32训练模型,然后做量化感知训练,最后用INT8部署。这样既能保证精度,又能发挥NPU的算力优势。

1.3 NPU存储层次:L1/L2/Global Memory

NPU的存储层次,跟CPU很像,但又有自己的特点。咱们从离计算单元最近的开始说。

1.3.1 L1 Memory(也叫Scratchpad Memory)

L1是MAC阵列直接访问的存储器。速度极快,通常一个时钟周期就能读写。但容量很小,一般几十KB到几百KB。

L1的作用是存放当前计算需要的数据。比如一个3x3的卷积核,权重就放在L1里。这样MAC单元每次计算时,都能以最快速度拿到数据。

但L1有个特点:它是软件管理的。不像CPU的L1 cache是硬件自动管理,NPU的L1需要编译器或程序员手动搬数据。这就给优化留下了空间——也留下了坑。

警告:

我曾经犯过一个错误:把L1当cache用,以为硬件会自动帮我管理。结果数据频繁被踢出L1,性能惨不忍睹。后来我才明白:NPU的L1是“显式管理”的,你得告诉它什么时候搬数据、搬多少、放哪里。

1.3.2 L2 Memory

L2是L1和Global Memory之间的缓冲。容量更大,通常几MB。速度比L1慢一些,但比Global Memory快得多。

L2的作用是“数据中转站”。比如一个卷积层,输入特征图可能很大,放不进L1。那就先放在L2里,然后分块搬到L1里计算。

这里有个关键点:L2的带宽往往比L1低。所以优化时,要尽量减少L2的访问次数。我常用的技巧是“数据复用”——同一个数据在L1里多用几次,别频繁去L2取。

1.3.3 Global Memory(也叫DRAM)

Global Memory就是NPU的“大仓库”。容量最大,通常几GB到几十GB。但速度最慢,访问延迟可能是L1的几十倍。

Global Memory存放的是整个模型和所有输入输出数据。编译器的工作之一,就是决定什么时候把数据从Global Memory搬到L2,再从L2搬到L1。

你想想看,如果编译器安排得不好,MAC阵列大部分时间都在等数据,算力再高也没用。这就是为什么NPU的性能瓶颈往往不在计算,而在数据搬运。

存储层次 典型容量 典型延迟 管理方式
L1 Memory 64KB - 512KB 1-2 cycles 软件显式管理
L2 Memory 1MB - 8MB 10-20 cycles 软件显式管理
Global Memory 4GB - 32GB 100-300 cycles 硬件/软件协同

1.4 NPU与AI编译器的关系

说到这儿,你可能会问:NPU硬件这么复杂,程序员怎么用?难道要手写汇编吗?

当然不是。这时候AI编译器就登场了。

AI编译器的作用,就是把PyTorch、TensorFlow这些框架写的模型,翻译成NPU能执行的指令。这个过程包括:

  • 图优化:合并算子、消除冗余计算。
  • 算子映射:把神经网络算子(比如Conv2D、ReLU)映射到NPU的硬件指令上。
  • 内存规划:决定数据在L1、L2、Global Memory之间的搬运策略。
  • 指令生成:生成NPU能执行的二进制指令。

我个人觉得,AI编译器是NPU生态里最关键的一环。硬件再强,编译器不行,性能也发挥不出来。我见过一些NPU芯片,硬件设计很漂亮,但编译器优化不到位,实际跑模型时效率只有理论峰值的30%。

核心观点:

NPU硬件和AI编译器是“共生关系”。硬件决定了性能上限,编译器决定了你能多接近这个上限。两者缺一不可。

举个例子。一个卷积层,硬件上MAC阵列算得飞快。但如果编译器把数据分块分得不好,导致L1频繁miss,那MAC阵列就得干等着。反过来,如果编译器优化得好,数据搬运和计算能重叠起来,那性能就能接近理论峰值。

我记得有一次,我们团队花了两周时间优化一个算子的内存搬运策略。最终性能提升了40%。而硬件本身没动过一根线。这就是编译器的力量。

1.5 本章知识体系总览

下面这张图,是我自己画的NPU架构知识体系。你可以把它当作本章的“地图”。后面每一章,都会围绕这张图里的某个点展开。

NPU架构知识体系总览 AI模型(PyTorch/TensorFlow) AI编译器(图优化 + 算子映射 + 内存规划) 核心任务:把模型翻译成NPU指令 NPU硬件架构 MAC阵列 核心计算单元 支持INT8/INT4 L1 Memory 软件管理 几十KB - 几百KB L2 Memory 数据中转站 几MB Global Memory(DRAM) 几GB - 几十GB,延迟高 图1:NPU架构三层结构——模型 → 编译器 → 硬件

这张图清晰地展示了NPU工作的完整链路:AI模型经过编译器翻译,最终在NPU硬件上执行。其中,MAC阵列负责计算,L1/L2/Global Memory负责数据搬运。编译器则负责让这一切高效协同。

好了,第一章就讲到这里。内容不少,但都是后面章节的基础。你只要记住三点:

  • NPU是为神经网络定制的专用处理器,核心是MAC阵列。
  • 存储层次是性能的关键,L1要手动管理,别当cache用。
  • AI编译器是连接模型和硬件的桥梁,优化空间巨大。

下一章,咱们会深入算子映射的具体细节。到时候见。