Diffusers 文档

稳定扩散 3

Hugging Face's logo
加入 Hugging Face 社区

并获得增强型文档体验

开始

稳定扩散 3

稳定扩散 3 (SD3) 由 Patrick Esser、Sumith Kulal、Andreas Blattmann、Rahim Entezari、Jonas Muller、Harry Saini、Yam Levi、Dominik Lorenz、Axel Sauer、Frederic Boesel、Dustin Podell、Tim Dockhorn、Zion English、Kyle Lacey、Alex Goodwin、Yannik Marek 和 Robin Rombach 在 Scaling Rectified Flow Transformers for High-Resolution Image Synthesis 中提出。

论文中的摘要为

扩散模型通过反转数据到噪声的正向路径来从噪声创建数据,并已成为一种强大的生成建模技术,适用于高维感知数据,例如图像和视频。 校正流是一种最新的生成模型公式,它将数据和噪声以直线连接。 尽管它具有更好的理论属性和概念上的简单性,但它尚未确立为标准实践。 在这项工作中,我们通过将现有噪声采样技术偏向感知相关的尺度来改进用于训练校正流模型的现有噪声采样技术。 通过大规模研究,我们证明了与用于高分辨率文本到图像合成的已建立的扩散公式相比,这种方法的优越性能。 此外,我们提出了一种新颖的基于 Transformer 的用于文本到图像生成的架构,该架构对两种模态使用独立的权重,并能够在图像和文本标记之间双向流动信息,从而提高文本理解排版和人类偏好评级。 我们证明这种架构遵循可预测的缩放趋势,并将较低的验证损失与通过各种指标和人工评估衡量的改进的文本到图像合成相关联。

使用示例

由于该模型是门控的,因此在使用 diffusers 之前,您需要先访问 稳定扩散 3 中等 Hugging Face 页面,填写表格并接受门控。 进入后,您需要登录,以便您的系统知道您已接受门控。

使用以下命令登录

huggingface-cli login

SD3 管道使用三个文本编码器生成图像。 为了让它在大多数商品硬件上运行,需要模型卸载。 请使用 torch.float16 数据类型来进一步节省内存。

import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_pretrained("stabilityai/stable-diffusion-3-medium-diffusers", torch_dtype=torch.float16)
pipe.to("cuda")

image = pipe(
    prompt="a photo of a cat holding a sign that says hello world",
    negative_prompt="",
    num_inference_steps=28,
    height=1024,
    width=1024,
    guidance_scale=7.0,
).images[0]

image.save("sd3_hello_world.png")

SD3 的内存优化

SD3 使用三个文本编码器,其中一个是 4.7B 参数的 T5-XXL 模型。 这使得在 VRAM 小于 24GB 的 GPU 上运行模型非常困难,即使使用 fp16 精度也是如此。 以下部分概述了 Diffusers 中的一些内存优化,可以更轻松地在低资源硬件上运行 SD3。

使用模型卸载运行推理

Diffusers 中提供的最基本的内存优化允许您在推理期间将模型的组件卸载到 CPU,以节省内存,同时推理延迟会略有增加。 模型卸载仅在需要执行模型组件时将其移动到 GPU,同时将其余组件保留在 CPU 上。

import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_pretrained("stabilityai/stable-diffusion-3-medium-diffusers", torch_dtype=torch.float16)
pipe.enable_model_cpu_offload()

image = pipe(
    prompt="a photo of a cat holding a sign that says hello world",
    negative_prompt="",
    num_inference_steps=28,
    height=1024,
    width=1024,
    guidance_scale=7.0,
).images[0]

image.save("sd3_hello_world.png")

在推理期间删除 T5 文本编码器

在推理期间删除内存密集型 4.7B 参数的 T5-XXL 文本编码器可以显着降低 SD3 的内存需求,同时性能略有下降。

import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_pretrained(
    "stabilityai/stable-diffusion-3-medium-diffusers",
    text_encoder_3=None,
    tokenizer_3=None,
    torch_dtype=torch.float16
)
pipe.to("cuda")

image = pipe(
    prompt="a photo of a cat holding a sign that says hello world",
    negative_prompt="",
    num_inference_steps=28,
    height=1024,
    width=1024,
    guidance_scale=7.0,
).images[0]

image.save("sd3_hello_world-no-T5.png")

使用 T5 文本编码器的量化版本

我们可以利用 bitsandbytes 库加载 T5-XXL 文本编码器并将其量化到 8 位精度。 这使您能够继续使用所有三个文本编码器,同时仅对性能产生轻微的影响。

