4、Ethos-U NPU架构详解:核心计算单元、内存层次、数据流、支持算子、量化特性

Ethos-U系列NPU是Arm针对Cortex-M与Cortex-A系列处理器设计的专用神经网络加速器,其设计目标是在极低功耗预算下完成TinyML推理任务。与GPU或桌面级NPU不同,Ethos-U没有复杂的可编程着色器或大规模SIMD阵列,而是采用固定功能引擎+微码控制的架构,将卷积、全连接、池化等算子映射到专用的硬件数据通路中。理解其架构是进行高效部署的前提——如果开发者不了解其内存层次与数据流约束,很容易写出“能跑但极慢”的推理代码,甚至因算子不支持而被迫回退到CPU执行。

Ethos-U55 NPU 架构总览(以U55-128为例) 外部DDR/SRAM 权重/输入/输出 (片外存储) AXI 命令队列 (微码指令) DMA触发/算子配置 控制单元 (MCU微码) 调度/同步 权重DMA 片外→SRAM (双缓冲) 输入DMA 片外→SRAM (行缓冲) 输出DMA SRAM→片外 (结果回写) 片上SRAM(~1MB) 输入特征图 (IFM) 权重缓冲 (WGT) 输出特征图 (OFM) 中间缓冲 (激活/池化) MAC计算阵列 128 MACs/周期(U55-128) 支持8bit/16bit/混合精度 图例: 控制通路 DMA数据通路 计算引擎 片上存储边界 注:U55-128为128 MACs配置,U55-256为256 MACs

上图展示了Ethos-U55的核心架构。整个NPU围绕片上SRAM构建,外部DDR仅作为最终数据仓库。所有计算必须先将数据搬运到SRAM中才能执行,这一设计从根本上决定了部署时的内存规划策略。下面从五个维度深入剖析。

4.1 核心计算单元:MAC阵列与专用引擎

Ethos-U的计算核心是MAC(乘累加)阵列,其规模直接决定算力上限。以U55-128为例,包含128个MAC单元,每个周期可完成128次乘加运算。在1GHz时钟下,理论峰值算力为128 GOPS(8bit整数运算)。但实际部署中,由于内存带宽限制,通常只能达到峰值的30%-60%。

MAC阵列采用脉动阵列(Systolic Array)结构,权重和输入数据以流水方式在阵列中流动。这种设计减少了寄存器堆的读写次数,但要求数据必须按特定格式排列——权重按[输出通道][输入通道][KH][KW]顺序存储,输入特征图按[高度][宽度][通道]的NHWC布局。Vela编译器会自动完成这种重排,开发者无需手工干预。

关键参数速查表(以Ethos-U55-128为例)
参数数值说明
MAC数量128每周期128次乘加
峰值算力128 GOPS @1GHz8bit整数运算
支持精度int8/int16/int32混合精度支持
激活函数ReLU/ReLU6/Tanh/Softmax硬件查表实现
池化Max/Average/Global专用引擎,不占MAC
卷积类型标准/深度可分离/空洞3x3、5x5、7x7等

除了MAC阵列,Ethos-U还包含激活函数查表引擎和池化引擎。激活函数通过查找表(LUT)实现,支持ReLU、ReLU6、Tanh、Sigmoid等常见函数。查表引擎与MAC阵列并行工作,在卷积输出写回SRAM前完成激活计算,避免额外的内存往返。池化引擎则独立于MAC阵列,可同时处理最大池化、平均池化和全局池化。

4.2 内存层次:三级存储体系与带宽约束

Ethos-U的内存层次分为三级:寄存器级(MAC阵列内部)、片上SRAM(关键性能层)、外部DDR(容量层)。其中片上SRAM是最宝贵的资源,U55-128配置了约1MB的SRAM,分为输入特征图缓冲区、权重缓冲区、输出特征图缓冲区和中间结果缓冲区四个区域。

内存带宽是TinyML推理的主要瓶颈。以一次3x3卷积为例,若输入特征图为64x64x32,权重为32x32x3x3,则单次卷积需要读取64x64x32=131,072字节输入和32x32x3x3=9,216字节权重。在1GHz下,若SRAM带宽为128bit/周期,则理论带宽为16GB/s,但实际可用带宽通常只有60%-70%。

