首页/知识库/Stable Diffusion(二):从原理到实战

Stable Diffusion(二):从原理到实战

✍️ AI Master📅 创建 2026-04-12📖 20 min 阅读
💡

文章摘要

从文本到图像,理解 Stable Diffusion 如何实现高质量图像生成

1从 Diffusion 到 Stable Diffusion

Stable Diffusion 是 Stability AI 于 2022 年发布的开源文生图模型,它将扩散模型的生成能力推向了新的高度。与 DDPM 等早期扩散模型直接在像素空间操作不同,Stable Diffusion 的核心创新在于将扩散过程转移到潜在空间(Latent Space)中执行。这一改变带来了革命性的效率提升:在 64x64 的潜在空间中进行扩散,比在 512x512 的像素空间中计算量降低了 48 倍。Stable Diffusion 的架构由三大组件构成:变分自编码器(VAE)负责像素空间与潜在空间之间的转换,U-Net 在潜在空间中执行去噪过程,CLIP 文本编码器将自然语言提示词转化为条件向量。三者协同工作,使得模型能够根据任意文本描述生成高分辨率、高质量的图像。Stable Diffusion 的训练数据是 LAION-5B,一个包含 58.5 亿图文对的超大规模数据集,这赋予了模型惊人的泛化能力。更重要的是,Stable Diffusion 以 860M 参数和 4GB 显存的低门槛实现了开源,彻底改变了 AI 图像生成的生态格局。

python
# Stable Diffusion 三大组件概览
from diffusers import StableDiffusionPipeline
import torch

# 加载预训练模型(自动下载 VAE + U-Net + Text Encoder)
pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
    safety_checker=None
)
pipe = pipe.to("cuda")

# 一键文生图
image = pipe(
    prompt="a futuristic city at sunset, cyberpunk style",
    negative_prompt="blurry, low quality",
    num_inference_steps=50,
    guidance_scale=7.5,
).images[0]
image.save("output.png")
python
# 模型参数量与显存需求对比
models = {
    "DDPM (256x256)":  {"params": "350M",  "vram": "~8GB",  "space": "像素空间"},
    "DALL-E 2":        {"params": "3.5B",  "vram": "~40GB", "space": "CLIP 空间"},
    "SD 1.5 (512x512)": {"params": "860M",  "vram": "~4GB",  "space": "潜在空间"},
    "SDXL (1024x1024)": {"params": "2.6B",  "vram": "~8GB",  "space": "潜在空间"},
}

for name, spec in models.items():
    print(f"{name:20s} | {spec['params']:>6s} | {spec['vram']:>7s} | {spec['space']}")
模型参数量显存需求操作空间开源

DDPM

350M

~8GB

像素空间 (256x256)

DALL-E 2

3.5B

~40GB

CLIP 隐空间

Stable Diffusion 1.5

860M

~4GB

潜在空间 (64x64)

Stable Diffusion XL

2.6B

~8GB

潜在空间 (128x128)

Imagen

4.6B

~20GB

像素空间 (级联)

初次使用建议从 SD 1.5 开始,4GB 显存即可运行,生态最成熟。

SDXL 虽然质量更高,但需要 8GB 以上显存,且提示词工程要求不同。

2潜在空间(Latent Space)

潜在空间是 Stable Diffusion 区别于传统扩散模型的核心创新。其基本思想是:自然图像在像素空间中高度冗余,相邻像素之间存在极强的相关性,直接在像素空间中进行扩散计算效率极低。Stable Diffusion 使用预训练的变分自编码器(VAE)将图像压缩到低维潜在空间。VAE 的编码器将 3x512x512 的图像压缩为 4x64x64 的潜在表示,压缩比达到 48 倍。在潜在空间中,扩散过程的计算量大幅降低,同时保留了图像的语义信息。VAE 的训练目标是重构损失加 KL 正则化,确保潜在空间连续且可解码。值得注意的是,Stable Diffusion 中 VAE 的训练与扩散训练是分阶段进行的:先训练好 VAE 冻结其权重,再训练 U-Net 在潜在空间中进行扩散。这种解耦设计使得每个组件可以独立优化。潜在空间不仅加速了扩散过程,还为后续的图像编辑(如 Inpainting、Outpainting)提供了天然的操作接口。

