这几年做AI基础设施,绕不开的一个话题就是国产AI芯片。芯片本身是一个层面,但真正决定能不能用、好不好用的,其实是围绕芯片的那层算子生态。CNCC2026上有不少场次都在聊这个主题,我也有幸参与了一些交流,今天把我在国产AI芯片算子生态方面的实践、观察和踩坑记录整理出来。这个话题的受众很明确:正在做推理部署的算法工程师、做AI平台基设的团队,以及准备在国产芯片上跑模型但是还在观望的决策者。看完之后你至少能搞清楚三件事:算子生态到底为什么卡脖子,当前国内主流的构建路线是什么,以及你手上一个具体的模型落到国产芯片上要经历哪些坑。
1. 算子生态到底是"什么问题"
1.1 先搞明白算子在体系里处于什么位置
AI模型跑起来的核心动作,本质上是张量计算。卷积、矩阵乘、归一化、激活函数、注意力机制,这些基本的计算单元在框架视角下被抽象成一个个"算子"。你可以把算子理解成AI世界的零件:网络模型就是组装图纸,算子的实现才是真正运转的齿轮。
关键在"实现"这两个字。同样是卷积,NVIDIA的cuDNN有一套针对自家GPU深度优化的卷积实现,寒武纪有自己的卷积算子库,昇腾底座是CANN里的算子实现。硬件指令集不同、内存架构不同、计算单元排布不同,同一个数学算子在不同芯片上是完全不同的代码路径。这就是算子生态的角力点:谁的算子实现覆盖全、性能好、迭代快,谁的芯片就能真正被用起来。
我见过不少刚接触这个领域的开发者的第一反应:"框架不是已经把模型打包好了吗?直接跑不就行了?"实际上计算图在设备端落地的时候,每一层都要被翻译成芯片能理解的算子序列。如果某个算子你的芯片没有实现,就会回退;如果回退路径的性能极差,推理一个上百层的Transformer就会出现灾难性的延迟。
1.2 国产芯片为什么总是"纸面性能漂亮,实际性能拉胯"
这就涉及"算子生态"这个概念的完整含义了。它至少包含三层:算子库(手写/半手写的核心算子实现)、算子编译器(自动将算子映射到芯片指令)、以及上层框架适配层(PyTorch、TensorFlow在这个芯片上的接入稳定性)。这三层里任何一层有短板,芯片的理论算力就无法等比兑现。
初代的国产AI芯片评测很好看,INT8算力动辄几百TOPS,FP16也标得很高。但这是理论峰值。实际跑一个ResNet-50或者LLaMA-7B,你会发现利用率可能只有20%到40%。差的这60%,绝大部分不是硬件问题,而是软件映射效率的问题——算子没优化到位。卷积在芯片上是用脉动阵列还是SIMD还是Vector流水线?数据在片上和片外的搬运怎么排?这些都直接决定了一个算子的效率。同样的理论算力,不同的算子实现质量,跑出两倍的性能差异太常见了。
1.3 一个容易被忽略的反常识:算子生态的瓶颈在生态位而不在算法
很多人以为算子实现难在"算法的数学推导",实际上成熟的卷积算法、矩阵乘算法早就写成论文了。真正的难点在于每个算子要适配一个具体芯片的具体微架构。这是一件极其"脏"的工程活:你需要吃透芯片的指令集手册、理解存储层次和数据流约束、知道计算单元间的同步机制、还得针对不同的输入形状各自调优。没有足够的应用场景反哺,没有大量真实模型做回归测试,算子库就粗糙;算子库越粗糙,用户越不用;用户越不用,场景越少,算子库迭代就越慢。这个正反馈闭环一旦转起来,芯片的命运基本就定了。
所以"算子生态"本质上不是技术攻坚问题,而是生态循环问题。谁能在早期快速建立覆盖面、让真实用户跑起来,谁就能进入良性循环。这解释了为什么芯片巨头和头部AI公司的思路高度一致:先重兵砸算子库,再开源、再讨好开发者。
2. 国内算子生态构建的三条路线
2.1 路线一:自研全栈,从指令集到算子库一体推进
以昇腾、寒武纪为代表的芯片厂商选的是这条路线。硬件指令集、底层驱动、算子编译器、算子库、上层框架适配全部自己掌控。好处是整栈的可定制空间最大,算子的性能天花板可以拉满;坏处是见效慢、投入巨大,而且开发者一旦习惯了CUDA的编程模型,在迁移到新体系时会有很强的抗拒感。
昇腾CANN这几年迭代频率明显加快,很重要的一个原因就是它意识到:不能只靠芯片方案商自己去适配模型,必须提供一个好用的开发环境,让下游的算法团队愿意直接在这套生态上写代码。但说实话,完全自研需要同时解决编译器和算子库两大硬骨头,时间刻度是以"年"为单位的,这对很多商业场景来说太慢了。
2.2 路线二:兼容CUDA生态,降低迁移成本
很多后发的GPU厂商选择了兼容路线——在软件栈层面尽量兼容CUDA的运行时和算子接口,让已有代码可以平移或者少改。这在商业上是非常聪明的做法:应用层不需要重写,算法工程师几乎没有学习成本,芯片的推广门槛瞬间被降低。
不过熟悉底层的人都知道,兼容CUDA并不等于直接跑cuDNN。方案一般是复刻一层CUDA runtime API,然后把算子调用映射到自己的实现上。这里最微妙的是性能和兼容性之间的平衡:你到底是100%语义兼容还是性能优先?如果语义兼容做不彻底,一些老代码里的极端用法会莫名其妙出bug。要是性能不做专门优化,用户一跑大模型就会感知到明显差异,口碑瞬间崩坏。这条路走得快,但后面的技术债不少,需要持续投入去填坑。
2.3 路线三:以编译器中转,用AI编译技术解放算子生态
在纯手写算子库路线的旁边,还有一条被谈论得越来越多的技术方向:基于AI编译器(如MLIR、TVM、Triton生态)来做算子自动生成和自动调优。思路是摆脱"每个算子都要人肉优化一次"的套路,用编译器把高层算子描述自动lower到芯片指令上。
这条路最有意思的地方在于,它一劳永逸地解决了"算子数量无限、人力有限"的核心矛盾。一旦编译器能力到位,新发布一个硬件架构只需要重写底层指令映射层,大量算子的生成逻辑是可以复用的。但问题也很现实:自动化生成的算子,在性能上往往打不过资深工程师针对热点算子手写优化的版本。所以现实中我们看到的多是混合方式——通用算子走编译器,热点算子(矩阵乘、卷积、Attention)仍然单独手写调优。
2.4 我的判断:未来是"编译器+手写库"的混合演进
这不是什么惊人结论,而是目前行业里的普遍共识。以LLM相关的算子为例,FlashAttention系列在NVIDIA上能获得巨大加速,靠的就是手写kernel和充分压榨硬件特性。纯编译器路线很难在短期达到同样的效果。反过来,随着模型结构越来越多样,纯靠人肉堆算子库也是不可持续的。所以健康的算子生态应该是:编译器把长尾算子自动化掉,工程师把头部热点算子打磨到极致。既保证覆盖率,又保证爆点性能。
3. 实操视角:算子在国产芯片上的优化链路
3.1 从模型到算子的落地链路拆解
讲完宏观路线,进到工程层面。把一个训练好的模型跑起来,算子层面的完整链路大致是这样的:
- 模型从PyTorch导出为计算图(TorchScript、ONNX,或者直接走Torch compile);
- 图优化:算子融合、常量折叠、冗余消除等等;
- 算子选择与分配:每个操作符被匹配到芯片后端算子库的某个实现;
- 算子编译/调优:针对具体硬件和输入shape做参数调优;
- 设备端执行。
链路里的每一步在国内芯片上都有特有的难点。图优化层面自研框架的融合规则不如PyTorch/ONNX生态完整;算子选择层面自研算子库覆盖不全会导致各种回退;到了调优层面,缺乏足够的模型扫描数据来支撑最优参数选择。这也就是为什么每个做国产芯片适配的团队都有一堆"从框架到底层逐个算子排查"的脏活。
3.2 导入模型时最常碰到的算子缺失问题
以我实际做过的Llama类模型适配国产芯片的经历来说,最经典的问题是算子不支持导致图编译失败。模型里一个很普通的RMSNorm算子,如果你的算子库正好没有这个融合版本,图优化阶段就会拉锯。解决方式通常是两条:要么在算子库里补一个自定义实现,要么把编译器的pattern匹配规则修改,让RMSNorm被分解成更底层的乘法和归一化算子组合。
这里我强烈建议:先检查算子库文档的"已支持算子清单",再决定模型层面的改写策略。不要一上来就自己写算子,先看看分解方案可行不可行。很多Transformer的Python实现里,开发者为了性能会手动做一些融合(比如把LayerNorm拆开和残差融合),这些写法在算子库不全的国产芯片上经常适得其反。
3.3 一个算子的优化实例:矩阵乘的调参记录
矩阵乘是硬件上的核心热点了,谁的矩阵乘不行,谁做LLM就不行。我在一块国产AI加速卡上做过GELU融合矩阵乘的调优,记录一下思路。
第一步是确定数据布局。NVIDIA习惯上是NCHW,但很多国产加速卡更偏好NHWC或者芯片自定义的5D格式。这一步的差异直接影响到指令效率和内存带宽利用率,不做显式调优,性能差30%到50%很正常。
第二步是切块策略。矩阵乘需要被拆成块,利用片上SRAM暂存中间结果,减少全局内存访问。块的大小跟芯片的片上缓存容量直接相关。实测下来对比:
| 切块方案 | 片上缓存命中率 | 全局内存带宽利用率 | 实测性能 |
|---|---|---|---|
| 512x512粗粒度分块 | 82% | 61% | 基准 |
| 128x128细粒度分块 | 94% | 76% | 提升约1.7倍 |
| 自适应分块 | 91% | 82% | 提升约2.1倍 |
因为不同的shape、不同的批次大小下最优分块参数都不一样,最后可用的方案还是自适应分块。这一层调优没法全手工完成,必须依赖类似Autotune的机制,在离线阶段跑一遍参数搜索。
3.4 用编译器模式快速覆盖长尾算子
手写算子覆盖不了的长尾算子,我的经验是用编译器自动生成。MLIR的多级抽象天然适配这种场景:先把框架的计算图低成Linalg或者TOSA这类方言,再在Dialect转换到芯片后端。整个过程不需要为每一个算子单独写核函数,只要在某个中间抽象层做好模式匹配规则和排布规则就行。对精度要求不高的算子走自动生成,我实测覆盖率达到95%以上没问题,剩下的少数热点算子再单独手写。
这么做的收益很直接:算子库的开发周期从以"算子维度"变成了以"模型维度"。上一个新模型,不需要逐算子检查,只要检查它用到的几个头部算子在热点库里的覆盖情况和性能,其他全部交给编译器生成。这是目前看来最可持续的工程路线。
4. 算力瓶颈的"最后一公里":为什么集成度往往被忽视
4.1 单算子性能行了,模型还是慢?问题在集成执行
很多团队跑国产芯片的推理项目,算子在逐个算子验证时性能都不错,但端到端的模型推理一跑就慢得一塌糊涂。这种情况超过八成不是算子本身的问题,而是执行时图和设备端的调度机制拖了后腿。
CPU侧负责发指令,设备侧负责异步执行,如果算子间的kernel launch没有做异步流水或者事件同步策略不对,设备就会出现大量等待间隙。算子层已经优化的性能,被调度层的空转浪费掉。NVIDIA生态里CUDA Graph这种机制就是为了解决这类问题的:把整张图的launch信息提前固化,减少CPU参与度。国产芯片的运行时也都有类似能力,但默认配合不好,动不动就同步一次,流水线全废。
所以做模型适配的时候,先看芯片是否支持图级别的一键执行模式,然后把图上所有算子的launch统一提交,核心计算之间做异步化处理。这一层的优化通常能带来翻倍级别的端到端收益,远高于单个算子再扣那5%的零头。
4.2 显存/内存带宽是更隐蔽的瓶颈
算力数字漂亮,不代表内存系统跟得上。大模型推理特别吃内存带宽。一个简单估算方式:每生成一个token,都要把全部权重过一遍。7B模型的INT8权重约7GB,如果加载一个token需要往返读一遍权重,内存带宽是300GB/s的设备,理论最快也就40 tokens/s左右。算力再高也没用,这里卡的是显存带宽。
国产芯片在这一代产品上的普遍短板也在这里。很多芯片标称算力很猛,但HBM带宽和NVIDIA同级产品比有差距。跑大模型的时候,性能曲线不是算力封顶,而是带宽封顶。建议在选型评估阶段,先根据模型的参数量和目标吞吐倒推所需的内存带宽需求,再对比各家芯片的实测带宽,而不是只盯着TOPS看。这个坑我见过不少团队踩过,测试卡上GPU利用率看着不高,还以为是算子问题,查了半天最后发现是内存带宽到极限了。
4.3 多卡互联决定能不能做大模型
单卡性能够用了,做千亿参数模型必然要上多卡。这时候卡间通信就成了新的硬指标。NVIDIA有NVLink,国产芯片各有各的互联协议,问题是互联带宽和延迟参差不齐。
做张量并行的时候,每一层Transformer都需要多次跨卡all-reduce通信。通信的开销占比如果超过单层计算时间的30%,扩展效率就很难看。实测经验是,提升并行度的收益在4卡以内最明显,8卡以上受制于拓扑结构和通信带宽,收益会快速衰减。部署方案设计的时候务必提前确认目标芯片的互联拓扑是环形、全连接还是树形,针对拓扑决定模型并行的切分策略,直接关系到最终的在线服务质量。
5. 常见问题与排查技巧实录
老实说,国产芯片算子生态的坑比NVIDIA生态多得多。这里把我踩过的一些高频问题和排查思路整理出来,算是给后来者留个清单。
| 现象 | 直接原因 | 排查路径 |
|---|---|---|
| 模型加载后fp16推理精度崩坏 | 部分算子回退到fp32路径,某些算子数值不稳 | 对比图优化前后的计算图,定位精度崩坏的算子层 |
| 算子耗时波动剧烈 | 未做算子autotune,运行时临时选参数 | 离线预跑一遍shape覆盖的参数搜索,固化最优配置 |
| 首token延迟高、后续tokens慢 | KV Cache在设备端分配不足,或缓存管理策略差 | 检查KV cache预分配策略,评估是否走paged attention |
| 小batch性能比大batch差很多 | 算子融合策略偏向大shape,小shape下launch开销占比大 | 针对小shape单独做算子编译优化,必要时走Graph模式 |
| 多卡训练时利用率上不去 | 通信算子和计算算子未重叠 | 用profiler查看时间线,检查all-reduce是否阻塞了计算流 |
5.1 精度回归排查的一个实用技巧
算子库在国产方案上最磨人的是精度问题。同一个算子在不同形状、不同数值范围下,定点化的误差表现可能完全不一样。我的做法是建立一套算子级精度回归基线:把每个算子单独提出来,用NVIDIA GPU输出作为参考结果,在国产设备上跑同一组输入,统计误差分布,设定误差置信区间。这套基线一旦建立,模型级出问题的时候定位就快多了,能直接锁定到具体算子的具体输入维度。
做这个其实不需要太复杂的工具,PyTorch里用track钩子把每个算子前后的tensor抓出来对比就行。麻烦的是数据量,但有了自动化脚本,跑一遍主流模型壳子基本能覆盖90%以上的算子分支。
5.2 Profiling用的工具链怎么选
国产芯片的调试工具链普遍比较分散,有的厂商提供了profiler,有的只有简单的计时输出。我的实操经验是三层组合方式:
第一层,框架层的dump tracing,用PyTorch自带的profiler看算子级别的耗时分布。第二层,芯片厂商提供的私有profiler,看设备端的执行详情和内核占用率。第三层,是在关键代码路径里手动插入同步计时点,看端到端流水段之间的gap。三层叠下来,大部分性能问题都能定位到是算子实现、图切片还是执行调度的问题。
5.3 和厂商共建是绕不开的功课
最后一条经验是心态层面的:不要指望拿NVIDIA的成熟度标准去要求国产生态。使用NVIDIA的时候思路是"框架软件栈已经齐了,直接用就好",但国产生态还在建设期,用的时候更像是在参与共建。具体动作包括定期整理算子缺失和性能差的用例发给厂商FAE、提供真实模型的trace帮助他们做优化优先级、参与到他们的兼容性认证计划里。多数厂商对关键客户的反馈响应速度还是不错的,而且早期参与共建的团队往往能拿到更好的技术支持待遇。
我在这个过程中体会最深的是:算子生态不是一个静态产品,它是一个持续演进中的工程系统。前两年在国产芯片上跑大模型还是"能不能跑"的问题,现在已经变成"怎么跑得更快"的问题,这种转变本身就说明生态是在往前走的。我个人的建议是,如果你的项目对推理成本敏感、长期有规模化部署需求,尽早投入人力去摸国产芯片的底细,越晚起步,迁移成本只会越高。别等生态完全成熟再进来,那时候你看到的就不再是机会红利,而是一堆已经站稳的竞争对手。