简介:本资源是一份面向Stable Diffusion初学者与进阶实践者的系统性学习导图,聚焦图像生成、修复及插件扩展等核心应用场景,帮助用户快速建立技术认知框架并指导实操落地。文件为单页PDF格式(162KB),内容高度结构化,覆盖SD基础(模型架构、VAE、Embedding、LoRA、Hypernetworks)、文生图/图生图全流程参数(CFG、采样器、迭代步数、提示词矩阵、蒙版控制)、局部重绘与高清修复技巧(边缘模糊度、缩放模式、放大算法强度)、商业级功能(Segment Anything、MultiDiffusion)及插件生态(自动/手动安装、版本切换、Clip/DeepBooru提示词反推)等30+关键模块。目前已有84人学习下载,思维导图采用分层递进式设计,将零散知识点整合为可追溯的学习路径,便于查漏补缺、快速定位参数逻辑与功能边界,是高效掌握SD全栈能力的高信息密度入门指南。
1. 这份《SD技术全套思维导图.pdf》不是知识罗列,而是 Stable Diffusion 工程师的「决策路径图」
很多人拿到“SD全套思维导图”第一反应是:收藏、打印、贴墙上——结果三个月后还在问“ControlNet 和 LoRA 到底谁该先加载”。其实这张图真正的价值,不在于覆盖了多少名词(Embedding、LoRA、ControlNet、SDXL、ComfyUI 节点流、T2I-Adapter、IP-Adapter……),而在于它把 Stable Diffusion 技术栈中所有可干预环节的因果链显性化了:从输入文本 tokenization 的 embedding 层开始,到 UNet 中间特征图被 ControlNet 条件注入的位置,再到 LoRA 矩阵在 attention projection 上的低秩替换时机,最后到 VAE 解码前的 latent 裁剪策略。它回答的不是“这是什么”,而是“改这里,会怎样影响生成质量、推理速度、可控性边界和显存占用”。适合两类人:刚跑通秋叶整合包但卡在“为什么加了 Canny 就崩图”的新手;以及正在用 ComfyUI 搭建企业级文生图 pipeline、需要快速判断该在 preprocessor 层做归一化还是在 model patch 层做权重缩放的工程师。下面我们就按这张图实际展开的逻辑层级,一层层拆解每个模块的落地要点。
2. Embedding 与 LoRA:模型微调的两种粒度,决定你是在“调参”还是在“造零件”
Stable Diffusion 的可扩展性,本质来自其参数空间的分层可插拔设计。Embedding(文本嵌入)和 LoRA(低秩自适应)虽常被并列提及,但作用域、生效位置、训练成本和部署方式存在根本差异。理解这点,才能避免把 LoRA 当成“高级 Embedding”来用,或误以为 Embedding 能替代结构化控制。
2.1 Embedding 的本质是文本语义的“快捷键”,不是模型权重
Embedding 文件(.pt或.bin格式)本质是一组预计算的 token 向量,用于替换 CLIP 文本编码器中特定 token 的原始 embedding。例如,一个cyberpunk_style.pt文件,通常绑定触发词cyberpunk_style,当提示词中出现该词时,模型会跳过 CLIP 的标准编码流程,直接查表取这组向量注入 text encoder 输出。它的生效位置在text encoder 的输出层之后、UNet 的 cross-attention 输入之前,属于纯文本侧增强。
提示:Embedding 无法改变图像结构。它能强化“赛博朋克”的光影质感或霓虹色调,但无法让生成图出现“带机械臂的女性”这种构图级控制——这必须靠 ControlNet 或 IP-Adapter。
2.1.1 加载 Embedding 的最小验证命令(WebUI)
# 启动 WebUI 时指定 embedding 目录(非模型目录!) webui-user.bat # 在 user.config 中确保: # embeddings_dir="D:\stable-diffusion-webui\embeddings" # 然后将 cyberpunk_style.pt 放入该目录 # 启动后,在 prompt 输入框写:"cyberpunk_style, a neon-lit street at night"该命令生效的关键参数是embeddings_dir路径必须独立于models/Stable-diffusion/。若混放,WebUI 会报Unknown model type错误。常见失败原因是用户把.pt文件丢进models/Lora/目录——LoRA 和 Embedding 的加载器完全隔离,路径错则彻底不可见。
2.2 LoRA 是对 UNet 或 Text Encoder 权重的“外科手术式修补”
LoRA 不修改原始模型文件,而是在目标层(如to_q,to_k,to_v,to_out.0)旁动态插入一对低秩矩阵(A 和 B),使原权重W变为W + α * A @ B。其核心优势在于:冻结主干模型,仅训练少量参数(通常 < 1%),且支持多 LoRA 并行热切换。它作用于 UNet 的注意力投影层,直接影响特征图的空间关系建模能力,因此能控制姿态、构图、线条风格等图像结构属性。
2.2.1 LoRA 训练时必须明确 target_module,否则无效
以kohya_ss训练脚本为例,关键参数--network_module和--network_dim决定修补范围:
accelerate launch train_network.py \ --pretrained_model_name_or_path="models/Stable-diffusion/sd_xl_base_1.0.safetensors" \ --network_module="lycoris.kohya" \ --network_dim="128" \ --network_alpha="64" \ --train_batch_size="2" \ --max_train_steps="1500" \ --learning_rate="1e-4" \ --output_dir="loras/cyberpunk_pose" \ --network_args="conv_dim=32,conv_alpha=16"--network_dim=128:设定 A/B 矩阵的秩(rank),值越大表达能力越强,但显存占用线性上升--network_alpha=64:缩放系数,实际更新量为(α / rank) * (A @ B),推荐设为rank的 0.5 倍以平衡稳定性--network_args="conv_dim=32":必须显式开启卷积层 LoRA,否则只修补 linear 层,对 SDXL 的 conv_in/conv_out 无影响,导致训练后效果微弱
注意:SDXL 模型因含 conv 层,若漏掉
conv_dim参数,即使训练 loss 下降,生成图也不会体现 pose 控制——因为卷积核权重未被适配。
2.2.2 LoRA 推理时的权重叠加逻辑(ComfyUI 节点配置)
在 ComfyUI 中,LoRA 加载需通过LoraLoader节点,其strength_model和strength_clip分别控制对 UNet 和 Text Encoder 的影响强度:
| 参数 | 典型值 | 效果说明 |
|---|---|---|
strength_model | 0.6–0.8 | 主要影响图像结构。值 >1.0 易导致崩图,<0.3 几乎不可见 |
strength_clip | 0.1–0.3 | 微调文本语义关联。过高会扭曲 prompt 原意,如cyberpunk_style变成cyberpunk_background |
实测发现:对 SDXL 模型,strength_model=0.75+strength_clip=0.15是多数 pose LoRA 的安全起点;而对 1.5 系列,strength_clip可提升至 0.25 仍稳定。
3. ControlNet:把“画什么”和“怎么画”解耦,实现像素级条件控制
ControlNet 不是插件,而是 Stable Diffusion 架构的一次范式升级——它将生成过程拆解为“主干扩散(生成内容)+ 辅助条件网络(约束结构)”双通道。其价值不在“能加边缘图”,而在于让人类意图(草图、深度图、姿态关键点)以可微分的方式参与每一步 denoising。一张思维导图若没标出 ControlNet 的 three-stage injection 机制(preprocess → encoder → mid-block injection),就等于没画出它的脊椎。
3.1 ControlNet 的三阶段注入点,决定控制精度上限
ControlNet 的核心创新是zero convolution 初始化:其 encoder 部分初始权重全为零,训练时仅学习“如何把条件图映射为 UNet 中间层的残差信号”。这意味着它不干扰原始模型的生成能力,只提供增量修正。其注入发生在 UNet 的三个关键位置:
- Input Block 注入:将 control 图经 encoder 编码后,加到 UNet 最底层的
input_blocks输出上(分辨率最高,控制细节) - Middle Block 注入:加到
middle_block输出(全局构图锚点) - Output Block 注入:加到各
output_blocks的 skip connection 处(平衡局部与全局)
提示:Canny、MLSD、Scribble 等 preprocessor 输出的是单通道 condition map,但 ControlNet encoder 实际接收的是3 通道输入(RGB)。因此 WebUI 中若上传灰度图,需在 preprocessor 设置里勾选
Save preprocessed image并确认其为 RGB 模式,否则 encoder 输入维度错配导致 NaN loss。
3.1.1 ComfyUI 中手动构建 ControlNet 流程(验证注入逻辑)
{ "3": { "class_type": "ControlNetLoader", "inputs": { "control_net_name": "controlnet-sd-xl-canny-sdxl-1.0.safetensors" } }, "15": { "class_type": "ImageScale", "inputs": { "image": ["14", 0], "width": 1024, "height": 1024, "crop": "disabled" } }, "17": { "class_type": "Canny", "inputs": { "image": ["15", 0], "low_threshold": 100, "high_threshold": 200 } }, "20": { "class_type": "ControlNetApplyAdvanced", "inputs": { "positive": ["6", 0], "negative": ["7", 0], "control_net": ["3", 0], "image": ["17", 0], "strength": 0.8, "start_percent": 0.0, "end_percent": 1.0, "mask": null } } }关键参数start_percent和end_percent定义控制生效的时间步区间。实测表明:
start_percent=0.0, end_percent=0.4:仅在高噪声阶段注入,适合弱引导(如轻微调整光影)start_percent=0.2, end_percent=0.8:主流用法,兼顾结构稳定与细节还原start_percent=0.5, end_percent=1.0:仅在低噪声阶段生效,易导致边缘断裂(因 UNet 早期已固化大结构)
3.1.2 ControlNet 模型选择的硬约束:必须匹配基础模型架构
SDXL 与 SD 1.5 的 ControlNet 模型完全不兼容。错误混用会导致KeyError: 'control_model.input_blocks.0.0.weight'。验证方法:用safetensors库检查模型键名:
from safetensors import safe_open tensors = safe_open("controlnet-sd-xl-canny.safetensors", framework="pt") keys = list(tensors.keys()) print([k for k in keys if "input_blocks" in k][:3]) # SDXL 输出应含 'control_model.input_blocks.0.0.weight' # SD1.5 输出应含 'control_model.input_blocks.0.0.weight' 但 shape 为 [320, 4, 3, 3](非 SDXL 的 [320, 128, 3, 3])若键名存在但weight.shape[1]为 4,说明是 SD1.5 版本;若为 128,则为 SDXL。强行加载会引发 tensor size mismatch,报错信息常被 WebUI 吞掉,只显示“CUDA error”。
4. 思维导图中的「协议栈」隐喻:从 prompt 解析到 latent 采样,每一层都可调试
把 Stable Diffusion 比作“协议栈”,并非营销话术,而是精准描述其数据流分层。一份合格的思维导图必须标出各层的输入/输出格式、可干预接口、典型故障现象。例如:当用户抱怨“写了masterpiece, best quality却没提升清晰度”,问题往往不在 prompt 本身,而在prompt parser层的 tokenizer 截断或CLIP skip layer设置错误。
4.1 Prompt 解析层:token length 与 CLIP skip 的隐性博弈
SD 1.5 默认使用 OpenCLIP ViT-L/14,最大 context length 为 77 tokens(含起始/结束符)。当 prompt 超长时,WebUI 默认截断后半部分——但用户看到的仍是完整 prompt 字符串,造成“写了没用”的错觉。而 SDXL 使用 dual text encoder(CLIP ViT-L/14 + OpenCLIP ViT-G/14),总 capacity 为 77+120=197 tokens,但两个 encoder 的 skip layer 设置独立。
4.1.1 查看实际 tokenized 长度的 Python 脚本
from transformers import CLIPTokenizer import torch tokenizer = CLIPTokenizer.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", subfolder="tokenizer") prompt = "masterpiece, best quality, 8k, ultra detailed, cyberpunk cityscape with flying cars, neon signs, rain wet streets" # 对 SDXL,需分别 tokenize 两个 encoder tokens_1 = tokenizer(prompt, truncation=True, max_length=77, return_tensors="pt").input_ids tokens_2 = tokenizer(prompt, truncation=True, max_length=120, return_tensors="pt").input_ids print(f"CLIP-L tokens: {tokens_1.shape[1]}, CLIP-G tokens: {tokens_2.shape[1]}") # 输出:CLIP-L tokens: 77, CLIP-G tokens: 120 → 说明 prompt 被完整编码若输出为CLIP-L tokens: 77, CLIP-G tokens: 120,证明 prompt 未被截断;若CLIP-G tokens小于 120,则需精简 prompt。注意:truncation=True是关键,否则max_length无效。
4.2 Latent 空间采样层:CFG Scale 与 Sampler 的耦合效应
CFG(Classifier-Free Guidance)Scale 并非独立超参,其效果高度依赖 sampler 类型。例如 Euler a 在 CFG=7 时稳定,但 DPM++ 2M Karras 在相同值下易振荡。思维导图若未标注“sampler-CFG 组合安全区”,就会误导用户暴力调高 CFG。
4.2.1 不同 sampler 的 CFG 敏感度实测对比(SDXL)
| Sampler | CFG=5 | CFG=7 | CFG=12 | 典型问题 |
|---|---|---|---|---|
| Euler a | ✅ 清晰 | ✅ 强化细节 | ❌ 过曝、纹理崩坏 | 高 CFG 下梯度爆炸 |
| DPM++ 2M Karras | ⚠️ 轻微模糊 | ✅ 平衡 | ❌ 结构失真 | 对噪声 schedule 敏感 |
| UniPC | ✅ 稳定 | ✅ 稳定 | ✅ 可用至 15 | 计算开销增加 20% |
验证方法:固定 seed 和 prompt,仅变更 sampler 和 CFG,用torch.norm(latent_diff)计算相邻 step 的 latent 变化幅度。当norm > 0.8时即判定为不稳定——这比肉眼观察更早暴露问题。
5. 用思维导图定位真实瓶颈:当 LoRA 训练显存爆满时,别急着换卡
“LoRA 训练显存占满”是高频报错,但 80% 的 case 并非显存不足,而是gradient_checkpointing未启用或cache_latents配置冲突。思维导图的价值,在于提供一条从现象反推根因的路径:看到CUDA out of memory→ 查导图中“训练优化”分支 → 定位到memory_efficient子节点 → 检查--gradient_checkpointing是否开启。
5.1 显存占用的三层分解:模型、数据、优化器
LoRA 训练显存 =模型参数显存 + 梯度显存 + 优化器状态显存。其中:
- 模型参数显存:由 base model 决定(SDXL ~ 12GB)
- 梯度显存:与 trainable parameters 成正比(LoRA rank=128 时约 +1.8GB)
- 优化器状态显存:AdamW 占用 2 倍梯度显存(即 +3.6GB)
因此,关闭--optimizer_type="adamw8bit"改用--optimizer_type="lion"(状态仅需 1 倍梯度),可省 1.8GB;而启用--gradient_checkpointing可将梯度显存降低 60%,代价是训练速度下降 25%。
5.1.1 一键检测显存瓶颈的 Bash 命令(Linux)
# 启动训练前,先运行此命令监控 nvidia-smi --query-compute-apps=pid,used_memory,process_name --format=csv -l 1 | grep -E "(python|train)" # 训练中若看到 used_memory 突增至 24GB+ 且 process_name 为 python,则确认是梯度/优化器问题 # 若稳定在 12~14GB,则可能是 cache_latents 导致的 latent 缓存堆积5.1.2 解决unsloth训练中评估占满显存的配置组合
unsloth的eval_steps默认在 GPU 上执行 full forward,导致评估时显存峰值翻倍。正确做法是:
from unsloth import is_bfloat16_supported trainer = Trainer( model=model, args=TrainingArguments( per_device_eval_batch_size=1, # 必须设为 1 eval_accumulation_steps=4, # 分批累积 logits fp16=not is_bfloat16_supported(), # bfloat16 优先 bf16=is_bfloat16_supported(), report_to="none", output_dir="outputs", logging_steps=10, optim="paged_adamw_32bit", # 关键:用 paged 版本减少碎片 lr_scheduler_type="cosine", # 避免 warmup 阶段显存尖峰 ), train_dataset=train_dataset, eval_dataset=eval_dataset, callbacks=[UnslothPeftSavingCallback], # 确保 LoRA 权重及时卸载 )核心是per_device_eval_batch_size=1+eval_accumulation_steps=4,让评估分 4 步完成,每步仅加载 1 个 batch,显存占用从 24GB 降至 14GB。实测在 24GB 显卡上可稳定运行 rank=128 的 SDXL LoRA 训练。
本文还有配套的精品资源,点击获取