Diffusers 文档

快速入门

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

快速入门

扩散模型经过训练,可以逐步去噪随机高斯噪声,从而生成感兴趣的样本,例如图像或音频。这引发了人们对生成式 AI 的极大兴趣,您可能已经在互联网上看到过扩散生成的图像示例。 🧨 Diffusers 是一个旨在使所有人都能广泛访问扩散模型的库。

无论您是开发者还是日常用户,这个快速入门都将向您介绍 🧨 Diffusers,并帮助您快速上手并开始生成!该库有三个主要组成部分需要了解:

  • DiffusionPipeline 是一个高级端到端类,旨在从预训练的扩散模型中快速生成用于推理的样本。
  • 流行的预训练模型架构和模块,可以用作创建扩散系统的构建块。
  • 许多不同的 schedulers - 控制如何添加噪声进行训练,以及如何在推理过程中生成去噪图像的算法。

快速入门将向您展示如何使用 DiffusionPipeline 进行推理,然后引导您了解如何组合模型和 scheduler 以复制 DiffusionPipeline 内部发生的事情。

快速入门是 🧨 Diffusers 入门 notebook 的简化版本,旨在帮助您快速开始。如果您想了解更多关于 🧨 Diffusers 的目标、设计理念以及其核心 API 的更多细节,请查看 notebook!

在开始之前,请确保您已安装所有必要的库:

# uncomment to install the necessary libraries in Colab
#!pip install --upgrade diffusers accelerate transformers

DiffusionPipeline

DiffusionPipeline 是使用预训练扩散系统进行推理的最简单方法。它是一个包含模型和 scheduler 的端到端系统。您可以开箱即用地使用 DiffusionPipeline 来完成许多任务。查看下表了解一些支持的任务,有关支持任务的完整列表,请查看 🧨 Diffusers 摘要 表。

任务 描述 Pipeline
无条件图像生成 从高斯噪声生成图像 unconditional_image_generation
文本引导的图像生成 根据文本提示生成图像 conditional_image_generation
文本引导的图像到图像转换 在文本提示的引导下调整图像 img2img
文本引导的图像修复 填充图像的蒙版部分,给定图像、蒙版和文本提示 inpaint
文本引导的深度到图像转换 在文本提示的引导下调整图像的各个部分,同时通过深度估计保留结构 depth2img

首先创建一个 DiffusionPipeline 实例,并指定您要下载的 pipeline 检查点。您可以将 DiffusionPipeline 用于 Hugging Face Hub 上存储的任何 检查点。在本快速入门中,您将加载 stable-diffusion-v1-5 检查点用于文本到图像的生成。

对于 Stable Diffusion 模型,在运行模型之前,请仔细阅读 许可证。 🧨 Diffusers 实现了 safety_checker 以防止冒犯性或有害内容,但该模型改进的图像生成能力仍然可能产生有害内容。

使用 from_pretrained() 方法加载模型

>>> from diffusers import DiffusionPipeline

>>> pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", use_safetensors=True)

DiffusionPipeline 下载并缓存所有建模、分词和调度组件。您将看到 Stable Diffusion pipeline 由 UNet2DConditionModelPNDMScheduler 以及其他组件组成。

>>> pipeline
StableDiffusionPipeline {
  "_class_name": "StableDiffusionPipeline",
  "_diffusers_version": "0.21.4",
  ...,
  "scheduler": [
    "diffusers",
    "PNDMScheduler"
  ],
  ...,
  "unet": [
    "diffusers",
    "UNet2DConditionModel"
  ],
  "vae": [
    "diffusers",
    "AutoencoderKL"
  ]
}

我们强烈建议在 GPU 上运行 pipeline,因为该模型大约包含 14 亿个参数。您可以像在 PyTorch 中一样将生成器对象移动到 GPU。

>>> pipeline.to("cuda")

现在您可以将文本 prompt 传递给 pipeline 以生成图像,然后访问去噪后的图像。默认情况下,图像输出包装在 PIL.Image 对象中。

>>> image = pipeline("An image of a squirrel in Picasso style").images[0]
>>> image

通过调用 save 保存图像

>>> image.save("image_of_squirrel_painting.png")

本地 pipeline

您也可以在本地使用 pipeline。唯一的区别是您需要先下载权重。

!git lfs install
!git clone https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5

然后将保存的权重加载到 pipeline 中。

>>> pipeline = DiffusionPipeline.from_pretrained("./stable-diffusion-v1-5", use_safetensors=True)

现在,您可以像在上面部分中一样运行 pipeline。

更换 schedulers

不同的 schedulers 具有不同的去噪速度和质量权衡。找出最适合您的 scheduler 的最佳方法是亲自尝试! 🧨 Diffusers 的主要功能之一是允许您轻松切换 schedulers。例如,要将默认的 PNDMScheduler 替换为 EulerDiscreteScheduler,请使用 from_config() 方法加载它。

>>> from diffusers import EulerDiscreteScheduler

>>> pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", use_safetensors=True)
>>> pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)

尝试使用新的 scheduler 生成图像,看看您是否注意到差异!

在下一节中,您将仔细查看构成 DiffusionPipeline 的组件 - 模型和 scheduler - 并学习如何使用这些组件生成猫的图像。

模型

大多数模型接受一个噪声样本,并在每个时间步预测噪声残差(其他模型学习直接预测先前的样本或速度或 v-prediction),即噪声较小的图像与输入图像之间的差异。您可以混合和匹配模型以创建其他扩散系统。