python
# VAE 编码与解码过程
import torch
import torch.nn as nn
from diffusers import AutoencoderKL

# 加载预训练 VAE
vae = AutoencoderKL.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    subfolder="vae",
    torch_dtype=torch.float16
)
vae = vae.to("cuda")

# 编码:像素空间 -> 潜在空间
# 输入: (1, 3, 512, 512) -> 输出: (1, 4, 64, 64)
with torch.no_grad():
    latent = vae.encode(pixels).latent_dist.sample()
    latent = latent * vae.config.scaling_factor  # 缩放因子 0.18215

# 解码:潜在空间 -> 像素空间
with torch.no_grad():
    latent = latent / vae.config.scaling_factor
    decoded = vae.decode(latent).sample
    # decoded shape: (1, 3, 512, 512)
python
# VAE 重构质量评估
import torch
from torch.nn.functional import mse_loss
from lpips import LPIPS

lpips_model = LPIPS(net="vgg").to("cuda")

def evaluate_vae(vae, images):
    """评估 VAE 的重构质量"""
    with torch.no_grad():
        # 编码
        posterior = vae.encode(images).latent_dist
        latents = posterior.sample() * vae.config.scaling_factor
        
        # 解码
        latents = latents / vae.config.scaling_factor
        reconstructed = vae.decode(latents).sample
    
    # 计算重构误差
    mse = mse_loss(images, reconstructed).item()
    lpips = lpips_model(images, reconstructed).mean().item()
    
    print(f"MSE: {mse:.6f}")
    print(f"LPIPS: {lpips:.4f} (越低越好, <0.05 为优秀)")
    return reconstructed
VAE 组件输入维度输出维度压缩比作用

编码器 Encoder

(B, 3, 512, 512)

(B, 8, 64, 64)

48x

提取特征

瓶颈层 Bottleneck

(B, 8, 64, 64)

(B, 8, 64, 64)

1x

均值与方差

采样层 Sample

(B, 8, 64, 64)

(B, 4, 64, 64)

2x

重参数化采样

解码器 Decoder

(B, 4, 64, 64)

(B, 3, 512, 512)

1/48x

重构图像

缩放因子 Scaling

(B, 4, 64, 64)

(B, 4, 64, 64)

0.18215

稳定训练

VAE 的重构质量直接影响最终生成图像的细节,选择高质量的 VAE 至关重要。

潜在空间中的操作(如编辑 latent)需要小心,超出训练分布可能导致解码异常。

3CLIP 文本编码器

CLIP(Contrastive Language-Image Pre-training)是 OpenAI 提出的图文对比学习模型,它为 Stable Diffusion 提供了理解自然语言的能力。CLIP 使用双塔架构:一个视觉编码器(ViT 或 ResNet)和一个文本编码器(Transformer),通过对比学习在大规模图文对上联合训练。在 Stable Diffusion 中,我们使用的是 CLIP 的文本编码器部分,具体为 ViT-L/14 架构,隐藏层维度 768,上下文长度 77 个 token。文本编码器将用户输入的提示词转换为 77x768 的序列嵌入,然后经过线性投影变为 77x1024,作为 U-Net 中 Cross-Attention 层的条件输入。CLIP 的强大之处在于它学习到了文本与图像之间的语义对齐,使得 "a red car" 的文本嵌入与红色汽车图像的视觉嵌入在共享空间中距离很近。这也是 Stable Diffusion 能够理解复杂文本描述的关键。需要注意的是,CLIP 对提示词的格式和顺序非常敏感,精心设计的提示词工程可以显著提升生成质量。

python
# CLIP 文本编码器解析
from transformers import CLIPTokenizer, CLIPTextModel
import torch

tokenizer = CLIPTokenizer.from_pretrained(
    "openai/clip-vit-large-patch14")
text_encoder = CLIPTextModel.from_pretrained(
    "openai/clip-vit-large-patch14")

# 文本 -> token -> 嵌入
prompt = "a beautiful sunset over the ocean, golden hour"
inputs = tokenizer(prompt, return_tensors="pt", padding="max_length",
                   max_length=77, truncation=True)

with torch.no_grad():
    outputs = text_encoder(input_ids=inputs.input_ids,
                           attention_mask=inputs.attention_mask)
    text_embeddings = outputs.last_hidden_state

