满心欢喜把 Stable Diffusion 装好,输入提示词,点下生成,结果风扇瞬间拉到起飞,进度条一点点爬,再等几秒直接弹出一行红字:CUDA out of memory。这种场景我见过太多次,尤其是显卡不是顶配的用户。每次聊起来,大家第一反应都是“换卡”,但说实话,大部分“跑不动”根本不是显卡不行,而是从软件配置到推理参数再到硬件设置,处处都在漏性能。
这篇文章就把我自己调 Stable Diffusion 性能的完整思路写出来,分显存和算力、软件漏点、推理参数、模型选型、硬件超频、以及一整套实测优化链路几个部分。适合那种手里有 4G 到 12G 显存显卡、不想砸钱换硬件但又不甘心让 SD 卡到海枯石烂的朋友。
1. 先搞清楚瓶颈在哪:显存容量、算力还是带宽
很多人以为“显卡性能不够”是一个笼统的问题,其实 Stable Diffusion 和打游戏不一样,它有三条完全不同的性能路径,卡在哪一条,症状完全不同。
1.1 显存容量决定“能不能跑”
SD 生成图片的过程简单说就是:把随机噪声交给模型,让 UNet 一步步去噪,最后通过 VAE 解码成图像。这个过程中,模型参数、中间特征图、噪声状态、各种缓冲数据全都要塞进显存里。显存不够最直接的结果就是 OOM,程序直接罢工,连结果都看不到。
以 SD 1.5 模型为例,模型权重加载到半精度大约占用 2G 显存,生成一张 512x512 的图,UNet 推理过程中的中间特征会占用大概 3G 到 4G 显存,再加上 VAE 解码和临时缓存,总占用很容易超过 6G。如果显存只有 4G,默认配置下几乎跑不动 512 尺寸的图,更不用说 SDXL 这种参数翻倍的模型。
本来 4G 卡也未必全是死路,这一章后面会讲,启动参数里有很多“用时间换空间”的办法,但前提是你得先知道自己是哪种瓶颈。看显存占用指标是最直接的:如果生成时显存占用冲到 95% 以上,然后报错,那是容量瓶颈;如果显存占用一直很低但速度很慢,那是算力瓶颈。
1.2 算力决定“快不快”
同样一张 512x512 的图,20 步采样,一块主流中高端卡可能只要十几秒,一块低端入门卡可能要一两分钟。这个差距就是算力决定的,计算单元不够多,每一轮去噪迭代花费的时间自然更长。
在这里要注意,SD 的算力消耗是显存容量和计算密度的两回事。显存多不代表算力强,很多大显存显卡因为核心规模小,跑起来照样很慢。反之,显存少的卡算力反而可能不错,比如某些 8G 显存的游戏卡核心性能很强,只是容量卡住了 SDXL。
判断算力瓶颈很简单:生成过程中把显卡利用率监控打开,如果利用率长期在 90% 以上,说明算力被吃满,这是正常的“计算瓶颈”;如果利用率只有 40% 到 60%,说明显卡在等数据或者被同步问题拖累,这种时候就算换了更豪华的卡,提升也可能有限。
1.3 带宽决定“大批量时顺不顺”
第三个容易被忽略的是显存带宽,也就是显存和计算核心之间交换数据的速度。SD 推理过程中,每完成一层计算就要把中间结果写回显存,再读下一层,数据搬运量非常大。
小图单张可能感觉不明显,但当你把分辨率拉高,或者一次批量生成 4 张图,带宽不足的卡会出现明显的性能下滑,甚至生成速度远低于按照算力推测的数值。一般显存位宽窄的卡最容易中招,这个信息在显卡规格里都能查到。
判断带宽瓶颈的办法是监测显存控制器负载,如果显存频率顶着 100% 占用但利用率只有 70%,多半是带宽卡住了。这时候单纯调模型参数效果有限,但可以像后面讲的那样减少批量并发、降低单次数据传输量。
1.4 用最简单的方式定位当前瓶颈
有一个很省事的判断方法:连续生成两张一模一样的图,第一张出现明显停顿和加载过程,第二张如果明显更快,说明第一次加载模型占了大量时间,这通常不算瓶颈;如果两张都慢且显存充足,看利用率就能分清是算力还是带宽。
我再提供一个经验参考表:
| 现象 | 瓶颈方向 | 优先手段 |
|---|---|---|
| 显存溢出报错 | 容量不足 | 启动参数、VAE切块、模型压缩 |
| 利用率高但速度慢 | 算力限制 | 优化采样步数、蒸馏模型、模型量化 |
| 利用率低且显存频率占满 | 带宽限制 | 降低批量大小、降低分辨率 |
| 生成正常但偶尔卡顿 | 加载/内存瓶颈 | 升级依赖、扩大虚拟内存 |
2. 先别急着超频,软件默认配置里的漏点先堵上
很多人的性能问题不是硬件不够,而是跑 SD 的软件环境根本没调过,默认配置就是给“能跑就行”设计的,根本不是给“跑得快”设计的。
2.1 启动参数里的免费性能
使用 WebUI 或 ComfyUI 的人,启动脚本里加不加参数,性能差距极其明显。我见过太多人装完就直接双击启动,连xformers都没有开。从 SD 1.5 的官方推荐配置看,关键启动项有这些:
--xformers:启用优化过的跨注意力加速模块,能显著降低显存占用并提升速度,老显卡和一些特定架构卡上都有效。如果遇到兼容问题,可以试试--opt-split-attention。--opt-sub-quad-attention:进一步把注意力计算分块,适合显存比较紧张的场景。--no-half-vae:防止 VAE 解码时因为半精度问题生成黑图,代码层面它把 VAE 部分保持高精度,代价是稍微多点显存。--medvram或--lowvram:按显存大小分配策略,中等显存用 medvram,小显存用 lowvram。原理是把模型一部分一部分地加载到显存、算完再换下一部分,属于典型的时间换空间。--precision full或--autocast:老卡没有原生支持 FP16 的时候才需要,现代显卡基本不用动。
我自己常用的 WebUI 启动脚本是类似这种格式:
python launch.py --xformers --no-half-vae --medvram如果你的卡是 8G 显存,--medvram可能不需要,加上之后反而会因为频繁切换模型导致绘图变慢。这里有个常见的误解:lowvram不是万能的,显存明明够用却强制用 lowvram,速度会大幅下降,因为它会不停把模块换进换出。
2.2 半精度陷阱:FP16 和 FP32 的真相
SD 的模型权重默认是 FP16(半精度)加载,这没什么问题,但 VAE 解码的时候用 FP16 在某些显卡上会产生一种很经典的“黑图”现象:生成的图片暗部全糊成一团,看起来像是曝光失败。遇到这种问题,很多人第一反应是换模型,其实只要启动参数里加上--no-half-vae就能解决。
反过来,也有人为了“画质更好”强行用 FP32 加载全部模型,结果显存翻倍、速度减半,画质提升肉眼根本看不出来。除非你是在做极专业的输出,否则这是个负优化。SD 的生成过程本来就是“对噪声做逼近”,FP16 的精度损失在 512 分辨率下几乎可以忽略。
2.3 依赖库版本:PyTorch 和 CUDA 版本差距很大
这是最容易被忽视的一环。Stable Diffusion 生态跑在 PyTorch 上,而 PyTorch 的推理性能除了看模型本身,很大程度取决于底层库的编译优化。新版本 PyTorch 对 GPU 的调度、显存分配、算子融合都做了大量优化,有时候同一张卡从旧版换到新版,性能能差 20% 到 30%。
怎么做?把你当前环境的 Python 包列出来,看下 PyTorch、CUDA 工具包、以及图像处理相关库的版本。不要急着升级到最新,先查一下当前社区主要使用的组合。我用过的最稳妥搭配是:Python 3.10 或 3.11,配 PyTorch 2.x 版本,CUDA 对应 11.8 或 12.x。如果本来就在较新版本上,就别乱动了。
还有一个经常被问到的“为什么同样的显卡,别人比我快一倍”的情况:对方可能开启了编译优化模式。比如你在 WebUI 的启动参数里加上--opt-split-attention,它会在推理前做一次算子融合,首次运行稍慢,后续每次生成都能吃到红利。
2.4 容易被忽略的虚拟内存和电源模式
有人显存不是瓶颈,速度也不是瓶颈,但生成一会儿就卡一下,风扇忽高忽低。这种情况往往不是显卡问题,而是系统内存不够,SD 会在显存和内存之间交换数据,内存吃紧时整个系统都在挣扎。
我的建议是给系统盘留足空间,把虚拟内存(页面文件)设置成自动管理或者手动调大,至少 16G 以上。运行 SD 时尽量不要同时开着十几个浏览器标签页再挂着大型软件,这听起来像废话,但真的很多人因为后台程序把内存和显存挤占掉导致 SD 生成速度暴跌。
笔记本用户还要注意电源计划,许多笔记本默认的“平衡模式”会限制显卡功耗。直接调到“高性能”模式,或者去显卡控制面板里把 SD 对应程序的电源策略改成“最高性能优先”。
3. 推理参数里藏着几倍速度差距:采样、分辨率与批处理
软件层堵完之后,就要看每次生成时的参数了。同一张显卡,用不同的采样步数和调度器,速度能差出两三倍,而出图效果的差距却未必有想象中那么大。
3.1 步数真的不是越多越好
很多人习惯把采样步数拉到 50、60,觉得画质能更精细,实际上步数超过 30 以后,画面细节提升微乎其微,但耗时按比例增长。我在不少模型上测试过,SD 1.5 的模型在 20 到 30 步之间基本已经收敛,SDXL 需要稍多一点,但也很少有人能从 40 步和 50 步之间看出实质区别。
采样器和步数是联动的,不同采样器收敛速度不同。比如 DPM++ 系列迭代效率高、画质也好,常见搭配是 20 到 30 步;Euler 是经典快采样器,20 步左右效果就不错;UniPC 是近几年很流行的加速器,能在 10 到 15 步内达到接近 20 步的效果。
我有一个常用的判断方法:用你要跑的模型,先设定一个步数,生成一批图,然后只把步数减半生成另一批,对比看。当两张图肉眼无法明显区分时,那个更低步数就是你的舒适区。
3.2 分辨率对显存和耗时的非线性影响
SD 的消耗不是随分辨率线性上涨的,而是近似平方关系。512 的图需要约 620 万像素的计算量,1080 的图则要到 1166 万左右,几乎是翻倍再翻倍。所以你把分辨率从 512 拉到 768,显存占用和生成时间都会暴涨一大截。
这里有个原理很多人不清楚:SD 的实际生成分辨率并不是你填的像素尺寸,而是模型内部 latent space 的尺寸,它大概是像素尺寸除以 8。也就是说 512 分辨率的图在 UNet 眼里是 64x64 的特征图,768 是 96x96,这每一格特征向量都参与注意力计算,计算量指数上升。
如果显存不够,可以尝试把图片尺寸控制在显存能稳定容纳的范围,宁可先生成较小的图再用放大功能处理,也不要强行用大尺寸硬刚。这属于“流程优化”而不是“硬件不足”。
3.3 批量生成 Batch Size 的甜蜜点
很多人以为 Batch Size 设得越大越好,因为一次生成多张图,模型加载成本摊薄了。理论上没问题,但实际受限于显存和带宽。Batch Size 翻倍,显存占用几乎也翻倍,带宽更是吃紧。
在我测试过的中端卡上,Batch Size 从 1 加到 2,速度提升只有 30% 到 50%,远没到两倍;加到 4 时,经常直接 OOM。如果你的卡不是旗舰级别,Batch Size 设 1 到 2 就够了,想多试几组图不如把流程拆开,一张一张跑,反而更灵活。
3.4 负面提示词、CLIP skip 和 Seed 的原理与可测教训
负面提示词本质是让模型在采样时避开某些特征,但它并不会直接拖慢速度。真正影响速度的是“提示词过长导致编码阶段变长”,不过编解码只占整个流程很小比例,几乎可以忽略。CLIP skip 改变的是不同 CLIP 层的输出,对速度影响微乎其微,主要还是影响语义理解的风格,新手不需要为了“性能”调它。
如果非要从参数里要性能,我的核心建议只有一个:在画质可接受的前提下,把步数压到最低,把批量压到最低,把尺寸压到最低,然后靠放大和细节修复来补画面。这看起来是绕远路,实际上是把算力花在刀刃上。
4. 显存不够自救手册:切块、压缩、模型选型
这部分是给 4G 到 6G 显存用户准备的。显存不够不完全是死路,SD 生态里有几种成熟的“降级方案”,核心思路都是牺牲一些时间和灵活性来换容量。
4.1 半精度、量化与权重压缩的取舍
前面说过 FP16 比 FP32 省一半显存,几乎不损失画质。除此之外,还可以考虑 INT8 量化模型,显存占用进一步减半。代价是纹理细节可能变得稍微生硬,极远处的结构容易糊。
实际操作中,低显存用户与其找量化版大模型,不如选择本身就小一号的模型分支。比如社区有很多压缩过的模型文件,占空间更小,加载更快,只是生成画质的上限稍低。我的建议是:显存紧张的时候,优先用 2G 级别的模型权重配 FP16,而不是硬啃 4G 多的大模型。
4.2 VAE 切块机制:为什么大图画到一半爆显存
当你把分辨率拉到 1024 以上,SD 默认的 VAE 解码会一次性处理整个图像,显存不够就爆。解决方法是开启 VAE 切块模式(有些启动器叫“VAE Tiling”),它把一大张图切成小块分别解码,再拼回去。
效果上几乎看不出接缝,代价是解码时间变长,可能要从一两秒涨到十几秒。但对大尺寸出图来说,这已经是“能不能出”和“出不出得来”的区别了。同样的原理也适用于注意力计算切块,对应启动参数里的--opt-split-attention或子图注意力模式。
4.3 SD 1.5、SDXL、Turbo 模型怎么选
如果你还在 SD 1.5 和 SDXL 之间纠结,先看显存:SDXL 的参数规模大约是 SD 1.5 的 4 倍,即使 FP16 加载,显存占用也直接拉到 8G 左右,推理时间更是翻倍。而 SD 1.5 虽然构图能力和细节不如 SDXL,但在低显存环境下胜在轻量和稳定。
还有一个高效率方向是蒸馏模型,也就是社区里的“Turbo”系列或类似名称。这类模型支持极少的采样步数(常常 1 到 4 步)就出图,生成速度比普通模型快得夸张。代价是图像风格趋向简单,复杂场景和特定构图要求下容易失真。它们适合快速验证构图、批量实验,不适合精修输出。
4.4 LoRA 插件不会增加多少显存
很多人担心加 LoRA 会让显存爆炸,其实 LoRA 本身占用的额外显存非常小,因为附加模型只包含极小的低秩差异矩阵。在使用上,一个 LoRA 增加的显存通常只有几十到几百 MB,对性能的影响主要是加载时多一步,推理时几乎可以忽略。
反过来,有些复杂 LoRA 数量太多,每个都加载到显存里,有可能会把 4G 卡推上边缘。解决办法是用完一个再换一个,不要同时堆 5 个。
5. 硬件侧还能榨出多少余量:功耗墙、显存频率与散热
软件方法榨干之后,硬盘玩家开心的地方就来了。显卡在设计时往往预留了超出默认标定功耗的能力,只是被功耗墙和温度墙限制住了。
5.1 先用监控工具记录基线数据
在动手之前,先把显卡在 SD 连续生成时的核心频率、显存频率、功耗、温度记录下来。这一步的目的是拿到“性能瓶颈在谁的墙上被卡住”的证据。例如有些卡核心频率高达 2400MHz,但功耗已经顶到上限,说明撞功耗墙;有些卡频率在跑图时掉得厉害,可以看是温度还是供电限制导致的。
在 SD 这种持续高负载场景下,很多显卡会在功耗墙限制下自动降频,如果你能稳固地把功耗墙往上拉 10% 到 20%,同时温度还是压得住的,核心频率就能稳定在更高位置,生成时间的缩短是实打实的。
5.2 功耗墙到底该怎么调
调整工具不是重点,重点是你得知道调整的原理。以我常用的方式为参考:打开显卡控制面板里的频率/功耗调节,把功耗限制提高到最大值,然后逐步调整核心频率偏移,每次加 30 到 50MHz,跑一轮 SD 测试,直到出现不稳定或热节流。
需要注意的是,显存频率超频对 SD 的收益在某些卡上甚至比核心频率还明显,因为前面提过 SD 是高数据搬运负载,显存带宽很关键。显存频率提升 100 到 200MHz 对生成速度的改善,有时候能比核心超频多出 5% 到 10%。
5.3 温度与散热的底层逻辑
超频不是白来的,功耗提升后发热立刻增加。显卡在核心温度升高时会自动降频保护,如果你把功耗墙拉高了却让温度撞到降频线,反而得不偿失。
实际测试中,温度每降低 10 度,显卡在高负载下的稳定频率能高出一档,对应到 SD 这类长时负载,就是整体生成时间减少。如果你的机箱风扇能调曲线,建议把起转温度调低一些;如果是笔记本,尽量垫高散热口,或者考虑外接散热底座。做好散热后,超频空间往往还能再挤出来一点。
5.4 超频的安全边界和我踩过的一些坑
安全超频的边界其实很明确:不要动核心电压的大幅范围,不要一次性把频率拉超过 200MHz 以上,显存频率提升也不要超过默认标称太多。
我见过最典型的翻车方式是把功耗和频率一起拉满,连测都不测直接生成一张图,跑到一半出现花屏或者黑屏重启。这通常不是硬件损坏,而是不稳定的信号,但长期在这种不稳定状态下跑长任务,对显存颗粒和供电模组都是一种折磨。我的建议是:每调整一次参数,就用 SD 生成一张 768 分辨率的图连续跑 5 到 10 次,确认每次都不花屏不重启,才算稳定。
还有一个小技巧:SD 并不是连续跑得越快越好,如果你的显卡在跑图时温度很快就贴到 80 度以上,可以把一次大批量任务拆开,中间留几秒“喘息”时间,让温度回落,整体速度反而可能更快,因为避免了持续降频。
6. 一套完整的优化实测链路:从慢到快的调参过程
前面讲了很多理论,这一节我用一台非常典型的中端配置来做演示:8G 显存,核心和显存性能中规中矩,跑 SD 1.5 模型。整个链路包括软件调整、依赖更新、推理参数优化和适度的硬件调教。
6.1 初始状态:默认配置下的基准数据
刚装好的环境下,启动脚本什么都没有加,采样器用默认的 Euler,步数 30,分辨率 512x512,Batch Size 1。生成一张图耗时大概 52 秒,显存占用大约 5.8G,温度 72 度,核心利用率偏低但偶尔有尖峰。
这个数据一出来就能判断:不是算力不够,也不是显存不够,是软件环境在拖后腿,以及显存占用刚好卡在一个不算富裕的边界上,导致调度器频繁做资源管理。
6.2 第一步:加上启动参数,把环境漏点补上
在启动脚本中加入--xformers --opt-sub-quad-attention,重启后再次生成同一张图。耗时从 52 秒降到 33 秒,显存占用反而降到 4.9G,核心利用率能稳定在 80% 以上。这说明之前的性能其实被跨注意力计算浪费掉了,用了优化模块后,同样路径下算得更快、存得更省。
这一步不花一分钱,收益却是所有操作里最大的。很多人跑 SD 慢,其实就是缺了这个启动项。
6.3 第二步:更新依赖,吃底层库优化的红利
第二步把 PyTorch 版本升级到当前主流的 2.x 组合,并用 WebUI 或 ComfyUI 自带的更新机制刷新依赖库。更新后再次生成同一张图,耗时从 33 秒降到 27 秒。底层库的算子调度优化在这台机器上带来了约 18% 的提升。
这里提醒一句:更新依赖有风险,如果当前环境运行稳定,可以先把配置备份好再更新。我的习惯是每次升级后先跑同一组测试提示词和种子,对比耗时和显存,确认没有退化。
6.4 第三步:把推理参数调到合理范围
接下来是参数层。采样器从 Euler 换成 DPM++ 2M,步数从 30 降到 22,同时分辨率保持 512x512。此时出图耗时降到 16 秒左右,画质和之前肉眼对比几乎没有差别。再把 Batch Size 原地设置为 1,避免批量并发触发不必要的显存交换。
这一阶段你会发现,显存占用已经降到了 4.1G 左右,温度降到 68 度,风扇噪音小了很多。这是参数优化的好处:不仅提高了吞吐,还减少了硬件压力。
6.5 第四步:适度的硬件调教
最后一步是把功耗墙拉高 10%,显存频率提升大约 150MHz,同时把风扇曲线调得更主动一些。再次生成同一张图,耗时从 16 秒降到 13.5 秒。作为对比,如果此时把分辨率提到 768,显存占用立刻回到 6G 出头,速度也回落到 26 秒左右,但依然在同配置默认环境下跑了近 60 秒的对比下优势明显。
这一步的收益没有软件层那么夸张,胜在稳定白赚。需要注意的是,超频之后务必按前面说的方法连续验证稳定性,特别是长时间跑图不花屏不重启。
6.6 整个链路的收益总结和复现清单
从 52 秒到 13.5 秒,整个链条下来大约提速 3.8 倍,显存占用还下降了 1.7G,温度更低,噪音更小。这不是靠某一项“魔法参数”,而是每一项都贡献了一部分提升。
按收益从大到小排列:
- 启动参数优化,加了优化后注意力计算模块,收益最明显。
- 推理参数合理化,降步数、换高效采样器。
- 依赖库更新,吃版本红利。
- 硬件频率和功耗调整,属于锦上添花。
每台机器的体质不一样,我的建议是照这个顺序逐步试:每一项调整后用同一张图和同一个种子做对比,方便精确判断哪一步带来了多少提升。
一个小提示:不要盲目照抄别人的“优化参数”
看到这里你可能发现一个问题:网上很多人晒出来的“神级配置文件”并不完全通用。同一个启动参数在不同显存容量、不同显卡架构上表现可能相反:显存充足时加--medvram会变慢,显存紧张时不加又会 OOM。最靠谱的做法是理解每个参数背后的原理,用固定的基准测试方法去验证,而不是照搬一份配置就万事大吉。
如果你不知道怎么建基准测试,就把我 6.1 里的步骤复现一遍:记录同一张图在同一提示词和种子下的耗时、显存占用、温度和利用率。任何时候改动环境或参数前先记录“当前状态”,改完了再记录“新状态”,这样所有优化是否有效都一目了然。
最后再分享一个我经常用的经验:真正影响 SD 体验的往往不是最高那一次生成速度,而是连续出图时的稳定性。很多人只盯着跑一张图的时间,忽略了跑十张之后显存会不会越占越多、温度会不会越拉越高。我建议你在调完所有参数后,连续跑 20 张风格不同的图,如果全程不爆显存、不花屏、不重启,这套配置才算真正毕业。