资讯动态

AI芯片软硬件协同设计:从架构探索到模型部署的实战指南

发布时间:2026/10/13 20:05:32 来源:尧图企业网站定制
这期聊聊AI芯片的软硬件设计确切地说是软硬件“协同”设计这件事。前两篇我们把AI芯片的大格局和基础概念都过了一遍这次进入最核心、也最让工程师头疼的环节一块AI芯片从定义到落地软件和硬件到底是怎么互相拉扯、互相成就的。如果你正在做芯片架构、嵌入式开发、模型部署或者只是在选型阶段想知道“为什么有的芯片工具链好用有的难用得要命”这篇都值得你花十分钟看完。我先抛个结论AI芯片的难点从来不只在硬件本身而在于你设计硬件的时候必须脑子里同时跑着软件栈写软件栈的时候又必须时刻想着硬件能给你什么、不能给你什么。两侧团队如果没有共同语言那这个项目大概率会在流片回来的第一天就陷入混乱。1. 软硬件协同设计为什么AI芯片必须“软硬一起想”1.1 通用计算时代的老办法在AI负载上行不通了过去的CPU设计思路本质上是一种“硬件先定软件适应”的模式。芯片公司把指令集架构定好把微架构做好然后扔给编译器团队和操作系统团队去适配。软件这边能做的优化基本都局限在“如何更好地利用现有硬件资源”的层面比如指令重排、缓存优化、分支预测调整等等。硬件和软件的交互被一个相对稳定的指令集边界切开了大家各管各的日子过得还算和平。但AI负载把这个平衡打破了。神经网络的计算模式非常集中密集的矩阵乘加、大规模的数据搬移、规则或不规则的访存pattern再加上从卷积到注意力再到各种归一化算子的多样化组合如果你还指望用一个通用指令集去硬扛再牛的编译器也救不回来。我见过太多团队最开始用通用CPU去跑Transformer推理优化来优化去延迟还是降不下来瓶颈全在数据搬运和指令开销上。这个时候你就明白了不是你的软件写得不好是硬件根本没有为这种负载形态提供合适的“地形”。1.2 AI负载的三个特征决定了设计思路先看访存密集。神经网络的计算密度和访存密度往往是不平衡的很多算子算力根本跑不满数据从内存搬来搬去的时间反而占了大头。我记得有人统计过某些模型在GPU上推理时真正用于计算的周期可能连30%都不到剩下的时间全在等数据。这意味着架构设计时必须把“数据供给”当成头等大事来考虑。再看算子多样化。早期很多AI芯片押注“把所有东西都做成矩阵乘”确实卷积可以拆成矩阵乘全连接也是矩阵乘但后来的Transformer带来了大量非矩阵类算子比如Softmax、LayerNorm、各类Elementwise操作甚至还有动态形状的算子。芯片设计如果只围着一种计算形态转遇到这些就抓瞎只能靠编译器软磨硬泡地拆解性能和效率都很难看。最后是动态性。模型的输入shape会变推理过程中的张量维度会变有的模型还会根据条件跳过一部分计算。硬件如果把一切都写死软件就没法灵活调度但硬件如果太灵活面积和功耗又受不了。这个“灵活度的灰度”怎么把握就是软硬件协同设计的核心命题。1.3 协同到底在“协同”什么说得直白一点软硬件协同就是双方商定一个“分工契约”然后各自在自己的领域把对方的需求前置考虑。硬件侧需要知道未来要跑什么模型、这些模型的算子频率分布是什么、哪些算子值得做成硬逻辑、哪些留在软件里更划算。软件侧需要知道硬件有几级存储、每个计算单元的吞吐是多少、数据在芯片内部怎么流动、哪些操作开销巨大必须绕开。具体落到四个层面指令集层面要不要为AI算子定制专用指令比如一条指令完成矩阵乘加存储层面片上SRAM的容量和层级怎么设计编译器才能在把数据切块的时候有足够的“操作空间”并行层面多核之间怎么调度、怎么同步runtime才不至于被任务切分折磨死精度层面硬件支持INT8还是INT4量化算法就得跟着走精度损失的账要怎么算。这四条线没有一条可以独立决策。我看到过不少失败案例本质都是硬件团队拍脑袋把架构定了软件团队拿到规格文档才发现这个设计根本没法写编译器。等到芯片回来一切推倒重来或者疯狂打补丁才是最痛的。2. 硬件视角AI芯片的关键架构决策2.1 计算单元从SIMD到脉动阵列各有各的账AI芯片的计算单元主流路线无外乎三大类第一种是经典的SIMD单指令多数据路线很多GPU的CUDA Core和端侧NPU的向量单元都沿用这个思路一条指令控制一堆处理单元做同样的运算灵活性好适合各类不同形状的算子但指令开销和调度开销相对较大。第二种是脉动阵列路线Google的TPU是典型代表让数据像流水线一样在一个二维阵列里“流”过每个处理单元把计算完的结果直接传给下一个邻居大大减少了数据搬运但它的形状适配能力有限遇到不规整的计算就有点尴尬。第三种是近两年大热的可重构计算路线把阵列的互联和计算模式变成可配置的芯片上电后软件可以根据模型结构去“画”一条适合当前计算的数据通路。选哪条路线本质上是在灵活性和效率之间做取舍。我做过一次很直观的测试同一个卷积层在脉动阵列上跑得非常快但换成一个动态shape的卷积流水线根本没法建立起来性能瞬间掉到和通用处理器差不多的水平。所以当你看到隔壁团队宣称他们的AI芯片算力有多高时一定要问一句在什么shape、什么模型上测出来的。抛开模型谈算力基本都是在耍牛忙。2.2 存储体系SRAM、HBM与“数据搬运才是大头”芯片设计界流传一句话算力是拿来算的但能耗和时延是花在搬数据上的。一个MAC操作可能只需要0.2皮焦但从DRAM搬一个数据能耗可能是它的上百倍。所以AI芯片的存储体系设计目标就一条让最常被用到的数据尽量留在离计算单元最近的地方也就是片上SRAM。片上SRAM有多大直接决定了软件编译器能把模型切成多大的块来做数据复用。举个例子假设你要在端侧跑一个7B参数的LLM光权重就是约7GB哪怕量化到INT8还是要约7GB。如果芯片只有几MB的片上SRAM那就意味着每一轮推理都要把权重从DRAM里搬进来搬出去带宽立刻变成天花板。这也是为什么新的AI芯片都开始上HBM或超大带宽LPDDR的原因——不是算力不够是喂不饱。但SRAM不是越大越好它会占面积、增加功耗还会拉长物理布局的走线。一个64MB的SRAM块和计算阵列之间的布线距离就可能让时钟频率上不去。所以你会看到很多芯片的设计选择“多级存储”L1给每个计算核私有L2做多核共享再往下挂DDR或者HBM。软件要做的就是把数据按热度层层放好让最热的权重留在最内层。2.3 NoC、启动和外围容易被低估的“水电煤”计算单元和存储是舞台上的主角但真正决定一块芯片好不好用的往往是那些“水电煤”性质的部分。片上网络NoC承担了数据搬运的任务设计不好多核之间一通信就堵死。缓存一致性也是大坑CPU和NPU共享内存时如果一致性协议处理得粗糙你会发现CPU改了数据NPU读到的还是旧值排查起来极其痛苦。另外两块容易被外行忽略的是启动流程和供电/时钟稳定。SoC从上电到NPU能跑模型中间要经过Boot ROM、启动固件、驱动加载、时钟使能等一系列环节。很多硬件工程师把看门狗当个摆设等芯片偶发跑飞了才发现没有看门狗拉一把系统就死那儿了。电源芯片的选型也一样我曾经遇到过NPU跑满负载时电压跌落超过5%导致计算单元偶发出错表现就是模型推理结果时不时跳变排查了三天才定位到电源动态响应不够快的问题。设计看门狗、电源、时钟这些“外围”和设计核心计算阵列一样需要投入甚至更需要。3. 软件视角把模型“翻译”给硬件听3.1 一条完整的软件栈每一层都是“翻译官”AI芯片的软件栈本质上是一条流水线负责把高层级框架里的模型变成硬件能执行的指令。最上面是前端工具读入PyTorch导出的ONNX或者直接对接框架的IR中间表示然后是图优化层把计算图做融合、消除冗余、重排算子顺序再往下是算子调度与指令生成把优化后的图映射到芯片的计算单元上切块、排流水、分配存储再往下是Runtime和驱动负责运行时资源管理、内存管理、任务提交最底下才是真正的硬件执行。每一层之间都有大量的“翻译损耗”如果任何一层做得粗糙前面所有层的努力都会打水漂。我见过最典型的例子某芯片公司号称支持Pytorch模型直接部署但实际转换流程极其繁琐一个模型转下来要手动改十几处不支持的操作遇到不支持的算子就直接报错。这个体验跟写代码时编译器报错不一样——编译器报错你知道怎么修算子不支持你只能改模型结构这是伤筋动骨的事。3.2 算子融合不只是少几次函数调用很多人以为算子融合就是把几个操作合并到一起省几次函数调用开销实际上收益要大得多。拿最经典的ConvBNReLU来说不融合的时候每一层都会把中间结果写回DRAM下一层再读出来这中间的读写成本远高于计算本身。融合之后中间结果留在片上寄存器和SRAM里直接完成下一层操作可能一个算子链的整体耗时能砍掉一半甚至更多。但融合不是随便合的它要求你对硬件的数据生命周期有精准的理解。比如融合点的选择要依赖硬件片上存储能容纳多大的中间结果如果中间结果太大硬塞进SRAM里反而会把后续计算的数据挤出去得不偿失。我习惯的排查方式是先在profile工具里看每一层的“数据写出/读入”量把访存开销最大的几个层挑出来优先融合效果立竿见影。3.3 量化把模型压到硬件能跑的状态AI芯片对INT8的偏爱本质是赌“低精度带来的效率增益能覆盖精度损失”。INT8的乘加器面积大概是FP16的四分之一能耗也更低同一块芯片塞下的计算单元数量可以翻倍。但量化不是直接把float数据截断成int就完事了至少你要做对称或非对称量化考虑zero-point和scale的选择还要决定是per-tensor还是per-channel的粒度。我做过一个分类模型训练后直接做PTQ训练后量化准确率掉了2.4%看起来不多但部署后发现在某些特定类别上错误率飙升。后来改用校准数据集重新跑量化调整了scale的分布准确率追回到只掉0.6%。这个经验告诉我量化校准数据的选取比想象中重要它必须覆盖模型在真实场景里会遇到的分布不能用一堆同类图片去校准。另外如果精度实在压不回来就得考虑QAT量化感知训练让模型在训练阶段就“适应”低精度的噪声工程量和效果通常都是可控的。4. 从设计到流片一个AI芯片项目的真实推进路径4.1 架构探索性能模型和RTL仿真怎么配合芯片项目立项后第一步是做架构探索确定各种微架构参数。这里的常识是先不要急着写RTL而是建一个performance model性能模型用高抽象的C或Python描述芯片的关键参数有几个核心、每个核心几个MAC、片上SRAM多大、内存带宽多少、NoC拓扑什么样。然后拿目标模型在这个模型上跑trace估算吞吐率和瓶颈。性能模型的好处是迭代快改一个参数几秒钟就能出结果方便做设计空间探索。但它模拟的精度有限一般只能做到“趋势正确”精确到周期开销就得靠RTL仿真。靠谱的做法是两者配合先用性能模型筛掉明显不行的方案再把候选方案落到RTL做cycle级精确仿真验证时钟、握手、存储冲突这些细节。我见过不少团队跳过性能模型直接写RTL结果参数一改就要改一大片代码等发现架构性缺陷时已经是几百万行代码的返工这种教训真的非常值得记下。4.2 芯片回来之前怎么验证软件栈很多软件工程师有个心理误区觉得要等芯片流片回来了才能开始写和调软件这完全错了。软硬件协同开发的精髓在于软件栈的开发和硬件验证是并行的靠的是FPGA原型平台、虚拟原型和指令集仿真器。FPGA原型是把RTL综合后跑到FPGA上频率可能只有真实芯片的十分之一但能跑真实的模型、真实的工具链。虚拟原型更灵活本质是一个用软件模拟硬件行为的模型schema脚本配好之后能在几分钟内启动一个虚拟SoC让驱动和runtime在上面跑起来。指令集仿真器则是纯粹逐条模拟指令的软件最慢但最容易调试。我实际项目中最常用的组合是工具链和编译器的早期开发跑在指令集仿真器上驱动和系统软件跑在虚拟原型上然后FPGA原型验证整个软硬件栈的集成。曾经有一次编译器在虚拟原型上跑一个模型是好的到了FPGA上就开始出奇怪的问题最后定位到是NoC上某个路由器的仲裁逻辑在特定访问模式下出现了死锁。如果没有FPGA这层验证这种问题就要等真芯片回来才暴露损失会大得多。4.3 芯片回来后Bring-up流程的第一天要做什么芯片回片后的Bring-up整个团队的紧张程度堪比发射卫星。我建议的流程是先验证最基本的电源和时钟不要一上来就跑复杂程序然后通过JTAG或串口访问内部寄存器确认CPU核能正常读写接着启动Boot ROM加载固件点亮一个LED或者打印一行串口日志就算阶段性胜利再之后才是让NPU跑第一个“冒烟测试”——通常是一个简单的向量加法或者单层卷积。冒烟测试的设计原则是“最最小化”不要跑任何复杂模型因为它一旦失败你根本不知道是硬件问题、驱动问题还是工具链问题。等冒烟测试通过后再逐步增加复杂度跑小型网络、中等网络、真实模型。这个阶段最容易暴露的是缓存一致性问题、内存映射错误、以及中断处理逻辑的缺陷。系统性测试矩阵也要在这时候建立起来从模块级到系统级层层递进记录每一次测试的环境、输入、输出和结论。5. 实操场记在一块带NPU的开发板上部署模型5.1 选板子、搭环境前期准备决定后期体验理论讲完来点实际的。这几年带NPU的开发板越来越多选型的时候我有一个三原则一看工具链社区活跃度二看NPU算力和带宽是否匹配你的模型规模三看开发文档里有没有“踩坑指南”。选好板子之后先把官方提供的Hello World跑通不要急着部署自己的模型。这一步的意义是验证环境本身没问题把交叉编译工具链、驱动、runtime、连接板子的流程走一遍。很多新人一上来就转换大模型失败了一堆报错结果最后发现只是驱动没加载好太浪费情绪了。5.2 模型转换和量化从PyTorch到芯片指令典型的部署流程大概是四步导出从PyTorch导出ONNX→ 转换用厂商提供的工具链转成芯片的模型格式→ 量化用校准集做精度换算→ 验证在板子上跑测试样例对比输出和原始模型的误差。转换这一步最容易出问题的是算子映射。官方工具链通常提供一张“支持算子清单”你看到清单的长度就知道这个芯片的软件生态有多成熟。遇到不支持的算子我的建议是优先绕开比如把一个复杂算子拆成几个简单算子的组合或者把某些计算放到CPU上执行NPU只跑重计算部分。用量化校准的时候务必用真实业务数据不要用一张通用图片集走天下不同业务场景的分布差异巨大用错校准集测试时精度挺好看上线就翻车。5.3 性能调优我常用的五个旋钮模型跑通之后就该调性能了。第一个旋钮是多核调度看看runtime有没有把所有NPU核心都用上有些工具链默认只跑单核配置一个环境变量就能满血。第二个旋钮是内存复用模型中间张量如果能在SRAM里复用缓冲减少在DDR上的分配和释放速度会明显提升。第三个旋钮是算子替换把慢的算子换成等价但更快的实现比如某些激活函数可以融合到前面或后面的算子中。第四个旋钮是动态形状处理很多推理框架会把动态shape当成静态shape来处理遇到多batch或者变长输入就会浪费算力。第五个旋钮是功耗模式很多开发板默认跑保守功耗档位改成高性能模式后NPU频率能明显提升但要注意散热。调优做完我习惯做一个“性能基线记录表”把模型名、输入尺寸、芯片频率、单次推理耗时、内存占用、功耗全部记下来。这个表不仅便于自己复盘也是跟其他团队协作时最有说服力的沟通工具。6. 常见问题排查与避坑速查6.1 算子不支持、转换报错这是部署时最高频的问题报错通常长这样“Unsupported operator: aten::group_norm”。遇到它第一反应不是补算子实现而是先查工具的samples和issues库大概率已经有人踩过坑。如果确实需要自己补可以分两步先看这个算子能不能拆解成多个支持算子的组合不能的话再看runtime支不支持插桩自定义算子。我建议尽量避免自研算子实现一旦你维护自己的算子库后续工具链升级很可能就会把你的补丁冲掉升级信心直接归零。6.2 精度下降精度问题排查有个固定套路。第一步把量化关掉用FP32跑一遍看误差是否还存在如果存在说明问题在算子映射或图优化阶段比如某个融合逻辑算错了。如果FP32正常第二步就是在量化参数上找问题检查scale和zero-point的数值是否异常、校准集是否覆盖真实分布。我遇到过最诡异的一次是模型里某个clip操作在低比特下把极小值截断成了0导致后续计算全部偏移最后是换了一个非线性激活函数才解决。6.3 性能不达标性能不达标通常有两个解释要么瓶颈在带宽要么瓶颈在算子本身。你先看一眼profile报告如果NPU利用率很低而内存吞吐已经贴着理论峰值那就是数据搬移的问题优化方向是多做数据复用和融合。如果带宽没跑满但算力也没跑满那就看看是不是算子被切得太碎调度开销太大或者有什么同步等待在拖后腿。6.4 系统不稳定、随机死机随机死机最怕的是“偶发”一旦出现先不要怀疑软件逻辑先看硬件层面的基础指标。排查顺序我建议是电源电压是否稳定、时钟信号是否有毛刺、看门狗是否被正确地喂狗、DDR训练参数是否正确、NoC有没有死锁。把这些硬件层面的因素逐一排除后再回头看软件当中是否有越界访问或者驱动竞态。多用日志和计数器记录现场别靠猜。下面这张表是我在多个项目里沉淀下来的排查速查直接照抄就行现象可能原因排查手段推荐解法转换报错算子不支持查看工具链支持算子清单拆解算子或换等价实现精度下降量化校准不当关闭量化对比FP32重新采集校准集或改用QATNPU利用率低数据搬运瓶颈查看profile带宽数据算子融合、增加数据复用推理结果偶发错误电源不稳/时序违规示波器量电源纹波优化电源供电、升压补偿系统随机死机看门狗失效/驱动竞态开看门狗日志修正喂狗机制或驱动锁7. AI芯片软件生态的新变量AI Agent与AI辅助开发7.1 端侧AI Agent给芯片出了新难题这两年AI Agent的热度飙升它对芯片软硬件设计的影响正在从“可选项”变成“必答题”。端侧AI Agent的特点是输入不再是单张图片或一段短文本而可能是多模态的、长上下文、且需要连续多轮交互。这意味着模型推理会从“单次短任务”变成“长时间多轮任务”对芯片的内存容量、带宽上限、功耗控制和多任务的并发调度都提出了新要求。多AI协作也是一个很有意思的方向。以后端侧场景可能会同时跑好几个模型——一个用于语音识别、一个用于视觉、一个负责决策和工具调用——这些模型同时存在、分时或并行执行。这对硬件的多核调度能力、模型间的内存隔离、以及runtime的优先级管理都是很大的考验。做软硬件设计的时候如果还只盯着跑单个模型去优化将来在真实的Agent场景里很可能就会“水土不服”。7.2 用AI辅助芯片设计本身提效但要留个心眼最后聊个行业内正在发生的趋势用AI来辅助芯片设计和软件开发。现在有团队在尝试用大模型生成Verilog代码辅助RTL设计用AI写编译器和runtime的单元测试用AI去读spec生成寄存器描述等。从我试用下来的感受看AI在代码生成和文档梳理上的效率提升是实打实的特别是那些“模式化”的胶水代码和测试用例AI写得又快又整齐。但我也要泼一盆冷水AI生成的代码务必当它是一个“需要严格review的结对编程对象”而不是直接信任的输出。芯片设计和底层软件的特点是容错率极低一个位错误可能让整个系统崩溃一个时序问题可能在特定工作负载下才暴露。AI生成的代码可能在语法上完美无瑕逻辑上却蕴含深层的理解偏差。我给自己定的规矩是AI生成的代码必须配合形式化验证或者架构级测试用例才能在项目里使用。辅助归辅助责任始终在人。如果顺着这个思路往下走AI芯片的软硬件设计会越来越依赖“人AI”的协作模式硬件架构师用AI探索设计空间软件工程师用AI生成和验证工具链而最终的关键决策和风险判断仍然需要人类工程师来拍板。这也是我个人觉得这个行业未来几年最有意思的部分——工具在变强但人的判断力反而更加值钱。

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

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

免费获取报价 →
↑