print(f"Token count: {inputs.input_ids.shape[-1]}")  # 77
print(f"Embedding shape: {text_embeddings.shape}")     # (1, 77, 768)
print(f"Tokens: {tokenizer.convert_ids_to_tokens(inputs.input_ids[0][:10])}")
python
# 提示词嵌入相似度分析
import torch
import torch.nn.functional as F

def compute_text_similarity(texts):
    """计算提示词之间的语义相似度"""
    tokens = tokenizer(texts, return_tensors="pt", padding=True,
                       max_length=77, truncation=True)
    with torch.no_grad():
        embeddings = text_encoder(**tokens).last_hidden_state
        # 使用 [CLS] token 的嵌入
        cls_embeddings = embeddings[:, 0, :]
    
    similarities = F.cosine_similarity(
        cls_embeddings.unsqueeze(1),
        cls_embeddings.unsqueeze(0),
        dim=-1
    )
    
    for i, t1 in enumerate(texts):
        for j, t2 in enumerate(texts):
            if i < j:
                print(f"{t1[:30]:30s} <-> {t2[:30]:30s}: " 
                      f"{similarities[i,j]:.4f}")

texts = ["a dog running in a park",
         "a cat sleeping on a sofa",
         "a beautiful dog playing outdoors"]
compute_text_similarity(texts)
CLIP 组件架构维度作用

Tokenizer

BPE 编码

77 tokens

文本分词

Text Encoder

Transformer (12层)

768 hidden

文本理解

Projection

Linear + LayerNorm

1024 dim

维度对齐

Visual Encoder

ViT-L/14

1024 hidden

图像理解

对比损失

InfoNCE

batch_size

图文对齐

使用加权提示词 (word:1.3) 可以增强特定概念的表达强度,这是常用的提示词技巧。

CLIP 对否定词理解较弱,negative prompt 在 Stable Diffusion 中作为独立机制处理。

4U-Net 去噪网络

Stable Diffusion 的 U-Net 是整个架构中参数量最大的组件,约 860M 参数。它在潜在空间中工作,接收 4x64x64 的带噪潜在表示和时间步嵌入,输出相同维度的噪声预测。与 DDPM 中的 U-Net 相比,SD 的 U-Net 做了三个关键改进:第一,引入 Cross-Attention 层,将 CLIP 文本嵌入作为条件注入到网络中,每个 Down 和 Middle 块都包含 Cross-Attention;第二,使用 GroupNorm 替代 BatchNorm,对小 batch size 更友好;第三,增加了 Attention 块的数量和维度,在 8x8 和 16x16 分辨率处使用 Self-Attention 捕获长程依赖。U-Net 的结构遵循编码器-瓶颈-解码器模式:四个 Down 块逐步降低空间分辨率并增加通道数(320->640->1280->1280),一个 Middle 块包含 Self-Attention,四个 Up 块逐步恢复分辨率。每个残差块中都会注入时间步嵌入,使得网络能够在不同去噪阶段使用不同的策略。这种设计让 U-Net 既能理解文本语义,又能在不同尺度上操作图像特征。

python
# Stable Diffusion U-Net 结构解析
from diffusers import UNet2DConditionModel
import torch

# 加载 U-Net
unet = UNet2DConditionModel.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    subfolder="unet",
    torch_dtype=torch.float16
)

# U-Net 参数统计
total_params = sum(p.numel() for p in unet.parameters())
print(f"Total params: {total_params / 1e6:.1f}M")  # ~860M

# 前向传播
cross_attention_dim = 768
latent = torch.randn(1, 4, 64, 64, dtype=torch.float16, device="cuda")
timestep = torch.tensor([500], device="cuda")
encoder_hidden = torch.randn(1, 77, cross_attention_dim, dtype=torch.float16, device="cuda")

with torch.no_grad():
    noise_pred = unet(latent, timestep, encoder_hidden_states=encoder_hidden).sample

print(f"Input:  {latent.shape}")     # (1, 4, 64, 64)
print(f"Output: {noise_pred.shape}")  # (1, 4, 64, 64)
python
# 分析 U-Net 各层结构
from diffusers import UNet2DConditionModel

unet = UNet2DConditionModel.from_pretrained(
    "runwayml/stable-diffusion-v1-5", subfolder="unet")

