AI SoC设计复盘:NPU、存储与互联的架构平衡之道

AI SoC设计复盘:NPU、存储与互联的架构平衡之道 我不是那种喜欢整天聊架构理念的人但做AI SoC这件事必须从架构理念聊起。过去几年我带团队完整走通了一颗面向边缘推理场景的AI SoC从需求定义、micro-architecture评审、RTL freeze到流片回来bring-up、跑通ResNet和LLM解码整个过程踩过的坑比想象中多。最深的体会是很多人看AI芯片只看NPU的TOPS数字真正决定一颗芯片好不好用的往往是存储子系统和互联结构。NPU算力是矛存储带宽是盾互联是粘合剂三者没配合好纸面算力再高也打不出实际性能。这篇内容算是我对整颗芯片设计过程的一次复盘核心围绕三个关键词展开NPU、存储、互联。如果你正准备投入AI SoC设计或者正在选型、评估别人的AI芯片方案希望能帮你在纷繁的技术名词里抓住一条主线。1. 先把“给谁用”想清楚一颗推理SoC的架构起点1.1 应用场景决定算力目标而不是反过来很多团队一上来就说“我们要做100 TOPS的芯片”这句话本身就值得追问100 TOPS是INT8还是INT4是稠密算力还是稀疏算力持续跑能稳在多少瓦给哪类模型用的一颗面向边缘推理的SoC和一颗面向数据中心训练的SoC设计逻辑完全是两回事。数据中心芯片功耗预算宽松可以堆HBM、堆互联带宽、堆功耗墙反正机房散热和供电条件好。边缘推理芯片则完全不同功耗板级可能只有5W到30W内存只能用LPDDR或者干脆靠片上SRAM扛散热条件有限还要考虑成本和量产良率。我的习惯是先做一套工作负载分析表把目标模型、分辨率、帧率、精度、内存占用全部列出来。比如要做4000x3000输入的YOLOv5s检测目标30FPSINT8精度那GFLOPs一目了然再折算成所需TOPS。这背后有几个效率系数要留足我第一次估算时就栽过跟头实际MAC利用率很难到100%一般按60%到80%规划预处理如Resize、Normalize、Color Space转换通常也要占用一部分算力后处理如NMS有时在CPU或专用硬件上做但数据搬运会产生带宽压力。所以真正要规划的算力是“理论TOPS乘以1.5到2”的裕量。这个裕量不是拍脑袋而是给算法模型迭代留空间因为产品上市后跑的新网络往往比立项时调研的更重。1.2 从系统视角做SoC架构选型算力需求确定后就要做SoC级架构选型。这里最核心的决策点是CPU、NPU、ISP、视频编解码器、DSP这些部件怎么组合。AI SoC里CPU通常是“大脑”做调度和通用计算NPU做重活ISP和编解码器为视觉应用服务。CPU架构上Arm和RISC-V是两大选择很多边缘AI SoC以Arm Cortex-A系列搭配自研NPU。另一个关键决策是系统一致性coherency。如果NPU要频繁和CPU共享数据就必须考虑硬件一致性缓存否则就需要软件手动做cache flush和invalidate性能损失特别大。这里推荐的做法是一开始就定义好哪些内存区域是不可缓存的device memory哪些是normal cacheable内存走ACE或CHI协议做一致性NPU的DMA是否经过SMMU/IOMMU。把这些定清楚后面软件栈会少掉一大半麻烦。很多团队一开始只想把RTL跑通等到软件联调时才发现共享数据的同步机制没做被迫在驱动里加一堆cache操作性能稀碎。2. NPU微架构算力到底从哪来2.1 MAC阵列规模与脉动阵列设计NPU的核心是MAC阵列。所谓MAC就是乘累加单元一次完成“乘法和加法”两个操作。业界习惯用“MACs”表示一个乘加操作而TOPS里的“OPS”通常把它当两次操作算所以1 TOPS INT8约等于每秒完成500G个MAC操作。选择MAC阵列的大小时有个平衡阵列太大利用率上不去很多小模型算不满阵列太小算力上限受限。以1GHz主频、INT8精度为例一个16x16的脉动阵列理论算力只有0.5 TOPS也就是256个MAC x 2 Ops x 1GHz。想要20 TOPS你得有20480个MAC阵列可以排成32x64或者64x32的形态。阵列形态直接决定数据流模式。老生常谈的三种数据流权重固定Weight Stationary权重复用最好适合卷积核较小的网络输入固定Input Stationary输入特征图复用适合输入通道数大的层输出固定Output Stationary累加器贴近PE减少中间累加值搬移对精度友好。实际做的时候单一数据流往往不够用。我见过比较成功的做法是MAC阵列支持可重构在卷积层切到权重固定或输出固定在全连接层和Transformer的矩阵乘里切到输入固定。但可重构带来的选择器、数据广播网络面积开销不小是否值得要拿典型模型去跑一遍看总体利用率。为了这个评估我们团队专门写过一个cycle approximate的模拟器比上位机跑TensorRT估算准确得多。2.2 片上管线从Activation到Pooling都自己做NPU和CPU的GEMV差别在于NPU要把一整条计算链在片内闭环。我的设计里MAC阵列后面接了激活函数单元、Pooling单元、以及可选的Eltwise单元。这些单元看起来小但对性能影响很大。拿ReLU来说如果激活在MAC阵列外做就得把特征图搬进搬出一次全连接层推理要产生几十兆字节的中间数据如果在MAC内部做融合这些搬运全省了。所以现代NPU普遍支持“算子融合”架构上叫Fused Pipeline。常见融合模式是卷积 - BatchNorm折叠 - ReLU - Pooling或者全连接 - LayerNorm - GeLU。LayerNorm和GeLU在Transformer推理中尤其重要GeLU的误差函数计算如果做成查找表精度和面积要权衡如果直接软件在CPU算又会产生同步点。我建议至少把LayerNorm的均值方差统计和归一化用硬件单元做否则LLM解码时KV Cache一长CPU根本忙不过来。2.3 量化和稀疏INT8是门槛INT4是趋势稀疏要谨慎推理SoC的NPU现在不做INT8量化基本说不过去因为编译器只要把模型里的权重和激活从FP32映射到INT8带宽和算力需求立即降到四分之一。这里有个关键点量化不是简单截断要做校准。很多团队在Calibration数据集上偷懒结果模型到硬件上精度崩了。我自己总结的量化落地顺序先做per-tensor量化模型简单时够用精度不够改per-channel尤其权重按输出通道分别给scale基本能覆盖大多数CNNTransformer类模型对激活值敏感激活建议per-token量化并做clip值搜索KV Cache量化要特别小心它直接影响文本生成的连贯性8bit起步4bit要有针对性校准。稀疏化则是把双刃剑。结构化2:4稀疏可以省一半权重存储和计算但需要权重排列器和零检测逻辑。对于边缘推理SoC如果主要跑小模型稀疏化带来的收益可能被额外的index编码开销抵消所以我们在第一版芯片里直接砍掉了对稀疏的硬件支持只保留了软件层面的剪枝让编译器跳过零块而不是在电路级别动态跳过单个零值。3. 存储层次设计带宽就是生命线3.1 片上SRAM怎么分才合理NPU计算速度再快数据喂不进来也白搭。片上SRAM是离MAC阵列最近的粮仓划分是否合理直接决定实际算力。常见划分包括输入特征图缓存Input Buffer权重缓存Weight Buffer累加器存储Accumulator SRAM输出的暂存和重排Buffer。我前面那颗芯片总片上SRAM做到12MB分配比例不是拍脑袋定的是靠性能模型反复迭代出来的。初始分配是8MB输入、2MB权重、2MB累加器后来跑Transformer时发现权重读取成了瓶颈原因是LLM的权重复用率低每次解码都要把全部权重从DDR拉进来。最后调整为5MB输入、5MB权重、2MB累加器LLM解码吞吐提升了接近20%。一个容易被忽略的指标是SRAM到MAC阵列的内部带宽。如果MAC阵列每个周期要读256个权重和256个输入那就需要512 Byte/Cycle的内部带宽。在1GHz下就是512GB/s。这个数字必须靠足够宽的数据总线支撑否则MAC阵列大部分时间都在等数据。设计时建议把内部带宽做到峰值算力需求的1.2倍以上别贴着头皮设计。3.2 主存储选型LPDDR、DDR还是HBM推理SoC的主存选型基本就三条路LPDDR、DDR、HBM。LPDDR适合低功耗移动和边缘设备DDR适合性能要求高一点但功耗不那么敏感的产品HBM基本是数据中心推理卡的天下容量大、带宽恐怖但成本和封装难度也恐怖。带宽估算是关键。LPDDR5 6400Mbps64bit单通道理论带宽是6400Mbps x 64 / 8 51.2GB/s。双通道就是102.4GB/s。HBM2e一颗Stack能做到409.6GB/s1024bit 3.2Gbps。当你需要200GB/s级别的带宽时用LPDDR5需要4通道引脚和PCB布线成本立即上来用HBM又太贵。这时候就要回头审视NPU数据复用设计尽量把热点数据留在SRAM里。我总结的一个带宽经验公式假设模型每层推理需要重复读取输入特征图和权重设R是平均数据重用次数那么外部带宽需求约等于“每层数据量 x 层数 / 推理时间 / R”。实际中CNN的R可以做到10到50Transformer解码时因权重一次性载入R接近1所以LLM参数大了以后对带宽极为敏感。这也解释了为什么LLM推理芯片普遍在互联和HBM上花大钱而不只盯着TOPS。3.3 一个算给自己看的带宽实例以我们自己20 TOPS INT8的NPU为例目标跑LLaMA-7B INT8权重约7GB。假设一次推理要完整扫描一遍权重300 tokens/s那权重带宽就是7GB x 300 2100GB/s这个量级LPDDR根本不可能满足HBM2e也吃紧。实际不可能每token全量扫描所以要通过分离KV Cache、权重压缩、投机解码等办法降低权重读取量或者干脆用多颗芯片做张量并行。这类计算应该在架构阶段就反复估算别等芯片回来再发现带宽瓶颈。我当时专门拉了个Excel表把不同模型、不同分辨率、不同batch大小全部列进去每次架构评审都对着这张表拍板。面试别人时我也常拿这个来检验候选人是否真的理解SoC设计。4. 互联结构把CPU、NPU、IO全部串起来4.1 片内总线协议选择AI SoC里同时有CPU cluster、NPU、DMA、PCIe控制器、ISP、编解码器等模块片内互联就是这些模块之间的高速公路。互联协议上Arm生态基本是AXI、ACE、CHI这三个代际。AXI适合简单主从通信ACE在AXI基础上加了缓存一致性信号适合中小规模系统CHI则是为大规模、高带宽、高一致性的SoC准备的可扩展性最好多Cluster缓存一致性、多个IO一致性接口都支持得更好。NPU这个角色比较特殊高性能又频繁访问内存还不像CPU那样主动维护缓存一致性。主流做法是给NPU配一个IO Coherency Port走CHI协议直接接入一致性网络这样NPU从DDR读取的数据如果CPU最近写过系统会帮你做一致性同步。初次实现时这部分最容易出现死锁和性能回退需要额外小心。我推荐在总线仲裁和QoS设置上多做文章比如给NPU的读请求更高的优先级同时限制CPU的burst长度防止CPU持续占据总线。4.2 NoC拓扑Mesh、Ring还是Crossbar片内互联的物理拓扑选择直接影响面积、功耗、布线拥塞和延迟。Crossbar带宽最大但面积随端口数平方增长适合端口少的场景Ring结构面积友好但带宽共享、延迟不确定Mesh网络在chiplet和多die场景更常见每个节点可以局部交换但需要考虑路由延迟和死锁避免。对于12nm、28nm工艺的SoC片内总线频率普遍在1GHz到1.5GHz这时我更倾向用Crossbar或者性能好的NoC配合AXI/CHI协议实现全局地址空间。NoC的好处是它把物理上的总线拓扑抽象成网络包能够用QoS区分不同主设备的带宽和延迟需求。比如NPU数据流需要高带宽低延迟配置成实时Virtual ChannelCPU的调试和上下文加载带宽要求不高放到Best Effort通道。这种“分级服务”在系统繁忙时能明显减少卡顿。4.3 多芯片/多die互联从板级到chiplet单颗SoC算力或带宽不够时就要做多芯片互联。传统做法是PCIe或以太网但延迟高不适合细粒度并行。数据中心和高端推理卡里NVLink、C2C、Infinity Fabric这类的低延迟私有互联已经成了标配。它们本质上是把多个die或芯片通过高速SerDes、甚至光互连接成一张高带宽低延迟网络让软件把多颗芯片看成一个大的加速器。对普通设计团队我建议把“互联”分两层考虑第一层是板级互联选择PCIe Gen5或Gen6、以及一些私有协议第二层是封装级互联走UCIe或自家die-to-die PHY。封装级的好处是延迟低到纳秒量级可以做统一内存。但chiplet在测试、散热、供应链上复杂度高不是所有团队都玩得转。如果团队第一次做我的建议是从板级多卡做起通过软硬件协同设计验证互联协议等技术成熟再考虑chiplet。5. 系统工程化从RTL到bring-up的完整链路5.1 验证与仿真别让“最后一版Bug”拖垮周期AI SoC的验证复杂度逐年上升尤其是NPU、一致性互联、DMA三个模块交界处是Bug高发区。验证环境上现在基本是UVM仿真为主FPGA原型验证为辅。UVM适合验证逻辑功能但跑模型推理太慢跑一个ResNet可能要模拟几小时FPGA原型能把速度提到接近真实频率跑真实模型做端到端验证。我们在项目里分了四个阶段Block level UVM验证只测每个模块协议时序SoC level 仿真用C模型生成激励验证总线读写和中断FPGA原型跑真实模型量化后的二进制验证NPU指令和软件栈流片后bring-up先跑hello world、再跑单层卷积、最后跑完整pipeline。很多团队在第二阶段偷懒直接跳到FPGA结果时序问题和功能问题混在一起排错特别痛苦。我强烈建议在SoC仿真阶段就引入“性能模型对比”把每层算子耗时、带宽占用和功耗数据全部记录下来和架构阶段的性能模型对照偏差超过20%就回头查原因。5.2 软件栈编译器、驱动和运行时缺一不可一颗AI SoC能不能用起来硬件只占一半另一半是软件工具链。NPU和CPU不一样没有现成的通用指令集编译器要把PyTorch/ONNX模型翻译成NPU指令流同时完成算子的调度、内存分配、量化、算子融合。这个编译器的设计和硬件微架构强相关必须在RTL设计阶段就定好指令集架构和内存管理方式。我们的选择是中间表示采用类MLIR的框架前端对接ONNX后端对接自研NPU指令。这样模型编译流程是前端优化算子融合、常量折叠、图剪枝中端优化量化、内存规划、数据布局转换后端优化指令调度、双缓冲、SRAM复用优化。编译器准备的图优化和内存规划直接决定NPU利用率。比如双缓冲如果没做好MAC阵列就会频繁等待DMA搬运数据利用率掉到40%都不奇怪。这块强烈建议在芯片设计早期就养一个软件团队别等流片后再招人否则硬件和软件的磨合期会吃掉整个产品窗口。5.3 常见问题速查表我踩过的一些坑问题现象根本原因解决思路NPU算力很高但吞吐上不去主存带宽不足层间数据搬运成为瓶颈增加片上SRAM容量优化算子融合减少中间数据落DDR多核NPU扩展效率低一致性广播流量太大NoC拥塞给NPU核划分独立地址域降低一致性流量或采用分布式二级缓存模型量化后精度明显掉Calibration数据集与真实数据分布偏差大用真实场景数据做校准逐通道/逐token量化加入KL散度或MSE评估CPU和NPU共享内存数据错乱缓存一致性问题引入SMMU/IOMMU和一致性接口软件层面规范内存属性跑LLM时延迟高权重加载瓶颈KV Cache访问频繁增加权重缓存优化解码调度考虑KV Cache量化或分离存储系统负载高时NPU被饿死总线QoS设置不合理为NPU配置高优先级的Virtual Channel限制低优先级请求这张表里的每一条都是团队在多个项目里花了几周甚至几个月才解决的。尤其前两条很多团队一开始不重视等芯片回来后才发现架构缺陷只能靠软件规避效果差强人意。5.4 关于后续演进的一点个人看法这颗推理SoC做完之后我们的技术路线在往两个方向走一是做chiplet化把NPU die、CPU die、IO die分开用UCIe做互连这样不同工艺节点可以灵活组合比如CPU用成熟工艺、NPU用先进工艺二是把互联延迟进一步压低因为Transformer类模型的逐token生成模式对延迟非常敏感token间延迟每降低一点用户体验提升都很明显。6. 想给后来者分享的几句实在话一颗高性能推理AI SoC远比“NPU核 DDR PCIe”这几个词看起来复杂。设计的关键不是单点性能而是NPU、存储、互联三者的平衡。TOPS再高存储带宽不够MAC阵列一大半时间在空转互联设计不当数据和一致性流量在各个模块之间打架系统整体吞吐就会被拖垮。我个人的体会是做AI SoC更像做系统集成而不是单纯做一块“算得很快”的硅片。最后分享一个小技巧无论做架构设计、微架构评审还是性能调优都建一套“真实的模型 真实的输入 真实的指标”的端到端基线。ResNet-50跑通不算数至少要跑YOLO系列、LLaMA系列、Stable Diffusion这些真实负载。拿这些基线数据说话再复杂的架构争论都能在半小时内得出结论。希望这篇复盘能给你提供一些可在自己项目里直接套用的思路少走些我们走过的弯路。