AI-Infra实战指南:从GPU调度到成本治理 1. 先搞清楚AI-Infra到底是个啥1.1 从一次模型跑不起来说起我最早接触AI-Infra这个概念不是在什么战略会议上而是一次特别狼狈的线上事故。当时我们有个团队训练一个十多亿参数规模的模型早上十点提交任务到下午三点还在排队。排队也就算了真正跑起来之后GPU利用率只有可怜的30%多。我过去一看数据加载的瓶颈卡在CPU端GPU每算完一个batch就要干等几百毫秒。那天我调了数据加载的prefetch参数、把TFRecord换成了更轻量的格式又临时加了两台CPU节点做数据预处理总算把利用率拉到了80%以上。但那种靠人肉救火的感觉实在让人后怕——如果当时多几个团队同时抢GPU系统早就瘫了。后来我才慢慢理解当时缺的其实不是某个参数而是一整套叫AI-Infra的东西。AI-Infra全称AI Infrastructure翻译过来是AI基础设施。它不是一个具体软件也不是某一台服务器而是围绕模型开发、训练、部署、运维全生命周期把算力、存储、网络、调度、监控这些底层能力打包成一套可靠服务体系。打个比方做AI模型像做饭模型算法是菜谱AI-Infra就是厨房里的水电气、锅碗瓢盆和排烟系统。你菜谱再牛厨房一开火就跳闸菜照样端不上桌。1.2 AI-Infra的核心组件与职责边界刚入门的朋友容易把AI-Infra理解成装个GPU驱动就行这真是大错特错。按我自己的经验一套能扛住生产环境的AI-Infra至少要覆盖下面这几个层面。第一层是硬件资源层。GPU、CPU、高速存储、RDMA网络这是底座。这里要解决的是硬件怎么被上层软件优雅地使用比如GPU驱动与CUDA版本兼容、显存管理、多机通信的拓扑感知。第二层是资源管理与调度层。这是AI-Infra的大脑。多团队共享集群时谁的任务优先跑遇到资源碎片怎么处理任务排队排到一半节点故障了怎么办Kubernetes加上GPU调度插件比如NVIDIA的设备插件和调度扩展通常是这一层的主角我需要根据场景和成本去选型。第三层是训练与推理工程层。数据清洗流水线、模型训练框架的分布式配置、超参调优、模型压缩、推理引擎选型比如vLLM、TensorRT-LLM都在这一层。很多算法工程师觉得Infra工程师只管机器其实不对这一层是算法和底层资源之间的翻译官。第四层是可观测性与运维层。监控告警、日志采集、链路追踪、成本账单。没有这一层前面再好的基础设施也像没有仪表盘的飞机——飞得起来但不知道什么时候会炸。这四个层面不是各自独立的而是像一条流水线。模型要训练先经过资源调度分配GPU再由工程层把数据和代码送上去期间所有状态都要被可观测系统记录。任一层出问题整个链路都会卡住。1.3 为什么一线工程师视角特别重要市面上写AI-Infra的书和课程不少但大多数站在架构师或CTO视角讲得特别宏大——什么万卡集群、大规模算力调度平台动辄几百页PPT。但真正在一线处理过问题的人都知道实际工作里90%的精力消耗在那些书上不会写的破事上比如CUDA版本和PyTorch版本不兼容导致训练任务莫名崩溃、GPU显存泄露但nvidia-smi看到的是正常状态、多机训练时网卡跑不满但带宽监控又看不出异常、集群里一票任务在用默认参数疯狂抢占带宽和磁盘IO……这些才是AI-Infra工程师的日常。所以这个系列文章我不想写那种顶层设计的正确废话。我想从一个在一线摸爬滚打的工程师角度聊一聊实际落地时怎么选型、怎么排障、怎么优化以及每一个选择背后的代价和取舍。第一章先打基础把帮助你从零搭建一套够用的AI基础设施的关键环节讲透。2. GPU资源管理算力调度是AI-Infra的第一道坎2.1 先学会看懂GPU的真实使用状态在谈调度之前先聊一个基础技能看懂GPU的真实使用状态。我经常看到同事跑过来问我的GPU利用率怎么才5%然后一脸懵。问题在于很多人只看nvidia-smi的Volatile GPU-Util这一列。这个指标的含义是采样周期内GPU忙碌时间的百分比但它并不能完整反映真实利用率。举个例子一个GPU显存占用90%GPU-Util显示98%看起来一切正常。但我用nvidia-smi dmon -c 1再看细粒度指标发现SM流式多处理器的活动频率很低而显存带宽利用率Memory Read/Write throughput也不高。这说明任务虽然在算但计算强度很低可能卡在数据搬运上GPU的大部分算力单元其实在空转。还有一个更隐蔽的坑很多训练任务在数据加载阶段GPU会周期性进入空闲-忙碌-空闲的锯齿状状态。你只看GPU-Util的平均值会觉得还行但如果用nvidia-smi --query-gpuutilization.gpu --formatcsv -l 1采样观察会发现GPU每隔几秒就掉到0%。这种周期性的饥饿状态比持续的低利用率更影响训练速度而且不容易被普通监控发现。2.2 GPU资源池化和共享的落地姿势有了看懂状态的基础再来谈资源池化和共享。一提到资源共享很多团队第一反应是上Kubernetes。但我想多说一句如果一个团队只有十几块GPU机型和型号还不一致上K8s的收益可能并不高。比如NVIDIA T4和A100混在一起调度器很难以统一方式分配还要额外维护一整套K8s组件反而加重了小团队的运维负担。这种情况下直接用虚拟化方案或者简单的排队脚本可能更务实。如果规模到了几百卡以上或者有多个团队共用集群K8s就是主流选择了。NVIDIA官方提供了GPU设备插件device plugin安装后K8s就能识别GPU资源并调度容器。你需要在部署时提前设置节点标签比如gpu-typea100因为不同任务的算力要求差异巨大——一个做模型微调的团队用T4可能就够了一个训练7B以上大模型的团队则非要A100不可。如果不打标签调度器把大模型任务分到T4上任务大概率跑不起来或者慢到让你怀疑人生。共享策略上也值得花心思。NVIDIA vGPU和MIG多实例GPU都能把一个物理GPU切成多个逻辑GPU。比如A100 80G可以切成7个MIG实例每个约10G显存适合推理场景。这里有个经验MIG适合部署多个小模型推理不太适合训练因为训练时张量并行要跨MIG通信性能损耗很大。像vLLM这种推理引擎也可以直接通过显存配置和并发参数实现单卡多服务共享不一定非要上虚拟化。我的建议是推理场景优先考虑模型层的并发和显存复用真到切分场景再说MIG。2.3 任务排队与优先级策略别让调度变成玄学GPU资源池化之后下一个头疼的是任务排队和优先级。我见过太多团队一开始没有排队机制谁先提交谁占资源后来发现有个团队一口气提交几百个任务把集群占满了其他团队全都堵住。更惨的是有些任务跑了两个多小时才发现参数错误白白浪费算力。引入优先级队列是必须做的。简单做法有三个原则第一按业务等级分队列。核心在线业务比如智能客服的模型推理优先级最高模型训练其次实验性探索和离线数据处理最低。用K8s的PriorityClass就能实现把高优先级任务的priorityClassName配高低优先级任务就能在资源紧张时被抢占或挤到等待队列。第二设置每个团队或每个用户的最大资源配额。这个可以用K8s的ResourceQuota或者LimitRange来控制。别嫌麻烦这一步能避免一尸队把集群吃干抹净的问题。第三做排队时间的可视化反馈。给算法团队一个入口能看到自己的任务排在哪个位置大概还要等多久。大部分人对等待的焦虑其实是对不确定的焦虑。看到排队时间后他们就不会反复来问我的任务还要多久了。踩过的一个小坑是K8s默认调度器在分配GPU时可能会把两个任务的GPU分配到不同的物理机上导致本来可以用NVLink加速的多卡训练退化成走PCIe甚至网络通信。解决方法是给调度器加拓扑感知约束让同一个任务的多卡尽量落在同一台节点或者同一台交换机下。NVIDIA官方提供了拓扑感知调度扩展值得研究。3. 训练与推理的工程化落地细节3.1 把训练任务跑稳从环境一致性到底层调优资源调度解决的是能不能跑的问题训练工程化解决的是跑得稳、跑得快、不出幺蛾子的问题。这一节里我想聊几个容易在真实训练任务里拖后腿的点。最优先要处理的是环境一致性问题。每个团队人员流动快算法同学今天用这个版本的PyTorch明天升级到那个版本的CUDA一旦训练仓库里的环境依赖没有锁定复现一个结果就变成噩梦。我用的是容器镜像加锁定版本号的方式用一个Base Dockerfile锁定Python版本、CUDA版本、cuDNN版本、PyTorch版本然后基于基础镜像构建训练镜像每次改动都打上新的tag。核心原则很简单——模型代码可以迭代但训练环境不能随意漂移。其次是数据加载的优化。很多训练任务慢不在GPU算得慢而在数据喂得慢。我之前那个案例就是典型。优化方向有三个一是用tf.data或者PyTorch的DataLoader时要把num_workers调到合适值通常和CPU核数正相关但每个worker都会复制一份数据loader状态开太多反而造成CPU和内存压力二是用内存映射或者直接预取到内存避免每个step都走磁盘IO三是把预处理和数据增强放到GPU上跑比如用NVIDIA DALI把数据管线和计算管线重叠起来。第三个容易忽视的是分布式训练的通信配置。多机训练时PyTorch DDP默认走NCCLNCCL的通信效率跟网络拓扑关系很大。如果机器之间是普通以太网NCCL可能自动降级算法性能惨不忍睹。建议启动训练前先用nccl-tests里的all_reduce性能测试工具跑一遍确认实际带宽和期望值差距。如果用了RoCE或InfiniBand还需要设好NCCL_IB_DISABLE0、NCCL_IB_HCA之类的环境变量否则NCCL根本不会走RDMA通道。3.2 推理服务的高效部署延迟、吞吐和成本的三方博弈训练只是前半段模型要产生价值还得部署成在线推理服务。推理优化里最核心的矛盾是延迟、吞吐和成本三者之间的博弈。拿我们部署一个70亿参数模型做知识问答为例。最早我们直接拿PyTorch原生的脚本部署单张A100上并发只能到20左右P95延迟却到了2秒多压根扛不住线上流量。后来换用vLLM做推理引擎通过PagedAttention把KV Cache的显存利用率大幅提上去单卡并发轻松到了几百P95延迟还降到了500毫秒以内。这个替换成本几乎为零因为vLLM兼容HuggingFace模型格式接口也走OpenAI风格代码改动的量级很小。推理部署时不建议一上来就整复杂的微服务架构。先用单引擎把核心接口调通再逐步加缓存层、负载均衡、弹性伸缩。比较务实的优化顺序是先换高性能推理引擎vLLM、TensorRT-LLM、Triton优先解决显存和并发瓶颈再优化模型本身量化、剪枝、蒸馏比如把FP16换成INT8或者FP8量化速度能再翻一倍但要注意精度跌损然后再谈集群层的弹性伸缩比如根据队列长度自动扩容Pod高峰结束自动缩容减少空闲GPU的浪费。这块有一个特别需要注意的点推理服务的内存和显存预估远比训练复杂。训练时只要显存放得下batch就行推理时显存既要放模型参数又要放动态变化的KV Cache还要留一点给输入输出的中间态。用vLLM时要设置好max_num_seqs和max_num_batched_tokens这两个参数直接决定了并发吞吐和显存占用。我的经验是先用python -c import torch; print(torch.cuda.mem_get_info())看空闲显存再根据模型大小反推KV Cache的余量宁愿保守一点也不要OOM。3.3 模型版本和数据集管理没人在意但早晚出事的环节训练推理都是高光时刻模型版本管理这类地下室工作最容易被人忽略。但我要说这个问题一旦爆发往往是灾难级的。比如你把一个模型上线了用户反馈效果变差你需要快速回滚到上一个版本。如果没有模型版本管理你根本不知道上一个版本在哪台机器的哪个目录里。又比如你用了一批新的数据重新训练结果效果更差了你想排查是不是数据清洗环节出了问题但连数据集的hash都没记录根本无从下手。我的做法很简单模型产物统一用对象存储目录按模型名/版本号/时间戳组织版本号用语义化规则比如v1.0.0每次发布都生成一个清单文件记录模型结构、训练脚本commit hash、数据集版本、超参数数据集每次清洗完就计算一个md5或者sha256存下来训练任务启动时校验数据版本防呆推理服务部署时把模型的版本打进镜像的tag或者环境变量里确保线上跑的是哪个模型一目了然。这些活儿看起来脏乱累但真正出现线上事故时能让定位从好几小时缩短到十几分钟。4. 可观测性与成本治理让算力花得明明白白4.1 监控到底该看哪些指标可观测性这块不少团队的监控面板花花绿绿几十个图表但真出了问题还是靠工程师登服务器敲命令排查。我总结出来一套少而精的监控指标体系给大家参考。GPU层核心指标是SM利用率、显存带宽利用率、显存占用、温度、功耗。注意SM利用率不等于GPU-UtilGPU-Util只是某个采样周期内有没有活干SM利用率才是计算单元有多忙。显卡温度超过85度就要警惕超过90度大概率是散热出问题了性能会明显下降。任务层要看训练吞吐比如每秒处理的样本数、单步耗时、loss曲线是否收敛。吞吐掉了一半模型和数据可能没问题反而是基础设施出事了。基础设施层要看CPU负载、内存、磁盘IO延时、网络重传率。网络重传率这个指标特别容易漏多机训练时如果重传率高通信效率基本报废。我的建议是监控指标宁可少但必须可解释。每个指标都要能回答如果这个指标变成红色我应该怎么排查。如果做不到这一点指标再多也只是给值班同学徒增噪音。4.2 成本归因从一笔糊涂账到一张明白表AI-Infra里最容易被业务方吐槽的就是成本。老板问上个月GPU费用怎么涨了30%如果你答不出来这个锅就是你的。成本归因的前提是把资源打上标签。K8s里给每个队列、每个团队、每个项目打Label然后用量数据定期汇总到一张表里。最少要做到三个维度团队维度、应用维度、时间维度。比如我会定期跑一组指标每个团队本月GPU使用总时长、平均利用率、单任务平均成本。这里有几个有意思的反直觉经验第一利用率高不等于成本低。一个团队每天把A100占满跑一堆低价值实验另一个团队每天只用两三个小时跑核心业务前者的账单是后者的好几倍但产出可能远不如后者。第二按需实例和包年包月或Spot实例的搭配很关键。K8s可以配置节点池的弹性伸缩稳定负载用包年实例突发负载用按需或抢占式实例。这个策略能把成本降低20%到40%。第三不要忘了存储和网络带宽的成本。很多人只盯着GPU费用结果发现账单里数据存储和跨区流量费也不少尤其在多副本备份和日志长期留存上。成本治理不是算总账而是要能拆到每个任务、每个团队、每一天形成环比和趋势分析。这样才能有理有据地和业务团队沟通资源用得合不合理而不是拍脑袋做决定。4.3 告警治理别让值班同学活成救火队长告警是AI-Infra里最见功力的一环。我见过太多集群告警一天几千条值班同学疲于点确认按钮真正重要的告警反而被淹没。告警治理有三条原则第一只告警需要立刻人工介入的事情。GPU利用率低不用告警最多生成一个日报让团队自己看但节点宕机、任务大面积失败、推理服务P95延迟超过阈值这些必须立刻告警。第二告警信息要足够定位问题。一条好的告警应该包含出错对象哪个节点/哪个任务、关键指标值、时间、可能影响的业务、以及一条排查入口链接。第三告警要有消除动作和升级机制。低级告警自动恢复后自动清除高级告警如果15分钟未被处理就要升级到更高级别的负责人。不然高峰期的告警错过后影响到业务才发现就晚了。我自己的实战配置里告警指标只保留了不到20个但值班同学比我单独看几十个图表更快能发现异常和处理问题。这是做AI-Infra最容易被低估的价值。5. 常见问题排查与避坑指南5.1 问题速查表这里把我这些年踩过的坑和群里常见的求助问题整理成一张表大家可以保存下来当手册用。症状可能原因快速排查手段训练速度突然变慢数据加载卡顿、NCCL通信性能差用nvidia-smi dmon看SM利用率跑nccl-tests的all_reduce测带宽GPU显存OOMbatch size过大、KV Cache设置过高用--shm-size加大共享内存调整max_num_seqs开启显存动态分配多机训练不收敛批量大小变了但学习率没调、不同节点数据分布不一致检查是否设置了正确随机种子确认DataLoader的shuffle和分布式sampler用法推理服务偶发超时线程池阻塞、显存碎片化、模型加载冷启动查引擎日志看请求队列长度用预加载或开启continuous batchingGPU-Util高但训练速度慢计算强度低卡在内存带宽换用更高效的算子或减少tensor core的浪费比例任务排队但集群显示空闲资源预留、亲和性导致有GPU不能用用kubectl describe node和kubectl get pods检查是否有Pending的Pod占着资源5.2 我踩过的几个典型大坑第一个坑是共享内存没设置够。Docker默认的/dev/shm只有64MB但PyTorch DataLoader的多进程数据加载会把共享内存写满导致任务莫名其妙地卡死或者报错。解决方案很简单启动容器时加上--shm-size8G或者换成--ipchost。这个坑特别隐蔽因为不是每次都报OOM而是时好时坏非常难排查。第二个坑是配置文件与代码版本不同步。有次我把一个训练任务的batch size从32改到64但忘了更新配置文件结果线上任务用旧配置跑了整整两天产出结果全部作废。从那以后我强制推行所有训练参数都写在配置文件中代码启动时读取并打印生效值这个原则绝不允许在代码里硬编码超参。第三个坑是推理服务的优雅退出没做好。K8s在Pod被删除前会发SIGTERM但如果推理服务没有处理这个信号正在处理的请求就会被直接掐断用户侧就是偶发报错。后来我在服务里加了信号量处理逻辑收到SIGTERM后先把正在处理的请求跑完再退出再配置terminationGracePeriodSeconds给足时间这个偶发错误彻底消失。5.3 新手起步建议从一套能跑通的方案开始对于刚接触AI-Infra的工程师我的核心建议是不要一上来就追求大而全的平台和框架先在一台有GPU的机器上把模型训练和推理跑通再逐步加调度、加监控、加成本治理。具体可以按这个顺序来操作第一步单机单卡。选一个自己熟悉的小模型比如一个简单的BERT或者其他几亿参数模型用PyTorch或TensorFlow完整训练一个任务学会看nvidia-smi、学会解决OOM、学会调DataLoader。第二步切到容器化。把训练代码装进Docker用Docker启动训练任务搞清楚GPU挂在容器里是怎么透传的--gpus all搞清楚镜像怎么管理版本。第三步本地用Docker Compose或者单机K8s启动一套推理服务接入vLLM或Triton学会看延迟指标。第四步多机多卡。用两台机器跑分布式训练配置好NCCL学会看网络通信的日志。这四个阶段走完你对AI-Infra的整个链路就有了一个非常具象的认知。这时候再去看那些大型平台架构的文章你会发现很多东西你之前没有概念的地方突然都能对上号了。做AI-Infra这个方向最忌讳的就是纸上谈兵。架构图画得再漂亮不如亲自把一张卡跑满再跑坏又把它修复的过程。我见过很多算法工程师转型做Infra最后成功的无一例外都是愿意蹲在机器前看日志、看监控、看底层状态的。这不是天赋问题而是投入时间的问题。最后再分享一个个人体会AI-Infra的工作价值很多时候不是某个性能指标从80%到99%的爽快而是让整个团队一个月不用找你处理问题。那种系统稳定到让人忘记它的存在的感觉才是这个方向真正精进的地方。如果哪天你的业务同学跑过来说训练任务太顺了我都忘了你在做Infra那就是给你最大的夸奖。