# 打印块结构
print("=== Down Blocks ===")
for i, block in enumerate(unet.down_blocks):
    has_attn = hasattr(block, "attentions") and block.attentions[0] is not None
    print(f"  Down {i}: channels={block.resnets[0].in_channels}, " 
          f"attn={has_attn}, downsample={block.downsamplers is not None}")

print("=== Middle Block ===")
mid = unet.mid_block
print(f"  Attention: {len(mid.attentions)} blocks")
print(f"  Resnets: {len(mid.resnets)} blocks")

print("=== Up Blocks ===")
for i, block in enumerate(unet.up_blocks):
    has_attn = hasattr(block, "attentions") and block.attentions[0] is not None
    print(f"  Up {i}: channels={block.resnets[0].in_channels}, " 
          f"attn={has_attn}, upsample={block.upsamplers is not None}")
U-Net 层级通道数分辨率Attention作用

Down Block 0

320

64x64

浅层特征提取

Down Block 1

320->640

32x32

降采样+特征

Down Block 2

640->1280

16x16

有 (Spatial)

中层语义

Down Block 3

1280->1280

8x8

有 (Spatial)

深层语义

Middle Block

1280

8x8

有 (Spatial+Cross)

全局理解

Up Block 0

1280->1280

8x8->16x16

上采样+融合

Up Block 1

1280->640

16x16->32x32

恢复细节

Up Block 2

640->320

32x32->64x64

恢复细节

Up Block 3

320->320

64x64

最终输出

使用 torch.compile 编译 U-Net 可以获得 20-40% 的推理加速,需要 PyTorch 2.0+。

修改 U-Net 架构(如添加层)后必须重新训练,不能直接复用预训练权重。

5采样器对比:DDIM / PLMS / DPM

采样器是控制扩散模型推理过程的核心组件,决定了从随机噪声到最终图像的迭代路径。Stable Diffusion 支持多种采样器,每种在速度和质量之间做出不同权衡。DDIM 是最基础的确定性采样器,将扩散过程视为 ODE 求解,支持 20-50 步的高质量生成。PLMS(Pseudo Linear Multistep)利用多步方法,用之前步骤的梯度信息加速收敛,通常 10-20 步即可获得不错结果。DPM-Solver 系列是目前最先进的采样器,基于常微分方程的高阶求解器,DPM-Solver++ 仅需 10-15 步就能达到 DDIM 50 步的质量。Euler 和 Heun 则是经典的一阶和二阶 ODE 求解器在扩散模型中的应用。采样器的选择还影响生成的确定性:确定性采样器(DDIM、DPM-Solver)相同种子产生相同结果,随机采样器(DDPM、Euler a)每次生成略有不同。实际应用中,DPM-Solver++ 2M Karras 是推荐的默认选择,在速度和质量之间取得最佳平衡。

python
# 不同采样器对比实验
from diffusers import StableDiffusionPipeline, \
    DDIMScheduler, EulerDiscreteScheduler, \
    DPMSolverMultistepScheduler, LMSDiscreteScheduler
import torch, time

pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

samplers = {
    "DDIM": DDIMScheduler.from_config(pipe.scheduler.config),
    "Euler": EulerDiscreteScheduler.from_config(pipe.scheduler.config),
    "DPM++ 2M": DPMSolverMultistepScheduler.from_config(pipe.scheduler.config),
    "PLMS": LMSDiscreteScheduler.from_config(pipe.scheduler.config),
}

prompt = "a portrait of a warrior queen, fantasy art"
results = []
for name, scheduler in samplers.items():
    pipe.scheduler = scheduler
    start = time.time()
    img = pipe(prompt, num_inference_steps=25, generator=torch.manual_seed(42)).images[0]
    elapsed = time.time() - start
    results.append((name, f"{elapsed:.2f}s"))
    img.save(f"output_{name}.png")
    print(f"{name:12s} | {elapsed:.2f}s")
python
# 采样步数收敛曲线
import torch
from diffusers import DPMSolverMultistepScheduler