内存规划经验:Vela编译器会尝试将整个网络的计算图分割成多个“区域”(Region),每个区域内的数据尽量驻留在SRAM中。当网络过大无法完全放入SRAM时,Vela会插入DMA搬运指令,在计算的同时预取下一块数据(双缓冲机制)。开发者应尽量选择深度可分离卷积替代标准卷积,因为其参数量和计算量都减少约8-9倍,能显著降低内存压力。

权重存储采用压缩格式。Ethos-U支持权重稀疏性压缩,对于全零权重块(如4x4块全零),仅存储非零块的位置索引。实测表明,经过剪枝的模型可减少30%-50%的权重存储量,同时减少DMA搬运时间。但需注意,稀疏压缩仅在权重块完全为零时才生效,随机稀疏无法获得收益。

4.3 数据流:命令队列驱动的异步执行

Ethos-U的数据流由命令队列(Command Queue)驱动。CPU(Cortex-M或Cortex-A)通过写入命令描述符来配置NPU执行特定算子,NPU内部的微控制器(MCU)解析命令并调度DMA和MAC阵列。这种设计实现了CPU与NPU的异步并行——CPU可以继续执行其他任务,而NPU独立完成推理。

典型的数据流执行过程如下:

  1. 命令下发:CPU将命令描述符写入NPU的命令队列寄存器,描述符包含算子类型、输入/输出地址、维度信息、量化参数等。
  2. DMA预取:NPU的MCU解析命令后,启动权重DMA和输入DMA,将数据从外部DDR搬运到片上SRAM。双缓冲机制允许在计算当前块的同时预取下一块。
  3. MAC计算:当SRAM中数据就绪后,MAC阵列开始计算。计算过程中,激活引擎和池化引擎同步处理输出。
  4. 结果回写:输出DMA将结果从SRAM写回外部DDR,同时触发中断通知CPU。
常见误区:很多开发者误以为NPU是“即调即用”的,忽略了命令队列的延迟。实际上,从CPU写入命令到NPU开始计算,通常有5-10微秒的固定开销。对于单次推理时间仅100微秒的TinyML任务,这个开销占比可达10%。因此,批量推理(Batch Inference)或流水线推理(Pipelined Inference)是提升NPU利用率的关键手段——将多个输入样本的命令连续下发,让NPU始终处于忙碌状态。

数据流设计还决定了算子融合的可能性。Vela编译器会将卷积+ReLU+池化等连续操作融合为单个命令,避免中间结果写回DDR。例如,一个典型的MobileNetV2块(深度卷积+逐点卷积+残差连接)可被融合为单个NPU命令,中间特征图完全驻留在SRAM中。

4.4 支持算子与量化特性

Ethos-U支持的算子集是固定的,并非所有TensorFlow Lite算子都能在NPU上执行。Vela编译器会将不支持的算子自动回退到CPU执行,但这会导致性能急剧下降。因此,部署前必须检查算子兼容性。

算子类别支持情况典型算子注意事项
卷积✅ 原生支持Conv2D、DepthwiseConv2D支持空洞卷积,不支持转置卷积
池化✅ 原生支持MaxPool、AvgPool、GlobalAvgPool池化窗口≤8x8
激活✅ 查表实现ReLU、ReLU6、Tanh、Sigmoid自定义激活需生成LUT
全连接✅ 原生支持FullyConnected可视为1x1卷积
元素运算✅ 部分支持Add、Mul、Minimum要求输入形状一致
归一化⚠️ 需融合BatchNorm必须融合到卷积中
Reshape/Transpose⚠️ 仅支持特定模式Reshape、SqueezeTranspose需在CPU执行
Softmax⚠️ 部分支持Softmax大输入尺寸时回退CPU

量化特性方面,Ethos-U原生支持int8对称量化和int16非对称量化。int8量化使用scale和zero_point参数,权重必须是对称量化(zero_point=0),激活可以是非对称量化。int16量化主要用于对精度要求较高的场景,但计算速度会降低约2倍。

量化参数传递示例(Vela编译日志片段):
INFO: Quantization parameters for node 'conv2d_3':
  Input: scale=0.0078125, zero_point=-128, dtype=int8
  Weight: scale=0.004289, zero_point=0, dtype=int8
  Output: scale=0.011764, zero_point=-3, dtype=int8
  Activation: ReLU6, clamp_range=[0, 6]

