想象你打算在古镇开一家“AI 画师餐厅”:客人报一句菜单(文字描述),后厨就要端出一盘独一无二的画。这套后厨有三个人——点单员把客人的话写成订单卡,大厨盯着订单卡反复调味二十到五十遍才肯出锅,装盘师把成品摆得漂漂亮亮端上桌。短短几秒,一道菜就成了。可你真要开店,会立刻撞上一连串问题:灶台(显卡)该买哪个牌子?贵的灶台出菜到底快多少?同一位大厨换套做法(推理框架)能不能更快?一锅同时炒几份(batch size)才最划算?食材要不要提前切好备好(量化)?后厨台面(显存)怎么摆才不打架?这一连串问题,正是文生图服务的推理性能基准测试要回答的——它不关心画多好看,只关心同样的画怎么用最少的钱、最快的速度端上桌。

岗位关联

学会设计和读懂基准测试,你就能在 GPU 选型、框架选择、批次策略上做出数据驱动决策,直接降低文生图服务的成本并提升用户等待体验。

目录
  1. 可视化演示
  2. 推理管线速览
  3. 基准测试方法论
  4. GPU硬件对比
  5. 框架加速路线
  6. 批次策略调优
  7. 量化加速方案
  8. 显存优化管理
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

推理管线速览

想象你刚盘下一家“AI 画师餐厅”。客人进门说“来一幅暮色下的赛博朋克城市”,点单员把这句话浓缩成一张后厨能看懂的订单卡;大厨拿到订单卡,从一团白噪声似的“生面团”开始,反复试味、调整细节,要折腾二十到五十遍才肯出锅;最后装盘师把这份“潜空间”里的半成品摆成一张像模像样的像素画,端上桌。这三个角色的分工,正是 Stable Diffusion 的三段核心管线。

在技术文档里,这三个人分别叫文本编码器(Text Encoder)、UNet 去噪网络、VAE 解码器。文本编码器把一句人话变成一堆数字向量,告诉模型“顾客到底想要什么”;UNet 是最大的体力活,它在潜空间里迭代很多步,每步都把噪声往“像画”的方向推一点点;VAE 解码器负责把处理完的潜空间数据还原成人眼可见的 RGB 图片。

既然知道工序有三段,测性能自然从分别计时开始。一次完整推理的总延迟等于三段耗时之和,其中 UNet 部分要乘上迭代步数 S(通常 20~50 步)。步数越多细节越丰富,但代价是总延迟直线上升:

Ltotal=Lenc+S×Lstep+Ldec\displaystyle L_{\text{total}} = L_{\text{enc}} + S \times L_{\text{step}} + L_{\text{dec}}

1. L_total 总出菜时间:一次完整推理的总延迟,从输入提示词到图片生成完毕的全过程耗时。

LtotalL_{\text{total}}

2. L_enc 与 L_dec 固定环节:文本编码和 VAE 解码各只执行一次,耗时相对固定且占比小,就像点单和装盘。

Lenc+LdecL_{\text{enc}} + L_{\text{dec}}

3. S × L_step 去噪总耗时:UNet 要重复执行 S 次去噪,每次耗时 L_step。步数越多,细节越丰富,耗时也越长,这是优化总延迟的首要目标。

S×LstepS \times L_{\text{step}}

弄清了这三个人,你就拿到了基准测试的第一把尺子:想优化整体出菜时间,先盯住占比最大的环节。这也是后面所有硬件、框架、批次优化主要围着 UNet 转的根本原因。

基准测试方法论

后厨效率体检,只看一道菜端上桌的时间够吗?不够。假设你有一个灶台,炒一份番茄炒蛋要两分钟,但一次能同时炒六份,平均每份只要四十秒。对客人来说,等两分钟和等四十秒体验完全不同;对你来说,高峰时段能不能吞下源源不断的订单,取决于“单位时间能出几道菜”。前者叫延迟,后者叫吞吐量,做基准测试必须分开看。

翻译到 Stable Diffusion 上:延迟指输入一个提示词到生成一张完整图片的总时间,单位是秒/张,直接决定用户等待体感;吞吐量指单位时间内能生成的图片数,常见写法是 it/s(每秒迭代步数)或 images/s(每秒图片数)。两者都很容易在报告里被混为一谈,但它们的优化目标完全相反——降延迟要小批次,提吞吐量要大批次。