模型使用 from_pretrained() 方法初始化,该方法还会本地缓存模型权重,以便下次加载模型时更快。对于快速入门,您将加载 UNet2DModel,这是一个基本的无条件图像生成模型,其检查点在猫图像上训练。

>>> from diffusers import UNet2DModel

>>> repo_id = "google/ddpm-cat-256"
>>> model = UNet2DModel.from_pretrained(repo_id, use_safetensors=True)

要访问模型参数,请调用 model.config

>>> model.config

模型配置是一个 🧊 冻结 🧊 字典,这意味着这些参数在模型创建后无法更改。这是故意的,并确保用于定义模型架构的参数从一开始就保持不变,而其他参数仍然可以在推理期间进行调整。

一些最重要的参数是:

  • sample_size:输入样本的高度和宽度尺寸。
  • in_channels:输入样本的输入通道数。
  • down_block_typesup_block_types:用于创建 UNet 架构的下采样和上采样块的类型。
  • block_out_channels:下采样块的输出通道数;也以相反的顺序用于上采样块的输入通道数。
  • layers_per_block:每个 UNet 块中存在的 ResNet 块的数量。

要将模型用于推理,请使用随机高斯噪声创建图像形状。它应该具有 batch 轴(因为模型可以接收多个随机噪声)、对应于输入通道数的 channel 轴,以及用于图像高度和宽度的 sample_size 轴。

>>> import torch

>>> torch.manual_seed(0)

>>> noisy_sample = torch.randn(1, model.config.in_channels, model.config.sample_size, model.config.sample_size)
>>> noisy_sample.shape
torch.Size([1, 3, 256, 256])

对于推理,将噪声图像和 timestep 传递给模型。 timestep 指示输入图像的噪声程度,开始时噪声较多,结束时噪声较少。这有助于模型确定其在扩散过程中的位置,是更接近开始还是结束。使用 sample 方法获取模型输出。

>>> with torch.no_grad():
...     noisy_residual = model(sample=noisy_sample, timestep=2).sample

要生成实际示例,您需要一个 scheduler 来引导去噪过程。在下一节中,您将学习如何将模型与 scheduler 耦合。

调度器

调度器管理如何从一个带噪样本,根据模型输出(在本例中为 noisy_residual),生成一个噪声较少的样本。

🧨 Diffusers 是一个用于构建扩散系统的工具箱。虽然 DiffusionPipeline 是开始使用预构建扩散系统的便捷方式,但您也可以选择自己的模型和调度器组件,分别构建自定义的扩散系统。

对于快速入门,您将使用 DDPMScheduler 及其 from_config() 方法来实例化它。

>>> from diffusers import DDPMScheduler

>>> scheduler = DDPMScheduler.from_pretrained(repo_id)
>>> scheduler
DDPMScheduler {
  "_class_name": "DDPMScheduler",
  "_diffusers_version": "0.21.4",
  "beta_end": 0.02,
  "beta_schedule": "linear",
  "beta_start": 0.0001,
  "clip_sample": true,
  "clip_sample_range": 1.0,
  "dynamic_thresholding_ratio": 0.995,
  "num_train_timesteps": 1000,
  "prediction_type": "epsilon",
  "sample_max_value": 1.0,
  "steps_offset": 0,
  "thresholding": false,
  "timestep_spacing": "leading",
  "trained_betas": null,
  "variance_type": "fixed_small"
}

💡 与模型不同,调度器没有可训练的权重,并且是无参数的!

一些最重要的参数是:

  • num_train_timesteps:去噪过程的长度,或者换句话说,将随机高斯噪声处理成数据样本所需的步数。
  • beta_schedule:用于推理和训练的噪声计划类型。
  • beta_startbeta_end:噪声计划的起始和结束噪声值。

要预测噪声稍少的图像,请将以下内容传递给调度器的 step() 方法:模型输出、timestep 和当前 sample

>>> less_noisy_sample = scheduler.step(model_output=noisy_residual, timestep=2, sample=noisy_sample).prev_sample
>>> less_noisy_sample.shape
torch.Size([1, 3, 256, 256])

less_noisy_sample 可以传递到下一个 timestep,在那里它会变得噪声更少!现在让我们将它们放在一起,可视化整个去噪过程。

首先,创建一个函数,该函数后处理去噪图像并将其显示为 PIL.Image

>>> import PIL.Image
>>> import numpy as np


>>> def display_sample(sample, i):
...     image_processed = sample.cpu().permute(0, 2, 3, 1)
...     image_processed = (image_processed + 1.0) * 127.5
...     image_processed = image_processed.numpy().astype(np.uint8)

...     image_pil = PIL.Image.fromarray(image_processed[0])
...     display(f"Image at step {i}")
...     display(image_pil)

为了加速去噪过程,将输入和模型移动到 GPU

>>> model.to("cuda")
>>> noisy_sample = noisy_sample.to("cuda")

现在创建一个去噪循环,该循环预测噪声较少样本的残差,并使用调度器计算噪声较少的样本

>>> import tqdm

>>> sample = noisy_sample

>>> for i, t in enumerate(tqdm.tqdm(scheduler.timesteps)):
...     # 1. predict noise residual
...     with torch.no_grad():
...         residual = model(sample, t).sample

...     # 2. compute less noisy image and set x_t -> x_t-1
...     sample = scheduler.step(residual, t, sample).prev_sample

...     # 3. optionally look at image
...     if (i + 1) % 50 == 0:
...         display_sample(sample, i + 1)

坐下来观看从纯粹的噪声中生成一只猫! 😻

下一步

希望您在这个快速入门中通过 🧨 Diffusers 生成了一些很酷的图像!接下来,您可以:

< > 在 GitHub 上更新