2. NPU硬件架构基础
NPU(Neural Processing Unit)的硬件架构决定了算子的执行效率、内存访问模式以及调度策略。与通用CPU不同,NPU针对深度学习中的矩阵乘法和卷积运算进行了专门优化,其计算单元、存储层次和带宽特性直接影响了自定义算子的设计边界。理解NPU的硬件结构,是编写高性能自定义算子的前提。本章从计算单元、存储层次、内存带宽、AI Core与AI CPU的差异四个维度展开,并分析这些硬件特性对算子设计的具体约束。
2.1 NPU计算单元:Cube、Vector与Scalar的分工
核心原理:NPU的计算单元采用异构设计,典型架构包含三类执行单元:Cube单元(矩阵运算)、Vector单元(向量运算)和Scalar单元(标量控制)。Cube单元是NPU的算力核心,以矩阵分块方式执行GEMM(通用矩阵乘法)和卷积运算,单周期可完成16×16或32×32的矩阵乘累加。Vector单元负责逐元素运算,如激活函数、归一化、逐元素加乘等。Scalar单元处理地址计算、循环控制、分支跳转等标量操作,相当于每个AI Core的“控制器”。
判断方法:在设计算子时,首先判断运算类型属于矩阵乘/卷积(应映射到Cube)、逐元素/归约(应映射到Vector)还是控制流/地址计算(应映射到Scalar)。通过分析算子的计算密度(算术强度=运算量/访存量),可以决定算子是否适合在Cube上执行。例如,一个卷积层若算术强度大于10 FLOPs/Byte,则Cube利用率较高;若低于2 FLOPs/Byte,则受限于内存带宽,需考虑算子融合。
| 计算单元 | 运算类型 | 数据精度 | 典型吞吐 | 适用算子 |
|---|---|---|---|---|
| Cube | 矩阵乘、卷积 | FP16/INT8 | 1024 MACs/cycle | Conv2D、MatMul、FC |
| Vector | 逐元素、归约 | FP32/FP16 | 256 FLOPs/cycle | ReLU、Softmax、LayerNorm |
| Scalar | 标量、控制流 | INT32/FP32 | 4-8 ops/cycle | 地址计算、循环控制 |
2.2 存储层次:从寄存器到HBM的容量与延迟阶梯
核心原理:NPU的存储层次设计遵循“容量小、速度快”的原则,从内到外依次为:寄存器文件(RF)、L0 Buffer、L1 Buffer、L2 Cache、HBM(高带宽内存)以及Host侧DDR。L0 Buffer是AI Core私有的片上存储,容量通常为256KB,访问延迟约10个周期;L1 Buffer为AI Core集群共享,容量1MB左右,延迟约30周期;L2 Cache为整个NPU共享,容量8-32MB,延迟约100周期;HBM容量可达64GB,但延迟在300周期以上。存储层次决定了数据复用策略:数据应尽量在L0/L1中重复使用,减少对HBM的访问。
操作流程:设计算子时,遵循以下数据放置原则:1)将输入特征图分块(Tiling)到L1,确保每个数据块在L1中至少被复用2次;2)将权重矩阵常驻L0,因为权重在推理中不变;3)中间结果优先写入L0,避免写回HBM再读回;4)使用DMA(直接内存访问)进行异步搬运,使计算与数据传输重叠。例如,在卷积算子中,将输入图像按通道分块为16通道一组,每组在L1中完成所有输出通道的计算,可显著减少HBM访问。
| 存储层级 | 容量 | 访问延迟 | 带宽 | 共享范围 |
|---|---|---|---|---|
| 寄存器文件 | 64KB | 1 cycle | — | 单线程 |
| L0 Buffer | 256KB | 10 cycles | 4TB/s | 单AI Core |
| L1 Buffer | 1MB | 30 cycles | 2TB/s | AI Core集群 |
| L2 Cache | 8-32MB | 100 cycles | 1TB/s | 整个NPU |
| HBM | 32-64GB | 300+ cycles | ~1TB/s | 所有NPU |
2.3 内存带宽:算力与带宽的平衡艺术
核心原理:NPU的峰值算力与内存带宽之间存在“算术强度”匹配关系。以某NPU为例,FP16算力为320 TOPS,HBM带宽为1.6TB/s,则平衡算术强度为320×10^12 / 1.6×10^12 = 200 FLOPs/Byte。这意味着:若算子的算术强度低于200,则受带宽限制(Memory-bound);高于200,则受算力限制(Compute-bound)。实际算子中,卷积和矩阵乘的算术强度通常在50-500之间,因此需要针对性地优化。
判断方法:通过Profiling工具获取算子的实际带宽利用率和算力利用率。若带宽利用率>80%而算力利用率<50%,则为带宽瓶颈;反之则为算力瓶颈。针对带宽瓶颈,采用算子融合(将多个Elementwise操作合并)、数据压缩(INT8量化)、更优的Tiling策略;针对算力瓶颈,则优化Cube的矩阵分块大小、使用向量化指令。
// 带宽优化示例:Tiling参数选择
// 输入特征图: [N=1, C=64, H=56, W=56], FP16
// L1容量: 1MB, 权重大小: 64*64*3*3*2B = 72KB
// 选择Tile_C=16, Tile_H=28, Tile_W=28
// 输入Tile: 16*28*28*2B = 25KB
// 输出Tile: 16*28*28*2B = 25KB
// 权重Tile: 16*64*3*3*2B = 18KB
// 总占用: 25+25+18 = 68KB < 1MB ✓
2.4 AI Core与AI CPU的差异及协同
核心原理:AI Core是专为深度学习设计的加速核心,采用VLIW(超长指令字)架构,支持Cube/Vector/Scalar并行执行,但不擅长复杂控制流和动态形状处理。AI CPU则是基于RISC-V或ARM架构的通用处理器核,频率较低(约1.5GHz),但支持完整指令集,可处理动态shape、条件分支、复杂索引等任务。两者通过共享L1/L2和同步机制协同工作。
判断方法:算子映射决策遵循以下原则:1)静态shape、计算密集、无数据依赖的算子→AI Core;2)动态shape、含大量分支/循环、需要调用系统库的算子→AI CPU;3)混合型算子→将计算部分放在AI Core,控制部分放在AI CPU,通过异步接口通信。例如,NMS(非极大值抑制)算子包含大量排序和条件判断,适合AI CPU;而其中的IoU计算可下放到AI Core的Vector单元。
| 维度 | AI Core | AI CPU |
|---|---|---|
| 指令集 | VLIW(自定义) | RISC-V/ARM |
| 主频 | 1.8GHz | 1.5GHz |
| 并行方式 | SIMD + 流水线 | 多核 + 多线程 |
| 支持数据类型 | FP16/INT8/FP32 | FP32/INT32/FP64 |
| 典型延迟 | 低(确定性) | 中(可中断) |
| 适用场景 | Conv/GEMM/Activation | NMS/Resize/动态shape |
2.5 硬件特性对算子设计的综合影响
核心原理:算子设计需综合考虑计算单元、存储层次、带宽和异构核心的协同。设计流程为:1)分析算子计算特征(矩阵乘/逐元素/控制流);2)评估算术强度,确定瓶颈类型;3)选择计算单元映射;4)设计Tiling策略和DMA流水线;5)进行性能Profiling和调优。整个流程中,硬件约束是硬性边界,算子逻辑必须适配硬件。
操作流程:以自定义卷积算子为例,设计步骤如下:1)将卷积转换为矩阵乘(im2col或Winograd);2)确定Cube分块大小(如16×16×16);3)设计L1 Tiling(按输出通道分块);4)配置DMA双缓冲(当前块计算时预取下一块);5)在Vector上执行Bias和ReLU融合;6)Profiling验证Cube利用率>70%,带宽利用率>60%。