资讯动态

AI芯片软硬件协同设计实战:架构选型、数据流与编译器栈拆解

发布时间:2026/10/13 21:33:03 来源:尧图企业网站定制
1. 为什么AI芯片的软硬件设计值得单独拿出来聊这两年跟不少做芯片和做算法的朋友交流发现一个特别有意思的现象做算法的觉得硬件那帮人不懂模型做硬件的觉得算法那帮人不懂时序。结果就是一颗AI芯片流片回来跑某个模型性能炸裂换个模型直接拉胯。问题出在哪就出在软硬件设计没有从一开始就协同。AI芯片跟传统CPU、GPU最大的区别在于它是为特定计算模式量身定做的。传统芯片追求通用性什么程序都能跑AI芯片追求的是在矩阵乘法、卷积、注意力机制这些特定运算上做到极致的能效比。这就意味着架构设计阶段就得想清楚要支持哪些算子、数据怎么流动、片上存储怎么分配。而这些决策又跟上层框架怎么调度、编译器怎么映射算子强相关。我打算把这篇文章写成一份偏实战的拆解笔记从架构选型、数据流设计、编译器栈、算子映射、验证方法这几个维度把AI芯片软硬件协同设计这件事讲透。适合正在做AI加速器设计的工程师、想了解底层原理的算法同学以及准备进入这个领域的学生参考。不会堆太多公式重点讲清楚每个设计决策背后的为什么。2. 架构选型从计算模式反推硬件结构2.1 先搞清楚你的芯片要跑什么很多人一上来就问用什么架构这个问题本身就问错了。正确的顺序是先确定目标工作负载再反推架构。你如果主要跑CNN推理那脉动阵列Systolic Array是很自然的选择因为卷积的权重复用率极高数据可以像流水线一样在PE阵列里流动。但如果你的目标是Transformer类模型情况就复杂得多——注意力机制里有大量的矩阵乘、Softmax、LayerNorm数据依赖关系跟CNN完全不同。我一般会建议团队先做一件事把目标模型的计算图拆开统计各类算子的占比。比如某类视觉模型卷积可能占90%以上的FLOPs但换成某类语言模型矩阵乘和逐元素操作的比例就完全不一样了。这个统计结果直接决定了你的PE阵列该做多大、支持哪些精度、片上缓存怎么分。2.2 数据流架构的三种典型选择AI芯片的数据流设计本质上是在回答一个问题数据从DRAM搬到计算单元的过程中怎么搬最省能量业界常见的有三种模式权重固定Weight Stationary权重加载到PE后不动输入特征图流动。适合卷积层因为权重复用率高。输出固定Output Stationary每个PE负责一个输出像素的累加输入和权重都流动。灵活性好但对带宽要求高。行固定Row Stationary折中方案在PE行内复用输入和权重。选哪种取决于你的模型里哪类算子占主导。我见过一个团队明明主要跑深度可分离卷积却选了输出固定的架构结果权重带宽成了瓶颈能效比怎么都上不去。后来改成权重固定同样的工艺节点能效比直接翻了一倍多。2.3 精度选择不是越低位越好现在大家都在谈INT8、INT4甚至二值化但精度选择要跟模型精度需求匹配。我做过一组对比测试某类检测模型INT8量化后mAP掉不到1个点但换成INT4某些小目标检测的精度直接崩了。原因在于不同层对量化的敏感度差异很大——第一层和最后一层通常需要更高精度中间层可以压得很低。所以现在比较务实的做法是混合精度关键层用INT8甚至FP16非关键层用INT4。这要求硬件支持可配置的精度模式编译器也要能做逐层的精度分配。这个协同设计点如果硬件做死了只支持一种精度后面算法迭代就会非常被动。3. 片上存储层次被低估的性能杀手3.1 为什么说存储决定了AI芯片的上限有个数据可能很多人没注意在典型的AI计算中数据搬运消耗的能量可能是计算本身的几十倍甚至上百倍。从DRAM读一次数据的能量够做几百次乘加运算。所以AI芯片设计里存储层次的设计比计算单元的设计更关键。片上存储一般分几级寄存器文件、PE本地缓存、共享缓存Shared Memory、全局缓存L2。每一级的容量、带宽、访问延迟都要跟计算单元的需求匹配。我见过太多设计计算阵列做得很大但共享缓存带宽不够PE经常饿着等数据利用率连50%都不到。3.2 双缓冲与数据预取的实际操作一个最基本的优化手段是双缓冲Double Buffering当PE在计算当前数据块时DMA已经在搬下一块数据了。这个技术听起来简单但实际做的时候有几个坑缓冲区大小要跟计算块的粒度匹配。太小了DMA频繁启动开销大太大了片上存储放不下反而降低并行度。边界处理要小心。卷积的边界填充、矩阵乘的非对齐维度都会让预取逻辑变复杂。同步机制要可靠。DMA完成中断和计算单元的状态同步如果没做好会出现数据竞争或者空等。我的经验是双缓冲的深度做到2到3级比较合适再深了收益递减但控制逻辑复杂度指数上升。3.3 数据复用策略的量化分析假设你有一个N×N的PE阵列要计算一个M×K的矩阵乘。输入矩阵AM×K和BK×N输出CM×N。如果没有任何复用你需要从DRAM读M×K K×N个数据。但如果做分块Tiling把A和B分成小块加载到片上复用率可以大幅提升。具体来说如果分块大小为T×T那么每个数据块可以被复用T次。总DRAM访问量降到(M×K K×N)/T。这个T的选择取决于片上缓存大小和PE阵列维度。我一般会建议T取PE阵列维度的平方根左右这样计算和访存能比较好地重叠。4. 编译器栈软硬件之间的翻译官4.1 为什么AI芯片必须自研编译器有人可能会想用现成的TVM或者MLIR不就行了理论上可以但实际做产品的时候自研编译器几乎是必然选择。原因很简单通用编译器不知道你硬件的特殊指令、特殊存储层次、特殊数据布局。比如你的PE阵列支持一种特殊的稀疏计算模式通用编译器根本不会去利用。自研编译器栈一般分几层前端接框架把计算图转成中间表示、中端做图优化算子融合、常量折叠、内存规划、后端做代码生成映射到硬件指令。每一层都有软硬件协同的设计点。4.2 算子融合的收益与代价算子融合是编译器优化里最见效的手段之一。比如把Conv BN ReLU融合成一个算子中间结果不用写回DRAM直接在片上传递。我实测过一个典型网络融合后DRAM访问量减少了将近40%端到端延迟降了25%以上。但融合不是免费的。融合后的算子对片上存储的需求更大如果缓存不够反而会导致频繁的溢出。所以编译器需要跟硬件协同硬件提供多大的片上缓存编译器就做多大粒度的融合。这个平衡点通常需要反复迭代才能找到。4.3 内存规划的实际操作内存规划是编译器后端最繁琐但也最关键的部分。它要决定哪些张量放在片上哪些放DRAM片上张量的生命周期怎么管理DMA搬运的时机和顺序怎么安排。我一般会用一种叫生命周期分析的方法先画出整个计算图里每个张量的产生和消费时间点然后做区间图着色把生命周期不重叠的张量分配到同一块内存。这个算法本身不复杂但难点在于要跟硬件的DMA引擎特性结合——比如DMA支持多少个并发通道、最大搬运粒度是多少、是否支持散射聚集Scatter-Gather。实操心得内存规划做完后一定要用模拟器跑一遍峰值内存占用。我见过好几次静态分析显示内存够用但实际运行时因为DMA并发和流水线重叠峰值占用比预期高出30%以上。5. 算子映射与调度把计算图落到硬件上5.1 卷积在脉动阵列上的映射方法卷积映射到脉动阵列核心思想是把卷积的滑动窗口计算转化成矩阵乘。具体做法是im2col把输入特征图按卷积核大小展开成矩阵然后跟权重矩阵做乘。但im2col有个问题——它会放大输入数据量尤其是大卷积核的时候。所以实际硬件里更常见的是隐式im2col不真正展开数据而是在数据加载时动态生成矩阵的行列索引。这要求DMA引擎支持复杂的地址生成模式。我调试过的一个设计里地址生成单元花了整整两个月才稳定下来因为各种边界情况太多了。5.2 注意力机制的硬件加速难点Transformer类模型的注意力机制计算模式跟CNN差别很大。它有三个矩阵乘Q×K、Softmax、Score×V中间还有Softmax这种非线性操作。Softmax需要求最大值、指数、求和、除法这些在传统AI加速器上通常没有专门指令。一个可行的方案是把Softmax拆成几个基本操作用向量单元做。但这样效率不高。更好的做法是硬件提供近似的指数计算指令精度够用就行。我测过用查表法加线性插值做指数精度损失不到0.1%但速度比精确计算快好几倍。5.3 动态shape的处理策略实际部署中输入shape经常是动态的——比如不同分辨率的图像、不同长度的序列。这对硬件调度是个挑战因为很多AI芯片的指令是静态编排的。处理动态shape一般有两种思路一是编译时生成多个版本的二进制运行时根据shape选择二是硬件支持动态循环和动态DMA描述符。前者实现简单但灵活性差后者灵活但硬件复杂度高。我倾向于混合方案常见shape预编译罕见shape走动态路径。6. 验证与调试流片前必须做对的几件事6.1 功能验证的层次化方法AI芯片的验证工作量通常比设计本身还大。我一般会分三个层次做单元级验证每个PE、每个DMA通道、每个存储块单独验证。用定向测试用例覆盖所有指令和边界条件。子系统级验证把PE阵列和存储子系统连起来验证数据流和控制流。这个阶段要用真实的算子做激励。系统级验证跑完整的模型跟黄金参考通常是Python模拟器对比输出。每个层次的验证环境都要能复用不然维护成本会失控。我习惯用一套统一的激励生成框架不同层次只是配置不同。6.2 性能验证的坑功能对了不代表性能达标。性能验证最容易被忽略的是边界情况当计算块大小不能整除PE阵列维度时当DMA搬运遇到DRAM刷新时当多个算子并发竞争带宽时。这些情况在实验室里可能跑不到但实际部署中一定会遇到。我的做法是在性能验证阶段专门构造最坏情况测试最小shape、最大shape、非对齐shape、连续算子切换。这些测试跑通了实际部署才稳。6.3 常见问题速查表现象可能原因排查方向PE利用率低数据供给不足检查DMA带宽、双缓冲深度、缓存命中率输出结果偶尔错误同步问题检查DMA完成信号、PE状态机、跨时钟域同步功耗超标数据搬运过多分析DRAM访问次数、优化分块策略编译器崩溃算子不支持检查算子覆盖列表、回退机制精度不达标量化策略不当逐层分析敏感度、调整混合精度配置避坑技巧流片前一定要做一次极端场景回归测试——把所有算子的输入设成全零、全最大值、随机稀疏看输出是否正常。我见过一个设计正常数据跑得好好的全零输入时因为某个状态机没复位直接死锁。7. 软硬件协同的迭代方法论7.1 从模型到硬件的闭环软硬件协同设计最怕的就是串行算法团队定模型硬件团队做架构编译器团队做映射最后发现跑不起来。正确的做法是并行迭代算法团队提供候选模型集合硬件团队做架构探索编译器团队同步开发映射策略三方每周对齐。我参与过的一个项目一开始就是串行开发结果硬件流片回来发现某个关键算子不支持只能软件模拟性能直接打对折。后来改成并行迭代第二轮流片时所有目标算子都在硬件上有原生支持性能达标。7.2 架构探索的量化方法架构探索不能靠拍脑袋。我一般会建一个分析模型输入是目标模型集合和硬件参数PE维度、缓存大小、带宽输出是预估的性能和功耗。这个模型不需要太精确但趋势要对。具体做法是用Python写一个周期级模拟器把计算图映射到硬件上统计每个周期的PE利用率和内存访问。跑几百组参数组合画出帕累托前沿选最优点。这个过程通常要几周但比流片回来发现架构选错要划算得多。7.3 编译器与硬件的联合调优编译器和硬件的关系有点像鞋和脚。硬件定了编译器要适配但编译器发现的问题也可能反过来推动硬件改进。比如编译器发现某个算子融合模式特别常见但硬件不支持那下一代硬件就可以考虑加这个指令。我习惯在编译器里加一个硬件反馈通道当编译器遇到无法高效映射的算子时自动记录并生成报告。这个报告定期同步给硬件团队作为下一代架构的输入。这个机制看起来简单但实际用起来效果很好能避免很多设计时没想到的问题。8. 一些个人体会做AI芯片软硬件设计这些年最大的感受是没有最好的架构只有最匹配的架构。你看到某家公司用脉动阵列做得很成功直接抄过来可能完全不适用你的场景。关键是要理解每种架构背后的假设——它假设数据复用率高、假设算子类型集中、假设精度需求固定。如果你的场景不满足这些假设就得换思路。另一个体会是编译器的重要性怎么强调都不过分。硬件做得再好编译器映射不上去性能就是上不去。我见过太多团队硬件团队很强编译器团队很弱最后产品竞争力大打折扣。如果你正在组建团队编译器的人一定要早招、多招。最后分享一个小技巧在架构设计早期先用FPGA搭一个原型把编译器和运行时都跑通。虽然FPGA的性能跟最终ASIC差很远但功能验证和软件栈开发可以提前进行。等ASIC回来软件已经成熟了可以快速上量。这个策略我们试过几次能省至少三到六个月的上市时间。

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

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

免费获取报价 →
↑