一份合格的基准测试报告,至少要交代四件事:什么 GPU、什么推理框架、批次多大、迭代几步。专业测试还会做预热(剔除首次加载的冷启动)、多轮取平均、固定随机种子保证每轮噪声起点相同、准备覆盖不同画风的提示词集,避免“只测一张猫图”的偶然性。吞吐量的核心公式很简单:

T=BLbatch\displaystyle T = \dfrac{B}{L_{\text{batch}}}

1. T 吞吐量:单位时间内端出的菜,即每秒生成的图片数,相当于餐厅翻台率。

TT

2. B 批大小:一锅同时炒几份,batch size 越大,一次处理的图片越多。

BB

3. L_batch 单批延迟:炒完一锅的总用时,从开火到出锅,它随批大小增加而变大。

LbatchL_{\text{batch}}

所以基准测试就是给餐厅做全方位体检:既量单桌等待,又算翻台率,还要规定“每桌都是同样的菜、同样的流程”,报告才可信。这也是你后面做任何选型决策前必须做的第一步。

GPU硬件对比

到了选灶台环节。古镇上有家用小灶——RTX 4060、RTX 4090 这类消费级显卡,也有酒店后厨的猛火灶——A100、H100 这类数据中心 GPU。小灶便宜、省电,但台面小(显存小)、火力输出有限;猛火灶贵得惊人,但台面大、配料摆得开,还能同时开好几口锅,出菜纪律完全不同。

消费级卡和专业级卡的差距,不在“单张图的画质”上——模型参数相同,画出来的图质量完全一致——差别主要体现在三件事:显存容量、显存带宽、多卡扩展能力。SD 的 UNet 权重在 FP16 下约占 3.4GB,激活值则随分辨率和 batch size 增长,消费级 8GB 显存跑大分辨率或大 batch 很容易溢出;专业级卡更高的显存带宽,让每次取权重都快得多。

既然灶台价格差了好几倍,就不能只看绝对速度,而要看性价比——每花一块钱能换回多少产出:

E=TgpuCgpu\displaystyle E = \dfrac{T_{\text{gpu}}}{C_{\text{gpu}}}

1. E 性价比:单位成本换来的吞吐量,是 GPU 选型的核心指标,相当于“每块钱能买几道菜”。

EE

2. T_gpu 该卡吞吐量:某块 GPU 在相同模型、相同批次下的每秒产出张数,来自基准测试实测。

TgpuT_{\text{gpu}}

3. C_gpu 总拥有成本:包含采购价、功耗、机房托管等长期开销,不能只看标价。

CgpuC_{\text{gpu}}

选灶台不是越贵越好,而是看“每花一块钱能炒出几道菜”。消费级卡做小规模服务和原型验证,数据中心卡做高并发商业服务,各得其所。

框架加速路线

灶台定了,同一位大厨还可以用不同流派的做法。普通流派(PyTorch 基线)像老老实实按菜谱一步步来,每步都稳妥但偏慢;xFormers 流派像给大厨配了一套特制刀具和颠勺技巧,专门优化最费力的“调味”环节;TensorRT 流派更像把整本菜谱提前背熟,甚至把几个灶眼合并成一条流水线,开火前一切都已排好。

xFormers 的核心是内存高效注意力(memory-efficient attention),它改写 UNet 里的注意力计算,用分块处理降低显存读写,速度通常提升 20%~50%,而且基本不损失画质。TensorRT 则更进一步:把整个 UNet 编译成针对当前 GPU 高度优化的引擎文件,做算子融合(把多个小运算合并成一次内核启动)、自动选低精度 kernel,但首次编译要花几分钟到几十分钟,换 GPU 或改分辨率就要重新编译。

怎么量化流派的差距?用加速比——优化后比优化前快几倍:

A=LbaseLopt\displaystyle A = \dfrac{L_{\text{base}}}{L_{\text{opt}}}

1. A 加速比:优化效果的标尺,大于 1 代表变快,数字越大收益越高。

AA

2. L_base 基线耗时:PyTorch 原生实现的单批推理耗时,作为“普通做法”的参照。

LbaseL_{\text{base}}