首先安装 bitsandbytes 库。

pip install bitsandbytes

然后使用 BitsAndBytesConfig 加载 T5-XXL 模型。

import torch
from diffusers import StableDiffusion3Pipeline
from transformers import T5EncoderModel, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model_id = "stabilityai/stable-diffusion-3-medium-diffusers"
text_encoder = T5EncoderModel.from_pretrained(
    model_id,
    subfolder="text_encoder_3",
    quantization_config=quantization_config,
)
pipe = StableDiffusion3Pipeline.from_pretrained(
    model_id,
    text_encoder_3=text_encoder,
    device_map="balanced",
    torch_dtype=torch.float16
)

image = pipe(
    prompt="a photo of a cat holding a sign that says hello world",
    negative_prompt="",
    num_inference_steps=28,
    height=1024,
    width=1024,
    guidance_scale=7.0,
).images[0]

image.save("sd3_hello_world-8bit-T5.png")

您可以在 此处 找到端到端脚本。

SD3 的性能优化

使用 Torch Compile 加速推理

在 SD3 管道中使用编译后的组件可以将推理速度提高多达 4 倍。 以下代码片段演示了如何编译 SD3 管道的 Transformer 和 VAE 组件。

import torch
from diffusers import StableDiffusion3Pipeline

torch.set_float32_matmul_precision("high")

torch._inductor.config.conv_1x1_as_mm = True
torch._inductor.config.coordinate_descent_tuning = True
torch._inductor.config.epilogue_fusion = False
torch._inductor.config.coordinate_descent_check_all_directions = True

pipe = StableDiffusion3Pipeline.from_pretrained(
    "stabilityai/stable-diffusion-3-medium-diffusers",
    torch_dtype=torch.float16
).to("cuda")
pipe.set_progress_bar_config(disable=True)

pipe.transformer.to(memory_format=torch.channels_last)
pipe.vae.to(memory_format=torch.channels_last)

pipe.transformer = torch.compile(pipe.transformer, mode="max-autotune", fullgraph=True)
pipe.vae.decode = torch.compile(pipe.vae.decode, mode="max-autotune", fullgraph=True)

# Warm Up
prompt = "a photo of a cat holding a sign that says hello world"
for _ in range(3):
    _ = pipe(prompt=prompt, generator=torch.manual_seed(1))

# Run Inference
image = pipe(prompt=prompt, generator=torch.manual_seed(1)).images[0]
image.save("sd3_hello_world.png")

查看完整的脚本,请点击 此处

使用长提示符与 T5 文本编码器

默认情况下,T5 文本编码器提示符使用最大序列长度为 256。可以通过设置 max_sequence_length 来调整接受更少或更多 token。请注意,更长的序列需要更多资源,并导致更长的生成时间,例如在批量推理期间。

prompt = "A whimsical and creative image depicting a hybrid creature that is a mix of a waffle and a hippopotamus, basking in a river of melted butter amidst a breakfast-themed landscape. It features the distinctive, bulky body shape of a hippo. However, instead of the usual grey skin, the creature’s body resembles a golden-brown, crispy waffle fresh off the griddle. The skin is textured with the familiar grid pattern of a waffle, each square filled with a glistening sheen of syrup. The environment combines the natural habitat of a hippo with elements of a breakfast table setting, a river of warm, melted butter, with oversized utensils or plates peeking out from the lush, pancake-like foliage in the background, a towering pepper mill standing in for a tree.  As the sun rises in this fantastical world, it casts a warm, buttery glow over the scene. The creature, content in its butter river, lets out a yawn. Nearby, a flock of birds take flight"

image = pipe(
    prompt=prompt,
    negative_prompt="",
    num_inference_steps=28,
    guidance_scale=4.5,
    max_sequence_length=512,
).images[0]

发送不同的提示符到 T5 文本编码器

你可以发送不同的提示符到 CLIP 文本编码器和 T5 文本编码器,以防止提示符被 CLIP 文本编码器截断并改善生成。

使用 CLIP 文本编码器的提示符仍然会被截断到 77 个 token 的限制。

prompt = "A whimsical and creative image depicting a hybrid creature that is a mix of a waffle and a hippopotamus, basking in a river of melted butter amidst a breakfast-themed landscape. A river of warm, melted butter, pancake-like foliage in the background, a towering pepper mill standing in for a tree."

