今年第一波大模型推理服务优化做到一半,我不得不面对一个老问题:AI加速器到底怎么选。说"老"是因为从GPU、TPU到NPU,这个名字已经被喊了好多年,但真到了要下单、要规划算力、要把模型部署上线的节点,绝大多数团队还是习惯性地把"显卡"当唯一答案。可现实是所有做AI加速的芯片,本质上都在回答同一个问题:你能不能把矩阵乘法和大量并行的数据搬运跑得更快、更省。这篇就是我对GPU、TPU、NPU三种架构的一次系统梳理,给你一套不需要懂太多硬件细节也能照着做的选型思路,适合正在给模型训练或者线上服务评估算力的算法工程师、平台架构师,以及被老板逼着"三个月内把推理成本降一半"的人。
1. 三种加速器的架构逻辑分歧:通用并行、矩阵脉冲与低精度算子
1.1 为什么会有三种加速器:从工作负载结构说起
所有AI加速器要解决的核心问题就一个:计算密度。深度学习负载和传统软件最大的差异在于,它绝大部分操作数是矩阵乘法和卷积,而且可以接受一定范围内的精度损失。这给了芯片设计者一个偷懒的机会——我可以不做通用的复杂指令,专门做"矩阵乘+激活函数+搬运数据"这几板斧,做得又大又快又便宜。GPU、TPU、NPU恰好站在同一条路线的三个不同位置。
GPU遵循的是大规模并行通用计算思路:它内部有几千个最小计算单元,每个都能执行相对通用的浮点运算,配合调度器把成千上万的线程并发跑起来。这个设计的优势是适应面广,无论你来的是矩阵乘、卷积、还是各种奇怪的自定义算子,只要能把问题拆成并行子任务,GPU都能吃下去。代价是控制逻辑和缓存占了大量芯片面积,计算单元本身的占比并没有你想象的那么高。
TPU走的是脉动阵列路线。整块芯片被设计成由大量小型计算单元组成的规则阵列,数据像流水线一样在相邻单元间流动,权重直接驻留在每个单元里,不需要反复从内存加载。这样做的结果是矩阵乘法效率极其惊人,同一块面积的芯片能塞进远多于GPU的计算单元。但它也有先天限制:阵列的调度策略是固定的,遇到矩阵乘以外的算子,比如动态形状的注意力计算、复杂归约,效率会断崖式下跌。
NPU则把专用化推到了另一个极端。它通常只做INT8或INT16低精度整数运算,数据宽度短、电路简单、功耗极低,而且大量算子被固化成了专用引擎,比如卷积引擎、全连接引擎、张量变换引擎。你可以把它理解成一口一个专项小灶:单个任务做得又快又省电,但换一道没见过的菜就抓瞎。
1.2 用"团队配置"来打比方:三支队伍的差别
我经常给人打这样一个比方:GPU是一个配备了多种岗位的成熟项目团队,成员都能干事,换个项目方向也有不少人能顶上;TPU是一条单品种中央厨房流水线,一旦菜谱定型,出菜速度惊人,但突然要加一道新菜,整条线都要停工改模具;NPU更像街边专卖店,种类少但极致专精,顾客排队只能买那几样,但翻台率和每笔单子的利润都很好。
这样一看,三类加速器各自的"能力圈"就很清楚了:
- GPU:适合训练复杂的模型、研究性试验、算子千奇百怪的多框架混合负载。它用通用性换取了工程上的"确定能跑"。
- TPU:适合规模化、形状稳定、以矩阵乘为主的大规模训练和推理任务。投入足够的改造时间后,每瓦性能很可观,但改造过程比较复杂。
- NPU:适合推理链路已经稳定的低精度任务,尤其是移动端、边缘设备和对功耗极度敏感的部署环境。
1.3 另一个容易忽略的角度:每瓦算力与每美元算力
选型的本质是在两个约束之间找平衡:墙上的电表额度,和手里的预算额度。GPU通常拥有三种架构中最高的单芯片绝对性能,但功耗和单价也最高;TPU的绝对性能不低,但往往以整机、整集群的形式交付,对中小企业来说门槛偏高;NPU的绝对性能看起来最小,但单位瓦数和单位人民币能买到的有效识别速度通常最好,所以端侧设备才会清一色选它。
我在早期做选型时犯过一个错误:只看单卡FLOPS数,完全忽略功耗和算力利用率。后来有一段时间我把推理服务从GPU迁移到一个低功耗NPU加速卡上,硬件成本砍了差不多一半,但峰值算力的纸面数据只有原来GPU的几十分之一。结果实测之后,图像分类服务的单并发时延反而快了,因为小模型在小功耗的NPU上不需要等复杂的任务调度,也没有巨大的显存带宽浪费。这件事给了我很深的一个印象——后文讲指标时我会再展开说,峰值算力真的不是一切。
2. 先把单位对齐再说:从FLOPS到TOPS,看懂算力指标的换算和陷阱
2.1 FLOPS、TOPS、OPS到底是什么关系
选型最容易翻车的地方,是拿不同架构的数据直接比大小。GPU厂商喜欢标FP32或FP16的TFLOPS,TPU厂商喜欢标BF16或INT8的混合精度算力,NPU厂商则特别喜欢强调INT8、甚至INT4的TOPS。这三个单位看着像,实际差了十万八千里。
FLOPS是每秒浮点运算次数,TOPS是每秒整数运算次数,OPS则是两者混用的统称。换算的第一步是明确精度:一次FP32运算如果要拆成INT8运算,往往需要多次整数运算才能近似。所以理论上一块芯片标称100 TOPS的INT8算力,大体可能相当于50 TFLOPS的FP16算力的一半甚至更低,具体要看架构内是否有专门的浮点单元。
我说一个更实际的换算方法:你只看INT8 TOPS便宜不便宜,纯属被营销数字牵着走。真正该问的是"你跑的这个模型,这100 TOPS里能用上多少"。
2.2 理论峰值之外的三个隐形指标
选型表格里真正值得逐行对比的,是下面三个:
一是内存带宽。深度学习不只是算得快,还得把权重和中间结果及时搬进计算单元。假设你的模型有7亿参数,FP16权重大约是1.4GB。每次走一遍前向推理,理论上至少要读一遍这么多数据。如果你的加速器内存带宽只有100GB/s,光读权重就要花14毫秒,哪怕计算单元再闲也没用。带宽决定了很多模型的下限。
二是片上缓存与数据复用能力。GPU和TPU都会尽量把数据分成块,扔进片上缓存里反复使用,避免频繁访问外面的内存。缓存越大、调度越积极,实际拿到手的算力就越高。NPU通常缓存较小,但因为它专攻低精度算子,所需数据本身就少,所以能用较小缓存达到不错效果。
三是卡间互联带宽。大规模训练时,梯度同步比前向计算还耗时间。如果加速器之间的互联带宽跟不上,就会出现"一千块卡跑不出三百块卡三倍性能"的情况。
2.3 用"算术强度"判断负载到底缺什么
判断负载到底是"算得慢"还是"搬得慢",业界有个简单指标:算术强度,即一次数据搬运对应多少次计算。单位通常是FLOPS/Byte。比如某个矩阵乘,数据量是2MB,计算量是1GFLOPS,那算术强度就是500FLOPS/Byte。芯片的硬件设计里有一条所谓"平衡点"曲线,当你的负载算术强度低于这个点时,性能被带宽卡死,算力再高也没用;高于这个点时,才轮到计算单元说话。
我建议你在选型前拿自己的模型做一个粗略口径测量。具体做法很粗暴:跑一个batch前向,用性能分析工具记录每秒实际读取的显存流量和实际FLOPS,两者一除,就是真实场景下的算术强度。把这个数和候选加速器的规格对比,你很快会知道瓶颈在计算还是带宽。这个动作,做上半小时,胜过看十页产品宣传册。
3. 分场景实测视角:训练、推理和端侧分别该盯什么
3.1 训练场景:矩阵乘不是全部,工程生态才是
训练阶段选GPU仍然是综合负担最小的选择,这话我敢说,因为它的软件生态已经成熟到"任何模型都有前人趟过坑"的程度。但这不代表GPU在所有训练场景都是最优。如果你的任务是超大规模预训练,矩阵乘的形状非常规整、权重形状稳定,TPU脉动阵列的效率会明显优于同代GPU,加速比可能达到1.5到2倍。代价是改造成本很高,数据加载、优化器状态、混合精度策略都得照着它的调度习惯重写一遍。
这里要特别提醒:训练不只有GEMM(通用矩阵乘)。反向传播里的各种逐元素算子、Gather/Scatter、动态Mask、注意力计算,这些在GPU上是顺手的事,在TPU和NPU上可能需要拆解成多个子步骤。我见过某团队把一套BERT规模的模型从GPU迁移到TPU,花了两周时间调性能,最后发现瓶颈居然卡在LayerNorm算子上。原因很简单:脉动阵列天生擅长规整运算,遇到逐元素归约就得打折扣。
如果你不是做超大规模预训练,而是普通微调、小规模训练、频繁改模型结构,现阶段最稳妥的还是GPU。好钢不能全用在刀刃上,你的刀刃是快速试错和灵活调参,不是每瓦特算力最大化。
3.2 推理场景:时延、吞吐、成本,三个指标一块算
推理场景和训练场景的最大区别是:模型结构已经完全固定,各种算子可以提前融合和量化。这时候NPU的优势才真正显现出来。
推理服务有两条路线可走。一条是追求最低时延:比如实时语音交互,每一帧都要在几十毫秒内返回。NPU因为算子固化、任务调度轻量,往往能提供更稳定的P99时延,而GPU上的时延抖动反而更明显。另一条是追求最高吞吐:比如离线批量图片处理,你的目标是在限定电费内处理尽可能多的图片。这时候就得比"单位功耗吞吐",NPU的INT8算力和低功耗会显得格外诱人。
我自己的经验是,推理选型必须先定死两个数字:可接受的P99时延,和每千次推理的成本上限。把这两个数字写出来,再去逐项对比候选设备,基本不会跑偏。如果一项纸面算力指标比竞品高一倍,但时延稳定性做不到,它就不该进入第二轮筛选。
3.3 端侧场景:NPU上最典型的两个坑
端侧部署是最典型、也最考验人的NPU应用场景。第一个坑是算子覆盖不全。你的模型可能95%的算子都被NPU支持了,剩下5%的算子会退回CPU执行,这一退回,性能反而可能比全跑CPU还慢。因为数据要反复在CPU和NPU之间搬运,搬运成本直接被放大。我见过一个手势识别Demo,声称用了NPU加速,实际只有30%的算子跑在NPU上,推理时延比纯CPU还高。
第二个坑是量化误差。NPU普遍只支持INT8或更低位宽,权重和激活值的动态范围一旦掌握不好,精度就会掉得很难看。很多团队在PC上用FP32模型跑出95%准确率,一搬到NPU上直接掉到88%,而且找不出原因。其实原因通常很朴素:没有做校准集、量化范围选得太宽、某个敏感层没有保留浮点。常见对策是先做逐层敏感度分析,把对量化敏感的层保留在CPU或更高精度单元上,其余层再做INT8。
4. 选型决策框架:从负载推导需求,而不是被架构名词带着走
4.1 别让架构名词替你做决定
很多选型讨论到最后都变成站队:GPU派、TPU派、NPU派。但架构名词只是实现手段,真正该做的是从工作负载往回推需求。我把这个方法总结成一个四象限分类法,每次选型先给任务画坐标:
- 第一象限:训练为主、模型频繁变动、算子多样。答案大概率是GPU。
- 第二象限:训练为主、模型结构高度稳定、矩阵乘绝对主导。可以认真评估TPU。
- 第三象限:推理为主、性能要求高、可以接受量化改造。考虑NPU。
- 第四象限:推理为主、但算子每天都在改,或者要兼容多个框架。GPU或高规格NPU都行,看成本。
当然现实中会有很多混合态。我见过一类平台,白天批量训练一个多模态模型,晚上对生产流量做高并发推理。这种混合负载其实不适合单一架构硬扛,GTX级别的通用卡做训练,再加一块专用推理卡做线上流量,可能比全部用顶级GPU方案更省钱也更快。
4.2 一张可以直接抄的选型检查清单
这里我把多年选型踩过的坑浓缩成一张清单,每项都对应一个真实翻车场景。你可以直接照着逐条检查:
- 模型结构是否稳定到半年内不会大改
- 是否有明确可测量的性能目标,比如P99时延小于50毫秒
- 是否有功耗约束,比如整个边缘盒子只能给15瓦
- 是否允许引入新的框架和算子手工适配
- 团队里是否有人熟悉该加速器的调试工具链
- 数据量是否大到需要卡间互联,互联带宽是否已纳入评估
- 是否有量化校准能力,能否承受精度损失
- 供应商是否提供持续驱动和编译栈升级,而不是一锤子买卖
每一条都打上通过或存疑,如果某一行开始犹豫,就值得先做那个负载的mini落地上板测试,再决定买不买。
4.3 混合部署与渐进式改造思路
老实说,绝大多数团队的算力规划都应该走渐进式改造,而不是一次性全换。比较好的做法是把模型分成两类路径:一类是"探索型负载",允许频繁改结构,统一跑在GPU上,保证迭代速度;另一类是"稳定型负载",上线后结构固定,再做迁移和优化。稳定型负载迁移到NPU或TPU后,有时候能把单位请求成本压到原来的一半以下。
我最近一次做图像质检项目,就采用了这种混合思路:白天训练模型阶段用GPU,模型定稿后把线上推理的数据增强、卷积主干和分类头在NPU上跑INT8量化版本,并把量化敏感的"注意力分支"留在CPU上。最终计算成本大约压低了40%,而精度只掉了0.2个百分点。混合部署听上去不那么"完美",但生产环境本来就该以性价比和稳定为宇宙第一法则。
5. 迁移落地的完整教训:算子对齐、精度容忍与性能验证
5.1 迁移前先做算子级风险清单
一旦确定了要从GPU迁到TPU或NPU,你第一件要做的不是装驱动,而是生成一份算子级风险清单。我通常的做法是拿一份训练好的模型文件,导出计算图之后,逐层扫描,把每个算子分类成三类:完全映射、需要改写、不支持退回CPU。这一步纯粹是体力活,但能提前暴露90%的坑。
拿常见视觉模型举例:常规卷积、BatchNorm、ReLU、Pooling这些在NPU上基本都有对应引擎;而像可变形卷积、动态条件分支、复杂的topk和自定义Loss,就很有可能是"需要改写"或者"不支持"的类型。把这些算子单独拎出来评估风险,比直接整模型扔上去跑、然后对着报错日志猜半天要高效太多。
5.2 精度对齐:量化后的误差容忍怎么设
精度对齐是迁移中最容易被低估的环节。很多人只盯着准确率看,比如"原来95分,现在94.8分,还行"。但生产环境里的问题往往藏在极端样本里,所以除了整体准确率,还应该对比逐条输出的数值差异。
我建议按照这样一个流程来做精度验证:先在原框架用FP32把测试集推理结果保存下来,作为基准;再把同一批样本在新加速器上、按目标精度(比如INT8)跑一遍;然后计算每条样本的输出差MAE,把差得最离谱的5%挑出来分析。你可以设置容忍阈值,比如分类任务允许95%条目的预测标签一致,且MAE不超过某个绝对数。一旦出现系统性偏差,优先找出是哪一层导致的,把那层单独切到高精度或CPU上重跑。
要是量化后精度掉得很厉害,先别急着怀疑芯片,大概率是校准集选得不对。校准集要覆盖真实部署时的数据分布,而不能随便抽几百张训练集图片,尤其不能全是易分类样本,那样会把动态范围估窄。
5.3 性能验证别只看总时延,要看拆解和稳态
性能测试最容易产生的错误判断,是拿第一次跑出来的端到端时延就下结论。真实世界的加速器在冷启动时往往很慢,跑几个batch后温度稳定、缓存命中上来了,性能才会进入正常曲线。我的经验是至少先跑10次预热,再用后50次的平均值作为代表,同时记录P95和P99而不是只盯P50。
除了总时延,务必要拆开每一段算子的耗时。加速器自带的性能剖析工具通常能给出每个算子的平均执行时间和调用次数。你要做的是一眼找出"耗时占比最大但又不在预期中的算子",那些就是迁移不完整、数据搬运过度的症状。最常见的问题是有几个算子在CPU上回退执行,导致CPU和加速器之间反复搬运数据,时延直接在搬运中翻倍。
5.4 我反复踩过、但你可以绕开的几个坑
总结几个与具体品牌无关的通用教训。第一,永远不要在迁移当天做重大发布,至少留出一周做灰度验证和回滚准备。第二,不要迷信"算子全部支持"的兼容性文档,文档说支持,和实测性能不崩是两件事。第三,厂商给的样例代码可以直接跑,但一定要拿自己的真实数据和真实batch shape再测一次,因为很多性能数据是在最优情况下测出来的,真实shape一旦不规则,专用加速器性能波动非常大。第四,保留一个GPU备用通道,线上出问题时你能在30分钟内回切到稳定基线,而不是干瞪眼等待厂商工单回复。
回到开头说的话题。选型这件事,本质是一场"算力峰值、功耗预算、工程兼容性"的三方谈判。GPU提供了通用性与确定性的安全网,TPU在特定形状的大规模矩阵运算里做到了极致效率,NPU则用低精度和专用化换来了极低功耗与单位成本。没有绝对最好的加速器,只有最适合你当前负载阶段的那一款。按照我今天讲的这套逻辑,先画负载类型,再算算术强度,然后跑性能验证,最后做混合部署兜底,你会比大多数只看参数表的人离真实答案近得多。