3. L_opt 优化后耗时:应用 xFormers 或 TensorRT 之后,同一批任务的推理耗时。

LoptL_{\text{opt}}

选哪种流派要看场景:海量离线任务,TensorRT 的编译成本摊薄后很划算;在线服务追求灵活性,xFormers 即插即用、兼容多变提示词,是更稳妥的选择。

批次策略调优

大厨能不能一锅炒六份?把六张订单丢进同一锅(一个 batch),模型把六张图一起算。好处是分摊调度开销、让 GPU 算力更饱和;坏处是每一份出锅时间变长,且台面(显存)需要更大。这就是批次大小(batch size)的取舍,也是线上调优最频繁碰到的旋钮。

延迟随 batch size 上升,通常近似线性:batch=4 的单批延迟大约是 batch=1 的 2~3 倍;但吞吐量 = 批大小 ÷ 单批延迟,分子分母同时变,结果是先上升、后趋平甚至下降的曲线,拐点就是甜点区。显存则是硬约束——batch=16 算得再美,显存放不下就一切免谈。最优批次可以由显存上限直接估算:

B∗=⌊MavailMsample⌋\displaystyle B^{*} = \left\lfloor \dfrac{M_{\text{avail}}}{M_{\text{sample}}} \right\rfloor

1. B* 最优批大小:理论上限内吞吐量最高的批次,通常用实测曲线确认。

B∗B^{*}

2. M_avail 可用显存:GPU 总显存减去框架和 CUDA 上下文占用后真正可用的部分。

MavailM_{\text{avail}}

3. M_sample 单样本开销:处理一张图所需的激活内存,随分辨率和步数变化。

MsampleM_{\text{sample}}

4. floor 向下取整:台面放不下就少放一份,括号里的除法结果只取整数部分。

⌊⋅⌋\left\lfloor \cdot \right\rfloor

找到那个“锅刚好装满、台面刚好放下”的批大小,是推理优化工程师的日常。在线交互场景通常固定 batch=1 保低延迟,离线批量场景才拼命往拐点靠。

量化加速方案

备菜是后厨提速的另一大招。食材要提前洗好、切好、装进保鲜盒,大厨炒菜时直接下锅,开火到出锅的时间就短了。模型量化就是这个思路:把参与计算的数字从高精度“降级”为低精度,数据体积变小,搬运变快,计算也变快。

Stable Diffusion 默认用 FP16 半精度,相比 FP32 已经省了一半内存;更进一步是 INT8 量化,把权重和激活从 16 位压到 8 位,理论上内存搬运需求再砍一半。但 INT8 不是简单把参数四舍五入,而是要先准备一小批有代表性的校准图片,统计激活值分布,确定缩放因子和零点,把精度损失压到最小。量化带来的理论加速,主要来自内存带宽的减半:

Aquant≈BWFP16BWINT8≈2\displaystyle A_{\text{quant}} \approx \dfrac{\text{BW}_{\text{FP16}}}{\text{BW}_{\text{INT8}}} \approx 2

1. BW 带宽需求:推理中搬运权重和激活消耗的内存带宽,位宽越低,搬运量越小。

BW\text{BW}

2. FP16 与 INT8 位宽比:16 位对 8 位,单个体积正好一半,搬运次数同比例下降。

168=2\dfrac{16}{8} = 2

3. 约等号:实际性能受内核实现、反量化、内存对齐影响,接近但很少正好等于两倍。

≈\approx

备菜能大幅提速,但菜切太碎可能影响口感。量化后必须做画质 A/B 对比和端到端加速比验证,确认没有明显画质崩坏,再决定是否上线。

显存优化管理

最后整理后厨台面。台面上摆着三样东西:常备调料罐(模型权重)、正在处理的半成品(激活值)、临时工具(中间缓存)。台面不够用,要么菜直接做不了(OOM 崩溃),要么得频繁跑仓库取放东西(显存换页),速度断崖式下跌。

推理阶段的显存构成,比训练简单得多:训练要存梯度、优化器状态,推理统统不需要。推理的峰值显存主要由两部分构成——权重和激活值。权重大小固定(FP16 下约 3.4GB),激活值随分辨率、步数、batch size 增长。常见优化手段有三类:激活内存复用(算完一块立即释放)、缓存文本编码结果(同一批提示词只编码一次)、以及前面说的 INT8 权重压缩。峰值显存的模型如下:

Mpeak=Mw+Ma\displaystyle M_{\text{peak}} = M_{\text{w}} + M_{\text{a}}

1. M_peak 峰值显存:推理过程中台面占用最高的那一刻,超出即 OOM。

MpeakM_{\text{peak}}

2. M_w 权重显存:模型参数的固定占用,FP16 的 UNet 约 3.4GB,量化后可再减半。

MwM_{\text{w}}

3. M_a 激活显存:随分辨率、步数、批次动态起伏的中间数据,是大批次的主要拦路虎。

MaM_{\text{a}}

台面收拾得越清爽,能同时做的菜就越多。所以显存优化和批次策略总是手拉手出现——先摸清显存构成,再决定 batch 开多大,最后用基准数据验证整个方案。

---

AI 应用场景

云厂商文生图 API 定价

阶段:推理服务部署与成本优化

解决的问题:传统做法是拍脑袋选 GPU、按峰值预付费买实例,结果闲时资源浪费严重。用基准测试数据驱动选型——对比 A10、L4、A100 的吞吐量和性价比,再配合 FP16 和 batch=4,就能把单张图的生成成本精确算出来,按量计费。

具体案例:某 API 平台把 A10 换成 L4 并开启 xFormers,batch 设为 4,吞吐量提升 80%,单张图片成本下降约四成,用户平均等待时间反而缩短。

电商商品图批量生成

阶段:离线批量推理

解决的问题:大促前要生成数百万张商品图,单张串行生成要跑好几天。用大 batch(如 8~16)+ TensorRT 引擎离线跑,把吞吐量顶到拐点,一次搞定。基准测试里测出的最优批次和加速比,直接变成批处理管线的配置参数。

具体案例:某电商团队在双十一前用 4 张 A100 跑 TensorRT 引擎,以 batch=8 批量生成白底商品图,三天下线百万张图,整体成本比原来小 batch 方案降低 55%。

实时交互式出图工具

阶段:在线低延迟推理

解决的问题:用户拖拽提示词、调参数时希望 1 秒内看到预览,batch=1 的大吞吐策略在这里不适用。基于基准数据,把延迟拆成编码、去噪、解码三段,针对性用少步数(如 20 步)+ TensorRT + 缓存文本编码结果,把单张延迟压到 1 秒以内。

具体案例:某 Stable Diffusion WebUI 插件团队通过基准测试发现,瓶颈在 UNet 单步耗时,于是换用 TensorRT 并将步数从 30 降到 20,预览延迟从 2.8 秒降到 0.9 秒。

Python 演示