prompt_3 = "A whimsical and creative image depicting a hybrid creature that is a mix of a waffle and a hippopotamus, basking in a river of melted butter amidst a breakfast-themed landscape. It features the distinctive, bulky body shape of a hippo. However, instead of the usual grey skin, the creature’s body resembles a golden-brown, crispy waffle fresh off the griddle. The skin is textured with the familiar grid pattern of a waffle, each square filled with a glistening sheen of syrup. The environment combines the natural habitat of a hippo with elements of a breakfast table setting, a river of warm, melted butter, with oversized utensils or plates peeking out from the lush, pancake-like foliage in the background, a towering pepper mill standing in for a tree.  As the sun rises in this fantastical world, it casts a warm, buttery glow over the scene. The creature, content in its butter river, lets out a yawn. Nearby, a flock of birds take flight"

image = pipe(
    prompt=prompt,
    prompt_3=prompt_3,
    negative_prompt="",
    num_inference_steps=28,
    guidance_scale=4.5,
    max_sequence_length=512,
).images[0]

适用于 Stable Diffusion 3 的微型自动编码器

适用于 Stable Diffusion 的微型自动编码器 (TAESD3) 是 Ollin Boer Bohan 对 Stable Diffusion 3 的 VAE 进行的微型蒸馏版本,可以几乎瞬间解码 StableDiffusion3Pipeline 潜码。

与 Stable Diffusion 3 一起使用

import torch
from diffusers import StableDiffusion3Pipeline, AutoencoderTiny

pipe = StableDiffusion3Pipeline.from_pretrained(
    "stabilityai/stable-diffusion-3-medium-diffusers", torch_dtype=torch.float16
)
pipe.vae = AutoencoderTiny.from_pretrained("madebyollin/taesd3", torch_dtype=torch.float16)
pipe = pipe.to("cuda")

prompt = "slice of delicious New York-style berry cheesecake"
image = pipe(prompt, num_inference_steps=25).images[0]
image.save("cheesecake.png")

通过 from_single_file 加载原始检查点

SD3Transformer2DModelStableDiffusion3Pipeline 类支持通过 from_single_file 方法加载原始检查点。此方法允许你加载用于训练模型的原始检查点文件。

为 SD3Transformer2DModel 加载原始检查点

from diffusers import SD3Transformer2DModel

model = SD3Transformer2DModel.from_single_file("https://huggingface.co/stabilityai/stable-diffusion-3-medium/blob/main/sd3_medium.safetensors")

为 StableDiffusion3Pipeline 加载单个检查点

加载不含 T5 的单个文件检查点

import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_single_file(
    "https://huggingface.co/stabilityai/stable-diffusion-3-medium/blob/main/sd3_medium_incl_clips.safetensors",
    torch_dtype=torch.float16,
    text_encoder_3=None
)
pipe.enable_model_cpu_offload()

image = pipe("a picture of a cat holding a sign that says hello world").images[0]
image.save('sd3-single-file.png')

加载含 T5 的单个文件检查点

以下示例加载存储在 8 位浮点格式中的检查点,这需要 PyTorch 2.3 或更高版本。

import torch
from diffusers import StableDiffusion3Pipeline

pipe = StableDiffusion3Pipeline.from_single_file(
    "https://huggingface.co/stabilityai/stable-diffusion-3-medium/blob/main/sd3_medium_incl_clips_t5xxlfp8.safetensors",
    torch_dtype=torch.float16,
)
pipe.enable_model_cpu_offload()

image = pipe("a picture of a cat holding a sign that says hello world").images[0]
image.save('sd3-single-file-t5-fp8.png')

StableDiffusion3Pipeline

class diffusers.StableDiffusion3Pipeline

< >

( transformer: SD3Transformer2DModel scheduler: FlowMatchEulerDiscreteScheduler vae: AutoencoderKL text_encoder: CLIPTextModelWithProjection tokenizer: CLIPTokenizer text_encoder_2: CLIPTextModelWithProjection tokenizer_2: CLIPTokenizer text_encoder_3: T5EncoderModel tokenizer_3: T5TokenizerFast )

参数

  • transformer (SD3Transformer2DModel) — 用于对编码图像潜在变量进行降噪的条件Transformer (MMDiT) 架构。
  • scheduler (FlowMatchEulerDiscreteScheduler) — 与 transformer 配合使用的调度器,用于对编码图像潜在变量进行降噪。
  • vae (AutoencoderKL) — 用于将图像编码和解码到潜在表示形式的变分自编码器 (VAE) 模型。
  • text_encoder (CLIPTextModelWithProjection) — CLIP,特别是 clip-vit-large-patch14 变体,附加了额外的投影层,该层使用对角矩阵初始化,对角矩阵的维度为 hidden_size
  • text_encoder_2 (CLIPTextModelWithProjection) — CLIP,特别是 laion/CLIP-ViT-bigG-14-laion2B-39B-b160k 变体。
  • text_encoder_3 (T5EncoderModel) — 冻结的文本编码器。Stable Diffusion 3 使用 T5,特别是 t5-v1_1-xxl 变体。
  • tokenizer (CLIPTokenizer) — CLIPTokenizer 类的令牌生成器。
  • tokenizer_2 (CLIPTokenizer) — CLIPTokenizer 类的第二个令牌生成器。
  • tokenizer_3 (T5TokenizerFast) — T5Tokenizer 类的令牌生成器。

