1. 吞吐与显存优化全景:为什么需要双管齐下?

做GPU优化这些年,我见过太多人只盯着一个指标猛调。有人死磕吞吐量,结果显存爆了;有人拼命省显存,结果计算慢得像蜗牛。说白了,吞吐和显存就像一对冤家——你压了这头,那头就翘起来。

今天咱们就来聊聊,为什么必须双管齐下。

吞吐瓶颈与显存瓶颈的辩证关系

先看个真实场景。我在优化一个大规模Transformer模型时,发现计算单元利用率只有30%。当时第一反应是加大batch size提吞吐。结果呢?显存直接OOM,训练崩了。

反过来,我试过用梯度检查点省显存。显存是降下来了,但计算图得重算,吞吐量掉了40%。

你想想看,这两个指标其实是互相牵制的:

  • 吞吐量:单位时间处理的数据量。通常靠大batch、高并行度来提。
  • 显存占用:模型参数、激活值、梯度等占用的显存空间。省显存往往要牺牲计算效率。

它们的关系,我画了张图帮你理解:

吞吐与显存优化辩证关系图 吞吐优化 增大batch size 提高并行度 减少kernel launch开销 显存优化 梯度检查点 混合精度训练 显存复用与卸载 冲突 双管齐下:寻找最优平衡点

这张图想表达什么?左边是吞吐优化的常用手段,右边是显存优化的常用手段。中间那个红色箭头,就是它们打架的地方。

核心观点:吞吐和显存不是非此即彼的选择题。真正的优化高手,是在两者之间找到那个「甜点」。

优化目标与评估指标

做优化之前,得先知道怎么衡量。我一般看三个核心指标:

指标 定义 我的经验
吞吐量 每秒处理的样本数 (samples/s) 别只看峰值,要看稳定运行时的均值。我踩过坑,峰值好看但实际跑起来波动很大。
显存占用 模型运行时占用的显存大小 (GB) 留10-20%余量。我曾经把显存压到99%,结果一个波动就OOM了。
算力利用率 实际算力 / 理论峰值算力 (%) 低于50%说明有瓶颈。我习惯用nvidia-smi和Nsight Systems一起看。

这三个指标怎么权衡?我举个例子你就明白了。

实战案例:我在优化一个BERT推理服务时,初始吞吐是1000 samples/s,显存占用8GB,算力利用率45%。

第一步,我把batch size从8提到32,吞吐涨到2500,但显存飙到20GB,超了卡的限制。

第二步,我启用FP16混合精度,显存降到12GB,吞吐反而因为计算加速到了3000。

第三步,我加了显存复用,最终显存稳定在10GB,吞吐3200,算力利用率72%。

你看,每一步都不是单点优化,而是联动调整。

为什么不能只盯一个指标?

我见过不少团队,上来就说「我要把吞吐翻倍」。结果呢?

  • 盲目加大batch → 显存爆了 → 得用梯度累积 → 训练时间反而变长
  • 或者反过来,拼命省显存 → 用梯度检查点 → 计算图重算 → 吞吐掉一半

说白了,这两个指标是跷跷板的两头。你只压一头,另一头就会翘起来打你脸。

避坑指南:我曾经在一个项目里,为了省显存把激活值全扔了,用的时候再重算。结果显存是省了2GB,但每个step多了30%的重算开销。最后吞吐反而降了15%。

所以我的建议是:先做profiling,找到真正的瓶颈在哪。是计算受限?还是显存受限?还是两者都有?

双管齐下的核心思路

那到底怎么双管齐下?我总结了三步走:

  1. 先诊断:用profiling工具看当前瓶颈。是计算单元在等数据?还是显存在等释放?
  2. 再权衡:根据瓶颈类型,选择优化手段。计算受限就提并行度,显存受限就压缩数据。
  3. 最后迭代:每次改一个参数,重新profiling。别一次改太多,不然你都不知道哪个改动起了作用。

嗯,这里要注意一点:没有银弹。不同的模型、不同的硬件、不同的batch size,最优解都不一样。我习惯用自动化搜索工具来找参数组合,但手动调优的经验也很重要。

好了,这一章咱们把全景讲清楚了。吞吐和显存就像左右手,缺一不可。接下来的章节,我会带你深入每个优化技术的细节——从计算优化到显存管理,再到实际案例拆解。

一句话总结:吞吐优化让你跑得快,显存优化让你跑得稳。双管齐下,才能跑得又快又稳。

可可精品资料库