简介:这份PDF文档面向想入门AI绘画的开发者与爱好者,系统讲解Stable Diffusion的安装与使用全流程,帮助读者从零搭建可运行的图文生成环境,解决环境配置、依赖安装与出图调参等常见问题。整个压缩包仅含1个PDF文件,体积约814KB,内容以步骤说明与命令行代码片段为主,按环境准备、依赖安装、代码与模型下载、运行出图等模块依次编排,便于对照操作。已有945人学习下载。文档在讲解中给出了Python 3.7以上版本、PyTorch及相关库的安装命令,虚拟环境创建方式,CompVis仓库克隆与预训练模型获取途径,并演示txt2img命令的调用;同时说明了prompt提示词、plms与ddim算法、steps步数等参数的调节思路,以及噪声调度、采样步数与GPU资源对生成速度和质量的影响,适合作为快速上手与参数对照的参考手册。
1. 一条命令跑完却出黑图:Stable Diffusion 装不起来的三类卡点
第一次装 Stable Diffusion 的人,八成会卡在同一个画面:命令敲完,进度条走满,outputs/txt2img-samples里躺着一堆纯黑方块。这套人工智能绘画软件的门槛从来不在"会不会敲命令",而在版本矩阵、权重路径、显存预算这三件事上错一位就全盘失效。它是把文本描述映射成图像的开源模型,能离线跑、能改代码、能批量出图,适合想自己掌控生成流程的开发者、需要批量产素材的设计岗,以及想把模型嵌进自己工具链的工程师。下面按真实安装顺序拆:环境怎么钉版本、权重放哪个目录、参数怎么联动,以及那些说明书上不会写的翻车点。
2. 环境准备:先把 CUDA 版本钉死,再谈 Python 依赖
装 Stable Diffusion 最反直觉的一点是:Python 版本不是第一优先级,显卡驱动和 CUDA 才是。很多人上来就pip install torch,装完发现torch.cuda.is_available()返回 False,于是退回 CPU 跑,一张 512×512 图要十几分钟,跑两次就放弃了。正确顺序是反过来的——先确认驱动支持的 CUDA 上限,再选对应的 PyTorch 轮子,最后才创建虚拟环境。这个顺序搞反,后面所有报错都是连锁反应。
2.1 版本矩阵比安装顺序更重要
原文写的是 Python 3.7 或更高,这句话在实践中会把人坑到。3.7 早就停止维护,很多依赖的新版本已经不提供对应轮子;3.12 又太新,pytorch-lightning和taming-transformers这类老依赖容易在编译阶段失败。我一般把 Python 锁在 3.10,这是目前兼容性最稳的一档:既满足模型代码对 f-string、类型注解的要求,又能让绝大多数预编译轮子直接命中。
CUDA 这边先做一件事:打开终端敲nvidia-smi,看右上角那行CUDA Version: 12.x。这是驱动能支持的最高运行时版本,不是已安装版本,但足够用来选轮子——只要 PyTorch 自带的 CUDA 运行时不高于这个数,就能跑。常见的对应关系是这样的:
| 驱动显示上限 | 建议装的 PyTorch 轮子 | 说明 |
|---|---|---|
| 11.8 | cu118 | 覆盖最广,老卡新卡都能用 |
| 12.1 | cu121 | 新驱动首选 |
| 12.4 及以上 | cu124 | 注意老依赖是否兼容 |
提示:不要为了追新驱动去装最新的 CUDA 运行时。Stable Diffusion 的官方脚本对 CUDA 12 之后的部分算子兼容性一般,先用 11.8 跑通,再考虑升级。
显存也要在这一步心里有数。nvidia-smi右下角那个 MiB 数字就是硬上限,它直接决定后面能不能开高分辨率、能不能一次出多张。4GB 卡能跑但必须降分辨率,6GB 是 512×512 单张的舒适线,8GB 以上才谈得上批量。
2.2 虚拟环境创建与 PyTorch 安装的完整命令
虚拟环境这步原文标了"可选但推荐",我的看法是:不是推荐,是必须。Stable Diffusion 会往环境里塞transformers、pytorch-lightning、open_clip这些版本敏感度极高的包,一旦和你机器上其他项目的环境混在一起,后面出现的AttributeError: module 'numpy' has no attribute 'float'这类报错能查一整天。
# 创建虚拟环境,名字随意,建议带上项目标识 python -m venv sd-env # Linux / macOS 激活 source sd-env/bin/activate # Windows 激活(cmd 或 PowerShell) sd-env\Scripts\activate # 确认当前解释器路径落在虚拟环境里,这一步别省 python -c "import sys; print(sys.executable)"激活成功的标志是命令行前面出现(sd-env),并且sys.executable指向sd-env目录下的 python。如果打印出来还是系统路径,说明激活没生效,后面的包会全装到全局环境里。
接着装 PyTorch 三件套。这里不要直接pip install torch,默认源拉的是 CPU 版本或者是和驱动不匹配的版本,一定要走官方给的 index-url:
# 以 CUDA 11.8 为例,替换成和自己驱动匹配的版本 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 顺手把 pip 升级掉,老版本 pip 会在解析依赖时给出误导性报错 python -m pip install --upgrade pip参数说明:--index-url指定轮子来源,官方为不同 CUDA 版本维护了独立目录,写错版本号会直接 404;torchvision和torchaudio必须和torch同版本,混装会出现RuntimeError: operator torchvision::nms does not exist。三个包版本不一致是新手最常踩的坑,装的时候盯一眼输出里三个版本号是否同源即可。
2.2.1 xformers 要不要装
xformers是个可选项,作用是替换注意力实现,实测能把显存占用降三成左右、单张图快 20% 到 30%。但它对版本极其挑剔,装错版本的表现是生成时直接段错误或者全黑图,比不装还麻烦。我的建议是:环境刚通、能出图之前别碰它,等跑通了再回头加。真要装就按官方说明匹配 PyTorch 版本,别用pip install xformers这种不带版本约束的写法。
2.3 装完先自检:三段验证脚本
依赖装完先别急着下模型。模型文件好几个 GB,下完发现环境有问题,时间全白费。我习惯跑三段自检,每段对应一层:PyTorch 能不能看见卡、半精度算不算得动、依赖能不能导入。
# check_env.py import torch print("torch 版本:", torch.__version__) print("CUDA 可用:", torch.cuda.is_available()) print("CUDA 版本:", torch.version.cuda) if torch.cuda.is_available(): print("设备名:", torch.cuda.get_device_name(0)) print("显存总量 GB:", round(torch.cuda.get_device_properties(0).total_memory / 1024**3, 2)) # 半精度自检:NaN 说明这张卡不适合 autocast a = torch.randn(512, 512, device="cuda", dtype=torch.float16) b = torch.randn(512, 512, device="cuda", dtype=torch.float16) c = (a @ b) print("半精度矩阵乘 NaN 数量:", torch.isnan(c).sum().item())这段代码的价值在最后两行。is_available()返回 True 只说明驱动和运行时对上了,不代表半精度算子能正常工作。部分显卡在 fp16 下会溢出成 NaN,而 Stable Diffusion 默认就用 autocast,结果就是你看到的那张纯黑图。NaN 数量大于 0,后面启动时必须加--precision full,这一点在第 5 章还会展开。
# 第二段:把 requirements 里的关键包一次性导入,看谁先炸 python -c " import pytorch_lightning, transformers, omegaconf import einops, kornia, PIL from PIL import Image print('pytorch_lightning', pytorch_lightning.__version__) print('transformers', transformers.__version__) print('全部关键依赖导入成功') "第三段留给模型侧:等仓库克隆完再执行python -c "from ldm.models.diffusion.ddpm import LatentDiffusion; print('ok')",能打印 ok 说明代码路径和依赖都通,再去下载几 GB 的权重。三层全过再进下一章,能省掉至少一半的排查时间。
3. 代码与权重落地:目录结构、ckpt 格式与显存预算
环境通了之后最容易翻车的地方是路径。Stable Diffusion 的脚本默认在固定位置找权重文件,你把 ckpt 随便丢在项目根目录,它会给你一句FileNotFoundError: No such file or directory,而这行报错通常被前面几百行日志淹没,很多人根本没看到。这一章把目录约定、权重格式和显存估算讲清楚,装完就能跑出第一张正常的图。
3.1 克隆仓库后先看 requirements.txt 再动手
克隆命令本身没难度,难的是仓库里那份 requirements。原文说pip install -r requirements.txt,实际执行时有相当概率卡住——里面有几个依赖是从 git 仓库直接安装的,网络稍有不稳就超时,报错信息还写得含糊。
# 克隆到本地,目录名保持 stable-diffusion git clone https://github.com/<官方仓库>/stable-diffusion.git cd stable-diffusion # 先看,不先装:把依赖列出来,重点看有没有 git+https 开头和带版本锁的行 cat requirements.txt看完再决定怎么装。我的做法是分两步:
# 第一步,先装带明确版本号的常规包 pip install -r requirements.txt --timeout 120 --retries 5 # 第二步,如果卡在某个 git 依赖上,单独拎出来装,并加上 --no-deps 避免它顺手改动已装好的包 pip install --no-deps "git+https://github.com/<依赖仓库>.git"--timeout 120把单包超时从默认 15 秒拉到 2 分钟,--retries 5让失败自动重试,这两个参数在拉 git 依赖时能救回大部分偶发失败。--no-deps的意义是:那个 git 依赖声明的子依赖可能和你刚装好的 PyTorch 版本冲突,跳过依赖解析、只装它本体,反而是更安全的做法。
装完立刻验证一遍:
pip check这命令会列出所有版本冲突。输出No broken requirements found.才继续,只要出现一行X requires Y, but you have Z,就先把那一条处理掉。带着冲突往下走,报错会出现在完全不相干的地方。
3.2 权重文件的三种格式和它们的放置路径
代码不带模型。权重文件是几 GB 的独立下载项,仓库 README 里会给入口。网络能直连就用页面上的下载按钮,不能直连就用下载工具断点续传——4GB 以上的文件下到 90% 断掉重来是很常见的事,浏览器自带的下载器在这件事上不太靠得住。
格式上有三种,选错会浪费很多时间:
| 格式 | 典型文件名 | 大小量级 | 说明 |
|---|---|---|---|
| 完整 ckpt | sd-v1-4.ckpt | 4GB 上下 | 含优化器状态,兼容性最好 |
| 剪枝 ckpt | v1-5-pruned.ckpt | 2GB 上下 | 去掉训练态权重,推理够用 |
| ema only | v1-5-pruned-emaonly.ckpt | 4GB 上下 | 只保留指数滑动平均权重,出图更稳 |
注意:推理场景优先选
emaonly版本。它的权重是训练过程中平滑过的,同样的 prompt 和种子,出图稳定性明显好于非 ema 版本,尤其在低步数下差距更明显。
放置路径是这一步的核心。scripts/txt2img.py的--ckpt参数有默认值,实际指向类似models/ldm/stable-diffusion-v1/model.ckpt的层级。最省事的做法是不改默认路径,直接把权重改名为model.ckpt放进那个目录:
# 目录不存在就先建出来 mkdir -p models/ldm/stable-diffusion-v1 # 把下载好的权重放进去并改名,注意文件名必须是 model.ckpt mv ~/Downloads/v1-5-pruned-emaonly.ckpt models/ldm/stable-diffusion-v1/model.ckpt # 确认文件完整:对比文件大小,和下载页标注的字节数差太多就是没下完 ls -lh models/ldm/stable-diffusion-v1/model.ckpt不放默认路径也行,每次启动显式传--ckpt指向真实位置。但我不建议这么干:命令行参数一多,--ckpt很容易复制漏掉,然后你会在报错日志里找半天。固定路径一次配好,后面所有命令都省一个参数。
3.3 按显存反推分辨率与 batch
显存决定你能开多大的图。这里有三个相互拉扯的变量:分辨率、单批数量--n_samples、迭代批次--n_iter。前两个吃显存,第三个不吃——--n_iter是串行跑多批,显存占用和跑一批一样,只是时间长。
经验数值大致如下,都是单张 512×512、--precision autocast的前提:
| 显存 | 512×512 单张 | 512×512 批量 | 768 单张 |
|---|---|---|---|
| 4GB | 勉强,需降步数 | 不可行 | 不可行 |
| 6GB | 可行 | n_samples=2 会 OOM | 高风险 |
| 8GB | 轻松 | n_samples=4 | 可行但慢 |
| 12GB 以上 | 轻松 | n_samples=8 | 轻松 |
反推逻辑很简单:分辨率翻倍,显存需求大约翻四倍(注意力是平方复杂度)。512 到 768 不是 1.5 倍而是约 2.25 倍,所以 6GB 卡开 768 基本必炸。命令行的--H和--W必须同时给,且最好是 64 的整数倍,否则模型内部的卷积下采样会对不齐,报维度不匹配。
# 第一次跑,用最保守的组合,先确认能出图 python scripts/txt2img.py \ --prompt "a stone bridge over a calm river, morning fog, matte painting" \ --ckpt models/ldm/stable-diffusion-v1/model.ckpt \ --H 512 --W 512 \ --n_samples 1 --n_iter 1 \ --ddim_steps 30 \ --plms \ --seed 42 \ --outdir outputs/first-run参数说明:--n_samples是单批同时生成的数量,直接乘在显存上;--n_iter是外层循环次数,每个 iter 存一次结果;--seed 42固定种子便于复现,不传就是随机;--outdir指定输出目录,不存在会自动创建。这条命令能在 6GB 卡上稳定跑完,跑通了再往上加参数。
4. txt2img 参数联动:prompt、采样器、steps 与 CFG 怎么配
能出图之后,问题就变成"怎么出好图"。Stable Diffusion 的参数不是各自独立的旋钮,它们之间存在明显的耦合:步数不够时调高 CFG 只会让画面变糊,CFG 太低时加步数也只是在噪声里多绕几圈。这一章按 prompt、采样器、CFG、种子的顺序拆开讲,每个参数都说清楚它影响什么、边界在哪。
4.1 prompt 不是关键词堆砌,是权重分配
文本提示通过一个文本编码器转成条件向量,再注入到去噪过程。这意味着 prompt 里的每个词不是"加分项",而是在 77 个 token 的窗口里争夺注意力权重。堆二十个形容词的结果是每个词分到的权重都很低,画面变成四不像。
我常用的结构是三段式:主体 + 环境/构图 + 风格/画质。
a fantasy landscape, floating islands above a sea of clouds, wide angle, volumetric light, matte painting, high detail第一段定主体,第二段定镜头和光线,第三段定画风。逗号分隔的短语比自然语言长句更有效,因为编码器对短语边界的处理更干净。wide angle、volumetric light这类是构图和光照控制词,matte painting是材质风格词,两者作用层不同,可以叠加。
关于负向提示,这里有个必须说清楚的事实:官方那套命令行脚本scripts/txt2img.py原生没有--negative_prompt参数,负向条件是在代码里通过uncond实现的。想要负向提示得改脚本或者换社区维护的 WebUI 前端。不要在命令行里硬塞一个不存在的参数,脚本会直接报 unrecognized arguments 退出。
步数和 prompt 长度的关系也值得注意。77 个 token 是硬上限,超出的部分会被截断,而且不会有任何提示。写了一大段描述发现效果不对,先数一下是不是超了。
4.2 PLMS 和 DDIM 的实际差别
原文提到--plms和--ddim是两种生成算法,这个说法对但不完整。DDIM 是默认采样器,不传参数就是它;PLMS 是后来加的多步线性采样方法,在相同步数下收敛更快。
| 对比项 | DDIM | PLMS |
|---|---|---|
| 默认状态 | 不传参数即启用 | 需显式加--plms |
| 20 步效果 | 结构基本成型,细节偏糊 | 细节明显更完整 |
| 50 步效果 | 收敛充分 | 与 20 步差距不大 |
| 单步耗时 | 略低 | 略高 |
| 适合场景 | 快速试构图 | 正式出图 |
实测结论:20 到 30 步这个区间,PLMS 的优势最明显;过了 50 步两者差距被抹平,再往上加步数收益极低,纯属烧时间。我一般试构图用 DDIM + 20 步,定稿用 PLMS + 30 到 40 步。--ddim_steps是两者共用的步数参数,脚本里还提供了--steps作为别名,两个写哪个都行,但别同时写,容易让人误以为有两个不同的东西。
另外还有一个--ddim_eta参数,控制随机性注入,默认 0.0 表示完全确定性。想在同一 prompt 下要一点变化,可以调到 0.2 到 0.5,但超过 0.7 画面会明显发散,不建议在出定稿时用。
4.3 CFG scale 与 seed 的复现逻辑
--scale就是 CFG scale(无分类器引导系数),控制模型多大程度上"听 prompt 的话"。默认 7.5,这是个相当合理的起点。
- 3 到 5:构图自由度高,但经常偏离描述,画面偏"意境"
- 7 到 9:描述还原和画面质量的平衡区,绝大多数场景用这个区间
- 12 以上:颜色开始过饱和,边缘出现明显光晕和高对比伪影
很多人以为 CFG 越高越"准",实际上超过 15 之后画面会在视觉上崩掉——高饱和、硬边、重复纹理。这是引导强度过大导致的过拟合,不是模型能力问题。
种子是复现的唯一钥匙。--seed不传时日志里会打印一个随机数,那个数就是本次结果的真实种子,记下来,下次传同样的值、同样的 prompt、同样的步数和采样器,能出几乎一致的图。注意"几乎"——不同显卡的半精度实现有细微差别,跨设备复现做不到逐像素一致,同设备同参数是可以的。
# 定稿参数:PLMS + 35 步 + CFG 8.0 + 固定种子 python scripts/txt2img.py \ --prompt "a fantasy landscape, floating islands above a sea of clouds, wide angle, volumetric light, matte painting, high detail" \ --ckpt models/ldm/stable-diffusion-v1/model.ckpt \ --H 512 --W 512 \ --n_samples 1 --n_iter 4 \ --ddim_steps 35 \ --scale 8.0 \ --plms \ --seed 20240517 \ --outdir outputs/final参数说明:--n_iter 4串行跑四批,每批存一次,配合固定种子能拿到四张同一风格、构图微变的候选图;--scale 8.0比默认略高,用于强化描述还原;--outdir换成独立目录,避免和试构图混在一起。跑完在outputs/final下能看到grid-0000.png这类汇总图以及逐张原图。
4.4 输出目录与文件命名
输出这块没什么技术含量,但不规范会给自己挖坑。每次跑完默认会同时存汇总网格图和单张图,文件多了根本分不清哪组是哪个 prompt。我的习惯是让目录名带上参数摘要:
OUT="outputs/$(date +%m%d)-plms35-cfg8-seed20240517" python scripts/txt2img.py \ --prompt "your prompt here" \ --ddim_steps 35 --scale 8.0 --plms --seed 20240517 \ --outdir "$OUT"这样做的好处是一周后再翻结果,光看文件夹名就知道当时的完整配置,不用去翻 shell 历史。生成时间单张 512×512 在 6GB 卡上约 25 到 40 秒(30 步 PLMS),四张串行两分钟左右,还算可接受。
5. 避坑与排查:黑图、OOM、依赖冲突的五条现场记录
前面几章讲的都是"顺利情况下的路径"。真实装机过程中,出问题的概率远高于一次成功。这一章列的五个坑,全部来自实际复现现场,每条按现象、原因、解决三段写,遇到对得上的直接照方抓药。
5.1 五条踩坑记录
第一条:进度条走完,输出全是纯黑图。
现象:命令正常退出,日志里 loss 那一行也没报错,但outputs里的 png 打开是全黑或全灰。
原因:半精度溢出。模型默认用--precision autocast,在部分显卡上注意力层的 fp16 计算出 NaN,NaN 经过后续层传播,最终解码出来就是黑图。第 2 章那段自检脚本里的isnan计数就是提前发现这个问题的。
解决:启动参数加--precision full走 fp32。速度会慢 30% 左右、显存多占一到两成,但结果是正确的。确定显卡不支持 fp16 之后,这条参数就长期挂着,别反复试。
第二条:CUDA out of memory,但显存明明够。
现象:torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 2.00 GiB,而nvidia-smi显示还有 3GB 空闲。
原因:显存碎片。PyTorch 的缓存分配器在多次大小不一的分配后会留下无法复用的空洞。或者是你机器上还有别的进程(浏览器硬件加速、其他 Python 进程)占着显存没释放。
解决:先nvidia-smi看Processes那一栏有没有残留进程,有就杀掉。确认没有之后把--n_samples降到 1,用--n_iter串行替代批量,显存峰值能降一大截。再不行就设环境变量PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128,限制单次分配块大小,减少碎片。
第三条:pip install -r requirements.txt卡在 git 依赖上。
现象:输出停在Collecting git+https://...几分钟不动,最后ReadTimeoutError。
原因:requirements 里有几个包是从源码仓库直接拉的,不走 PyPI 镜像,速度完全看网络状况,而且默认超时只有 15 秒。
解决:加--timeout 120 --retries 5,或者把那个 git 依赖单独拎出来用--no-deps装,装完再跑一次pip check确认没引入冲突。实在拉不动就把那一行注释掉,先保证主流程能走,缺的包在导入报错时再补。
第四条:权重放对了,却一直报找不到 ckpt。
现象:FileNotFoundError: [Errno 2] No such file or directory: 'models/ldm/stable-diffusion-v1/model.ckpt',但ls看文件明明在那儿。
原因:相对路径问题。脚本用的是相对当前工作目录的路径,你在scripts/目录里执行python txt2img.py,相对路径就变成了scripts/models/...。
解决:要么统一在仓库根目录执行python scripts/txt2img.py,要么每次显式传绝对路径的--ckpt。我一般选前者,并把cd写进启动脚本里,避免手动切换目录时忘了。
第五条:改了--steps却发现效果和没改一样。
现象:把--steps从 30 调到 50,出图质量毫无变化,日志里的步数还是 30。
原因:--steps和--ddim_steps是同一个参数的两个名字,如果你在别处被人塞了一份包含--ddim_steps 30的配置,两个同时出现在命令行里,后者覆盖前者的行为取决于解析顺序,很容易出现"改了没生效"。
解决:整条命令里只保留一个步数参数,统一用--ddim_steps。启动前把命令完整打印一遍,肉眼确认没有重复参数。
5.2 报错日志怎么定位到具体模块
Stable Diffusion 的报错日志很长,但真正有用的信息集中在最后 15 行和第一个Traceback。我一般的读法是倒着看:
# 只留最后 30 行,去掉 tqdm 进度条刷屏 python scripts/txt2img.py --prompt "test" --plms 2>&1 | tail -n 302>&1把 stderr 合并到 stdout,否则错误信息可能被进度条冲掉。看的时候找三样东西:异常类型(RuntimeError/FileNotFoundError/OutOfMemoryError)、最后一行提到的文件名、以及文件名所在的那个模块。异常类型决定大方向,文件名决定具体位置。
| 异常类型 | 高概率原因 | 先查哪里 |
|---|---|---|
FileNotFoundError | 路径或权重缺失 | --ckpt、--outdir、当前工作目录 |
OutOfMemoryError | 显存超限 | 分辨率、--n_samples、残留进程 |
RuntimeError: expected scalar type | 精度不一致 | --precision与半精度开关 |
ModuleNotFoundError | 依赖没装全 | pip check输出 |
KeyError: 'model' | 权重结构和代码版本不匹配 | ckpt 与仓库分支是否同代 |
KeyError这一类最隐蔽,通常是把新版权重喂给了旧版代码,或者反过来。解决办法只有一条:权重和代码版本对齐,别混搭。
6. 进阶:用 --from-file 批量出图并让种子可追溯
单条命令试参数还行,一旦要做风格探索就得批量跑上百条 prompt。这时候手写循环很蠢,scripts/txt2img.py自带--from-file参数,读一个每行一条 prompt 的文本文件,配合--n_iter可以一次性跑完整个列表。
# prompts.txt 每行一条,空行会被跳过 cat > prompts.txt <<'EOF' a fantasy landscape, floating islands, volumetric light, matte painting a stone bridge over a calm river, morning fog, high detail a deserted lighthouse on a cliff, stormy sky, dramatic light EOF python scripts/txt2img.py \ --from-file prompts.txt \ --ckpt models/ldm/stable-diffusion-v1/model.ckpt \ --H 512 --W 512 \ --n_samples 1 --n_iter 2 \ --ddim_steps 30 --scale 7.5 --plms \ --seed 1000 \ --outdir outputs/batch-01--n_iter 2表示每条 prompt 出两张,总共 3×2 共 6 张。有个细节必须注意:--seed只设了起始值,脚本内部会按批次递增,所以在outputs/batch-01里每张图的真实种子是从 1000 往上数的,顺序对应生成顺序。想要精确追溯某一张的种子,得人工对照文件名和顺序,这是命令行版的局限。
我的做法是写一层薄包装把每次配置落成 JSON:
import json, subprocess, itertools from pathlib import Path configs = list(itertools.product( [7.0, 8.0, 9.0], # CFG 三档 [25, 35], # 步数两档 )) run_id = "sweep-01" base = Path(f"outputs/{run_id}") base.mkdir(parents=True, exist_ok=True) manifest = [] for i, (cfg, steps) in enumerate(configs): seed = 4000 + i out = base / f"cfg{cfg}-step{steps}" cmd = [ "python", "scripts/txt2img.py", "--prompt", "a fantasy landscape, floating islands, volumetric light", "--H", "512", "--W", "512", "--n_samples", "1", "--n_iter", "1", "--ddim_steps", str(steps), "--scale", str(cfg), "--plms", "--seed", str(seed), "--outdir", str(out), ] subprocess.run(cmd, check=True) manifest.append({"cfg": cfg, "steps": steps, "seed": seed, "dir": str(out)}) (base / "manifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2))这段脚本的价值不在省事,在于manifest.json把每组参数和输出目录绑死了。跑完直接翻 JSON 就能比对哪一档 CFG 配哪一档步数效果最好,不需要回忆或翻 shell 历史。check=True保证任何一组失败时立刻抛错停下,而不是默默跳过——批量任务里跳过失败是最难排查的状态。
最后说一句我踩过的教训。刚开始做参数扫描时,我图省事所有组共用一个--outdir,结果几百张图全混在一个目录里,后来想对比 CFG 7 和 CFG 9 的差别,只能靠回忆生成顺序手工挑,血的教训。从那以后我每次批量跑图,目录名、manifest、种子三样必须同时落盘,缺一样就不开跑。希望帮到你。
本文还有配套的精品资源,点击获取