__call__

  • prompt (strList[str], 可选) — 用于引导图像生成的提示或提示列表。 如果未定义,则必须传递 prompt_embeds。 代替。
  • prompt_2 (strList[str], 可选) — 要发送到 tokenizer_2text_encoder_2 的提示或提示列表。 如果未定义,则将使用 prompt 代替
  • prompt_3 (strList[str], 可选) — 要发送到 tokenizer_3text_encoder_3 的提示或提示列表。 如果未定义,则将使用 prompt 代替
  • height (int, 可选, 默认为 self.unet.config.sample_size * self.vae_scale_factor) — 生成的图像的高度(以像素为单位)。 默认情况下,它设置为 1024 以获得最佳效果。
  • width (int, 可选, 默认为 self.unet.config.sample_size * self.vae_scale_factor) — 生成的图像的宽度(以像素为单位)。 默认情况下,它设置为 1024 以获得最佳效果。
  • num_inference_steps (int, 可选, 默认为 50) — 降噪步骤的数量。 更多的降噪步骤通常会导致更高质量的图像,但会降低推理速度。
  • timesteps (List[int], 可选) — 用于降噪过程的自定义时间步长,用于支持其 set_timesteps 方法中 timesteps 参数的调度器。 如果未定义,将使用在传递 num_inference_steps 时的默认行为。 必须按降序排列。
  • guidance_scale (float, 可选, 默认值为 7.0) — 如 Classifier-Free Diffusion Guidance 中定义的引导尺度。guidance_scale 定义为 Imagen 论文 中公式 2 的 w。通过设置 guidance_scale > 1 来启用引导尺度。较高的引导尺度鼓励生成与文本 prompt 紧密相关的图像,通常以降低图像质量为代价。
  • negative_prompt (strList[str], 可选) — 不引导图像生成的提示或提示。如果未定义,则必须传递 negative_prompt_embeds。当不使用引导时(即,当 guidance_scale 小于 1 时)会被忽略。
  • negative_prompt_2 (strList[str], 可选) — 要发送到 tokenizer_2text_encoder_2 的不引导图像生成的提示或提示。如果未定义,则使用 negative_prompt 代替
  • negative_prompt_3 (strList[str], 可选) — 要发送到 tokenizer_3text_encoder_3 的不引导图像生成的提示或提示。如果未定义,则使用 negative_prompt 代替
  • num_images_per_prompt (int, 可选, 默认值为 1) — 每个提示要生成的图像数量。
  • generator (torch.GeneratorList[torch.Generator], 可选) — 一个或多个 torch 生成器 以使生成确定性。
  • latents (torch.FloatTensor, 可选) — 预先生成的噪声潜伏,从高斯分布采样,用作图像生成的输入。可用于使用不同的提示调整相同的生成。如果未提供,则潜伏张量将通过使用提供的随机 generator 采样而生成。
  • prompt_embeds (torch.FloatTensor, 可选) — 预先生成的文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,文本嵌入将从 prompt 输入参数生成。
  • negative_prompt_embeds (torch.FloatTensor, 可选) — 预先生成的负文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,negative_prompt_embeds 将从 negative_prompt 输入参数生成。
  • pooled_prompt_embeds (torch.FloatTensor, 可选) — 预先生成的池化文本嵌入。可用于轻松调整文本输入,例如提示加权。如果未提供,池化文本嵌入将从 prompt 输入参数生成。
  • negative_pooled_prompt_embeds (torch.FloatTensor, 可选) — 预生成的负面 pooled 文本嵌入。 可用于轻松调整文本输入,例如提示权重。 如果未提供,则 pooled negative_prompt_embeds 将从 negative_prompt 输入参数生成。
  • output_type (str, 可选,默认为 "pil") — 生成的图像的输出格式。 在 PIL: PIL.Image.Imagenp.array 之间选择。
  • return_dict (bool, 可选,默认为 True) — 是否返回 ~pipelines.stable_diffusion_xl.StableDiffusionXLPipelineOutput 而不是普通元组。
  • joint_attention_kwargs (dict, 可选) — 如果指定,则传递给 AttentionProcessor 的 kwargs 字典,如 diffusers.models.attention_processor 中的 self.processor 所定义。
  • callback_on_step_end (Callable, 可选) — 在推理过程中每个去噪步骤结束时调用的函数。 该函数使用以下参数调用: callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int, callback_kwargs: Dict)callback_kwargs 将包含由 callback_on_step_end_tensor_inputs 指定的所有张量列表。
  • callback_on_step_end_tensor_inputs (List, 可选) — callback_on_step_end 函数的张量输入列表。 列表中指定的张量将作为 callback_kwargs 参数传递。 您只能在管道类 ._callback_tensor_inputs 属性中列出的变量。
  • max_sequence_length (int 默认为 256) — 与 prompt 一起使用的最大序列长度。

