从单卡跑通到多卡训练原地崩溃,中间隔着的就是AI Infra这层巨大的知识盲区。我见过太多算法背景的同学,模型结构信手拈来,一部署到真实集群环境就抓瞎——GPU利用率上不去、训练任务跑着跑着就OOM或者直接断掉、模型上线后推理延迟和成本双双爆炸。这些问题看起来是“环境问题”,本质上却是AI基础设施的工程问题。
这篇笔记是我对AI Infra知识全景的一次系统性梳理,不是某个具体工具的说明书,而是帮你把散落在各处的知识点拼成一张完整的地图。内容覆盖算力资源管理、分布式训练、训练稳定性、推理服务化,以及入行AI Infra的学习路径。适合从应用开发往底层工程走的工程师,也适合刚接触大模型部署、想搞清楚背后原理的同学。我会尽量用大白话和真实场景来讲,没有故弄玄虚的术语堆砌。
1. AI Infra解决的核心矛盾:算力的昂贵与不稳定
1.1 三个场景帮你建立直觉
先说第一个场景。某公司训练一个视觉模型,买了一批加速卡,结果发现集群平均利用率只有25%左右。查下来不是模型写错了,而是数据管线的读取延迟太高,显卡每轮迭代都在干等数据。这种“算力资源大量闲置”的问题,就是AI Infra要解决的第一件事。
第二个场景。某个训练任务在大规模GPU集群上跑了三天,快出结果的时候节点故障导致任务直接失败。因为没有做好的容错和断点续训机制,所有计算全部作废,商业发布被迫延期。训练任务跑得久、容易崩、恢复代价极高,这是AI Infra区别于常规后端系统的核心痛点。
第三个场景。模型训练好了,部署上线之后发现推理成本高得离谱。单张卡只能扛几十路并发,延迟还经常超时。后来通过连续批处理优化和混合精度推理,同样的硬件撑起了几百路并发,成本骤减。这背后考验的是推理服务化能力,也是AI Infra的重要一环。
这三个场景分别对应了AI Infra的四个核心工程问题:怎么做才能让昂贵的算力利用率最大化?怎么让长周期训练任务稳定不崩?怎么把数据、存储、网络这些周边系统做成与训练配套的流水线?怎么让训练好的模型用最低成本对外提供服务?
1.2 AI Infra与传统后端基础设施的差异
传统后端基础设施的核心资源是CPU、内存和普通存储,它们的特征是相对便宜、稳定、可预期。AI基础设施的核心资源是加速卡,特点完全相反:单卡价格极高、故障概率远高于普通CPU机器、性能对周边环境极其敏感。
可以这么理解:传统后端像运营一条常规货物运输线,车辆便宜、路况稳定,重点是调度逻辑;AI Infra像运营一支F1车队,赛车昂贵且娇贵,任何一点微小的部件问题、维修耗时都会直接影响比赛成绩。你的工作不只是调度车,还得时刻维护车、保障供油、处理意外翻车。
| 对比维度 | 传统后端 | AI Infra |
|---|---|---|
| 核心资源 | CPU、内存、磁盘 | 加速卡、显存、高速互连 |
| 资源成本 | 中等,可横向堆叠 | 极高,单卡代价巨大 |
| 失效模式 | 较稳定,重启恢复快 | 高故障率,恢复代价大 |
| 性能瓶颈 | 常为逻辑与IO | 常为显存带宽、通信延迟 |
| 核心指标 | QPS、响应时间、可用性 | 算力利用率、训练吞吐、每token成本 |
这个差异决定了AI Infra工程师的工作方式:不是“把功能跑通就行了”,而是要在资源受限的前提下,不断追求极致效率与稳定性。
2. 全景知识地图:从一块加速卡到一套模型服务
2.1 六层架构模型
我自己的学习经验是,可以把AI Infra拆成六个层次去理解,每一层都有自己的核心问题和技术栈。高层的设计决策会传导到底层,底层的物理约束会影响上层的可行性。
| 层次 | 核心解决问题 | 关键技术关键词 | 入门切入点 |
|---|---|---|---|
| 硬件与算力层 | 算力从哪来、怎么衡量、怎么选型 | 加速卡、显存、高速互连、功耗 | 看懂产品规格表,跑一次性能基准 |
| 资源管理层 | 多任务如何共享、隔离、调度 | 容器、编排调度、任务队列 | 自己搭一个多卡调度环境,提交任务 |
| 数据与存储层 | 训练数据怎么喂得快、存得稳 | 并行文件系统、缓存、数据加载器 | 监测数据加载耗时,优化读取流程 |
| 训练编排层 | 大规模模型怎么跨卡协同训练 | 分布式训练框架、混合精度、断点续训 | 跑通数据并行,再做模型并行 |
| 模型服务层 | 训练完的模型怎么高效上线 | 推理引擎、批处理、量化 | 用现成推理框架部署一个模型 |
| 可观测与运维层 | 系统状态如何感知、问题如何定位 | 监控指标、日志、链路追踪、基准测试 | 建立GPU利用率监控,设置告警 |
2.2 每层的核心能力与学习切入点
硬件与算力层是最容易被忽视的。很多人写代码的时候根本不关心底层硬件特性,等到通信成为瓶颈或者显存不够用才回来看手册。我建议从阅读某主流加速卡的规格表开始,弄清显存大小、算力单位、卡间通信带宽这几个关键参数,然后用性能测试工具实测一次训练与推理的吞吐量。
资源管理层解决的是“多个人、多个任务怎么用同一批卡”。核心思路是以容器为粒度打包训练环境,由编排调度系统统一管理。学习时不必从源码入手,先把“提交一个训练任务、查看调度情况、动态扩缩容”这几个基本操作跑通,再逐步理解调度策略。
数据与存储层是训练系统里最容易被低估的一环。很多人以为GPU多买几块训练就一定快,结果数据加载成了木桶短板。学习重点要放在:数据集如何存放、读取是否并行、缓存如何设计,以及断点续训时需要保存哪些元数据。
训练编排层是AI Infra的核心地带。这里要理解分布式训练的基本范式,包括数据并行、模型并行、流水线并行之间的区别,以及通信库在背后做了什么。建议先用小模型在自己的多卡机器上做一次数据并行训练,观察通信压力和效率变化。
模型服务层把训练成果变成在线服务。核心指标从“训练吞吐”切换为“推理延迟”和“吞吐成本”。入门时先部署一个标准模型,用推理基准工具测量延迟与并发关系,再去理解连续批处理、量化推理等技术。
可观测与运维层是贯穿所有层次的底座。没有监控,再好的系统也像蒙眼开车。至少要建立几个基础指标:GPU利用率、显存占用、数据加载耗时、通信耗时、迭代吞吐。从这些指标的异常走势反推系统瓶颈,是AI Infra工程师最常用的工作方式。
3. 算力与显存:训练性能优化的第一把尺子
3.1 用三个指标衡量训练系统快不快
衡量训练系统的性能,不能只看“显卡厉不厉害”,至少要同时看三个指标:算力上限、显存带宽、通信带宽。
算力上限指的是每秒能完成的浮点运算次数,决定了理论最快运算速度。显存带宽指的是数据从显存读取到计算核心的速度,很多算子实际上被这个指标卡住。通信带宽指的是多卡之间交换数据的速度,分布式训练里一旦通信跟不上,算力再高也会空转。
打个比方。算力上限像是水泵的铭牌功率,代表最高能打多少水;显存带宽像是连接泵和蓄水池的管道粗细,管道细的话水泵根本发挥不出额定功率;通信带宽则是多个水库之间的调水通道,水库再大,调水干线不行,整体供水量也上不去。
训练一笔数据的过程,通常分为“把数据搬运到显存”“在计算单元之间做运算”“必要时把结果同步给其他卡”。三个阶段中的任何一个慢了,整体就慢。这就是为什么很多人疑惑“我的卡明明很贵,为什么GPU利用率上不去”——很可能瓶颈根本不在计算,而在搬运和同步。
3.2 分布式训练的基本玩法
当一块卡放不下模型或者算力不够时,就需要把训练拆到多块卡上。最常见的几种范式各有侧重:数据并行是每张卡放同一份完整模型,各吃一块数据,算完同步梯度;模型并行是把一个大模型切成几段,不同的卡负责不同的层;张量并行是对某一层内部的矩阵运算切分;流水线并行则把不同层分配到不同设备,让数据像流水线一样依次流过各段。
同步梯度的过程是最容易忽视成本的地方。数据并行场景下,每轮迭代结束都要做一次全局梯度合并。这个合并操作在通信库中叫AllReduce,它需要让所有卡先求出平均值,再把结果广播回去。通信次数随卡数增加呈平方级增长,所以卡越多,通信开销越大。
我见过一个很形象的类比:一群人要统计所有人的平均分,最简单的方式是每个人都把自己的分数喊一遍,然后各自加起来除以人数。这个“喊一遍再合并”的过程就是AllReduce。如果参与的人太多、地方又远,单单“喊话”的时间就会超过“算分”的时间。
3.3 实际案例:GPU利用率从30%到80%的排查过程
某个模拟项目X在训练一个图像分类模型时,单卡GPU利用率长期徘徊在30%左右。第一反应是模型太小、计算密度不够,但换了大模型后利用率依然不高,说明问题不在计算本身。
排查的第一步是看数据加载耗时。给训练脚本加上时间统计后发现,每次迭代里CPU读取batch的时间平均是180毫秒,而GPU实际计算只需要100毫秒,数据加载几乎成了两倍瓶颈。进一步追查,问题是每张卡都在同一个共享存储路径上逐张读取图片,还做了大量重复的随机读取,文件打开开销极高。
优化过程分三步。第一步把图片提前打包成大文件,减少随机小文件读取;第二步启用并行读取和预取,让CPU在GPU计算的同时准备下一批数据;第三步利用缓存热点数据,避免重复走存储网络。改完之后,单卡利用率从30%升到接近80%,整个训练时间缩短一半以上。
这类问题的通用排查顺序是:先看数据加载,再看算子类型,然后看通信压力,最后看是否有频繁的日志写入或评测动作干扰训练主循环。数据层往往是第一个需要怀疑的对象。
提示:加设备并不一定能线性加快训练。遇到“卡多反而更慢”的情况,优先查通信和存储,而不是继续加机器。
4. 训练稳定性:跑得久比跑得快更重要
4.1 训练跑崩的原因和排查顺序
训练任务不是跑完就算成功,跑得稳、能恢复才是工程级的要求。实际训练中最常见的故障有三大类:训练过程出现数值异常(NaN或损失值飙升)、节点和容器因硬件或网络问题被中断、以及长时间训练后模型收敛效果明显变差。
数值异常排查有一个固定顺序:先检查学习率是否过大,再看混合精度相关的缩放逻辑是否正确,然后检查训练数据里是否有脏数据(例如损坏的图片、缺失的文本、乱码字段),最后排查代码中的梯度更新逻辑。不要一上来就怀疑模型结构,数值爆炸在大多数情况下是工程配置问题。
节点中断恢复的核心手段是断点续训机制。它会在训练过程中周期性保存模型权重、优化器状态、当前迭代轮次和随机数生成器状态。只需要保存模型权重是不够的,优化器状态丢失会导致训练精度明显下降;随机状态丢失则可能让后续数据增强不可复现。
下面给出一个典型的恢复点配置文件写法,注意包含恢复点保存周期、保存路径和传输方式,这部分是很多人容易忽略的。
checkpoint: save_interval: 1000 # 每1000轮保存一次 max_to_keep: 5 # 最多保留5份历史恢复点 storage_path: /data/checkpoints async_save: true # 异步保存,避免阻塞训练 save_optimizer: true # 必须保存优化器状态 save_rng_state: true # 保存随机数状态,保证可复现 compression: true # 压缩后再上传,减少存储压力4.2 故障恢复机制的设计细节
断点续训并不是保存一下就行,里面有很多工程细节。保存太频繁,存储开销和IO开销都会影响训练性能;保存太少,故障后丢失的进度过大。一个常见策略是每隔N轮做一次轻量保存,每N倍间隔做一次重量保存,并根据训练总量动态调整频率。
另一个细节是异步保存。如果保存操作是同步的,训练主线程会被阻塞,每1000轮就卡一次,累积起来可能损失数小时训练时间。异步保存配合独立临时目录,先写好再原子替换,可以大幅减少对主训练循环的影响。
恢复点的“最后一公里”是恢复验证。我在实际工作中见过不少案例:保存文件存在,损失函数也能从0开始训练,但恢复到保存时的数值就出错。所以每次保存恢复点之后,要抽测恢复一次,看初始损失值是否和保存时一致。这个抽测动作虽然简单,却能避免“白跑三天最后发现根本恢复不了”的事故。
多故障同时发生时还要考虑“安全启动”顺序:先恢复权重和优化器,再恢复随机状态,最后恢复数据迭代器的位置。我遇到过恢复后发现数据重复读了几千条的情况,原因就是数据迭代器位置没有正确恢复。
4.3 模型掉点复盘清单
训练任务完整跑完,输出效果却比小规模实验差很多,这就是掉点问题。掉点排查比故障排查更加隐蔽,因为它不会报错。
我总结了一份每次训练掉点都要过的检查清单:数据顺序是否混洗一致、训练配置是否完全复现、学习率调度策略是否随训练数据总量变化、混合精度环境下某些层是否需要特殊处理、以及评估指标计算方式是否与验证集相同。这五项里任何一项不一致,都可能造成客观效果差异。
真实案例中,某团队发现扩大训练数据后效果反而下降,追查到最后是数据清洗规则在扩包时发生了变化,脏数据比例升高。这种问题在日志里完全看不出来,只有通过数据分布对比才能发现。掉点问题很多时候不是代码跑错,而是数据和配置不一致。
5. 推理服务化:把模型变成产品的最后一公里
5.1 为什么推理比训练更难受
训练优化讲究“吞吐大、跑得稳”,推理服务讲究“延迟低、成本省”。后者在某种程度上更难,因为它要在严格的响应时间约束下,尽可能提高吞吐并压低成本。模型结构已经定型,工程手段成为唯一杠杆。
| 对比维度 | 训练阶段 | 推理阶段 |
|---|---|---|
| 核心目标 | 吞吐量最大化 | 延迟与吞吐的平衡 |
| 输入模式 | 固定batch不断迭代 | 并发、实时、动态到达 |
| 资源压力 | 算力吃满为主 | 显存、算力、调度全维度压力 |
| 稳定性要求 | 可容忍较长失败恢复 | 服务中断直接影响用户体验 |
| 优化空间 | 分布式训练策略 | 批处理、量化、压缩、缓存 |
一个典型问题:训练时习惯把batch尺寸调大来提升效率,但推理接入真实流量后,请求到达时间不可控。如果每次都等攒够一个batch才开始推理,第一批请求的延迟就会高到无法接受。因此推理框架必须在“批处理收益”和“排队延迟”之间寻找平衡。
5.2 降低成本与延迟的三个工程流派
第一个招数是动态批处理和连续批处理。动态批处理允许请求边到边走,进程等待一个极短的时间窗口,攒到一定数量就启动推理;连续批处理更进一步,它把长序列请求拆成小片段,做完一个片段立即插入新的请求,让加速卡在每个时刻都在干活。相比静态等待攒批,连续批处理能显著提升吞吐。
第二个招数是量化推理。把模型权重从高精度变成低精度表示,比如从32位浮点压缩到16位甚至8位,可以让同样的显存放更多权重,也会让算得快一些。代价是精度可能下降。实际项目中通常先做校准测试,对比量化前后在验证集上的指标差异,控制在可接受范围再上线。
第三个招数是模型结构层面的优化,比如蒸馏与剪枝。蒸馏把大模型的能力迁移到小模型上,剪枝把不重要的参数删掉,两者都是为了减少单次请求的计算量。做这类优化的前提是先量化评估推理服务的饱和度,只有在确实存在性能瓶颈时再做,避免过度优化。
5.3 容量规划与扩缩容的思路
推理服务上线前一定要做容量压测。很多团队把压测放在临近上线才做,结果发现系统根本扛不住预期流量。正确做法是在开发完成后就建立一个包含并发数、延迟、吞吐三个维度的基准数据表,通过对不同硬件配置的压力测试,确定单副本承载能力。
基于这个基准,后续扩容就方便了。你可以根据业务峰值流量估算需要的副本数,配合弹性伸缩策略自动扩缩容。这里要特别留意冷启动问题:新扩容的副本需要加载模型权重和初始化推理引擎,耗时可能长达几十秒甚至几分钟。如果流量高峰来得太快,扩容速度可能赶不上增长曲线。
可以在服务列表中预置一个常驻小副本池,让容量变化在一个固定水位上下波动。这种方式综合成本和弹性,比全量预置更省钱,又比全动态扩容更可靠。
6. 学习路径:如果你想进入AI Infra
6.1 从单卡起步,不急着上集群
我见过很多新人一上来就研究千卡规模的调度系统,结果因为缺乏微观感知,学到后面全是空中楼阁。我的建议是先在一张卡上把性能优化的手感建立起来:用性能分析工具看算子和GPU利用率,尝试把数据加载、算子融合、混合精度这些基础操作都过一遍。
单卡优化跑通之后,再进入多卡。第一步先做数据并行,观察通信耗时随卡数增加如何变化,尝试理解为什么卡数翻倍不等于时间减半。前面所说的AllReduce开销,在这个阶段你会亲眼看到。
再往上才是集群层面的知识,包括资源调度、容器网络、存储规划。有前面的微观基础之后,这些宏观工具不再是抽象概念,而是为了解决你亲手遇到的瓶颈。
6.2 推荐的知识组合
AI Infra岗位对知识面的要求很宽,我建议按“操作系统、网络、调度、数据工程、ML模型基础”五个方向来搭建。操作系统要掌握CPU调度、内存管理、IO路径;网络要理解常见的通信库和网络拓扑;调度要理解资源分配策略;数据工程要熟悉大文件存储和并行数据读取;ML模型基础则帮助你和算法同事高效沟通。
这五块内容不需要全部精通再上岗,边用边学才是常态。重要的是保持能读源码的习惯,遇到性能问题能顺着调用栈往下追一层。
6.3 几个常见的错误学习姿势
最典型的错误是“只学工具不学原理”。某人在生产环境用某个框架跑通了任务,就以为自己掌握了AI Infra,但一旦遇到框架不支持的新场景就束手无策。工具只是接口,底层的调度、通信、存储原理才是可以迁移的能力。
第二个错误是“轻视可观测性”。很多新手只关心训练结果,不看监控指标变化,一旦出问题就毫无排查线索。我建议从一开始就养成为系统加监控的习惯,每个实验都记录训练的吞吐和资源利用率。
第三个错误是“重复造轮子的时间分配不当”。自己动手实现一个简单的多进程数据并行,确实对理解原理很有帮助,但生产级别的大规模分布式训练调度复杂度远超个人能力边际。正确做法是先用成熟方案建系统,再基于原理做二次开发与配置调优。
我在实际带人的过程中还有一个体会:AI Infra岗位尤其适合能够“耐受模糊”的人。系统中的性能问题往往不是单一因素造成的,需要同时关注硬件、网络、存储、代码甚至数据质量。每次排查都是一次小型侦查工作,不能急于求成。保持记录问题、复盘归因的习惯,一年下来积累的排查经验会远远超过那些只刷文档的人。
如果你准备转行进入这个方向,记住别贪多:先把单卡性能调明白,再逐步扩展到多卡训练、推理服务和容量规划。真实场景中的问题永远比教程里的案例复杂,但底层原理是有限的。把每一个小瓶颈追根究底,AI Infra的知识全景就会在你自己动手的过程中自动拼完整。