第12章:AI 系统性能优化 175+ 项检查清单
把全书方法论压成一份可勾选 cheat sheet——12 大类 175+ 条:从心态到 OS 到 CUDA 到训练到推理到电与冷,拿到任何新集群都能按图索骥
前 11 章把方法论、硬件、OS、通信、案例、未来都讲完了——本章做最后一件事:压成一份可以打印出来贴在显示器旁的清单。175+ 条要点按 12 大类组织,每条 1-2 句中文。这不是教程,是工具:每次拿到新集群、debug 新问题、做新一轮优化时,翻出来挨个过一遍。覆盖不了所有情况,但 80% 的常见性能问题在这里都能找到对应入口。
📑 目录
- 使用方法
- A. 性能心态与成本意识(12 项)
- B. 可复现与文档(10 项)
- C. 系统架构与硬件规划(8 项)
- D. Grace-Blackwell 统一架构(5 项)
- E. 多卡扩展与互连(9 项)
- F. OS 与驱动(15 项)
- G. GPU 资源管理与调度(9 项)
- H. 数据 Pipeline 与 I/O(15 项)
- I. Profile 与监控(10 项)
- J. CUDA 与 Kernel 调优(16 项)
- K. 精度与混合精度(8 项)
- L. 分布式训练与网络(9 项)
- M. 推理与服务(12 项)
- N. 电力与散热(9 项)
- 全栈检查”5 分钟自测”
- 参考资料
使用方法
🌟 正确姿势:这份清单是逆向工具,不是顺序教程。流程是:
- 拿到一个性能问题,先用第 1 章的 Goodput 视角和第 5 章的 profile 工具定位瓶颈层
- 根据瓶颈层翻到对应大类(比如通信瓶颈 → L 类、kernel 瓶颈 → J 类)
- 在那一类里挨个核对——很多时候不是一条 fix 解决,是几条共同凑够 5-10% 加速
- 改动完重新 profile 验证——清单只是 hypothesis 来源,不是真理
⭕ Pareto 原则:175+ 条不是要你全部做完——80% 的收益来自 20% 的项目。新集群第一次过这份清单时,先扫一遍标 ⭐ 的高价值项。
A. 性能心态与成本意识
工程师的”软功夫”——决定你优化得对不对、值不值。
- ⭐ 优先优化 80% 时间所在——profile 看 hottest path,别在占 1% 的细节上打磨
- ⭐ 改动前后必 profile——直觉常错;凭”我觉得”的优化可能反而变慢
- 设定优化时间预算——大型重复 job 可投几周,一次性脚本不值 1 天
- 跟进框架版本 —— PyTorch 2.x → 2.y 经常有 ~10-40% 白送加速
- 跟硬件厂商保持沟通——驱动 / 库的小升级常解决”诡异”性能问题
- ⭐ 用 Goodput 而非 raw FLOPs——衡量真在做有效工作的部分
- ⭐ Performance-per-Watt 与 Performance-per-Dollar 同等重要——大规模下能耗就是钱
- 云上活用 spot / reserved 实例——前提是 job 能容忍中断
- 持续监控集群利用率 —— DCGM + Prometheus 起步,看到 50% util 就深挖
- 超参也是性能参数——batch size、序列长度、MoE active experts 都可调
- 记录每次改动 + 收益——形成团队知识库,新人不重踩坑
- 简单解决方案优于复杂解决方案 —— torch.compile 够用就别上手写 kernel
B. 可复现与文档
没数据的”我加速了 30%” 在工程团队里没信用。
- ⭐ 所有配置 / benchmark 脚本进 Git ——版本化是复现的前提
- CI/CD 跑 perf 回归 ——MLPerf、DeepBench 当基线,挡住悄悄变慢的 PR
- End-to-end profile 优先于单层 profile ——单层很快不等于全 pipeline 快
- 自动监控 + 异常告警 —— Grafana dashboard + 利用率骤降告警
- 容错设计——分布式 checkpoint、冗余硬件、动态 reschedule
- 激进编译选项 + profile-guided optimization —— -O3 不是终点,PGO 还有空间
- 安全和性能协同优化 ——加密 / HSM 不能让吞吐崩盘
- ⭐ 内部知识库 ——记录每次踩坑 + 解法,新人一周内上手老问题
- 可扩展架构设计——硬件 / 软件迭代时不需要从头重写
- ⭐ 小规模先验证再上大集群——8 卡 AllReduce 已经 20% 的话,1024 卡只会更糟
C. 系统架构与硬件规划
选硬件就像装修——错了很难补。
- ⭐ Goodput 是设计目标——不是 raw FLOPs/TB
- 优先现代 GPU——Blackwell 等代际跨越带来的 perf/W 远超调参
- NVLink/NVSwitch > PCIe ——多卡训练别只用 PCIe
- 平衡 CPU / GPU / 内存比例——典型每 GPU 配 1+ fast CPU 核给 dataloader
- 数据 locality 优先——紧耦合任务别跨 NVLink 域
- 找最慢一环先升级——10% I/O 瓶颈花再多 GPU 也救不了
- 集群规模避免过冲——N 卡到 95% 利用率再考虑 2N 卡
- 散热和电力前置规划 —— 120 kW NVL72 不是普通机房能直接接
D. Grace-Blackwell 统一架构
一颗 superchip 的玩法,在传统服务器上学不到。
- ⭐ 利用 EGM 统一内存——480 GB Grace + 192×2 GB HBM 当一个池子
- 热数据放 HBM、冷数据放 LPDDR5X——LPDDR 比 HBM 慢约 10×,别误放
- GPU 直接读 CPU 内存——绕过 cudaMemcpy,前提是访问模式批量友好
- 充分用 Grace CPU——72 ARM 核做 tokenization、preprocessing、batch collation
- 超大模型用 EGM overflow——单 superchip 跑 500 GB 模型不需要切分,前提是 hot 部分能放进 HBM
E. 多卡扩展与互连
NVL72 改写了并行策略的设计准则。
- ⭐ 全互联 NVL72 内可激进切分——TP / PP / EP 都放柜内
- 拓扑感知调度——同一 job 的 GPU 永远在同一 NVLink 域
- 认清 NVLink 5 带宽 —— 1.8 TB/s/GPU 双向、单柜 130 TB/s bisection
- 跟进新版 NCCL ——PAT 算法、SHARP 集成,新版常更快
- 细粒度模型并行成为可能 ——以前不可行的 layer-wise 切分现在 OK
- 关注链路饱和 ——profile 看 NVSwitch 利用率,真饱和时聚合大消息
- 跨 rack 计划分层通信——柜内先做局部 reduce,跨柜再做全局
- 混合云 / 边缘自适应通信协议——异构环境下动态负载均衡
- NVLink 域可扩到 576 GPU ——8-rack NVL72 + 二级 switch
F. OS 与驱动
Ch3 的浓缩版,新机器拿到手按这个过一遍。
- HPC 调过的 Linux 内核——禁用不必要服务,CPU governor=performance
- ⭐ vm.swappiness=0 ——训练永远不要 swap
- 预分配大内存块 ——减少运行时 fragmentation
- OMP / MKL 线程数对齐物理核——避免过度争抢
- ⭐ NUMA-aware pinning —— numactl —cpunodebind —membind
- ⭐ NIC IRQ 绑同 NUMA 核 —— irqbalance 配 NUMA-aware
- ⭐ THP=always 或 madvise ——大模型场景必开
- ulimit -l unlimited ——pinned memory 不被卡死
- ⭐ 驱动 / CUDA / cuDNN / NCCL 全集群版本一致——避免诡异错误
- GPU Persistence Mode 开——
nvidia-smi -pm 1,消除 1-2 秒冷启动 - MIG 模式下 Persistence 也必须开——切片配置不会重置
- 隔离 OS housekeeping 核—— cpuset / isolcpus 把训练核独立
- NVMe 用 mq-deadline / noop scheduler + noatime mount
- BIOS / 固件保持更新 ——常解决 PCIe 带宽 / IOMMU 问题
- 容器
--ipc=host+--ulimit memlock=-1——别让 Docker 卡死共享内存
G. GPU 资源管理与调度
同一张 GPU 上跑多任务的 trade-off 表。
- ⭐ MPS 用于”两个轻任务共卡” ——overlap 推理 / 训练,提升综合 util
- MIG 用于”多租户强隔离” —— Hopper 7 切片、Blackwell 27 GB×7 起
- MIG 持久化保持 ——boot 时配好就别动,改动要重启
- benchmark 时锁频 ——
nvidia-smi -lgc/-lmc防 throttle 污染数据 - ⭐ ECC 永不关 ——长训练任务一次 bit flip 可能毁掉几周成果
- K8s / SLURM 拓扑感知调度 ——避免 job 跨远端 GPU
- CPU 与 GPU 配比合理 —— 8 GPU 至少 16 CPU 核给 dataloader
- ⭐ NVSwitch 系统必跑 Fabric Manager ——否则 NVLink 全互联根本不工作
- 节点级 job packing ——两个 2-GPU 任务可能比一个 4-GPU 更优,前提是不冲突
H. 数据 Pipeline 与 I/O
第 1 章的 4 大杀手中,“数据饥饿” 占第二。
- ⭐ DataLoader num_workers > 0 ——单 worker 多半喂不饱 GPU
- ⭐ pin_memory=True + non_blocking=True ——DMA 速度 2-3×
- CPU compute 与 H2D 重叠——双缓冲 / 流水线 prefetch
- 本地 NVMe 优先于网络存储——单盘 5-6 GB/s 够喂 8 卡
- 数据分片 + 多文件并行读 ——避免单文件单服务器瓶颈
- 小文件打包成 TFRecord / WebDataset / Parquet ——避免 metadata 风暴
- 客户端缓存 + 多 epoch 友好 ——OS page cache + RAM disk + 3FS 类系统
- 轻量压缩(LZ4 / ZSTD-fast)交换 CPU 换 I/O ——前提 CPU 不饱和
- 持续监控 pipeline 吞吐——
dstat+ DCGM,GPU < 100% util 八成在等数据 - 集群级 I/O 容量规划 —— 100 节点 × 1.6 GB/s = 160 GB/s,中央存储够吗
- Checkpoint 异步写——别让 step 卡在磁盘上
- 二进制数据格式 ——TFRecord / LMDB / mmap 比文本快几倍
- 关闭 hyper-threading(CPU bound dataloader)——某些场景反而更稳
- DALI 等 GPU 增强库 ——把 image augmentation 推到 GPU
- ⭐ end-to-end profile 看真 I/O 占比——synthetic data vs real data 对比
I. Profile 与监控
没看到瓶颈在哪,所有调优都是瞎猜。
- ⭐ Nsight Systems 看时间线 ——CPU / GPU / 通信 / I/O 全貌
- Nsight Compute 看单 kernel ——occupancy / memory throughput / warp 效率
- PyTorch Profiler + TensorBoard ——框架级看 forward / backward / optimizer
- NVTX 标记切片——把 dataloader / forward / comm 在时间线上分清楚
- GPU Util + SM Efficiency 区分—— util=100% 不代表 SM 全用上
- 掉到 50% util 找根因——常是 data wait / sync / OS jitter
- 检查 warp divergence——branch efficiency 低时重组数据 / 排序
- 多卡训练看 rank 平衡——rank 0 常做额外 stats,变成瓶颈
- GPU 内存 / CPU paging 持续监控 ——climbing 多半是 leak
- 回归测试——driver / 框架 / 代码升级后跑 benchmark 防偷偷变慢
J. CUDA 与 Kernel 调优
写自己的 kernel 时的 cheat sheet。
- ⭐ 内存层级理解 ——register > shared > L2 > HBM,数据尽量往上推
- ⭐ 全局内存合并访问 —— warp 内 32 线程访连续地址
- shared memory tiling ——矩阵 / 卷积的经典套路
- 避免 bank conflict ——shared mem 访问 stride 不要让 32 个 bank 抢同一个
- 128B 对齐 + float4 vector load ——一次拉更多数据
- batch 多次小 cudaMemcpy 合并成一次大的 ——launch overhead 不是免费的
- GPU 内存池复用——
cudaMallocAsync或 PyTorch caching allocator - occupancy 与 ILP 平衡 ——register / shared mem 用太多反而 occupancy 掉
- Nsight Compute Occupancy Calculator ——别凭直觉,用工具算
- ⭐ Hopper TMA / Blackwell
cp.async——异步 copy 隐藏 HBM 延迟 - 手动 prefetch ——
__prefetch_global或显式 register 预加载 - Cooperative Groups 替代全 block barrier ——细粒度同步
- warp divergence 降到最低 ——sort 数据让 warp 内 32 线程一致
__shfl_sync等 warp 原语 ——绕过 shared memory 的 reduction- ⭐ CUDA Streams 并发 ——独立 kernel 不同 stream
- 优先用 cuBLAS / cuDNN / NCCL / NIXL ——工业级,接近 speed of light
- 小 op fuse 成大 kernel ——减少 launch + 中间 HBM 往返
- CUDA Graphs(重复训练 loop 用) ——Launch overhead 砍一大半
- roofline 分析看是否撞墙 ——还差多少到硬件极限
- 必要时看 PTX / SASS ——bank conflict / 冗余计算可能藏在汇编里
K. 精度与混合精度
低精度是免费午餐,但不能盲开。
- ⭐ AMP/BF16 是默认起点 ——大多数训练 2-8× 加速,精度损失可控
- 关键累加保 FP32 ——loss / 梯度归约稳定性
- FP8 + Transformer Engine(Hopper+) ——LLM 训练再 ~2× 加速
- ⭐ FP8 单独开常变慢 ——必须配 torch.compile + 大 batch(参考第 10 章 MobileEye)
- FP4 仅 Blackwell+ ——推理优先,训练谨慎(精度敏感层保高精)
- 量化敏感层(早期 / norm / softmax)保高精 ——TE2 自动做,自定义算子要自己处理
- 量化校准 / QAT ——INT8 推理别裸跑,先 calibrate
- 结构化稀疏 2:4 ——Ampere+ Tensor Core 自动 2× 加速
L. 分布式训练与网络
万卡集群的”心脏”调试手册。
- ⭐ RDMA 优先(IB / RoCE) ——延迟比 TCP 低 5-10×
- TCP 路线必须调 buffer + jumbo frame ——
net.core.rmem_max/ MTU=9000 - NIC IRQ + dataloader 同 NUMA ——又是 NUMA pinning
- ⭐ NCCL_DEBUG=INFO 是排障第一步 ——看实际选了 NVLink/IB/TCP 哪条路径
- ⭐ NCCL_NTHREADS / NCCL_BUFFSIZE 调优 ——大消息 / 多卡场景
- ⭐ SHARP 启用 ——
NCCL_SHARP_ENABLE=1给 AllReduce 2-5× 加速 - 慢网络用 gradient accumulation ——通信频率降到 1/K
- 分层 AllReduce ——柜内先做,跨柜再做(NCCL 默认会做,profile 验证)
- NIC 别 oversubscribe —— 8 GPU AllReduce 200 Gbps 流量,单 100 Gbps NIC 不够
M. 推理与服务
Goodput 推理侧定义:满足 SLO 的请求占比。
- K8s + 自定义性能指标动态扩缩 ——Burst 流量友好
- ⭐ Dynamic batching(Triton / vLLM) ——请求来一个就尝试合并
- ⭐ TensorRT-LLM / vLLM / Dynamo 优于自写 inference——除非你团队投入很大
- ⭐ INT8 量化 ——推理常用,4× 显存 + 2-4× 加速,前提 calibrate 验证精度
- NIXL 用于跨节点 KV-Cache —— PD 解耦推理必备
- KV-Cache 卸载到 NVMe—— 长对话场景,GPUDirect Storage + 异步 fetch
- Speculative decoding ——draft 小模型 + 大模型 verify,延迟换吞吐
- ⭐ 监控 tail latency P99 ——平均值好看不代表用户体验好
- 冷启动 warmup ——服务前跑几次 dummy 推理,避免首请求高延迟
- 训练 / 推理混部时给推理资源保护 ——MIG 切片或独立节点
- Grace CPU 做 tokenization / batch collation ——别让 GPU 干 CPU 活
- 边缘 AI 端到端协议优化 ——中心 → 边缘传输也是性能问题
N. 电力与散热
120 kW 时代,瓦数就是金钱。
- ⭐ 监控 GPU 温度 + 频率——
nvidia-smi dmon,接近 85°C 开始降频 - 能耗感知调度 ——可再生能源高峰跑大 job、电费低谷跑非紧急
- ⭐ Perf-per-Watt 调优 ——memory-bound kernel 略降频,功耗大降而 runtime 几乎不变
nvidia-smi -pl <W>调 power cap ——80% power 常给 95% 性能- 集中负载,提高单卡 utilization —— 1×90% 比 2×45% 更省电
- 风扇 / 进气口物理检查 ——老机房灰尘是隐形吃性能杀手
- 持续 power 监控——AllReduce 阶段功耗低、dense 计算阶段尖峰,排开避免跳闸
- 长期 job 略降功耗 ——90% power cap 几乎不掉吞吐,硬件寿命延长
- 流体冷却参数监控——流速 / 入水温,GB200 NVL72 60-70°C 是健康区间
全栈检查”5 分钟自测”
性能问题不是看 175 项慢慢挑,先用这 12 个问题快速定位,缩到对应大类:
- GPU Util 多少? < 80% → 跳到 H(I/O)、L(通信)、I(profile)
- NCCL_DEBUG 显示路径对吗? 退回 TCP → L 类
- 温度 / 频率正常吗? 降频 → N 类
- Topology 对吗? GPU/NIC 不同 NUMA → F 类 IRQ + K8s topology
- SHARP 启用了吗? 没启用 → L 类
- AMP/FP8 开了吗? 没开 → K 类
- DataLoader num_workers + pin_memory? 没配 → H 类
- kernel hot path 是哪个? → J 类对应优化
- 多卡 rank 是否平衡? rank 0 卡 → I 类 / 分担工作
- Memory 持续增长? Leak → I 类 + memory snapshot
- Tail latency 高? → M 类(推理) / I 类(训练抖动)
- 能耗超预算? → N 类
🌟 最后一句:这份清单覆盖不了一切——它是地图,不是现场。最大的优化往往在清单之外——一个领域专家的直觉比 175 项标准项都管用。把清单当成确保你没有漏掉低垂果实的工具,真正的杠杆在你看完清单之后还在想的那个东西。
📚 参考资料
蓝本书籍
- AI Systems Performance Engineering (Chris Fregly, O’Reilly 2025):learning.oreilly.com —— 本章 175+ 项框架来自此书 Ch12
工具速查
- NVIDIA Nsight Systems / Compute:docs.nvidia.com/nsight-systems/ / docs.nvidia.com/nsight-compute/
- NVIDIA DCGM:docs.nvidia.com/datacenter/dcgm/
- NCCL 环境变量完整列表:docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html
- PyTorch Profiler:pytorch.org/tutorials/recipes/recipes/profiler_recipe.html
- nccl-tests:github.com/NVIDIA/nccl-tests
- Hugging Face Ultra-Scale Playbook —— 多卡调优实战
- MLPerf Benchmarks:mlcommons.org/benchmarks/
本系列其它模块的延伸
- 模块一 前置知识:GPU / Transformer / 集合通信基础
- 模块二 CUDA:具体算子实现
- 模块三 分布式训练:并行策略具体实现
- 模块四 推理优化:vLLM / TensorRT-LLM / Dynamo / 量化具体实现
- 模块五-十二 Agent 系列:把性能优化思路用到上层 Agent 系统
🎉 恭喜完成模块零(已完成的 7 章 + Ch5-9 待补)。
模块零是地图,具体街道在模块二/三/四。从这份清单里抽 1-3 项明天就在你的集群上跑一遍——优化是练出来的,不是读出来的。