AI芯片软硬件协同设计:从计算阵列到编译器与量化的全链路解析

📅 发布时间:2026/10/13 21:20:37
AI芯片软硬件协同设计:从计算阵列到编译器与量化的全链路解析
做过几块AI加速芯片后再回头看这个领域我最真实的感受是AI芯片的难点从来不在某个单一模块而是在软硬件之间那道看不见的接口。芯片公司里最热闹的会不是算法会也不是版图会而是编译器团队和硬件架构团队吵调度策略的会。硬件拍板用怎样的计算阵列软件就得在上面“跳舞”软件希望拥有怎样的灵活性硬件就得预留对应的控制通路。这套互相迁就、互相约束的设计过程就是所谓的“AI芯片软硬件设计”。做AI芯片远不是把一堆乘法器堆在硅片上那么简单。模型在训练框架里是一张计算图到了芯片上却要被拆成一条条微指令、一块块数据搬运任务、一段段流水线节奏。这个拆解过程贯穿了硬件架构、编译器、算子库、量化工具很多项目最终没有达到预期算力往往不是芯片本身跑不快而是软件接不住数据喂不进来。这篇文章我就从自己多年接触AI芯片软硬件设计的经验出发把整个链条里的关键决策、核心原理和实操体会摊开聊聊。适合刚入行的算法工程师、做芯片验证的同学也适合想把模型真正部署到自研芯片上的系统软件工程师。1. AI芯片到底在算些什么先从硬件架构的棋盘说起1.1 通用CPU为什么跑不动大模型很多人第一次接触AI芯片都会有一个疑问现在的CPU不也很快吗主频动不动就是3GHz以上为什么非要做专门的AI芯片。CPU的强项是处理复杂逻辑分支。它依赖乱序执行、分支预测、大缓存这些机制把一条指令拆成很多流水级。但深度学习的核心计算是矩阵乘法和卷积这类计算的规律性特别强没有太多跳转只有大量重复的乘加操作。如果让CPU去做一次大矩阵乘法它要用AVX或者SSE指令一截一截地算把数据从内存搬进寄存器算完再存回去。这套过程里大部分能量和时间都花在了指令分发和数据搬运上真正做乘法的时间占比很低。而AI芯片的思路是换一种计算范式把成千上万个乘加单元排成阵列让数据像流水线一样从阵列中流过每个时钟周期都在执行乘法而不是在等待取指。这种架构被称为数据流架构或脉动阵列架构牺牲了通用性换来了极高的乘加吞吐效率。在架构上做这个取舍是所有AI芯片设计的起点。一旦选了这条路后面的编译器、调度策略、存储层次全都要跟着调整。所以参与AI芯片项目前我建议先想清楚一个问题目标市场主要是跑什么样的模型是Transformer还是CNN是训练还是推理这决定了硬件最基础的计算形态。1.2 从算力公式开始理解AI芯片的三个基本模块随便找一颗AI芯片的数据手册通常会标多少TOPS。TOPS的全称是Tera Operations Per Second指每秒执行多少万亿次运算。算力公式大致可以写成TOPS 处理器数量 × 主频 × 每个周期完成的乘加次数 × 2 / 10^12乘加次数乘以2是因为一次乘加操作通常算作两次操作。比如某颗芯片有1024个乘加单元跑1GHz每个周期做1024次乘加那么它的算力大约是1024 × 1G × 1024 × 2 2.1 TOPS。看起来很简单但真正的设计难点根本不在这。难点在于这些乘加单元要从哪里取数据取来的数据能不能持续供给这些单元。一套AI芯片大体由三个部分组成计算单元阵列、片上存储系统、片上网络互联。计算单元阵列负责乘加片上存储负责放权重和中间结果互联负责把数据从存储送到计算单元。芯片厂商在发布会上喜欢强调第一个部分因为数字好看。但真正决定实际性能的是后面两个部分。我在评估一颗芯片的真实性能时很少只看TOPS数字而是会去看一个指标计算访存比。也就是说运算字节数和访存字节数的比例。假设一个卷积层需要做100次乘加运算每次乘加需要读取2个字节的数据那么计算访存比就是50。如果计算单元跑得太快而数据供给跟不上硬件就会一直在空转。从架构角度说AI芯片设计本质上就是在回答一个问题怎样最高效地把权重和激活值送进计算阵列再把结果送出来。很多设计团队在这里做出了截然不同的选择也决定了后续编译器层的复杂度。1.3 从架构到指令集软硬件的第一道接口硬件有了计算阵列、存储、互联之后软件怎么让这些硬件干具体的活呢。靠的是指令集和控制寄存器。指令集是硬件向软件开放的接口决定了编译器能把计算图“翻译”成什么样的底层指令。常见AI芯片的指令集设计有几种风格。有些是传统的SIMD风格扩展每条指令都要显式指定操作类型、输入地址、输出地址硬件上有足够的自由度编译器也相对好写但控制逻辑复杂功耗高。另一类是数据流风格的指令一条指令发出后数据按照预设的路径在计算阵列中流动硬件可以自动流水单条指令的效果更强但编译器要管好数据的生命周期一旦调度错了跑出来的结果就是乱的。我自己做算子开发时对这些差异体会特别深。SIMD风格的芯片写算子就像写普通程序先load数据再算再store。数据流风格的芯片要组织数据流窗口和乒乓缓冲代码量不大但思考量成倍增长。所以软硬件协同设计的第一课就是定义指令集时一定要让编译器团队参与进来。硬件团队觉得一条指令做更多的事很酷但如果指令太抽象、约束太多编译器根本无法高效地利用它芯片最终可能在真实模型上跑不出标称算力。硬件设计的一个基本准则是留一个足够简单但完备的指令集给软件把复杂的优化放到编译器和算子库层面这样系统迭代才灵活。2. 硬件是棋盘软件是棋手编译器与算子的协同智慧2.1 计算图到硬件指令的中间表示算法工程师眼里的模型是一张由算子节点组成的有向无环图。这张图要被芯片使用处理器需要把它转换成一段可执行的指令序列。这里就涉及AI芯片软件栈最核心的组件编译器。AI编译器一般分为前端和后端。前端负责把训练框架导出的计算图转换成统一的中间表示IR做平台无关的图优化。后端负责把IR映射到具体芯片的指令集上做寄存器分配、内存规划、指令排序等。很多人会忽略一个细节AI芯片编译器里的IR不是一份通常是多层IR。图级别的IR用来做算子融合、冗余消除、常量折叠算子级别的IR用来描述一个算子内部如何分解成循环和切片。层与层之间还有大量的约束比如某个硬件支持的卷积形态只有特定几种编译器要把通用卷积拆成硬件友好的切片这个过程叫算子降级。在真实项目里算子降级往往是最耗时的部分。通用矩阵乘GEMM在不同尺寸下最优的循环分块策略完全不同如果编译器用一套静态规则很容易在某些shape上性能暴跌。所以成熟的AI编译器都会引入自动化调优机制在硬件上做大量微benchmark通过机器学习或穷举搜索找到每个shape下的最优参数形成调优数据库。这是软件侧最能体现“协同”二字的环节硬件提供了哪些支持编译器才能执行哪些调度。2.2 算子映射把一个抽象算子落到具体硬件上算子映射是AI芯片软件栈中最难的技术活之一。单看矩阵乘法标准的实现是三重循环直接把三重循环映射到硬件上有三种可选的循环顺序i-j-k、i-k-j、k-i-j。不同的顺序决定了数据的重用方式。以卷积为例硬件计算阵列是一张二维网格。要把一个3x3的卷积映射到计算阵列上至少要决定一个问题把卷积核的9个权重放到哪些处理单元上把输入图像的一小块窗口放到哪些处理单元上。如果处理单元间的数据传递是固定的脉冲阵列那么每个单元需要固定持有某个权重系数数据沿着阵列流向相邻单元每个周期完成一次乘累加。这种硬件结构特别适合卷积但到了Transformer的自注意力计算因为矩阵尺寸不稳定脉冲阵列的优势就不那么明显了反而需要更灵活的权重调度能力。我参与过的某个模拟项目就是典型的妥协方案硬件阵列支持两种工作模式一种偏脉动风格适合卷积一种偏单指令多数据风格适合矩阵运算。模式切换由控制寄存器决定。这套方案增加了硬件验证工作量但换来了算子开发的便利性因为要部署不同模型时编译器可以选更适合的模式而不必把复杂模型强行压到一种架构上。讲算子映射时还有一个常见的概念叫切块。如果模型很大权重放不进片上存储就必须把矩阵切成小块逐块计算中间结果回写到片外。切得太大放不下切得太小数据搬运开销高。编译器要根据片内容量、数据流方向和带宽限制来寻找最优切分方案这一环节非常依赖硬件提供的缓存大小和DMA能力。2.3 算子融合省掉一次访存就是省掉一大截功耗算子融合是AI编译器里性价比最高的优化手段。最典型的是把卷积、批归一化、激活函数融合成一个算子。在不融合的情况下卷积结果要写回片外DRAM然后批归一化再把它读进来激活函数再重复一遍读写。如果融合成一个算子卷积的每个输出元素算出来之后马上在寄存器或片上SRAM里完成归一化和ReLU直接写出最终结果。一次访存省掉了两三次DRAM访问。DRAM访问有多贵呢。片上SRAM的能效比片外DRAM高差不多一个数量级功耗可以差到几十倍。所以在几乎所有AI芯片评估中DRAM带宽都是最稀缺的资源。编译器、算子库设计师想尽一切办法提高数据复用率本质都是在压缩DRAM访问次数。除了算子融合还有一个高频优化叫大算子分解。比如大矩阵乘法在硬件上算不了要拆成子块。编译器需要安排好外层循环的顺序让A的子块和B的子块尽可能在片上待久一点以服务于多个输出块。这个优化思路跟写高性能CPU程序的循环分块是相通的只不过AI芯片把分块策略固定到了芯片结构里。做算子融合时最容易踩的坑是量化节点的融合。带有量化参数的网络如果融合顺序和量化尺度不对齐数值结果就会和参考实现产生偏差。所以算子融合不是简单地在图上游走合并打印指令还需要维护每个节点对应的数学语义。3. 精度与速度的拉锯战量化与数值格式的协同设计3.1 为什么要量化算力翻倍的秘密AI芯片要想让算力数字好看另一个关键技术是低精度量化。FP32的乘加器面积大、功耗高改成INT8之后同样的硅片面积可以塞下差不多一倍的乘加单元带宽需求还能减少一半以上因此算力数字会好看很多这也直接降低了端侧部署的成本。但量化不是简单地把参数从浮点数强制转成整数。数值分布范围一压缩精度损失马上就会显现。所以软硬件在这里又必须协同硬件提供足够的数值格式支持软件做好量化和训练补偿。目前主流AI芯片都支持多种精度格式FP32、FP16、BF16、INT8、INT4。BF16特别有意思它把FP32的符号位和指数位完整保留只砍掉尾数位所以数值范围能和FP32完全一致在训练场景下基本不需要做稳值处理。这让很多训练卡直接采用了BF16作为主力格式。相比之下FP16的指数范围比FP32小很多过大或过小的数很容易变成Inf或0。做芯片软硬件设计时硬件决定支持哪些精度软件决定在什么条件下使用哪种精度。两者耦合得非常紧。比如硬件只用INT8那么软件做模型部署时的量化策略就非常重要如果硬件支持动态量化和混合精度软件的灵活度就高得多但硬件实现的复杂度也会爆炸。3.2 量化校准与敏感层分析从软件侧提升智慧在推理引擎里做INT8量化通常会经历一个校准过程。先从训练好的FP32模型上跑一批代表性数据统计每一层激活值的分布找到合适的量化阈值。传统的最大绝对值量化实现简单但如果激活分布存在明显长尾就会把大量有效的数值压缩到很小的量化步长里精度损失很大。所以更聪明的做法是采用百分位或相似度评估的校准方法。比如抛弃分布中极少数的最大点以保留中间密集区间的量化精度。这类校准方法需要一套评估工具完成量化后把FP32模型和INT8模型逐层比较输出张量定位误差最大的层然后对这些敏感层特殊处理。要么保持高精度格式要么做混合量化。敏感层分析是量化实践中最有用的一项工作。我在部署项目时习惯先把所有层统一量化测一遍端到端指标再针对误差最高的几个层逐一调整格式。很多时候只需要调整一两层模型指标就能完全恢复到可接受水平而平均精度依然维持INT8。这个流程本身也体现了软硬件设计里“按需提供精度”的思想整个模型并不需要所有层都全精度的算力只要在敏感位置保持更高精度其他位置就可以用低精度换取算力和带宽整体收益很可观。3.3 数值格式与硬件细节的账本不该省的别省如果硬件把量化做到算子内部比如卷积直接支持“输入是INT8、权重是INT4、累加器是INT32”的混合精度计算那软件侧的量化粒度就灵活多了。但这样的硬件支持也意味着卷积内部要增加额外的扩展单元和饱和处理逻辑芯片面积一定上升。这类面积换灵活性的取舍就是软硬件协同设计的常见场景。我遇到过某次规格评审硬件团队想省掉INT32累加器理由是“INT8乘以INT8不会超过INT32”。这是对的但问题在于一个卷积要累加很多次特别是通道数很大的情况。如果累加器只做到INT16中间结果溢出风险极高软件侧就不得不频繁做分段累加和结果合并带来巨大的性能惩罚。最终这个设计被否掉了。这种问题上硬件的每一个“省”最后都会换算成软件层的复杂度和性能损失。定规格之前最好先让编译器团队把他们已经适配的模型都跑一遍找出最差情况的需求再决定硬件资源到底要不要省。4. 从仿真到整机软硬件联合验证的实操路线4.1 硬件仿真环境下的算子性能预验证一颗AI芯片从设计到流片通常要经过很长时间。硬件不可能等流片回来才发现编译器有BUG所以软硬件必须先在仿真环境里联合调试。芯片设计阶段硬件团队会提供周期级仿真器可以跑RTL仿真速度极慢但准确适合做小算子正确性验证。再往上是基于FPGA的原型验证平台把芯片的RTL代码综合到FPGA上运行速度能到几兆赫兹可以跑完整模型的端到端推理是软件栈开发的主力平台。软件团队在FPGA平台上要做的事情和真实部署几乎是完全一致的。先用模型转换工具把算法工程师的模型转成芯片编译器认识的格式再做量化、编译、加载到运行时最后读取硬件的寄存器状态和计算输出。因为我用过太多次这种流程我最大的建议是从项目第一天就把回归测试自动化跑起来不要等版本积累多了再补。等到软件栈体积变大一个算子回归失败很难定位到底是谁改坏的自动化的回归工具能及时把问题暴露在最小范围内。4.2 性能建模为什么TOPS高但效果差是常事性能评估是AI芯片项目最容易起争执的地方。芯片团队会拿峰值算力说事算法团队却抱怨实际部署速度不达标。两个数字对不上是因为中间缺了一层性能模型。性能模型是一种用于估算特定硬件配置和软件映射策略下性能的工具它考虑了计算引擎吞吐量和存储带宽瓶颈。JPEG解码器大家都不陌生它的性能瓶颈往往在于熵编码的顺序依赖。同样AI芯片上就算乘法单元很宽如果数据依赖链太长吞吐也上不去。我在性能评估时通常会做一个分层测算先测计算阵列的峰值吞吐再测包含片上缓冲和互联时的实际吞吐最后测接入DRAM后的端到端吞吐。三层吞吐逐层下降是必然的但下降幅度能揭示系统瓶颈。如果第二层就下降了50%说明片上缓冲的带宽设计不足或者数据分配策略有问题。如果下降主要发生在第三层说明数据调度对片外带宽的利用不够编译器需要优化切块大小。这个分层方法在排查性能问题时价值非常大。另一个关键工具是上板硬件计数器。芯片里一般会埋设若干性能计数器统计每个计算单元的忙碌周期、DMA等待周期、指令停顿周期。软件运行后通过读这些计数来确定计算访存比的具体表现。做软硬件协同设计一定要重视这些计数器设计计数器要覆盖哪些事件、如何关联到某个算子这些在硬件设计阶段就要规划好否则软件上线后会遇到很多困难。4.3 端到端评估选对评价指标芯片好不好最终要看真实模型跑起来的效果。评估矩阵一般包括延迟、吞吐率、功耗、能效比。但不同应用场景对指标权重的要求差别非常大。自动驾驶场景最在意延迟最好是确定性的延迟因为每一帧处理时间必须稳定。云端推荐场景更看吞吐率可能一次推理不在乎多几毫秒但批量并发要顶得住。手机端则最看重能效比同样跑一个模型功耗降低20%意味着能用更多时间去处理其他任务。所以我做发布报告时会刻意把“理想体积模型下的延迟”和“真实模型下的端到端吞吐”放在一起对比而不是只放那张峰值算力表。这样做可以倒逼团队关注软件栈的真实水平避免硬件性能漂亮但用户用不上这种尴尬局面。端到端评估也要搭配合理的模型样例集。样例集不仅要覆盖CNN网络、Transformer网络还要覆盖不同input shape、不同batch size。有些芯片架构对batch size特别敏感单batch跑起来调度成本高batch变大后才展现出优势。只有把这些shape差异纳入回归集软件优化才能有序推进。5. 软硬件协同设计的影响范围与演进方向5.1 云端和边缘的软硬件分工差异AI芯片的部署场景不同软硬件设计思路也有明显差别。云端训练卡追求的是全精度训练、大模型、大batch芯片硬件越通用越好因为在训练过程中模型的张量形状和算子组合千变万化太特化的硬件反而用不上。云端推理卡则偏向于牺牲一点灵活性换取更高的吞吐和更低的功耗因为推理时模型结构和算子集合是相对固定的编译器可以在模型编译阶段把所有优化做足。边缘侧芯片的限制更大功耗有上限存储有上限。边缘芯片上软硬件设计更强调“深度定制”硬件可能只支持少数几类算子软件则必须把模型转换到这几类算子上。为了解决这个问题边缘芯片厂商往往会提供一个模型压缩工具链包括蒸馏、剪枝、量化让模型在进入芯片编译器之前就已经是硬件友好的形态。边缘侧选型还有一个容易忽略的点芯片的通用性决定生命周期。AI算法演进很快今天主流的算子几年后可能就不再是核心如果硬件过于特化芯片很快就会过时。在贴近市场的芯片定义阶段软硬件团队必须一起展望未来几种主流算法对该芯片的适配程度而不是只对着当前跑分最高的一两个模型做优化。5.2 从端侧到云端统一的工具链生态一个成熟的AI芯片产品必须配备一套把用户从训练框架引导到硬件部署的完整工具链。工具链的流畅度直接决定芯片能不能被广泛接受很多功能强大的芯片就是因为工具链难用最终在市场上走得很艰难。我心目中的理想工具链是这样一条流水线导入模型格式转换并做图优化自动量化校准编译生成指令端侧运行时加载并执行。全流程要有清晰的中间日志和调试工具用户在异常发生时能够快速定位是精度问题还是编译失败。最关键的一点是标准化格式。各家芯片如果只支持自己私有格式生态就切割了。社区里主流的做法是先从ONNX、MLIR这类统一中间格式接入模型再做后续操作。哪怕芯片内部有私有指令对外接口保持标准对开发者会友好很多。MLIR这个技术栈尤其值得关注。MLIR允许硬件厂商定义自己的方言和算子语义再通过渐进降级把模型逐步映射到芯片指令。相比传统的一步到位式转换MLIR的多层抽象能保留更多优化信息也让硬件后端开发变得更模块化。5.3 大模型时代给软硬件设计带来的新挑战生成式大模型给AI芯片带来的最大变化不是单纯的算力需求增加而是显存与带宽的需求出现了数量级式提升。大模型权重动辄百亿千亿参数无法完全放进片内推理时每生成一个token就要访问一次全部权重。这颗访存需求直接掀翻了传统卷积芯片的优势框架如果芯片带宽不够哪怕计算阵列很强大整体推理速度依然会被拖垮。应对这个挑战现在主要有几个方向。一个是高带宽存储技术直接在封装内集成存储芯片显著提升带宽另一个是稀疏化设计通过硬件支持结构化稀疏让零权重跳过计算节省带宽。软件方面则大力发展投机推理和键值缓存管理把模型推理时的重复计算进一步压缩。从软硬件协同角度看这个领域最核心的技术方法是算子融合与KV Cache的硬件化。注意力机制的KV缓存非常占资源如果硬件能提供专用的KV缓存管理引擎软件侧的调度开销会大幅降低。这类以硬件结构匹配软件算法的做法正是AI芯片软硬件协同设计在未来的长期方向。我在实际参与AI芯片项目时最深的体会是软硬件协同设计没有终态每一代模型都在推翻前一代的优化依据。程序员和硬件工程师必须长期处在一个互相学习的状态里硬件团队要知道模型在变大软件团队要理解硬件在变快。如果你正准备进入这个方向我的建议是先把一套简单的编译器与模拟器跑通再去做复杂的调度优化。先把流程跑顺性能优化永远是在正确结果之后才有的故事。