python48 行
import math  class GpuBenchSimulator:    def __init__(self, base_latency, per_sample_cost,                 memory_total, memory_per_sample):        self.base_latency = base_latency        self.per_sample_cost = per_sample_cost        self.memory_total = memory_total        self.memory_per_sample = memory_per_sample     def latency(self, batch_size):        return self.base_latency + self.per_sample_cost * (batch_size - 1)     def throughput(self, batch_size):        return batch_size / self.latency(batch_size)     def max_batch_by_memory(self):        return max(1, int(self.memory_total // self.memory_per_sample))     def best_batch(self):        cap = self.max_batch_by_memory()        best_b, best_tp = 1, 0.0        for b in range(1, cap + 1):            tp = self.throughput(b)            if tp > best_tp:                best_tp, best_b = tp, b        return best_b, best_tp  def main():    sim = GpuBenchSimulator(        base_latency=0.35, per_sample_cost=0.06,        memory_total=24, memory_per_sample=4.5,    )    print("batch | 延迟(秒/批) | 吞吐量(张/秒)")    for b in [1, 2, 4, 8, 16]:        if b > sim.max_batch_by_memory():            print("  %3d  |   显存不足   |   --" % b)            continue        print("  %3d  |   %.2f    |   %.2f"              % (b, sim.latency(b), sim.throughput(b)))    b, tp = sim.best_batch()    print("最佳批次: %d, 最大吞吐量: %.2f 张/秒" % (b, tp))  if __name__ == "__main__":    main()
目的:用模拟数据复现“批次策略调优”的完整流程——给定延迟模型和显存上限,求出最优 batch size 和最大吞吐量。
  1. return self.base_latency + self.per_sample_cost * (batch_size - 1)模拟“炒一锅”的耗时随份数线性增长,就像 batch 增大导致单批延迟变长。
  2. return batch_size / self.latency(batch_size)翻台率等于一锅几份除以一锅耗时,这正是正文的吞吐量公式。
  3. max(1, int(self.memory_total // self.memory_per_sample))用显存上限除以单份占用,算出台面最多放几份。
  4. for b in range(1, cap + 1):从 1 份到满额逐个试探,实测吞吐量曲线,而不是拍脑袋定批次。
  5. if __name__ == "__main__":脚本可执行入口,运行后直接输出每个批次的延迟和吞吐量对比表。

常见误区

误区我看到一份基准报告写着“每秒迭代 20 次”,心想那每秒能出 20 张图,这卡真快。

正解it/s 说的是 UNet 单步迭代的速度,而一张图要迭代 20~50 步,还要加上文本编码和 VAE 解码。每秒 20 it/s 意味着单步 50 毫秒,完整一张图要 1~2.5 秒。就像大厨颠勺一秒钟颠十下,不代表十道菜一秒出齐。看报告要先分清 it/s 和 images/s 两个单位。

为何常见:社区讨论 SD 性能时铺天盖地用 it/s,小白很容易把这个中间指标当成最终出图速度。

误区既然一锅炒六份比一份省事,那 batch 开到 32、64 不是爽翻?显存不够就加钱上大显存卡。

正解吞吐量曲线会先上升后趋平甚至下降——当批延迟的增长快过批次增长时,吞吐量反而下滑;显存是硬顶,OOM 直接崩。正确做法是实测找到拐点,同时区分场景:在线交互用小 batch 保低延迟,离线批量才用大 batch 冲吞吐量。

为何常见:“批量=便宜”的直觉是对的,但忽略了延迟增长不是免费午餐,盲目加大批次会撞上收益递减和显存墙。

误区TensorRT 加速比那么高,无脑上 TensorRT,所有场景都快,xFormers 可以扔了。

正解TensorRT 强在编译期算子融合和低精度内核,但首次编译要几分钟到几十分钟,换 GPU、换分辨率、换模型版本都要重新编译;对动态形状、频繁变化提示词的在线服务,xFormers 的灵活性和通用性反而更好。加速比是相对量,必须结合基线和场景判断。

为何常见:只看单条 Benchmark 的加速比数字,忽略了编译成本和适用边界,把“特定条件下的快”当成了“全场景的快”。

误区量化后内存少一半、速度翻倍,画质肉眼看差不多,那把线上服务全部换成 INT8 就完事了。

正解INT8 需要精心挑选校准集,校准集分布覆盖不全,某些风格会崩坏;部分算子没有 INT8 优化实现,端到端速度反而更慢;量化后必须做画质 A/B 和真实加速比验证。跟备菜一样,切好的菜省时间,但刀工差会把食材毁掉。

为何常见:FP16 相对 FP32 接近无损的先验被错误迁移到 INT8 上,忽略了校准过程和潜在的精度回退。

面试题

Q1. 下面哪项是文生图推理吞吐量的标准单位?

单选题 · easy

  • A.每秒生成的图像张数← 正确答案
  • B.每张图像的推理延迟
  • C.UNet 单步迭代耗时
  • D.模型参数量的大小

答案:A。吞吐量衡量“单位时间产出多少张图”,单位就是张/秒。B 是延迟的单位,C 是单步耗时,D 是模型规模,都不描述产出速率。就像翻台率看的是每小时接待几桌,不是单桌吃多久。

Q2. 在 SD 推理总延迟中,通常占比最大的阶段是?

单选题 · easy

  • A.文本编码器的编码耗时
  • B.UNet 的迭代去噪过程← 正确答案
  • C.VAE 潜空间图像解码
  • D.输入图像尺寸的缩放

答案:B。UNet 要迭代 20~50 步,每步都有完整的前向计算,总耗时稳居第一。文本编码和 VAE 解码各只执行一次,占比很小。这就像大厨反复调味二十遍,点单和装盘再慢也追不上。

Q3. 将 batch size 从 1 提升到 4,通常发生什么?

单选题 · mid

  • A.单批推理延迟反而下降
  • B.吞吐量上升但单图延迟升← 正确答案
  • C.显存占用基本保持不变
  • D.生成图的画质必然下降

答案:B。批次增大让单批延迟变长(约 2~3 倍),但产出从 1 张变 4 张,所以吞吐量通常上升。显存一定增加,画质由模型决定与批次无关。一锅炒四份,上菜总时长增加,但翻台率提高了。

Q4. 下列哪些属于 xFormers 的典型优化手段?

多选题 · mid

  • A.内存高效注意力机制← 正确答案
  • B.算子融合与图编译
  • C.降低注意力计算复杂度← 正确答案
  • D.适用于 Transformer 模型← 正确答案

答案:ACD。xFormers 的核心是内存高效注意力,通过分块计算降低 attention 的复杂度和内存读写,天然适用于 Transformer 架构。B 的算子融合和图编译是 TensorRT 的拿手好戏,不是 xFormers 的主打。

Q5. TensorRT 加速的关键机制不包括哪项?

单选题 · mid

  • A.编译为独立优化引擎
  • B.利用低精度推理加速
  • C.算子融合降低内核开销
  • D.自动改写提示词提升画质← 正确答案

答案:D。TensorRT 做的是“编译引擎 + 低精度 kernel + 算子融合”,它优化计算速度,完全不碰提示词内容,更管不了画质。D 属于应用层功能,与推理引擎无关,就像换一口好锅不会改变菜谱本身。

Q6. 推理阶段显存主要由哪两部分构成?

单选题 · mid

  • A.权重参数与激活值← 正确答案
  • B.权重与优化器状态
  • C.反向传播梯度缓存
  • D.训练数据集样本

答案:A。推理没有反向传播,不需要梯度和优化器状态,那是训练阶段的事;数据集也不常驻 GPU 显存。推理的峰值显存 = 权重 + 激活值,相当于后厨台面上只有调料罐和半成品,没有账本。

Q7. 关于 INT8 量化,下列说法正确的有?

多选题 · hard

  • A.需要校准集统计激活分布← 正确答案
  • B.带宽需求约为 FP16 的一半← 正确答案
  • C.量化后模型必然变慢
  • D.可能引入精度损失需验证← 正确答案

答案:ABD。INT8 的缩放和零点要从校准集中统计激活分布来确定;位宽从 16 降到 8,带宽需求理论上减半。但部分算子缺少高效 INT8 实现,端到端不一定变快,且可能损失精度,必须 A/B 验证。C 说“必然变慢”太绝对。

Q8. 做推理延迟基准测试时,为得到稳定数据应怎么做?

单选题 · hard

  • A.只运行一次记录结果
  • B.预热后再多次运行取平均← 正确答案
  • C.每次更换随机种子再对比
  • D.不预热直接测首次结果

答案:B。首次运行包含模型加载和 CUDA 上下文初始化,必须预热剔除;多次运行取平均能消除系统噪声。C 换种子是反面做法,会引入画质差异干扰计时。就像餐厅体检不会在刚开门没生火时测,要等后厨进入稳定状态。

Q9. 消费级 GPU 与数据中心 GPU 相比,主要差距通常不在于?

单选题 · easy

  • A.显存容量的大小差距
  • B.显存带宽的规模差距
  • C.单张图像画质的高低← 正确答案
  • D.并行计算核心数量

答案:C。模型权重和推理算法相同,画质由模型本身决定,与用哪块 GPU 无关。消费级和专业级的主要差距在显存容量、带宽和算力规模,这也是基准测试要量化对比的维度。灶台火力有大小,但菜谱相同,菜的味道不会变。

Q10. 文生图服务降本增效时,数据驱动的优化手段包括哪些?

多选题 · hard

  • A.按峰谷动态调整实例数量← 正确答案
  • B.大批量离线与低延迟在线分流← 正确答案
  • C.用基准数据指导 GPU 选型← 正确答案
  • D.无限增大批次直到显存溢出

答案:ABC。流量弹性伸缩、离线批量与在线实时分场景配置、用性价比数据选 GPU,都是典型的成本优化手段。D 无视显存上限和收益递减,必然导致 OOM 或吞吐量下滑,是反面教材。