资讯动态

AI芯片软硬件协同设计:从算子映射到编译器与多核互联的系统优化

发布时间:2026/10/27 17:20:54 来源:尧图企业网站定制
AI 芯片的软硬件设计从算子映射到系统调优的完整链路做AI芯片这几年我见过最打击人的场景不是流片失败而是芯片造出来、峰值算力标得漂漂亮亮算法团队一跑模型性能连一半都摸不到。明明INT8算力到了上百TOPS实际跑个Transformer却卡在访存上GPU能跑到几十毫秒的延迟自家芯片连人家一半都不到。问题往往不在芯片而在软硬件设计这条链路上的某个环节断了。这篇是“AI芯片软硬件设计”系列的第三篇我会把算法到硬件这条映射链路拆开讲——算子在芯片上怎么落地、编译器在其中扮演什么角色、多核互联如何影响系统性能以及我在真实项目中踩过的坑和排雷经验。适合正在做AI芯片工具链、算子库、部署优化的工程师也适合想搞懂“芯片为什么跑不快”的算法同学。1. 同样一块AI芯片为什么有人能榨出80%算力有人连30%都摸不到很多团队评估芯片只看一个指标峰值算力。但这个数字在真实业务里几乎没有参考价值。同样的芯片有人能做到优异的端到端性能有人做出来的模型延迟惨不忍睹差异不在于芯片本身而在于软硬件设计的协同深度。1.1 一个让我印象深刻的性能压测案例之前有一次帮客户调试一款自研AI加速芯片。同一块芯片、同一个ResNet-50模型客户自己的团队调了一周batch size 32下的吞吐是每秒钟处理850张图。我们接手后没改任何算法只是在编译策略和算子实现上做了调整同样的精度、同样的硬件吞吐翻到了每分钟超过32000张——折算下来是每秒530多张整体提升了接近两倍多。我说这个例子不是为了秀操作而是想说明一个事实芯片的物理能力是固定的能让它发挥多少取决于软件栈。那位客户的团队其实很认真算子库写了指令也调了但有一个根本问题他们一直把“芯片”当成一个独立的硬件来看而没有把“算法—编译器—硬件”当成一个整体来设计。软硬件协同设计说的就是这件事——从算法表达的第一天起硬件架构、数据流方式、存储层级就在影响结果而不是等芯片回来再适配。1.2 软硬件协同设计解决的不只是“加速”而是“利用率”芯片设计里有个概念叫算术利用率MAC Utilization指的是单位时间内实际参与计算的MAC单元比例。峰值算力是“所有MAC全部塞满”的理论值而利用率能到70%就相当不错了。为什么到不了100%因为数据喂不过来。我举个例子你们就明白了。假设一个AI芯片有128x128的MAC阵列运行在1GHz那么每个周期理论上能完成16384次乘加运算每秒就是16.4 TMACs如果是INT8算力就是16.4 TOPS附近。看起来没问题。但要让这16384个MAC同时干活每个周期至少要喂进去对应卷积窗口的输入激活和权重数据。如果其中一部分MAC在等待数据利用率就掉下来了。数据在哪等不是在片外DRAM就是在片上SRAM和计算阵列之间的搬运路上。访存越远等待越久利用率越低。所以软硬件协同设计的第一个目标是让数据尽量在片上自洽循环减少对外部存储的依赖。第二个目标是让计算模式和存储匹配把“算法结构”映射成“数据结构”再把“数据结构”映射成“硬件执行结构”。这三层映射任何一层错位性能都会打折扣。1.3 拆开AI落地链路算法表达、算子实现、指令映射、硬件执行一个神经网络要跑在AI芯片上至少经过四层算法表达层PyTorch、TensorFlow里的Conv、MatMul、LayerNorm是高度抽象的数学描述算子实现层把张量运算拆成循环、矩阵分块、地址偏移等代码逻辑指令映射层通过编译器和手写汇编把算子代码变成芯片能执行的指令序列硬件执行层指令驱动MAC阵列、访存单元、片上网络真正跑起来每层之间都有翻译损耗。算法层一个BatchNorm折叠优化能在指令层减少几十上百次内存访问算子层一个tile size选错能让后端指令多造很多次没必要的SRAM reload指令层一个依赖调度没排好执行层就只能空转等数据。所以你不要问“为什么芯片算力高却跑不快”而是问“这四层之间有没有做过协同优化”。提示评估AI芯片前期先拿一个真实模型跑通全链路再谈选型。只看RTL仿真和峰值算力做决策等拿板子的时候很容易被现实打脸。2. 算子落到芯片上的关键一公里数据流、存储层级与计算阵列的配合现在我们把镜头拉近到芯片内部看单个算子——以卷积为例——到底怎么在硬件上落地。这一层是软硬件设计最硬核的部分也是最容易被软件背景的人忽略的部分。2.1 MAC阵列的三种主流数据流风格权重固定、激活固定、输出固定卷积本质是乘累加但同一个卷积在硬件上可以用不同方式调度数据。学术界和工业界总结下来主要有三种数据流风格区分标准是“哪个数据被固定在计算阵列里不动”。权重固定Weight Stationary权重矩阵加载到MAC阵列的寄存器里然后不断换输入激活、累加输出。DianNao、PaddlePaddle很多加速器用这个风格。好处是卷积的每个输出只算一次、权重复用率极高适合卷积权重相对固定、逐层加载的场景。坏处是对激活值的广播带宽有要求每一层都要重新装载权重权重切换开销也存在。激活固定Input Stationary输入激活被固定在片上多个输出并行计算配不同的权重。这种风格适合深度可分离卷积这类激活复用多的算子但在普通卷积里激活窗口没有那么大收益不明显。输出固定Output Stationary每个PE负责计算某个输出像素的部分和多个PE之间传递权重和激活来做数据复用。英伟达Tensor Core其实更接近这种思路——一个warp的矩阵乘法被切分到不同工位上做累加。输出固定风格的优势是它能保存部分和而不必频繁回写DRAM对于全连接、MatMul这类算子特别友好。你不要问我哪种最好——这取决于你要跑什么模型。这也是软硬件协同设计里最难的部分架构定了、数据流风格定了就等于器件期权的上限定了之后算法只能去适配它。所以架构选型阶段就要把目标负载的算子和统计特性拉出来。2.2 片上带宽才是真正的稀缺资源比算力宝贵得多回到刚才那个128x128 MAC阵列的例子继续算数据账。每个周期16384个MAC完成一次乘累加如果每个数据是INT8每个MAC需要一个权重字节加一个激活字节那就意味着每个周期阵列至少要消耗32KB数据。1GHz下就是32TB/s的带宽。这个数字在当下芯片里有效现实吗片上SRAM通常能做到每周期提供几百byte到几KB级别的带宽注意这是总额。要支撑32TB/s需要超大位宽的片上总线面积和功耗都会爆炸。所以硬件设计者才想尽办法做数据复用卷积里一个权重要被很多输入用一个输入像素也要和很多权重做乘加只要把数据搬一次、用多次等效带宽就大幅下降。这里有一个基本公式性能天花板取决于算力除以算术强度Arithmetic Intensity。算术强度计算量/访存量单位是FLOPs/Byte。如果一个算子的算术强度低于Roofline模型里的拐点那它一定是带宽受限的再快的MAC阵列也只能等着。我在实际项目里见过太多团队盯着峰值算力优化算子最后发现瓶颈全在DRAM带宽。先算清楚你的目标算子是计算受限还是访存受限再决定优化方向能省一半力气。2.3 算子重写硬件适配软件软件也要适配硬件那么算法层程序员能做什么答案是算子重写Operator Rewriting。这个是软硬件协同里最接地气的一环门槛不高但收益直观。举个例子很多人直接拿PyTorch里的nn.Conv2d跑自研芯片发现慢得离谱。问题往往不在卷积本身而在于数据布局。PyTorch默认的NCHW布局下芯片每次想要取出一个通道的连续数据地址很可能正好卡在DRAM burst对齐的边界上导致有效带宽砍半。你要是把数据重排成NHWC或者干脆用通道优先布局访存一下子就顺了。另外还有几个常见操作降低内存粒度计算过程中尽量用tile分块访问SRAM不要动不动全图走DRAM地址对齐把张量的行宽pad成芯片访存单元对齐的字节数算子融合把前面的ReLU融合到卷积里省掉一次中间结果的写回和读取精度包装INT8比FP16在同样的带宽下能多传一倍数据能量粒度也更细这些都不是很深的技巧但每一条都要求你理解硬件是怎么访存和计算的。这就是软硬件协同设计对工程师直接的要求。3. 编译器与工具链软硬件协同的翻译官决定芯片好不好用算子写好了还要有工具把它部署到芯片上。很多芯片团队早期觉得“硬件做好了编译器随便配一个就行”结果产品发布后被吐槽工具链稀烂成了最大的短板。编译器在AI芯片里的角色不是简单的“翻译官”更像一个优化调度器它决定了哪些算子融合在一起、数据在哪个层级停留、计算单元怎么流水。3.1 从计算图到机器码需要经历哪些阶段一个深度学习模型经过工具链时通常要经历这几个阶段我简化一下前端解析把ONNX或自定义格式的计算图读进来做算子的合法性检查与张量形状推断图优化算子融合、常量折叠、公共子表达式消除、删除无用节点物理化/布局转换把逻辑张量映射到具体的存储布局NHWC/NCHW/NC1HWCO等指令生成把算子循环展开成目标芯片支持的指令序列包括DMA搬运、矩阵计算、SIMD向量、同步等待调度与寄存器分配安排指令在硬件流水线上的先后顺序和并行粒度每一步都可能让性能发生数量级变化。比如图优化里的算子融合把ConvBNReLU合成一个算子中间结果不用写回DRAM直接以寄存器/片上SRAM的形式传递这能省掉的访存次数经常是惊人的。实测中ResNet-50里融合几个关键算子之后端到端延迟能提升40%到60%——这在纯硬件层面是不可能出现的提升幅度。3.2 算子融合和内存布局编译器最有价值的两个优化算子融合的原理一句话减少中间张量的物理物化materialization。但融合不是无脑做。有些融合能稳赚有些反而亏。比如ConvReLU的融合几乎总是赚的因为ReLU是逐元素操作不需要改变数据布局。但ConvLayerNorm就要小心LayerNorm需要统计整体均值和方差如果直接把两层融合要么提前缓存全部卷积输出省了访存但占了片上资源要么分块计算但需要多次扫描增加了开销。编译器的取舍实际是工程权衡每类芯片的资源模型不同融合决策也不同。内存布局就更关键了。对卷积来说数据是NCHW还是NHWC或者像寒武纪用过的NC1HWCO这种带子通道的变体直接决定卷积那个循环怎么展开。布局选得好一个卷积可以是用向量指令硬算选不好大量时间花在数据重排transpose和copy上。我见过有的芯片跑一个1x1卷积实际计算时间占比不到15%剩下全在搬数据。出现这种情况八成是布局和硬件访存模型不匹配。注意编译器里如何布局往往不是自动得出的很多时候需要手写“layout transform”或者干脆写一个专用卷积的实现把重排和计算融为一体。3.3 自动调度并非万能手写算子库的价值在哪里现在开源社区非常推崇自动调度TVM、MLIR、Triton这些工具能通过搜索找到性能好的tiling和循环顺序。但我的实际经验是自动调度在“芯片能力比较规整”的GPU上表现很好在一个新架构的自研AI芯片上它经常找不到最优解因为搜索空间和硬件建模不够细。差距的根源在于“代价模型”。编译器判断一条指令好不好需要预测它在硬件上的执行时间。如果硬件行为很复杂——比如有bank冲突、指令发射延迟、DMA搬移重合等——代价模型建模不准确那搜索出来的调度就是纸上谈兵。所以在真实项目里好的做法是两者并行的双轨策略框架自动调度兜底保证95%的模型能跑起来且性能不差核心算子用手写汇编或C intrinsics硬优化把每个周期省下来哪些算子值得手写通常是高频、耗时的那二三十个3x3卷积、大尺寸MatMul、Attention里的QK^T和Softmax、各种LayerNorm。这些算子的共同特点是占用端到端时间比例很高且内部有清晰的并行结构可以手工优化。我甚至会在编译器接受不了的场景下直接绕过编译器“下降”到手工加载权重、手工DMA的方式写推理。这个做法看着粗暴但每轮手写优化都能稳定提升。4. 从单芯片到多核互联系统级软硬件设计不容忽略的环节芯片不止一个核。今天的AI芯片动辄几百个计算核心甚至像Cerebras那种晶圆级芯片。多核系统下性能瓶颈又从“单核有效利用率”变成“多核协同、数据同步、片间通信”这一层软硬件协同设计往往被低估。4.1 多核AI芯片绕不开的带宽墙假设你有64个核心每个核心每秒需要10GB数据那片内总需求就是640GB/s从L2/系统缓存到核的带宽要满足这个量级。如果每个核标配一个局部SRAM那问题就变成数据怎么分布到各个核上以及核间怎么共享中间结果。最经典的操作是“模型并行”或“张量并行”——把一个大层切成多份每个核存一份权重、算一份输出。但切分就会产生通信开销。比如全连接层如果输出要跨核做concat就需要一个NoC上的多路广播或收集操作代价随核数增长。这就是带宽墙核多了计算确实快了但每次通信的体积也成倍增长最后时间反而被通信填满。4.2 Ring、Mesh与NoC互联拓扑的取舍互联拓扑是系统软硬件设计里成本最高的部分之一。简单说三种常见方案吧。Ring互联所有核连成一圈数据接力传。优点是布线简单、成本低缺点是远距离通信的延迟随跳数线性增长不适合数据密集的全局操作。适合低期望值下的简单场景。Mesh互联每个核和上下左右邻居相连2D格子网络。这是半导体工艺友好的选择扩展性好。英伟达的NVSwitch和许多多核AI芯片都用类似设计。Mesh的问题在于要避免“热点”——如果某个核频繁和其他核通信它所在的格子会成为拥挤点。NoC片上网络更一般化的交换/路由网络类似微型的互联网路由器。它能把通信调度的复杂度放到运行时但面积功耗都不低。软硬件协同的视角下NoC更好做负载均衡。实际项目的选择逻辑是如果目标模型精度较高、层间张量大建议Mesh或NoC因为可以支持乱序和动态路由如果目标场景是端侧小模型、权重本身就小Ring就能满足还省成本。4.3 端到端延迟与吞吐指标怎么选做多核系统评估时我常看到一个错误只看总体吞吐throughput忽略单次延迟latency。推理场景往往对延迟敏感——比如视频里每一帧都不能等太久。多核并行通常能拉高吞吐但如果你每层输出都要跨核同步延迟反而会恶化。正确做法是建立系统级性能模型。假设一个操作切到N个核上计算时间减少到T/N但通信时间加上同步开销C那端到端延迟T/NC。当N太大C可能比T/N还大。所以存在一个最优核数不是越多越好。这块用Roofline或者更细的执行时间模型都能算重点是把通信的成本“进模型”。经验不要在测试时只比较算力利用率要直接跑端到端的batch 1延迟和不同batch下的吞吐并记录通信时间的占比。如果通信占比超过30%你的互联设计或数据布局大概率有问题。5. 真实项目中软硬件协同设计的排雷清单最后这部分我结合这些年踩过的坑整理一个排雷清单。每一项都是我实际在项目里遇到过并且花了不少时间才解决的问题。5.1 评估芯片前先评估工具链别被峰值指标迷惑选了芯片之后发现算子支持不全、编译器质量糟糕是迟到的代价。芯片流片前就要确认工具链的支持范围它支持哪些算子支持动态shape吗量化工具可不可用有没有在线编译能力这些能提前从文档和SDK里查出来别拖到板子到手。如果团队可以给工具链提定制需求优先做三件事保证主流模型的计算图能无错编译过即使性能不是最优提供算子的回退fallback路径防止编译器死掉整个流程内置基础性能测试工具方便开发者定位瓶颈5.2 量化精度与性能的权衡没有免费的午餐INT8量化几乎是推理芯片的标配了但量化失败的项目我见了不少。常见问题用per-tensor的scale量化敏感模型导致精度大跌然后团队互相甩锅。其实问题不难解关键在软硬件协同的两个层面算法层做量化感知训练QAT把量化的误差模拟进训练过程硬件层支持per-channel量化或在矩阵乘法部分用混合精度比如用INT8算主体、FP16做累积和残差连接性能收益和精度损失要提前量化。我一般会在项目初期跑一个量化精度测试表同样的模型用FP16、INT8、混合量化跑一遍记录各种指标对比再决定优化方向。5.3 Roofline模型是软硬件协同的通用语言我做评估和优化时最常用的工具不是特别高深的框架而是一张Roofline模型图。横轴是算术强度FLOPs/Byte纵轴是性能硬件的能力体现为一条或多条峰值性能线软件的实际性能在图上就是一个点。点落在横线以下说明是带宽受限优化方向是改布局、压缩、提高复用点贴到横线上说明是计算受限优化方向是增强向量化、改进流水几乎每个算子优化问题都能用Roofline定出方向再落到细节。尤其在做软硬件协同设计时架构师、编译器工程师、算法工程师可以用这张图对齐语言你说你算子慢慢在哪一轴一画便知。拿我们那次ResNet调优来说一开始analyze出来Conv层的点都在带宽线下面——数据搬运瓶颈明显。我们改了数据布局和融合策略点往上移动最后几个算子贴到了计算线上利用率才算正常。没有Roofline引导我不会定位得那么准。5.4 最后一件事性能回归测试要自动化软硬件团队分工总会导致一个问题算法团队改模型结构、编译器团队升级代码、硬件团队微调频率各自都觉得自己的改动“没影响性能”。结果集成到一起整机性能降了20%谁都不认账。性能回归测试一定要自动化并且纳入CI。每次工具链、算子库或驱动更新后同一组模型必须跑一遍基准吞吐和延迟任何一个关键指标掉了5%以上就自动告警。没有这个机制性能劣化会在几周内悄悄累积到你很难定位。这个工作不复杂但能治软硬件协同里的最大顽疾——信息断层。从算子映射到系统级互联再到工具链AI芯片的软硬件设计从来不是某一个角色单独的事。我越来越觉得好的芯片产品是架构师、编译团队、算法团队和系统团队一起“吵”出来的架构师听算法团队说负载需要什么编译器团队告诉架构师哪些微架构特性不现实系统团队在最后集成时兜住所有的性能风险。这条链路很长但每一步都有迹可循、有模型可算、有捷径可走。希望这篇文章能帮你在自己的项目里少走几段弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