1. NPU内存架构概览
各位同学,咱们今天正式开讲。第一章,我打算先把NPU的内存架构给你讲透。为什么要把这个放在最前面?
因为我在做YOLO部署时,踩过最大的坑,十有八九都跟内存有关。模型结构调得再好,算子融合做得再漂亮,内存没管好,推理速度照样拉胯。说白了,NPU推理的瓶颈,很多时候不在算力,而在数据搬运。
1.1 NPU与CPU内存系统的差异
先问一个问题:CPU和NPU,都是处理数据的芯片,它们的内存系统到底有什么不一样?
我刚开始接触NPU时,也以为差不多。后来发现,这俩的思维模式完全不同。
| 对比维度 | CPU内存系统 | NPU内存系统 |
|---|---|---|
| 核心目标 | 低延迟、随机访问、缓存命中率 | 高吞吐、流式数据、带宽利用率 |
| 缓存策略 | 多级Cache(L1/L2/L3),硬件自动管理 | 显式管理的SRAM(Scratchpad),软件控制 |
| 数据粒度 | 64字节缓存行(Cache Line) | 张量块(Tile/Block),通常KB~MB级别 |
| 一致性模型 | 强一致性(Cache Coherency) | 弱一致性或无需一致性,依赖同步指令 |
| 典型带宽瓶颈 | 内存带宽(DDR) | 内部总线带宽 + DDR带宽 |
你看这个表格,最核心的区别在哪?
CPU的Cache是硬件帮你管的,你写C代码时根本不用操心数据在L1还是L2。但NPU不一样,它的片上SRAM需要你手动管理——什么时候从DDR搬数据进来,什么时候把计算结果写回去,都得你说了算。
关键认知:NPU的内存管理,本质上是数据流编排。你不是在写程序,你是在设计一条数据搬运的流水线。
我记得第一次在NPU上跑YOLOv5s,直接套用CPU上的数据加载方式,结果推理延迟比预期高了3倍。查了半天,发现是数据在DDR和SRAM之间来回倒腾,带宽全浪费在无效搬运上了。
1.2 NPU内部SRAM与外部DDR的分工
好,咱们具体看看NPU的内存层次。一个典型的NPU芯片,内存系统大致分两层:
- 内部SRAM(片上存储):容量小(几MB到几十MB),但带宽极高,延迟极低。它直接连在计算阵列旁边,是真正用来做计算的数据存放地。
- 外部DDR(片外存储):容量大(几GB到几十GB),但带宽相对有限,延迟高。模型权重、输入图像、中间结果的大头,都放在这里。
这两者的分工,我习惯用一个比喻:
SRAM是工作台,DDR是仓库。你干活时,只把当前要用的工具和材料放在工作台上,用完就放回仓库,再拿下一批。工作台就这么大,你得精打细算。
我的经验:YOLO推理时,权重参数通常常驻SRAM(如果放得下),而输入图像和每一层的特征图,需要按需搬运。我曾经在一个只有2MB SRAM的NPU上跑YOLOv8n,不得不把模型切成多个片段,逐段加载权重——这就是典型的“工作台太小,得分批干活”。
具体到YOLO的推理流程,数据流动大概是这样的:
- 输入阶段:图像从DDR加载到SRAM,做预处理(Resize、归一化)。
- 计算阶段:每一层卷积/池化/激活,都在SRAM中完成。权重和输入特征图必须在SRAM中准备好。
- 输出阶段:每一层的计算结果,要么留在SRAM给下一层用,要么写回DDR(如果SRAM不够)。
- 后处理阶段:最终的检测结果(边界框、类别)从DDR读回CPU或NPU,做NMS等操作。
这里面有个关键问题:什么时候该把中间结果写回DDR?
我见过不少新手,为了省事,每层计算完都把特征图写回DDR,下一层再读进来。这样做,推理速度直接腰斩。正确的做法是:尽量让数据在SRAM里多待几层,减少DDR访问次数。
1.3 内存带宽对YOLO推理的影响
内存带宽,是NPU推理中最容易被忽视的瓶颈。你算力再强,数据喂不进去,白搭。
咱们来算一笔账。以YOLOv8s为例:
- 模型大小:约22MB(FP16权重)
- 输入图像:640×640×3 = 约1.2MB
- 每层特征图:从几KB到几MB不等
- 一次完整推理:需要读取权重 + 读写特征图,总数据量通常在100MB~200MB
假设你的NPU内存带宽是20GB/s(这个数字在边缘NPU里算不错了),那么光数据搬运的时间就是:
搬运时间 = 总数据量 / 带宽
= 150MB / 20GB/s
= 7.5ms
如果计算本身只需要5ms,那总延迟就是12.5ms,其中60%的时间花在搬数据上。你说带宽重不重要?
注意:上面的计算是理想情况。实际中,DDR访问有延迟、总线有竞争、SRAM有容量限制,真实搬运时间只会更长。我曾经在一个项目里,因为DDR带宽被其他任务抢占,YOLO推理延迟从15ms飙升到40ms——排查了整整两天才找到原因。
那么,怎么缓解带宽压力?我总结了几条实战经验:
- 权重压缩:用INT8量化,权重体积直接减半,带宽需求也减半。
- 数据复用:让同一个数据在SRAM里被多次使用,避免重复从DDR读取。
- 流水线重叠:计算和DMA搬运并行进行,用计算时间掩盖搬运时间。
- 张量融合:把多个小算子合并成一个大算子,减少中间结果的DDR读写。
这些策略,咱们后面的章节会一个一个展开讲。今天先有个概念。
1.4 NPU内存架构全景图
说了这么多,咱们用一张图把整个架构串起来。下面这张SVG图,画的是NPU推理时的内存层次和数据流。
这张图把咱们刚才讲的内容都串起来了。你看,数据从DDR出发,经过DMA搬运到SRAM,然后在SRAM里完成多层计算,最后结果写回DDR。整个过程中,SRAM是核心战场,DDR是后勤基地。
本章核心要点:
- NPU内存管理是数据流编排,不是传统编程
- SRAM是工作台,DDR是仓库,分工明确
- 带宽是硬约束,量化、复用、流水线是三大法宝
- YOLO推理的延迟,一半以上可能花在数据搬运上
嗯,第一章就到这里。内容不多,但都是基础。后面的章节,咱们会基于这个架构,一步步深入YOLO的内存优化技巧。你先把这张图印在脑子里,后面学起来会轻松很多。