def convergence_test(pipe, prompt, steps_list, seed=42):
    """测试不同步数下的生成稳定性"""
    pipe.scheduler = DPMSolverMultistepScheduler.from_config(
        pipe.scheduler.config)
    
    # 基准:100 步
    pipe.scheduler.set_timesteps(100)
    gen = torch.Generator("cuda").manual_seed(seed)
    ref = pipe(prompt, num_inference_steps=100, generator=gen).images[0]
    
    for steps in steps_list:
        gen = torch.Generator("cuda").manual_seed(seed)
        img = pipe(prompt, num_inference_steps=steps, generator=gen).images[0]
        # 计算与基准的 LPIPS 距离
        lpips_val = compute_lpips(ref, img)
        print(f"Steps: {steps:3d} | LPIPS vs 100-step: {lpips_val:.4f}")

convergence_test(pipe, "a cute cat", steps_list=[4, 8, 12, 16, 20, 25, 50])
采样器类型推荐步数速度质量确定性

DDIM

ODE 一阶

20-50

确定

Euler

ODE 一阶

20-30

确定

Euler a

SDE 随机

20-30

随机

DPM-Solver++

ODE 高阶

10-20

很快

很好

确定

DPM++ 2M Karras

ODE 多步

15-25

很快

优秀

确定

PLMS

多步伪线性

10-20

很快

中等

确定

Heun

ODE 二阶

15-20

很好

确定

日常使用推荐 DPM++ 2M Karras,25 步即可获得优秀质量。

步数少于 10 时所有采样器质量都会明显下降,不要为了速度过度减少步数。

6控制生成:ControlNet 与 LoRA

Stable Diffusion 原生只支持文本条件生成,但实际应用中往往需要更精细的控制。ControlNet 通过复制 U-Net 的编码器并添加零卷积层,将额外的空间条件(如边缘图、深度图、姿态图)注入到去噪过程中。关键设计是零卷积初始化:训练初期 ControlNet 的输出为零,不影响原始模型的生成能力,随着训练逐步学习条件控制。这使得 ControlNet 可以附加到任何预训练 SD 模型上,而无需重新训练整个网络。LoRA(Low-Rank Adaptation)则提供了一种轻量级的模型微调方法。它通过在注意力层的权重矩阵上添加低秩分解矩阵 A*B 来微调模型,参数量仅为原始的 1-10%。LoRA 的优势在于:训练文件仅几 MB 到几百 MB,可以快速切换不同风格,且不会破坏原始模型能力。结合 ControlNet 的结构控制和 LoRA 的风格控制,可以实现高度精确的图像生成。此外,IP-Adapter 等技术进一步支持了图像条件生成,使模型能够参考输入图像的风格和内容。

python
# ControlNet:边缘图控制生成
from diffusers import StableDiffusionControlNetPipeline, \
    ControlNetModel, UniPCMultistepScheduler
from controlnet_aux import CannyDetector
import torch
from PIL import Image

