考试通知
群里的朋友又在问第七篇的预告什么时候出说来也巧这一篇恰恰是整个系列里最“磨人”的一篇。前几篇聊架构微架构、聊内存子系统、聊工具链基础多少都能从公开资料里找到影子唯独“AI芯片的软硬件设计”这个主题必须同时站在芯片和编译器两边用一套心智模型把两边串起来。这篇文章我尽量不端着把做项目中真实踩过的坑、想通的关键点、反复权衡的取舍讲清楚。适合正在入门AI芯片设计、刚接触软硬件协同开发、或者准备做异构计算平台选型的工程师参考。1. 软硬件协同设计的全局观1.1 为什么软硬件必须一起设计很多刚接触这个领域的朋友会先入为主觉得AI芯片嘛无非是把一堆乘加器排在一起配上大缓存再把编译器弄出来能跑模型就行。真上手做就会发现硬件一旦流片回来软件栈还停留在“能点灯”的阶段整个项目就废了一半。AI芯片的性能最终由软件映射效率决定这句话听起来像口号实际上每一条都对应着硬件的真实约束。我举一个最普通的例子。很多AI加速器在设计时片上SRAM容量定得很大以为这样就能减少DDR访问。可编译器如果缺乏对整个计算图的全局分析能力算子粒度就切得碎中间结果频繁写回DDR片上缓存利用率很低。这种情况下硬件上的“豪华配置”根本转化不成实际性能。反过来说如果编译器足够聪明可以把连续多个算子的中间张量融合在片上哪怕SRAM只有几兆也能跑出比“大缓存但是编译器稀烂”的硬件更好的性能。所以软硬件协同设计的本质是硬件架构为软件映射提供“可能性边界”软件栈则决定在这条边界上能逼近多少。这个边界包括计算阵列的排布方式、数据通路宽度、存储层次结构、同步与流水机制也包括指令集或者配置寄存器的设计。软件栈必须从硬件寄存器级抽象开始设计而不是在API层面套一个通用编译框架就万事大吉。1.2 算力需求如何推导硬件规格做软硬件协同设计第一步不是选工艺、定频率而是先算清楚“目标模型家族”的算力和访存需求。业界常用的是一个非常朴素的公式[ \text{所需MAC数} \text{模型FLOPs} \times 2 / \text{目标功耗时的时钟数} ]单位时间内的MAC吞吐直接决定了加速器要放多少个MAC单元而模型中间张量的尺寸和复用特性则决定了片上存储的容量和带宽下限。我记得做一个8比特推理加速器时目标是在10瓦功耗内跑一个主流检测网络。计算下来需要约2000个MAC并行工作频率目标尽量压到500MHz以下以保证功耗达标。可提到“能不能让编译器把算子融合好、把数据搬移降到最低”时发现软件团队对硬件的存储结构还不清楚沟通了整整两周。这里我强烈建议在做软硬件协同设计时先不要急着写RTL更不要急着做芯片验证。先做一轮“架构-编译器”纸面对齐把目标模型的每层特征图大小、卷积核大小、通道数资料化然后推演每一层在硬件上的执行方式、中间数据会出现在哪里、片上存储需不需要回写DDR。这个推演过程消耗的时间通常是两周但节省的返工时间可能是两个月。2. 核心计算单元与存储层次的协同设计2.1 脉动阵列 vs 单指令多数据流的取舍计算阵列的微架构选择往往是AI芯片设计中争论最激烈的地方。脉动阵列思路数据在阵列中像流水线一样相邻处理单元传递每个处理单元都只和相邻单元通信好处是数据复用度高、布线压力小、能效比出色坏处是编译器压力极大因为必须严格控制数据流入流出的时序稍微映射不好整个阵列就大量空转。单指令多数据流风格则更灵活每个处理单元可以独立执行不同操作编译器只需把计算任务切分到不同单元上但代价是每个单元附近都要有自己的寄存器或者小块缓存指令路由和数据进行交叉互连面积效率和功耗都不如脉动阵列。在实际产品里纯脉动或者纯单指令多数据流的架构都很少更多采用的是“两者融合”的方案。核心计算块用脉动或者近脉动阵列保证卷积类算子的高能效同时在阵列旁边配了少量可以随机访问的向量处理单元用来处理归一化、池化、激活函数这类对数据流不那么规律的算子。这么设计的目的很明确——编译器只需要对主力算子做严格的数据流规划其余算子可以在向量单元上“随手”处理软件复杂度大大降低。我个人的体会是如果你所在团队软件编译器力量很强可以大胆一点用脉动阵列因为性能上限更高如果软件团队人力有限还是选择带灵活性的架构更稳不要为了追求纸面峰值算力给后续的工具链带来无底洞。2.2 片上缓冲区与数据复用策略计算阵列之外最核心的资源就是片上缓冲区。几乎每一篇AI芯片的论文都在强调数据复用可实际设计时这个“复用”是分层次的。卷积计算有输入特征图的通道复用同一个像素被多个卷积核使用和输出特征图的累积复用多次部分和累加全连接层则主要是权重复用一个权重要乘以多个输入向量。硬件设计时你需要在SRAM容量和编译器能力之间做一次明确分工。这里我推荐的做法是在架构层定义好三种数据复用模式——输入驻留、权重驻留、输出驻留每种模式对应不同的数据流排布方式。编译器根据算子的特征自动选择把哪个数据留在片上其余数据按画好的流水线搬运。这个设计思想源自经典的数据流分析理论搬到AI芯片上同样适用。举个例子一个常见的3x3卷积算子输入通道数256输出通道数256输出特征图尺寸112x112。如果权重驻留在片上那么权重占用的SRAM约为3x3x256x256字节用8比特量化就是576KB输入特征图每次搬运一个滑动窗口输出部分和持续累加。此时计算阵列可以保持很高的利用率但编译器必须保证输入数据流入的速度刚好配得上计算节奏否则脉动阵列必然出现气泡。这种流水级的规划必须在硬件寄存器设计阶段就为编译器预留好可编程的控制字段而不是等RTL写完了才回头商量。2.3 存储墙问题在片上的体现CPU时代大家就谈存储墙到了AI芯片时代这个问题更加尖锐。计算阵列动辄几千个乘加器同时工作每个时钟周期消耗的数据量是几千字节即便SRAM能提供几百GHz的带宽依然很容易被计算阵列“抽空”。实际上仅仅增加SRAM容量往往治标不治本因为大容量SRAM物理上通常集中在一个固定位置访问延迟和布线面积都会变大所有处理单元都去访问这一个块也会造成拥塞。更务实的思路是构建分布式的多级存储层次。每个处理单元附近放一小块私有存储用来保存需要在该单元局部复用的数据然后一层中等容量的共享SRAM用于多计算单元之间的协调最后才是DDR这类外部存储。这种结构和软件线程映射强相关编译器需要感知每一级存储的容量和延迟才能做出现实的调度决策。设计时我会给编译器团队提供一份存储层次带宽图包括理论上每个端口每周期能读写多少字节、冲突会发生什么行为让编译器在生成指令时尽量避开冲突这也是“软硬件接口文档”里最关键的章节。3. 软件工具链的落地实现3.1 编译器中间表示与算子映射AI芯片的编译器中间表示层决定了后续优化能走多远。这里我不建议直接复用通用编译器的中间表示因为AI编译器优化的核心对象是张量的数据流和布局变换而不只是标量运算和循环变换。针对硬件特性设计专门的AI编译器中间表示能保留张量的维度和数据类型信息同时能显式描述数据在存储层次之间的搬移操作。中间表示往下需对接硬件抽象层这里最容易出的问题就是“硬件抽象层过厚”。有些团队为了方便把加速器的底层寄存器封装成一套复杂的驱动接口编译器只能看到API看不到硬件行为特征。这会导致编译器优化时完全凭猜测性能惨不忍睹。正确做法是让编译器后端能够直接操作加速器的配置寄存器映射时能精确控制数据流的启动和停止。即使牺牲一些通用性这也是值得的。算子映射这件事本质是把一个计算图中的每个算子翻译成加速器上可执行的基本指令序列。这些指令可以不是传统的CPU指令而是一组配置字告诉计算阵列的数据流模式、输入数据的起始地址和步长、以及循环的层数和边界。我见过很多团队一开始粗暴地把算子切成一小块一小块执行导致数据搬到片上就为了算一小块卷积效率极低。要解决这个问题编译器必须做一个大的算子融合过程把连续的卷积、激活、归一化等算子直接融合成一张大的执行计划。3.2 运行时调度与多任务切分的细节实际部署场景中芯片很少只跑一个模型更常见的是视频流输入多个任务抢占加速器资源。这时候运行时的调度策略就变得很重要。硬件设计师常常忽略运行时层面的设计总觉得编译器把计算图排好就没问题了。可一旦多任务并发中断处理、上下文切换、内存隔离这些问题都需要软硬件共同定义好接口。我的建议是运行时直接和硬件控制层协作不要像操作系统那样采取抢占式调度因为AI计算任务一旦在阵列上流动起来贸然打断会导致流水线排空损失非常大。更高效的是协作式调度每个计算任务在启动前显式申报硬件资源运行时统一裁决按照某种优先级分配时间片或空间资源。协作式调度对硬件的要求也简单很多不需要复杂的现场保护只需要在任务边界上设置同步屏障。实践证明空间复用比时间复用对AI芯片友好得多。如果计算阵列足够大可以把整张阵列切成几个独立的子阵列每个子阵列跑一个任务这样多个任务并行互相之间不受干扰。硬件设计时就要预先留下一组“子阵列划分寄存器”供运行时动态配置而不是把所有计算单元绑死在一个任务上。3.3 性能分析工具如何设计没有性能分析工具AI芯片的优化基本等于盲人摸象。性能分析工具要回答的核心问题有三个计算阵列的利用率是多少片上存储的读写带宽是否饱和数据在外存和片上之间的搬运量比理论最低值高了多少这三个数据看起来简单但实现难度都在硬件调试用的探针上。我建议在RTL设计阶段就把性能计数器的位点规划清楚。计算阵列控制器里记录空闲周期的计数器、存储端口记录占用率的计数器这些几乎不需要额外硬件开销却能在后续测试中帮大忙。很多团队流片回来才发现完全没有观测手段只能靠猜这种教训并不少见。有了性能工具就能形成一个优化闭环运行模型→看到性能瓶颈→调整算子映射策略→修改编译参数→再运行。这个闭环跑顺了软硬件协同设计才算真正转起来。而优化闭环的第一步往往是先找到一个足够小的基准样例反复测比如一层卷积加一层激活而不是直接上完整模型。4. 验证与物理实现中的关键细节4.1 功能验证要覆盖编译器生成的边界情况AI芯片验证的难点不在于功能点太多而在于编译器生成的指令序列组合空间太大。手写的测试用例能覆盖常规路径但编译器总会生成一些你没想到的边界情况比如某些维度不为8对齐的算子或者超大特征图导致地址空间越界。这些边界组合在验证阶段缺乏关注流片后美国队长也救不回来。我建议在验证计划中单独列一个“编译器随机压力测试”类别通过随机修改算子参数生成大量合法但罕见的指令序列在仿真平台上回归测试。这个方法听起来简单实际做起来效率极高能在早期发现大量RTL逻辑漏洞。功能验证的另外一个重点是数据精度。AI芯片普遍支持8比特甚至更低的量化精度RTL里乘累加的顺序变化会导致精度表现微妙差异。验证阶段要专门比较编译后的硬件执行结果和参考模型的计算结果容差设定不能太宽松也不能严到完全不切实际。这里需要软硬件团队共同定一个标准一般是逐层比较输出的余弦相似度或者误差百分比。4.2 物理设计与低功耗的博弈物理实现阶段最棘手的问题倒不是电路能不能收敛而是高频率和大面积带来的功耗和发热。AI芯片里面计算阵列的翻转率通常很高动态功耗巨大如果不做精细的时钟门控静态功耗和动态功耗叠加起来芯片温度很快逼近上限。一个非常有效的做法是在阵列级做细粒度的时钟门控当某块子阵列没有任务时硬件控制逻辑直接把对应区域的时钟关闭。但这要求编译器能够在指令流里显式标注任务的开始和结束位置硬件在结束位置自动触发时钟门控。这个配合我在两个项目里实践过效果立竿见影功耗最多能省下30%以上。低功耗的另一个层次是数据搬移的功耗。从DDR读数据的能耗比从SRAM读数据高一个数量级更远高于计算本身的能耗。所以“数据搬移尽量少”不仅是性能优化的目标也是功耗优化的核心手段。软硬件协同设计到最后会发现性能优化和功耗优化的策略常常是一致的那就是尽量把计算留在片上把数据复用做到极致。4.3 后仿真与性能预评估物理设计完成后拿到带寄生参数的网表跑后仿真这个时候芯片的实际情况已经和图样很接近了。我建议后仿真阶段一定要用真实的软件工具链生成的实际应用场景负载不要只用简单的测试向量。因为只有真实的负载才能模拟出存储带宽冲突、多任务并发的效果。这一步能提前暴露出几个问题内存接口的时序裕量是否足够、片上网络在多端口同时访问时是否出现死锁、时钟树偏差对高速路径的实际影响。在流片前尽早发现这些风险哪怕需要微调布局布线也比之后芯片回来再补救要便宜得多。后仿的性能预评估数据也是软件团队调优的依据。因为此时还能修改编译器调度策略如果预评估发现某个算子频繁因为存储端口冲突而停顿编译器就可以提前改变数据布局避免访问竞争这个优化窗口在流片后就永久关闭了。5. 常见问题与项目复盘心得5.1 编译器掉队导致硬件空转我见过不止一个项目死在这种情况芯片算力纸面数据很好看编译器迟迟达不到预期映射效率最终整体性能只有峰值的二三成。这种问题的根源普遍在于软件的启动时间晚于硬件的设计周期等硬件快完工了软件才发现架构上某个关键限制让映射束手束脚。要避免这个问题唯一可行的方案是把“最小软件栈”的启动节点前移甚至在架构定义阶段就有编译器人员在旁参与。不必等完整工具链只需要一个能映射少量算子、走过完整软硬件数据通路的原型哪怕性能很低也能暴露软硬件接口的核心矛盾。这个实践看起来拖慢了前期进度实际上是为整个项目买保险。5.2 中间张量如何调度最经济推理和训练场景中中间张量的调度都很有讲究。我见过很多编译器默认把中间张量全部留在DDR简单但性能很差另一些编译器反过来试图把所有中间张量都留在片上结果容量爆了频繁换入换出性能同样拉垮。折中的方案是给每个张量标注一个预期生命周期然后做容量规划让生命周期最短的张量优先使用片上存储生命周期长的流式数据直接走DDR。这和操作系统里的页面置换算法有点类似但区别在于编译器可以全局地预知所有张量的生命周期所以可以做出比运行时算法更优的静态分配。5.3 文档即接口软硬件协同设计团队最容易被低估的交付物不是代码不是架构文档而是“程序员参考手册”。这份文档需要精确到每个控制寄存器的位域含义、每个状态机的跳转条件、每条同步指令的时序开销。没有这份文档编译器后端开发人员和硬件设计人员日常沟通就会变成一场冗长的马拉松。我现在的习惯是硬件RTL第一版冻结的同时强制要求硬件团队同步完成寄存器手册的初稿后续每改一次RTL手册必须在同一天更新。这个约定执行起来并不容易但坚持三周后你会发现软件团队的返工请求大幅减少。文档即接口这不是一句口号是无数项目经验换来的血泪教训。回到这篇“AI芯片的软硬件设计 7”我个人最想强调的还是那个看起来有点老生常谈的结论软硬件协同不是两个团队各自做接口对接而是从一开始就为一个共同目标设计。硬件多留一点可编程性软件多理解一点硬件约束最终的性能和功耗收益都是乘法级别的。项目做到后期你会发现最珍贵的不是某个灵光一现的架构创新而是这一套从编译器到寄存器的完整默契。这套默契建立起来之后后面再做下一代芯片的时候前期磨合的时间能省下一大半。
AI芯片软硬件协同设计:从编译器到寄存器的完整默契
NEXT STEP
看完公告,下一步怎么走?
把报考交给靠谱的人:材料预审、批次抢报、考前辅导、复审提醒,全程有人跟。