返回

~pipelines.stable_diffusion_3.StableDiffusion3PipelineOutputtuple

如果 return_dict 为 True,则为 ~pipelines.stable_diffusion_3.StableDiffusion3PipelineOutput,否则为 tuple。 当返回元组时,第一个元素是包含生成的图像的列表。

调用管道进行生成时调用的函数。

示例

>>> import torch
>>> from diffusers import StableDiffusion3Pipeline

>>> pipe = StableDiffusion3Pipeline.from_pretrained(
...     "stabilityai/stable-diffusion-3-medium-diffusers", torch_dtype=torch.float16
... )
>>> pipe.to("cuda")
>>> prompt = "A cat holding a sign that says hello world"
>>> image = pipe(prompt).images[0]
>>> image.save("sd3.png")

encode_prompt

< >

( prompt: Union prompt_2: Union prompt_3: Union device: Optional = None num_images_per_prompt: int = 1 do_classifier_free_guidance: bool = True negative_prompt: Union = None negative_prompt_2: Union = None negative_prompt_3: Union = None prompt_embeds: Optional = None negative_prompt_embeds: Optional = None pooled_prompt_embeds: Optional = None negative_pooled_prompt_embeds: Optional = None clip_skip: Optional = None max_sequence_length: int = 256 lora_scale: Optional = None )

参数

  • 提示 (strList[str], 可选) — 要编码的提示
  • prompt_2 (strList[str], 可选) — 要发送到 tokenizer_2text_encoder_2 的提示或提示。如果未定义,则在所有文本编码器中使用 prompt
  • prompt_3 (strList[str], 可选) — 要发送到 tokenizer_3text_encoder_3 的提示或提示。如果未定义,则在所有文本编码器中使用 prompt 设备 — (torch.device): torch 设备
  • 每个提示的图像数量 (int) — 每个提示应该生成的图像数量
  • 是否使用分类器自由引导 (bool) — 是否使用分类器自由引导
  • 负面提示 (strList[str], 可选) — 不指导图像生成的提示或提示。如果未定义,则必须改用 negative_prompt_embeds。当不使用引导时被忽略(即,如果 guidance_scale 小于 1,则被忽略)。
  • negative_prompt_2 (strList[str], 可选) — 要发送到 tokenizer_2text_encoder_2 的不指导图像生成的提示或提示。如果未定义,则在所有文本编码器中使用 negative_prompt
  • negative_prompt_2 (strList[str], 可选) — 要发送到 tokenizer_3text_encoder_3 的不指导图像生成的提示或提示。如果未定义,则在所有文本编码器中使用 negative_prompt
  • prompt_embeds (torch.FloatTensor, 可选) — 预生成的文本嵌入。可用于轻松调整文本输入,例如 提示权重。如果未提供,则将从 prompt 输入参数生成文本嵌入。
  • negative_prompt_embeds (torch.FloatTensor, 可选) — 预生成的负面文本嵌入。可用于轻松调整文本输入,例如 提示权重。如果未提供,则将从 negative_prompt 输入参数生成 negative_prompt_embeds。
  • negative_pooled_prompt_embeds (torch.FloatTensor, 可选) — 预生成的负文本嵌入池。 可以用来轻松调整文本输入,例如 提示权重。 如果未提供,将从negative_prompt输入参数生成 pooled negative_prompt_embeds。
  • clip_skip (int, 可选) — 在计算提示嵌入时,从 CLIP 跳过的层数。 值为 1 表示将使用倒数第二层的输出来计算提示嵌入。
  • lora_scale (float, 可选) — 如果加载了 LoRA 层,则将应用于文本编码器所有 LoRA 层的 lora 比例。
< > 在 GitHub 上更新