Vela编译器会自动处理量化参数的传播和优化。例如,当检测到ReLU6激活时,Vela会将输出量化范围裁剪到[0, 6]对应的整数区间,减少量化误差。开发者应使用TensorFlow Lite的量化感知训练(QAT)工具链,而非训练后量化(PTQ),因为QAT能更好地适配Ethos-U的量化规则。

4.5 实战案例:MobileNetV2在Ethos-U55上的部署优化

下面通过一个实际案例展示架构理解如何指导部署优化。假设我们有一个在ImageNet上预训练的MobileNetV2模型(输入224x224x3),目标部署到Cortex-M55+Ethos-U55-128平台。

初始状态:直接使用TensorFlow Lite转换器生成int8量化模型,Vela编译后得到以下性能指标:

  • 推理时间:385ms
  • SRAM使用:412KB
  • DDR带宽利用率:42%
  • NPU利用率:38%

分析过程:通过Vela的性能分析报告发现,瓶颈在于输入层(第一个标准卷积)和最后的全连接层。输入层计算量小但数据搬运量大(224x224x3的输入),全连接层参数量大(1000类输出)导致权重DMA频繁。

优化步骤:

  1. 输入裁剪:将输入从224x224缩小到192x192,精度损失约0.3%,但推理时间降至312ms(-19%)。
  2. 全连接层替换:将最后的全连接层替换为全局平均池化+1x1卷积,参数量从1000x1024降至1000x1,权重DMA时间减少80%。
  3. 算子融合:确认Vela已将BatchNorm融合到卷积中,并检查是否有未融合的Add操作(残差连接)。通过调整模型结构,将残差Add操作与后续卷积融合。
  4. 双缓冲配置:在Vela配置文件中启用double_buffer=true,并设置sram_size_kb=1024,让Vela自动优化DMA预取策略。

优化后结果:

指标优化前优化后提升幅度
推理时间385ms198ms-48.6%
SRAM使用412KB356KB-13.6%
NPU利用率38%67%+76.3%
精度(Top-1)71.2%70.8%-0.4%

风险与代价:输入裁剪导致精度轻微下降,对于某些对精度敏感的应用(如医学影像分类)可能不可接受。全连接层替换改变了模型结构,需要重新训练或微调。双缓冲配置增加了SRAM压力,如果网络过大可能导致编译失败。

复盘经验:Ethos-U的性能优化不是单点突破,而是内存规划、算子选择、数据流配置三者的协同优化。建议开发者在项目初期就使用Vela的--report选项生成详细分析报告,识别瓶颈后再针对性优化。同时,保持模型结构尽量“规整”——避免不规则张量形状、避免过多分支、避免小卷积核(1x1除外),这些都能让Vela生成更高效的代码。

4.6 常见误区与总结

在Ethos-U部署实践中,以下误区最为常见:

  • 误区一:认为所有TensorFlow Lite算子都能在NPU上加速。实际上,Vela会静默地将不支持的算子回退到CPU,导致性能骤降。务必检查编译日志中的CPU fallback警告。
  • 误区二:忽略量化误差。Ethos-U的int8量化对权重范围敏感,若权重分布不均匀(如存在极端值),量化误差会显著增大。建议使用QAT并监控每层的量化误差。
  • 误区三:过度追求SRAM利用率。将SRAM填满到95%以上可能导致DMA冲突和调度延迟,反而降低性能。建议保留10%-15%的SRAM余量。
  • 误区四:忽视命令队列深度。Ethos-U的命令队列深度有限(通常为8-16条),若CPU下发命令速度跟不上NPU执行速度,会导致NPU空闲等待。

总结而言,Ethos-U的架构设计体现了TinyML场景的极致权衡:用固定功能硬件换取能效比,用片上SRAM换取确定性延迟,用命令队列换取CPU异步并行。开发者需要从内存层次出发理解性能瓶颈,从数据流出发优化执行效率,从算子支持出发调整模型结构,从量化特性出发保证精度。掌握这四者的协同关系,才能真正发挥Ethos-U的潜力。