# 加载 Canny ControlNet
canny = ControlNetModel.from_pretrained(
    "lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=canny, torch_dtype=torch.float16)
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
pipe = pipe.to("cuda")

# 提取边缘图并生成
input_img = Image.open("input.png").convert("RGB")
canny_img = CannyDetector()(input_img, low_threshold=100, high_threshold=200)

result = pipe(
    prompt="a beautiful landscape, photorealistic, 4k",
    image=canny_img,
    num_inference_steps=20,
    controlnet_conditioning_scale=0.8,
).images[0]
python
# LoRA 训练与推理
from diffusers import StableDiffusionPipeline
from peft import LoraConfig, get_peft_model
import torch

# 方法一:加载预训练 LoRA 权重
pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

# 加载 LoRA(仅 ~200MB,远小于全模型 4GB)
pipe.load_lora_weights("path/to/lora_weights", weight_name="pytorch_lora.bin")
pipe.fuse_lora(lora_scale=0.8)  # 融合到主模型

# 生成
image = pipe("a warrior in anime style").images[0]

# 方法二:使用 diffusers + peft 训练
lora_config = LoraConfig(
    r=16,
    lora_alpha=27,
    target_modules=["to_q", "to_k", "to_v", "to_out.0"],
    lora_dropout=0.05,
)
print(f"LoRA params: {sum(p.numel() for p in lora_params) / 1e6:.2f}M")
技术控制方式文件大小训练成本适用场景

ControlNet

空间条件(边缘/深度/姿态)

~1.4GB

中等

结构精确控制

LoRA

风格/概念微调

~100-400MB

风格迁移

Textual Inversion

新词汇嵌入

~10-100KB

极低

新概念学习

DreamBooth

全模型微调

~4GB

个性化主体

IP-Adapter

图像参考

~100MB

风格/内容参考

LoRA 可以叠加使用(如风格 LoRA + 角色 LoRA),通过调整各自权重实现精细控制。

ControlNet 的条件图必须与生成图像分辨率一致,否则会引入伪影。

7diffusers 库实战

Hugging Face 的 diffusers 库是 Stable Diffusion 生态中最流行的 Python 框架,提供了模块化的管道设计和丰富的模型支持。本节通过一个完整的项目展示 diffusers 的核心用法:从基础文生图到高级的图像编辑。diffusers 的设计哲学是管道(Pipeline)模式,将 VAE、U-Net、Text Encoder 等组件组合成端到端的可用接口。每个管道都支持进度回调、安全过滤器、多 GPU 推理等高级功能。实战中最重要的技巧包括:使用 attention_slicing 降低显存占用,使用 enable_xformers_memory_efficient_attention 启用 Flash Attention 加速,使用 torch.compile 编译整个管道。对于生产环境,建议使用 safetensors 格式加载权重以避免 pickle 安全风险,并始终设置随机种子以确保可复现性。diffusers 还支持 ONNX 导出、CoreML 转换等部署选项,使得模型可以在不同平台上高效运行。

python
# 高级 diffusers 管道配置
from diffusers import (
    StableDiffusionImg2ImgPipeline,
    StableDiffusionInpaintPipeline,
    DPMSolverMultistepScheduler,
)
import torch
from PIL import Image

# 优化配置:显存效率 + 推理加速
def setup_pipeline(model_id="runwayml/stable-diffusion-v1-5"):
    pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
        model_id,
        torch_dtype=torch.float16,
        use_safetensors=True,
    )
    # 显存优化
    pipe.enable_attention_slicing()
    pipe.enable_vae_slicing()
    # 推理加速(需要安装 xformers)
    try:
        pipe.enable_xformers_memory_efficient_attention()
    except Exception:
        print("xformers not available, using default attention")
    
    pipe.scheduler = DPMSolverMultistepScheduler.from_config(
        pipe.scheduler.config)
    return pipe.to("cuda")

pipe = setup_pipeline()
print(f"Pipeline ready, device: {pipe.device}")
python
# 完整工作流:文生图 -> 图生图 -> 局部重绘
import torch
from PIL import Image
import numpy as np

pipe = setup_pipeline()
generator = torch.Generator("cuda").manual_seed(42)

# Step 1: 文生图
prompt = "a medieval castle on a cliff, epic lighting"
result = pipe(
    prompt=prompt,
    negative_prompt="ugly, blurry, watermark",
    num_inference_steps=30,
    guidance_scale=7.5,
    generator=generator,
).images[0]
result.save("step1_castle.png")

# Step 2: 图生图(添加季节变化)
autumn_result = pipe(
    prompt=prompt + ", autumn foliage, golden leaves",
    image=result,
    strength=0.4,  # 0=完全保留, 1=完全重绘
    num_inference_steps=30,
    guidance_scale=7.5,
    generator=generator,
).images[0]
autumn_result.save("step2_autumn.png")

# Step 3: 局部重绘(添加飞鸟)
mask = create_bird_mask(result.size)  # 自定义掩码
bird_result = inpaint_pipe(
    prompt="birds flying in the sky",
    image=autumn_result,
    mask_image=mask,
    num_inference_steps=30,
).images[0]
bird_result.save("step3_final.png")
优化技术显存节省速度提升适用条件

attention_slicing

~30%

~10%

所有 GPU

vae_slicing

~20%

~5%

所有 GPU

xformers

~40%

~30%

需要安装 xformers

torch.compile

~0%

~40%

PyTorch 2.0+

CPU offload

~60%

-50%

显存极度受限

8-bit 量化

~50%

-10%

需要 bitsandbytes

使用 seed 固定随机数生成器,确保相同提示词和参数产生完全相同的结果。

生产环境务必设置 safety_checker 或使用自定义内容审核管道。

继续你的 AI 学习之旅

浏览更多 AI 知识库文章,或者探索 GitHub 上的优质 AI 项目