做了这么些年AI推理平台和异构算力调度,我明显感觉到2024年到2025年这两年间,推理侧的计算架构正在从“GPU单打独斗”向“GPU、ASIC、存算一体设备混部协同”快速演进。过去我们聊推理优化,翻来覆去就是显存、batch size、量化精度,现在不一样了,机房里开始出现不同的芯片形态,一套调度系统要统一管理多种加速器,按任务特征把请求分发到最合适的计算单元上。很多人第一次听到“多芯协同”觉得是概念,但实际跑过才发现,这是成本、功耗和性能三座大山倒逼出来的必然选择。
这篇文章我打算把自己在架构选型、硬件测试和平台落地过程中看到的东西,完整梳理一遍。包括GPU为什么还是主力、ASIC和存算一体设备到底卡在哪儿、以及真正把三种芯片放到同一个推理服务里时需要解决的调度、驱动、显存和框架兼容问题。无论你是做AI平台运维、大模型推理服务,还是正在评估推理算力方案,这篇文章都值得花十分钟看完。
1. 为什么推理侧先感受到算力焦虑
1.1 训练堆算力,推理卡在效率上
训练大模型和跑推理,对算力资源的需求逻辑完全不一样。训练阶段的核心目标是“把模型收敛出来”,这个阶段可以堆上千张GPU,用大规模并行去压缩训练时间,哪怕算力利用率低一点、通信开销大一点,也能接受,因为总成本摊到整个研发周期里是可控的。但推理不一样,推理面对的是持续不断的线上请求,每次请求都有明确的延迟要求。我见过不少团队在训练阶段拿到很漂亮的吞吐数据,一上生产就露馅:GPU利用率上不去,显存带宽吃不满,响应时间忽高忽低。
这里面最核心的差异在于计算模式的“重复性”。训练是反复迭代同一批数据,每一次前向和反向传播都能把矩阵运算规模拉满,天然适合GPU这种大规模并行架构。推理则是一个模型要服务无数个不同请求,每个请求的输入长度不一样、需要的计算量不一样,而且有严格的时延上限。这导致推理场景里,单卡能同时处理的请求数、显存能塞下的KV Cache大小、算子能否融合、访存是否局部化,这些因素比纯粹的计算吞吐更关键。
所以推理侧的“算力焦虑”从来不是怕芯片不够快,而是怕芯片的算力发挥不出来。这也是为什么GPU这种通用加速器,在纯推理场景里其实有很多算力是被浪费掉的。你买一张旗舰卡,理论算力看起来很吓人,但在小batch、短序列的在线推理场景下,能跑出的有效算力可能只有峰值的两三成。当这种浪费被乘以几千个节点、再乘以一年8760个小时,数字就非常惊人,逼着人开始寻找更“专用”的路径。
1.2 GPU独占时代出现的第一道裂缝
前两年大家做推理服务,选型基本没悬念,就是NVIDIA的GPU,顶多加个推理引擎优化一下。但最近这一年,我明显感觉到GPU独占的格局出现裂缝了,而且裂缝是从两个方向同时裂开的。
第一个方向是成本。高端GPU的价格持续高位,而且供应周期拉长,很多团队根本等不起。我接触过几家做AI应用的公司,业务量上来了,推理资源不够用,想去加卡,结果要么没货,要么预算批不下来。这种情况下,把一部分高吞吐、低时延要求的任务放到ASIC芯片上,用大算力换低成本,就变得非常有吸引力。尤其像Transformer解码这类结构相对固定、计算模式清晰的任务,ASIC带来的成本优势是实打实的。
第二个方向是功耗。GPU的功耗大家心里都有数,一张卡就是几百瓦,整机下来动不动就两三千瓦。数据中心机柜的电力配额是有限的,当GPU数量堆到一定程度,电就变成了比算力更稀缺的资源。我见过有客户为了在有限电力下扩容,宁可采购功耗更低但性能也低一些的国产加速卡或ASIC方案,也不愿继续加GPU。这说明推理侧的选型已经不是单纯的性能竞赛,而是一场“每瓦特能产出多少有效推理请求”的效率竞赛。
1.3 多芯协同不是概念,而是成本逼出来的选择
很多人听到“多芯协同”觉得这又是个高大上的技术概念,但以我的实际经验,真正推动这件事的其实是算力成本。当一个平台里既有GPU又有ASIC还有存算一体设备时,你不用刻意去“协同”,成本压力会逼着你把不同类型的任务拆开,塞到性价比最高的芯片上去。
打个比方,一个推理服务里通常同时存在几种特征差异很大的请求:有的是并发量巨大、延迟要求高、计算模式固定的“长跑型”请求,适合ASIC;有的是逻辑复杂、算子多样、需要频繁if-else的“短跑型”请求,适合GPU;还有的是访存量极大、计算量不大、主要在搬运数据的任务,这种如果能让数据在存储附近直接算完,存算一体设备就有优势。你不能让所有流量都走同一条路,那是对资源最大的浪费。
所以多芯协同的本质,是让“任务特征”和“芯片特性”匹配起来。它不是一个可选优化项,而是在规模化推理成本压力下,一个成熟的算力平台必须走的路。我们后面聊的调度、显存管理、框架适配,本质上都是在为这种“匹配”服务。
2. 三条技术路线的真实边界
2.1 GPU:高性能背后的显存与功耗两堵墙
GPU在推理侧的地位短期内还是无法撼动。它的优势在于通用性和软件生态。PyTorch、TensorRT、vLLM这些框架天然支持CUDA,模型从训练到推理基本无缝衔接,做量化、做算子融合、做并行切分都有成熟的工具链。对绝大多数团队来说,GPU仍然是部署推理服务的默认选项,因为它意味着“最少的时间成本”和“最低的工程风险”。
但我长期用下来,GPU在推理场景里有两堵墙绕不开。第一堵是显存墙。大模型推理的显存消耗主要表现在两处,一处是模型权重,另一处是KV Cache。模型权重可以通过量化压缩,但KV Cache会随着并发请求数和序列长度动态增长。当显存被KV Cache占满时,哪怕GPU算力还有大量空闲,系统也只能通过降低并发或淘汰请求来维持稳定,这时候你再好的GPU也发挥不出来。我测过一张80GB显存的卡,理论并发很高,实际跑长上下文任务时,显存先撑爆的情况占了大多数。
第二堵是功耗墙。GPU的能效比在推理任务上并不理想,尤其是处理小batch请求时,大量计算单元处于空闲状态但基础功耗还在。我做过一个简单的测算:单张GPU处理一个小batch推理请求的功耗,跟处理一个满batch请求的功耗差距不到20%,但吞吐差距可能是好几倍。这意味着如果你业务流量有波峰波谷,波谷时段GPU大部分算力是空转的,电费却照付不误。这也是我觉得GPU不可能在推理侧永远一家独大的核心原因。
2.2 ASIC:极致效率与场景绑定的双刃剑
ASIC最近讨论热度很高,因为它在特定推理场景下能做到比GPU高一个数量级的能效比。逻辑上很好理解:GPU是通用芯片,要照顾成千上万种计算模式,芯片面积里塞了很多你可能永远用不到的模块;而ASIC把电路设计直接对准Transformer解码、卷积、矩阵乘这些固定算子,没有多余功能,晶体管利用率极高。
以现在最主流的大模型推理任务为例,大部分时间都花在矩阵乘法和Attention计算上。矩阵乘法是典型的计算密集型任务,适合用大规模乘加单元阵列来加速;Attention则是访存密集型任务,瓶颈在数据搬运,不在计算。好的ASIC设计会把这两种负载分别用不同的硬件模块处理,并且把数据流设计成流水线模式,让计算单元始终处于饱和状态。我实测过某款推理ASIC,在7B模型batch size为1的场景下,单芯片吞吐与一张主流GPU相当,但整卡功耗只有后者的三分之一。
但ASIC的另一面也很明显,就是场景绑定。你做了一款专门针对Transformer的芯片,遇到非Transformer结构的模型就“水土不服”。我遇到过客户想用ASIC跑视觉模型,结果算子支持不全,性能直接掉到GPU的十分之一。ASIC不像GPU那样“什么都能跑”,它对模型结构、精度格式、算子类型都有严格限制。部署前你得花大量时间做算子迁移和性能验证,这个隐形成本如果没算清楚,ASIC带来的硬件成本优势可能全被工程成本吃掉。
2.3 存算一体:打破冯·诺依曼瓶颈的工程化挑战
存算一体是目前听起来最颠覆、落地起来最痛苦的路线。传统计算架构里,数据和计算是分离的:数据存在内存或显存里,计算单元要先把数据读过来,算完再把结果写回去。这套流程在推理场景里有一个致命问题:Transformer的Attention计算需要频繁访问KV Cache,如果数据量超过缓存容量,计算单元就只能长时间等待数据搬运,算力再高也白搭。存算一体的思路很直接,就是在存储单元旁边甚至内部直接做计算,让数据不用长途跋涉。
我刚接触存算一体的时候觉得这个方向确实有道理,因为大模型推理的瓶颈已经从计算转向了访存。模型权重动辄几十GB,KV Cache也是GB级别,每次请求都要重复读取权重、更新缓存,数据搬运量极其惊人。如果用存算一体在存储阵列内部完成矩阵乘法和Attention计算,理论上可以大幅降低数据搬运开销,从而提升能效和降低延迟。
但工程化的坑比我想象中多。存算一体目前主要还停留在特定算子的加速上,要支持完整的推理模型,需要把模型切分成“可以存内计算的部分”和“必须走传统计算的部分”,再把两部分组合起来。这种混合执行模式对编译器要求极高,而且芯片的实际性能受制于模拟计算精度、单元间通信带宽、散热等工程因素。我自己测过一款存算一体原型芯片,在特定矩阵乘法上的能效确实漂亮,但一跑完整模型,因为数据需要在存算单元和外部处理器之间来回倒腾,端到端延迟反而比GPU还要差。这说明存算一体要走进生产环境,还有很长的路要走。
3. 落地一套多芯协同架构的实操记录
3.1 异构资源调度:GPU为主、ASIC为辅的分层设计
我把一套真实跑过多芯协同推理服务的架构拆开讲。整个平台目前管理了三种计算资源:GPU、ASIC推理卡,还有少量存算一体设备作为试验节点。我的核心设计思路是“GPU兜底、ASIC分流、存算一体做探索”,具体来说,GPU负责所有模型的默认推理,保障服务的完整性和稳定性;ASIC只处理已验证过性能达标的固定模型和固定算子;存算一体节点则单独隔离,用影子流量跑测试。
调度层面我没有自研一套全新的调度器,而是在现有的Kubernetes基础上做了扩展。通过Device Plugin机制把不同芯片的资源信息上报给kubelet,然后在调度器里加入自定义的筛选逻辑:根据模型类型、请求延迟要求、当前各芯片负载情况,决定把Pod调度到哪类芯片上。这样做的最大好处是能让研发团队继续使用标准的容器化和编排工作流,不需要为了上ASIC就重写整套服务。
这里有一个很关键的设计点:不要把调度的原子单位设成“整张卡”。GPU可以被MIG或时间片切分,ASIC一般也支持多路推理并发,如果你的调度器只能整卡分配,很容易出现一张卡只跑了一个小模型,其他算力全部浪费的情况。我建议把最小的调度单位细化到“算力分片”,比如一张卡支持4路并发推理,就把它切成4个分片上报给调度器,每个模型按需申请1个或多个分片。实测这样资源利用率能提升30%以上。
3.2 显存、带宽与数据搬运的三维权衡
多芯协同架构里,最难的不是把任务调度到不同芯片上,而是管理不同芯片之间的数据流动。很多人的直觉是“任务分到哪就在哪算完”,但实际的推理服务往往不是一个模型独占一张卡,而是多个模型实例跨卡部署,同时请求还可能要走prompt缓存、embedding查询、结果后处理等多个环节。每一步都可能涉及数据和中间结果的跨芯搬运。
我整理过一个简单的决策模型,每次数据传输前都先问自己三个问题:数据多大?搬运频率多高?目标芯片计算能省多少时间?如果一份数据只有几KB、偶尔搬运一次,那迁移成本可以忽略;但如果是大模型权重这类GB级数据,搬一次就要几十秒,那每次芯片间切换都是一次灾难。所以我们平台做芯片间调度时,有一条硬性规则:模型权重必须常驻目标芯片的本地存储,推理过程中绝不动态搬运。
显存管理上我也踩过不少坑。GPU侧有大显存优势,ASIC侧显存小但访问效率高。初期我试图做“全局统一显存池”,希望把不同芯片的显存抽象成统一资源,结果发现厂商之间甚至不同架构之间的显存管理接口差异巨大,强行统一的结果是性能严重劣化。后来我放弃了这种理想化的统一内存方案,改为按芯片类型分池管理,调度器在分配任务时同时考虑算力余量和显存余量,显存不匹配的宁可排队也不做数据迁移。这个妥协换来了稳定性,牺牲了一点灵活性。
3.3 从驱动到框架:协同平台的组装路线
说说我们是怎么把一个多芯协同平台从零组装起来的。整个过程可以分成四步,每一步都有对应的关键动作和容易踩的坑。
第一步是环境摸底。先整理好机房里所有芯片的型号、驱动版本、固件版本、支持的计算精度、显存容量和通信接口。不要小看这一步,我见过太多团队上来就写代码,结果跑了两周才发现某款芯片在特定驱动版本下支持不了目标模型需要的算子。我的建议是第一步先建一张硬件能力清单,把每类芯片的Capability Matrix整理出来,后面所有软件决策都拿这张表对照。
第二步是驱动和容器化适配。GPU这边走标准流程,装好驱动、CUDA、container toolkit,然后用nvidia-container-runtime接管容器GPU可见性。插一句,不少人在装驱动时习惯用在线安装,但我强烈建议在离线环境下载好对应版本的runfile和依赖包再装,因为在线源随时可能变,版本一旦漂移,后面排查问题会非常痛苦。
ASIC和存算一体设备稍微麻烦一点,它们一般提供自己的运行时和容器插件,需要把设备挂载到容器里。我们当时折腾了两周时间才搞定一个稳定版本。常见的坑包括:设备节点权限没放开、容器内缺少固件文件、运行时库版本和用户态驱动不一致。我的经验是把这些设备的挂载逻辑全部模板化,用Helm Chart统一管理,避免每个人手动配。
第三步是框架对接。GPU走常规路径,PyTorch直接调用即可;ASIC一般要求用厂商自研的推理引擎,把模型从PyTorch导出成中间格式再转换。这里要注意一点:并不是所有PyTorch算子都能转成ASIC支持的算子,转换前最好先用模型结构扫描工具做一次算子兼容性检查,把不支持的算子提前找出来。
存算一体设备就更特殊了,目前基本没有成熟的推理框架对接方案,更多是用厂商提供的DSL或者底层库手写算子。我们把存算一体阶段的目标定得很低,只让它跑一个经过验证的矩阵乘法算子,然后逐层往上构建。第四步是流量验证,先让影子流量跑一周,对比GPU和ASIC在相同模型上的延迟和成本,再决定是否切真实流量。
4. 踩坑实录与问题速查表
4.1 多芯混排下,驱动和容器版本到底谁说了算
同时管理GPU、ASIC和存算一体设备,最头疼的问题就是驱动和容器版本冲突。GPU要求CUDA版本不能低于某个阈值,ASIC可能要求内核版本在某区间,存算一体的固件只认特定驱动。三者共用一个宿主机时,很容易出现“装好了A卡的驱动,重启后B卡识别不到了”的情况。
我的踩坑经历是这样的:有一次机房里加了一款新的ASIC卡,安装它的驱动时自动升级了内核的一个头文件包,结果重启后GPU容器全都启动失败,报的是CUDA driver version mismatch。排查了半天才发现是内核头文件版本变了,导致NVIDIA内核模块重新编译后和新驱动不匹配。从那以后,我定了一条铁律:任何驱动安装操作之前,必须做系统快照,装完后立即验证所有芯片的可用性,验证脚本要提前写好。
4.2 显存容量到底该按推理还是训练来测算
这个问题被问过非常多次,我每次的答案都是:如果你面向的是推理场景,显存容量必须按推理来测算,而且要把KV Cache算进去。很多人给推理服务配显存时只算了模型权重的大小,比如一个7B模型量化后4GB,就觉得16GB显存够用了,结果上线一跑,并发稍微上来一点KV Cache就把显存撑爆了。
我的经验公式是:所需显存 = 模型权重大小 + KV Cache平均值 + 推理引擎和框架的常驻内存 + 冗余余量。KV Cache的大小跟模型层数、注意力头数、隐藏层维度和并发请求的上下文长度直接相关,LLM推理框架一般会提供估算接口。我给团队的指导原则是:宁可用低精度的量化换显存空间,也不要为了省显存降低并发,因为并发才是推理服务吞吐的生命线。
4.3 调度器抢占导致的“假死”排查
多芯协同平台上线之后,我遇到过一个非常诡异的现场:GPU节点看起来都没满载,但新增请求一直排队等不到资源,而ASIC节点负载很低,却没有任何请求被调度过去。从监控面板看一切正常,但整个服务就像“假死”一样。
排了两天查不出原因,最后翻日志发现是调度器的抢占机制出了问题:某个长期运行的GPU任务触发了抢占,把原本要调度到ASIC节点的Pod删掉重排,结果新的Pod又因为GPU资源不够被卡在Pending状态,而ASIC节点的资源资格在调度器缓存里被标记成“正在被清理”,导致后续请求一个都过不去。这个问题其实很典型,调度器在异构场景下做抢占时,不会自动意识到“其他芯片的资源也可以用”。清理掉那个卡死的Pod后,我把调度策略改成“非必要不抢占”,同时给ASIC节点设置了独立的等待队列,从流程上避免跨芯片的调度锁死。
4.4 存算一体芯片接入现有框架的地狱式兼容
如果你手头有存算一体的设备,想让它直接接入PyTorch生态,我建议你做好心理准备。大部分存算一体的厂商SDK还停留在“提供底层矩阵计算库”这个阶段,根本不支持PyTorch中的自动求导、算子分发这些机制。你没办法像换GPU一样,把模型. cuda() 改成就地计算完事。
我们的做法是在模型里把能用存算一体的关键算子(比如大矩阵乘法)挑出来,单独封装成一个自定义autograd Function,在前向和反向时调用存算一体设备提供的接口。这个过程相当繁琐,而且精度对齐非常痛苦,常常出现同一份权重在GPU上是fp16、到了存算一体设备上变成低精度模拟计算后掉点严重。我只能建议大家在模型精度敏感度测试通过之前,不要轻易把真实流量切到存算一体设备上。
4.5 推理平台问题速查表
我整理了一份多芯协同推理平台的问题速查表,很多问题都是反复出现过的,可以直接拿来对照。
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
| GPU容器启动报CUDA驱动错误 | 内核升级导致NVIDIA模块不匹配 | 查看nvidia-smi是否正常输出,必要时重装驱动 |
| ASIC卡温度正常但无推理输出 | 用户态运行时版本与固件不一致 | 对照厂商兼容矩阵,检查固件和runtime版本 |
| 调度器一直有任务Pending | 芯片资源分片被错误标记 | 查询调度器缓存,清理异常Pod状态 |
| 多芯混部后延迟飙升 | 任务频繁在不同芯片间切换 | 检查模型权重是否做了本地常驻 |
| 存算一体设备精度掉点严重 | 模拟计算精度与训练不一致 | 单独验证该算子在全精度数据下的误差 |
| CPU内存持续上涨 | 推理框架的显存分配策略异常 | 开启显存池复用和实例回收功能 |
这张表不是万能的,但它能帮你快速定位多芯协同场景里大部分高频问题的排查方向。实际运维时还要配套完整的监控和日志系统,才能做到更早发现、更早处理。
根据我个人这两年的实际体会,做多芯协同平台最大的挑战不是技术实现,而是心态。你可能花了很长时间把一个模型在ASIC上跑通了,结果客户换了个模型,所有算子兼容性工作又要重来一遍。这种情况下,重要的不是追求“全场景多芯协同”,而是找准你自己的业务重心,把最核心最典型的推理路径打磨到极致,把其他场景继续留在GPU上兜底。算力架构演进从来不是一夜之间完成的,它有惯性、有妥协,也有冲突。如果你正在规划推理侧的基础设施,我的建议是:从现在开始就关注多芯协同,但要从一个小场景试起,让数据和实际结果推动你下一步的决策。