资讯动态

AI Infra 知识全景:从硬件到编排的系统学习笔记

发布时间:2026/10/22 4:01:41 来源:尧图企业网站定制
1. 为什么我要系统梳理 AI Infra 这张知识地图过去两年我陆续参与过几个模型训练与推理平台的搭建项目从最初只会调参跑脚本到后来需要独立负责一个推理服务的稳定性中间踩过的坑几乎覆盖了整条技术栈。最深的感受是AI Infra 这个领域最大的问题不是知识点太难而是知识太散。你可能今天在调 GPU 显存分配明天在研究分布式通信原语后天又要去搞容器编排和存储加速每个方向单独拎出来都有大量资料但很少有人把它们串成一条线讲清楚彼此之间的关系。这就是我动手整理这份知识全景学习笔记的起因。它不是某一项技术的深度教程而是一张覆盖 AI Infra 主要分支的认知地图帮你在面对一个具体问题时能快速定位它属于哪个层次、依赖哪些上下游组件、常见的解决思路有哪些。适合已经有一定工程基础、想从“会用”进阶到“懂原理”的开发者也适合刚转入这个方向、需要快速建立全局视野的同学。整份笔记我按“硬件层—通信层—训练框架层—推理与服务平台层—编排与运维层”这条主线来组织每一层都会讲清楚它解决什么问题、核心组件有哪些、关键参数怎么算、实际落地时容易在哪里翻车。下面就把我整理过程中的思路和干货逐层展开。2. 整体知识框架的设计思路2.1 为什么按“层次”而不是按“工具”来组织一开始我尝试按工具来分类比如 PyTorch 一块、CUDA 一块、Kubernetes 一块。但很快发现这种分法有个致命问题同一个问题往往横跨多个工具。举个例子“训练时显存不够”这个现象可能涉及数据加载策略、梯度累积、混合精度、通信缓冲区大小、甚至容器内的共享内存配置。如果按工具切分你得在四五个章节之间来回跳很难形成因果链。按层次组织的好处是每一层有明确的职责边界。硬件层负责算力和显存通信层负责多卡多机之间的数据交换框架层负责把模型定义翻译成硬件能执行的指令推理层负责把训练好的模型高效地服务出去编排层负责把这些组件调度到集群上并保证可用性。当你遇到一个问题时先判断它发生在哪一层然后沿着层与层之间的接口往上或往下排查思路会清晰很多。注意层次划分不是绝对的有些组件横跨多层比如 NCCL 既涉及通信也涉及硬件拓扑感知。我在笔记里会把它归到通信层但在相关章节会标注它与其他层的交互点。2.2 每一层需要回答的三个核心问题为了让笔记不流于表面我给每一层都设定了三个必须回答的问题。第一这一层存在的根本原因是什么也就是它解决了什么不可回避的矛盾。第二这一层的核心抽象和关键组件有哪些它们各自的职责边界在哪里。第三这一层最常见的性能瓶颈和故障模式是什么排查手段有哪些。以通信层为例。它存在的根本原因是单卡显存和算力有物理上限模型规模一旦超过单卡承载能力就必须把计算图切分到多卡上而切分之后卡与卡之间需要交换梯度、激活值或参数这就产生了通信需求。核心抽象包括集合通信原语AllReduce、AllGather、ReduceScatter 等和通信拓扑Ring、Tree、NVLink、InfiniBand 等。常见瓶颈则是通信带宽不足导致计算单元空转或者拓扑感知没做好导致跨节点通信走了低速链路。这三个问题贯穿每一层你在阅读后续章节时也可以带着它们去对照看看自己是否真的理解了每一层的设计动机。2.3 知识全景的依赖关系图文字描述虽然不能用图表但我可以用文字把层与层之间的依赖关系说清楚。最底层是硬件层包括 GPU、高速互联总线、网卡和存储设备。硬件层之上是驱动与运行时层包括 GPU 驱动、CUDA 运行时、通信库运行时。再往上是对外暴露编程接口的通信层和计算库层比如 NCCL、cuBLAS、cuDNN。框架层构建在这些库之上提供张量抽象、自动微分和分布式策略。推理与服务平台层则面向线上服务处理批处理、量化、缓存和弹性伸缩。最上层是编排与运维层负责资源调度、监控告警和故障恢复。这个依赖关系意味着当你排查一个上层问题时往往需要逐层往下确认。比如推理服务延迟高可能是编排层资源不足也可能是推理层批处理策略不合理还可能是框架层算子实现低效甚至硬件层降频。有了这张全景图你就知道该按什么顺序去排除。3. 硬件与驱动层的关键细节3.1 GPU 显存到底被谁吃掉了很多人第一次遇到显存溢出时第一反应是模型太大。但实际项目中模型参数往往只占显存的一半甚至更少。剩下的显存被几部分吃掉激活值、梯度、优化器状态、通信缓冲区、CUDA 上下文和碎片。以一个 7B 参数的模型为例假设用 FP16 存储参数光参数就是 14GB。训练时梯度同样需要 14GB如果用的是 Adam 优化器它还会为每个参数维护一阶和二阶动量又是 28GB。这三项加起来已经 56GB还没算激活值。所以单卡 80GB 显存训练 7B 模型时如果不做任何优化激活值稍微大一点就会溢出。激活值的大小取决于批次大小和序列长度。粗略估算每层激活值约占batch_size × seq_len × hidden_dim × 层数 × 精度字节数。实际中因为注意力机制的存在序列长度对激活值的影响是平方级的。这也是为什么长序列训练特别吃显存。实操心得排查显存问题时先用torch.cuda.memory_summary()看 reserved 和 allocated 的差值。如果 reserved 远大于 allocated说明碎片严重可以尝试设置PYTORCH_CUDA_ALLOC_CONFexpandable_segments:True来缓解。3.2 高速互联总线对训练效率的实际影响单机多卡训练时卡与卡之间的通信走的是高速互联总线。不同代际的总线带宽差异很大这直接决定了张量并行和流水线并行的效率。如果总线带宽不足通信时间会超过计算时间多卡加速比就会惨不忍睹。我实测过一个对比同样的模型和批次大小在总线带宽较高的机器上四卡训练的吞吐是单卡的 3.6 倍而在带宽较低的机器上四卡吞吐只有单卡的 2.3 倍。差距就来自通信开销。所以做多卡训练前一定要确认卡间互联的拓扑和带宽别盲目堆卡。拓扑感知也很重要。如果四张卡不是两两直连而是通过桥接芯片中转那么通信路径就会变长。你可以用nvidia-smi topo -m查看拓扑矩阵确认卡间连接类型。理想情况下参与张量并行的卡应该在同一高速互联域内。3.3 驱动版本与运行时版本的匹配陷阱驱动和运行时版本不匹配是新手最容易踩的坑之一。CUDA 运行时版本、GPU 驱动版本、深度学习框架编译时依赖的 CUDA 版本这三者必须兼容。常见现象是框架能 import 但一跑算子就报错或者多卡通信库初始化失败。我的经验是先确定框架版本然后查它官方文档推荐的 CUDA 版本再根据 CUDA 版本去选驱动版本。不要反过来先装最新驱动再随便装框架。另外容器化部署时宿主机驱动版本必须不低于容器内运行时要求的最低版本否则容器内会看不到 GPU 或者通信库初始化失败。注意升级驱动前一定要确认当前训练任务是否在跑驱动升级通常需要重启机器会中断所有 GPU 任务。生产环境建议先在测试节点验证。4. 通信层的核心机制与调优4.1 集合通信原语到底在做什么集合通信原语是多卡训练的基石。最常用的是 AllReduce它的作用是把所有卡上的梯度求和后广播回每一张卡。Ring AllReduce 是最经典的实现它把每张卡的数据分成 N 份通过两轮环形传递完成求和与广播通信量与卡数无关只与数据量有关。除了 AllReduce还有 AllGather、ReduceScatter、Broadcast、AllToAll 等。AllGather 是把所有卡的数据拼起来分发到每张卡常用于张量并行中拼接分片结果。ReduceScatter 是先求和再分散常与 AllGather 配合实现 AllReduce 的等价效果但更省显存。AllToAll 则用于专家并行中把 token 路由到对应的专家所在卡。理解这些原语的关键是搞清楚数据在卡之间怎么流动、通信量是多少、能否与计算重叠。比如在流水线并行中如果能把通信和计算重叠起来就能隐藏大部分通信开销。4.2 通信与计算重叠的实操方法通信与计算重叠是提升多卡效率的核心手段。基本思路是在计算当前微批次的同时传输上一个微批次需要通信的数据。框架层面PyTorch 的 DDP 已经内置了梯度分桶和通信重叠但默认配置不一定最优。你可以调整bucket_cap_mb参数来控制梯度分桶大小。桶太小通信次数多启动开销大桶太大重叠效果差因为要等整个桶的梯度算完才能开始通信。经验值是在 25MB 到 50MB 之间具体取决于模型结构和网络带宽。我通常先用默认值跑一轮看通信时间占比再逐步调整。另一个技巧是使用gradient_as_bucket_viewTrue让梯度直接写入通信桶减少一次内存拷贝。这个选项在显存紧张时特别有用但要注意它和某些自定义梯度操作可能不兼容。4.3 多机通信的瓶颈定位多机训练时瓶颈往往出现在节点间的网络上。先用ibstat或网卡厂商工具确认链路速率和状态。然后跑一个纯通信的基准测试比如 NCCL 自带的测试工具看实际带宽是否达到链路标称值。如果带宽远低于预期检查几个点一是网卡是否绑定了正确的驱动和固件二是通信是否走了低速路径比如本该走高速网络却走了管理网三是是否有其他任务在抢占带宽。我遇到过一次两台机器之间的通信带宽只有标称的十分之一最后发现是其中一台机器的网卡协商速率降级了换线后恢复正常。实操心得多机训练前务必先跑一次全节点通信基准测试把每个节点对的带宽都测一遍。不要假设新机器就没问题线缆和光模块的故障率比想象中高。5. 训练框架层的分布式策略5.1 数据并行、张量并行、流水线并行的选择逻辑数据并行是最简单的并行方式每张卡持有完整模型副本处理不同批次数据梯度通过 AllReduce 同步。它的优点是实现简单、扩展性好缺点是每张卡都要存完整模型和优化器状态显存占用高。张量并行把单个算子切分到多张卡上比如把矩阵乘法按列切分。它的优点是能降低单卡显存占用缺点是通信频繁对卡间带宽要求极高通常只在单机内使用。流水线并行把模型按层切分成多个阶段每个阶段放在不同卡上数据像流水线一样依次通过各阶段。它的优点是能跨节点扩展缺点是存在流水线气泡需要精心设计微批次调度来减少空闲时间。实际项目中这三种策略经常混合使用。比如单机内用张量并行降低显存机间用流水线并行扩展规模同时外层再套数据并行提升吞吐。选择哪种组合取决于模型大小、集群规模、卡间带宽和节点间带宽。5.2 混合并行下的显存与通信平衡混合并行最难的是一碗水端平。张量并行度太高通信开销大流水线并行度太高气泡多数据并行度太高显存不够。我通常按以下顺序决策先看单卡显存能放下多大的模型分片确定张量并行度再看单机内卡数是否够用不够则引入流水线并行最后用数据并行填满剩余资源。举个例子假设有 16 台机器每台 8 张卡共 128 张卡。模型有 70B 参数FP16 下参数加优化器状态约 560GB。如果单卡 80GB至少需要 8 张卡才能放下模型状态所以张量并行度设为 8正好用满一台机器。剩下 16 台机器做数据并行每台机器内 8 卡做张量并行。这样配置下机内通信走高速总线机间通信只同步梯度压力小很多。5.3 梯度累积与微批次调度的配合梯度累积是在显存受限时增大有效批次大小的常用手段。它的原理是多次前向反向累积梯度再一次性更新参数。但梯度累积和流水线并行配合时要注意微批次的数量要能被流水线阶段数整除否则会出现气泡或数据不均衡。我一般会先确定全局批次大小然后根据单卡显存确定微批次大小再算出需要累积多少步。如果同时用流水线并行还要确保累积步数是流水线阶段数的整数倍。这些参数在训练脚本里通常都有对应配置项但文档往往讲得不清楚需要自己推导一遍。注意梯度累积时如果用了 BatchNorm要注意统计量的更新频率。累积步数大于 1 时BatchNorm 的 running mean 和 variance 更新会变慢可能需要调整 momentum 或改用 GroupNorm。6. 推理与服务平台层的核心要点6.1 推理引擎的批处理策略怎么选推理服务和训练最大的区别是推理对延迟敏感而且请求是动态到达的。批处理策略直接决定了吞吐和延迟的平衡。静态批处理是攒够一批再一起推理延迟高但吞吐大。动态批处理是请求随到随处理延迟低但吞吐受限于单次处理能力。连续批处理则是在一个批次里已经完成的序列提前退出新请求随时加入兼顾吞吐和延迟。选择哪种策略取决于业务场景。离线批量推理可以用静态批处理把批次开到最大。在线对话服务适合连续批处理因为请求长度差异大连续批处理能显著提升 GPU 利用率。我实测过一个对话模型用连续批处理比静态批处理吞吐提升了近三倍平均延迟还降低了。6.2 量化对推理性能的实际影响量化是降低推理成本的重要手段。常见的量化方案有 INT8 和 INT4。INT8 量化通常能把显存占用减半吞吐提升 1.5 到 2 倍精度损失很小。INT4 量化能把显存占用降到四分之一吞吐提升更多但精度损失需要评估。量化不是万能的。有些模型对量化敏感尤其是小模型或者输出分布尖锐的模型。我建议先在小规模流量上做 A/B 测试对比量化前后的输出质量和延迟指标。另外量化后的模型不一定在所有硬件上都能加速有些老卡对 INT4 的支持不好反而会变慢。实操心得量化时优先量化权重激活值量化要谨慎。权重分布相对稳定激活值受输入影响大量化后容易出异常值。如果必须量化激活值建议用动态量化或者保留部分层不量化。6.3 推理服务的弹性伸缩与冷启动推理服务的流量往往有波峰波谷。弹性伸缩能根据负载自动调整实例数但冷启动是个大问题。模型加载、显存分配、预热推理都需要时间如果扩容太慢波峰来了服务已经超时了。我的做法是保留一个最小实例数保证基本容量。同时设置基于队列长度的扩容策略而不是基于 CPU 或 GPU 利用率因为利用率有滞后性。另外模型加载可以做成懒加载加分片加载先加载部分层就能开始服务剩余层后台加载。预热则是在实例启动后先跑几轮空推理把显存池和计算图都初始化好。7. 编排与运维层的落地经验7.1 资源调度如何避免 GPU 碎片GPU 是稀缺资源调度不当会产生大量碎片。比如一个任务申请 4 张卡但集群里只有分散的 22任务就调度不上去。解决思路一是用拓扑感知调度尽量把任务调度到同一节点或同一高速互联域内二是用 gang scheduling要么全部满足要么不调度避免部分分配导致的死锁。Kubernetes 生态里设备插件负责上报 GPU 资源调度器负责分配。但默认调度器对 GPU 拓扑不感知需要额外配置。我通常会给节点打上拓扑标签然后在调度策略里加亲和性规则让同一任务的卡尽量落在同一节点。7.2 监控告警该盯哪些指标AI Infra 的监控和普通服务不同除了 CPU、内存、网络还要盯 GPU 利用率、显存占用、通信带宽、温度、功耗和 ECC 错误。GPU 利用率低但显存占用高可能是数据加载瓶颈。通信带宽低但计算利用率高可能是通信没重叠好。温度高导致降频会直接拉低训练速度。告警阈值要根据业务设定。训练任务对延迟不敏感但对中断敏感所以显存溢出和 ECC 错误要立即告警。推理服务对延迟敏感所以 P99 延迟和队列长度要重点监控。我一般会设置两级告警警告级别先通知严重级别直接触发自动扩容或重启。7.3 故障恢复与断点续训的实操细节大规模训练任务跑几天甚至几周硬件故障是常态。断点续训能救命但要做好并不简单。首先要定期保存检查点保存频率取决于任务时长和可接受的回滚损失。其次要保证检查点的一致性多卡保存时要等所有卡都完成再标记检查点有效。恢复时要注意随机数状态、数据加载器状态和优化器状态都要恢复。只恢复模型参数是不够的否则训练曲线会跳变。我习惯在检查点里额外保存当前步数、学习率调度器状态和每个数据加载器的偏移量。恢复后先跑几十步观察 loss 是否连续确认无误再继续。注意检查点存储要选高吞吐的共享存储不要存在本地盘。本地盘故障会导致检查点丢失而且多机恢复时本地盘不可见。共享存储的写入带宽要能支撑所有卡同时写检查点否则保存时间会很长。8. 常见问题与排查技巧实录8.1 训练速度突然变慢的排查顺序训练速度变慢是最常见的问题排查要按从外到内的顺序。先看硬件层用nvidia-smi确认 GPU 是否降频、温度是否过高、是否有 ECC 错误。再看通信层跑一个通信基准测试确认带宽是否正常。然后看框架层检查是否有数据加载瓶颈比如 CPU 利用率是否打满、数据预处理是否太慢。最后看模型层确认是否有异常值导致计算变慢。我遇到过一次训练速度突然掉一半最后发现是数据加载的 num_workers 设得太小GPU 经常等数据。把 num_workers 调大后恢复正常。这个问题的隐蔽性在于GPU 利用率看起来不低但实际有效计算时间少。8.2 多卡训练 loss 不收敛的常见原因多卡训练 loss 不收敛首先要确认数据是否被正确切分。如果每张卡拿到的是相同数据梯度就失去了多样性等价于单卡训练但批次没变。其次检查学习率是否随卡数调整数据并行下全局批次变大学习率通常要相应放大。然后检查梯度同步是否正确有没有卡掉队导致梯度不一致。还有一个容易被忽略的点是随机种子。如果每张卡的随机种子相同数据增强和 dropout 的行为会完全一致降低模型泛化能力。正确做法是给每张卡设置不同的种子但保证整体可复现。8.3 推理服务延迟毛刺的定位方法推理服务延迟毛刺通常来自几个方面批处理策略导致的长尾请求、显存碎片导致的分配延迟、GC 或后台任务抢占资源、网络抖动。定位时先看延迟分布如果 P99 高但 P50 正常说明是长尾问题重点查批处理策略和请求长度分布。如果整体都高查资源利用率和网络。我处理过一次毛刺问题最后发现是日志组件在高峰期同步写磁盘导致主线程阻塞。改成异步写日志后毛刺消失。这个问题的教训是推理服务里的任何同步 IO 都可能成为毛刺源包括日志、监控上报和配置读取。问题现象可能原因排查手段解决方向训练速度骤降GPU 降频、通信降级、数据瓶颈nvidia-smi、通信基准、CPU 监控散热、换线、调 num_workersloss 不收敛数据未切分、学习率未调、种子相同检查数据加载、学习率配置、种子设置修正切分、缩放学习率、差异化种子推理延迟毛刺批处理长尾、同步 IO、显存碎片延迟分布、IO 监控、显存摘要连续批处理、异步 IO、内存池配置多机通信慢网卡降级、路由错误、带宽抢占ibstat、基准测试、流量监控换线、修路由、隔离流量显存溢出激活值大、碎片、缓冲区大显存摘要、批次大小、通信桶梯度累积、内存池、调桶大小9. 我在这条路上踩过的几个典型坑第一个坑是盲目追求最新版本。有一次我把框架和通信库都升到最新结果多卡训练直接 hang 住回退版本后正常。后来我养成了习惯生产环境只用经过验证的稳定版本组合新版本先在测试环境跑通再上。第二个坑是忽略数据加载的瓶颈。早期我总以为 GPU 是瓶颈后来发现很多任务里 GPU 利用率只有百分之六七十剩下时间都在等数据。优化数据加载后同样的硬件训练速度提升了近四成。数据加载的优化包括用更快的存储、增加 worker 数、预取和缓存。第三个坑是检查点保存太频繁。有一次我设了每 100 步保存一次结果保存时间占了总训练时间的百分之十五。后来改成每 1000 步保存一次并且用异步保存训练效率明显提升。检查点频率要在容错和效率之间找平衡任务越稳定保存间隔可以越长。第四个坑是监控指标太多导致告警疲劳。一开始我把所有能采集的指标都设了告警结果每天收到几百条告警真正重要的反而被淹没。后来我精简到只保留核心指标并且分级告警才让监控真正发挥作用。这些坑的共同点是它们都不是技术难题而是工程决策问题。AI Infra 的很多挑战不在于某个算法多难而在于如何在资源、效率、稳定性和成本之间做出合理的权衡。这份笔记里的每一层最终都要落到这些权衡上。你在实际项目中遇到具体问题时可以回到对应的层次看看这一层的核心矛盾是什么再结合手头的资源和约束去选择方案。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