1. 吞吐调优全景

大家好,我是你们这堂课的主讲人。咱们开门见山,聊聊吞吐调优这件事。

说实话,我见过太多团队,模型在单卡上跑得挺欢,一上多卡就「翻车」。GPU利用率不到30%,显存爆了,通信卡住了,训练三天三夜结果发现白跑了。嗯,这些坑我基本都踩过。

所以第一节课,我想先帮你把「调优全景」这张地图画出来。你知道了路怎么走,后面才不会迷路。

1.1 为什么需要调优?—— 算力很贵,时间更贵

先问个问题:你花了几十万买来的A100,利用率只有20%,你心疼不心疼?

我个人习惯,拿到一个新集群,第一件事就是跑个基准测试。有一次我测出来,某个分布式训练任务,GPU计算时间只占30%,剩下70%都在等数据加载和通信。说白了,你的钱有一大半打了水漂。

调优的核心目标就两个:

  • 压榨硬件:让GPU、CPU、网络、存储都跑满,别闲着
  • 缩短时间:同样的模型,别人跑3天,你跑1天,这就是竞争力

核心公式:吞吐量 = 总样本数 / 总训练时间

调优就是让这个公式的分子变大,分母变小。

1.2 性能瓶颈的常见类型 —— 你的模型卡在哪了?

我在项目中遇到过各种各样的瓶颈,总结下来,无非这四大类:

瓶颈类型 典型表现 我踩过的坑
计算瓶颈 GPU利用率高(>95%),但吞吐上不去 模型太大,算子效率低,小算子太多
IO瓶颈 GPU利用率低,CPU忙,磁盘读写高 数据加载太慢,GPU在等数据
通信瓶颈 多卡训练时,通信时间占比高 AllReduce卡住,网络带宽不够
显存瓶颈 OOM,或者batch size上不去 激活值太大,模型参数放不下

你想想看,如果你的GPU利用率只有40%,那大概率不是计算瓶颈,而是IO或通信在拖后腿。我曾经调过一个项目,GPU利用率死活上不去,查了三天发现是数据预处理线程数设少了。就这一行代码,改了之后利用率直接飙到90%。

小技巧:用 nvidia-smi 看GPU利用率,用 top 看CPU,用 iostat 看磁盘。三个命令一敲,瓶颈在哪一目了然。

1.3 调优的通用方法论 —— 三步走,不迷路

调优不是玄学,是有套路可循的。我总结了一个「三步走」方法论,这些年一直在用:

  1. 测量:先别动手改代码,先搞清楚现状。跑个profiling,看看时间花在哪了。
  2. 分析:找到最长的那个「短板」。是计算慢?还是通信慢?还是IO慢?
  3. 优化:针对短板下手。一次只改一个变量,改完再测,看效果。

我曾经犯过一个错误:一上来就调batch size、改学习率、换优化器,结果越调越乱。后来学乖了,老老实实先做profiling,找到瓶颈再动手。嗯,这个教训挺深刻的。

避坑指南:千万不要「凭感觉」调优。我曾经有个同事,觉得模型跑得慢就加GPU,结果加了4张卡,速度反而更慢了——因为通信开销超过了计算收益。所以,先测量,再动手。

1.4 吞吐调优的知识体系

下面这张图,是我自己画的吞吐调优全景图。你把它存下来,后面每节课都可以回来对照着看。

吞吐调优全景知识体系 吞吐调优 计算瓶颈 IO瓶颈 通信瓶颈 显存瓶颈 算子融合 数据预加载 梯度压缩 激活重计算 三步走:测量 → 分析 → 优化 PyTorch Profiler Nsight Systems nvidia-smi iostat / top 图:吞吐调优全景知识体系

这张图把整个调优体系串起来了。你看,从「吞吐调优」这个核心出发,左边是四大瓶颈,右边是对应的优化手段,下面是方法论和工具。后面每一节课,都会围绕这张图展开。

1.5 调优的「道」与「术」

最后我想聊点虚的,但我觉得很重要。

调优这件事,有「道」和「术」两个层面。

  • 术:具体的技术,比如怎么用profiler、怎么调batch size、怎么改数据加载。这些后面都会讲。
  • 道:调优的思维方式和习惯。比如「一次只改一个变量」、「先测量再动手」、「不要过早优化」。

我个人觉得,「道」比「术」更重要。技术可以学,但思维方式需要慢慢培养。我见过太多人,学了一堆调优技巧,但一上手就乱改一气,最后越调越差。

我的建议:从今天开始,养成一个习惯——每次调优前,先问自己三个问题:

  1. 现在的瓶颈是什么?
  2. 我改这个参数,预期会有什么效果?
  3. 改完之后,我怎么验证效果?

好了,第一节课就到这里。内容不多,但都是干货。你把这节课消化了,后面的内容学起来会轻松很多。