扩散模型课程文档

🤗 Diffusers 简介

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

Open In Colab

🤗 Diffusers 简介

diffusers_library

在本 notebook 中,你将训练你的第一个 diffusion 模型来 生成可爱的蝴蝶图片🦋。在此过程中,你将学习 🤗 Diffusers 库的核心组件,这将为我们稍后在课程中将要介绍的更高级应用打下良好基础。

让我们深入了解!

你将学到什么

在本 notebook 中你将:

  • 看到一个强大的自定义 diffusion 模型 pipeline 的实际操作(并了解如何制作你自己的版本)
  • 通过以下步骤创建你自己的迷你 pipeline:
    • 回顾 diffusion 模型背后的核心思想
    • 从 Hub 加载数据用于训练
    • 探索我们如何使用 scheduler 为这些数据添加噪声
    • 创建和训练 UNet 模型
    • 将各个部分组合成一个可工作的 pipeline
  • 编辑并运行一个用于初始化更长训练任务的脚本,该脚本将处理:
    • 通过 🤗 Accelerate 进行多 GPU 训练
    • 实验日志记录以跟踪关键统计数据
    • 将最终模型上传到 Hugging Face Hub

❓如果你有任何问题,请在 Hugging Face Discord 服务器的 #diffusion-models-class 频道中提出。如果你还没有注册,可以在这里注册:https://huggingface.co/join/discord

先决条件

在深入研究本 notebook 之前,你应该:

  • 📖 阅读第 1 单元的材料
  • 🤗 在 Hugging Face Hub 上创建一个账户。如果你还没有账户,可以在这里创建:https://huggingface.co/join

第 1 步:设置

运行以下单元格以安装 diffusers 库以及其他一些依赖项

%pip install -qq -U diffusers datasets transformers accelerate ftfy pyarrow==9.0.0

接下来,访问 https://huggingface.co/settings/tokens 并创建一个具有写入权限的访问令牌(如果你还没有的话)

Screenshot from 2022-11-10 12-23-34.png

你可以使用命令行 (huggingface-cli login) 或运行以下单元格来使用此令牌登录

>>> from huggingface_hub import notebook_login

>>> notebook_login()
Login successful
Your token has been saved to /root/.huggingface/token

然后您需要安装 Git-LFS 才能上传您的模型检查点

%%capture
!sudo apt -qq install git-lfs
!git config --global credential.helper store

最后,让我们导入将要使用的库,并定义一些方便的函数,我们将在 notebook 的后面部分使用它们

import numpy as np
import torch
import torch.nn.functional as F
from matplotlib import pyplot as plt
from PIL import Image


def show_images(x):
    """Given a batch of images x, make a grid and convert to PIL"""
    x = x * 0.5 + 0.5  # Map from (-1, 1) back to (0, 1)
    grid = torchvision.utils.make_grid(x)
    grid_im = grid.detach().cpu().permute(1, 2, 0).clip(0, 1) * 255
    grid_im = Image.fromarray(np.array(grid_im).astype(np.uint8))
    return grid_im


def make_grid(images, size=64):
    """Given a list of PIL images, stack them together into a line for easy viewing"""
    output_im = Image.new("RGB", (size * len(images), size))
    for i, im in enumerate(images):
        output_im.paste(im.resize((size, size)), (i * size, 0))
    return output_im


# Mac users may need device = 'mps' (untested)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

好的,我们都准备好了!

Dreambooth: 抢先一睹未来

如果你在过去几个月里关注过任何与人工智能相关的社交媒体,你一定听说过 Stable Diffusion。它是一个强大的文本条件潜在 diffusion 模型(别担心,我们将会学习所有这些术语的含义)。但它有一个缺点:除非我们足够出名,我们的照片遍布互联网,否则它不知道你我长什么样。

Dreambooth 让我们能够创建我们自己的模型变体,使其对特定的人脸、物体或风格有额外的了解。Corridor Crew 制作了一个出色的视频,使用这项技术来讲述具有一致角色的故事,这是这项技术能做什么的一个很好的例子。

>>> from IPython.display import YouTubeVideo

>>> YouTubeVideo("W4Mcuh38wyM")

这是一个使用在一个名为“土豆头先生”的流行儿童玩具的 5 张照片上训练的模型的例子。

首先,我们加载 pipeline。这将从 Hub 下载模型权重等。由于这将为一个单行演示下载数 GB 的数据,欢迎你跳过此单元格,只欣赏示例输出!

from diffusers import StableDiffusionPipeline

# Check out https://huggingface.co/sd-dreambooth-library for loads of models from the community
model_id = "sd-dreambooth-library/mr-potato-head"

# Load the pipeline
pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16).to(device)

一旦 pipeline 加载完成,我们就可以生成图像

>>> prompt = "an abstract oil painting of sks mr potato head by picasso"
>>> image = pipe(prompt, num_inference_steps=50, guidance_scale=7.5).images[0]
>>> image

练习: 尝试使用不同的提示词自己动手试试。sks 标记在这里代表新概念的唯一标识符——如果省略它会发生什么?你也可以尝试改变采样步数(可以设置多低?)和 guidance_scale,它决定了模型将多大程度上尝试匹配提示词。

那个神奇的 pipeline 中发生了很多事情!到课程结束时,你将了解这一切是如何工作的。现在,让我们来看看如何从头开始训练一个 diffusion 模型。

MVP (最小可行 Pipeline)

🤗 Diffusers 的核心 API 分为三个主要组件

  1. Pipelines: 高级类,旨在以用户友好的方式从流行的已训练 diffusion 模型中快速生成样本。
  2. Models: 用于训练新 diffusion 模型的流行架构,例如 UNet
  3. Schedulers: 在*推理*期间从噪声生成图像以及为*训练*生成噪声图像的各种技术。

Pipelines 对最终用户来说非常棒,但如果你来这里参加这门课程,我们假设你想知道幕后发生了什么!所以,在本 notebook 的其余部分,我们将构建我们自己的 pipeline,能够生成小的蝴蝶图片。这是最终结果的演示:

>>> from diffusers import DDPMPipeline

>>> # Load the butterfly pipeline
>>> butterfly_pipeline = DDPMPipeline.from_pretrained("johnowhitaker/ddpm-butterflies-32px").to(device)

>>> # Create 8 images
>>> images = butterfly_pipeline(batch_size=8).images

>>> # View the result
>>> make_grid(images)

也许没有 DreamBooth 示例那么令人印象深刻,但我们是从头开始训练,使用的数据量大约是训练 Stable Diffusion 的 0.0001%。说到训练,回想一下本单元的介绍,训练一个 diffusion 模型大致如下:

  1. 从训练数据中加载一些图像
  2. 添加不同程度的噪声。
  3. 将输入的噪声版本输入模型
  4. 评估模型在去噪这些输入方面的表现如何
  5. 利用这些信息更新模型权重,然后重复

我们将在接下来的几节中逐一探讨这些步骤,直到我们有一个完整的训练循环工作,然后我们将探讨如何从训练好的模型中采样,以及如何将所有东西打包成一个 pipeline 以便轻松分享。让我们从数据开始……

第 2 步:下载训练数据集

对于这个例子,我们将使用 Hugging Face Hub 上的一个图像数据集。具体来说,是这个包含 1000 张蝴蝶图片的集合。这是一个非常小的数据集,所以我们也包括了一些更大选项的注释代码行。如果你更喜欢使用自己的图像集合,也可以使用注释掉的代码示例来从文件夹加载图片。

import torchvision
from datasets import load_dataset
from torchvision import transforms

dataset = load_dataset("huggan/smithsonian_butterflies_subset", split="train")

# Or load images from a local folder
# dataset = load_dataset("imagefolder", data_dir="path/to/folder")

# We'll train on 32-pixel square images, but you can try larger sizes too
image_size = 32
# You can lower your batch size if you're running out of GPU memory
batch_size = 64

# Define data augmentations
preprocess = transforms.Compose(
    [
        transforms.Resize((image_size, image_size)),  # Resize
        transforms.RandomHorizontalFlip(),  # Randomly flip (data augmentation)
        transforms.ToTensor(),  # Convert to tensor (0, 1)
        transforms.Normalize([0.5], [0.5]),  # Map to (-1, 1)
    ]
)


def transform(examples):
    images = [preprocess(image.convert("RGB")) for image in examples["image"]]
    return {"images": images}


dataset.set_transform(transform)

# Create a dataloader from the dataset to serve up the transformed images in batches
train_dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True)

我们可以抓取一批图像并像这样查看其中的一些

>>> xb = next(iter(train_dataloader))["images"].to(device)[:8]
>>> print("X shape:", xb.shape)
>>> show_images(xb).resize((8 * 64, 64), resample=Image.NEAREST)
X shape: torch.Size([8, 3, 32, 32])

我们坚持使用一个包含 32 像素图像的小数据集,以使本 notebook 中的训练时间可控。

第 3 步:定义 Scheduler

我们的训练计划是获取这些输入图像并向其添加噪声,然后将噪声图像输入模型。在推理过程中,我们将使用模型的预测来迭代地去除噪声。在 diffusers 中,这两个过程都由 scheduler 处理。

噪声调度决定了在不同时间步长添加多少噪声。以下是我们如何使用“DDPM”训练和采样的默认设置创建一个 scheduler(基于论文 “Denoising Diffusion Probabilistic Models”

from diffusers import DDPMScheduler

noise_scheduler = DDPMScheduler(num_train_timesteps=1000)

DDPM 论文描述了一个在每个“时间步”添加少量噪声的破坏过程。给定某个时间步的 $x_{t-1}$,我们可以通过以下方式得到下一个(稍微更嘈杂的)版本 $x_t$

$q(\mathbf{x}t \vert \mathbf{x}{t-1}) = \mathcal{N}(\mathbf{x}t; \sqrt{1 - \beta_t} \mathbf{x}{t-1}, \betat\mathbf{I}) \quad q(\mathbf{x}{1:T} \vert \mathbf{x}0) = \prod^T{t=1} q(\mathbf{x}t \vert \mathbf{x}{t-1})$

也就是说,我们取 $x{t-1}$,将其乘以 $\sqrt{1 - \beta_t}$ 并加上乘以 $\beta_t$ 的噪声。这个 $\beta$ 是根据某个调度为每个 t 定义的,并决定了每个时间步添加多少噪声。现在,我们不一定想做这个操作 500 次来得到 $x{500}$,所以我们有另一个公式来在给定 $x_0$ 的情况下得到任意 t 的 $x_t$

$\begin{aligned} q(\mathbf{x}t \vert \mathbf{x}_0) &= \mathcal{N}(\mathbf{x}_t; \sqrt{\bar{\alpha}_t} \mathbf{x}_0, {(1 - \bar{\alpha}_t)} \mathbf{I}) \end{aligned}$ 其中 $\bar{\alpha}_t = \prod{i=1}^T \alpha_i$ 且 $\alpha_i = 1-\beta_i$

数学符号总是看起来很吓人!幸运的是,scheduler 为我们处理了所有这些。我们可以绘制 $\sqrt{\bar{\alpha}_t}$ (标记为 sqrt_alpha_prod) 和 $\sqrt{(1 - \bar{\alpha}_t)}$ (标记为 sqrt_one_minus_alpha_prod) 来查看输入 (x) 和噪声在不同时间步是如何缩放和混合的

>>> plt.plot(noise_scheduler.alphas_cumprod.cpu() ** 0.5, label=r"${\sqrt{\bar{\alpha}_t}}$")
>>> plt.plot((1 - noise_scheduler.alphas_cumprod.cpu()) ** 0.5, label=r"$\sqrt{(1 - \bar{\alpha}_t)}$")
>>> plt.legend(fontsize="x-large")

练习: 你可以通过在此处替换为注释掉的选项之一,来探索此图如何随 beta_start、beta_end 和 beta_schedule 的不同设置而变化

# One with too little noise added:
# noise_scheduler = DDPMScheduler(num_train_timesteps=1000, beta_start=0.001, beta_end=0.004)
# The 'cosine' schedule, which may be better for small image sizes:
# noise_scheduler = DDPMScheduler(num_train_timesteps=1000, beta_schedule='squaredcos_cap_v2')

无论你选择哪个 scheduler,我们现在都可以使用 noise_scheduler.add_noise 函数来添加不同数量的噪声,如下所示

>>> timesteps = torch.linspace(0, 999, 8).long().to(device)
>>> noise = torch.randn_like(xb)
>>> noisy_xb = noise_scheduler.add_noise(xb, noise, timesteps)
>>> print("Noisy X shape", noisy_xb.shape)
>>> show_images(noisy_xb).resize((8 * 64, 64), resample=Image.NEAREST)
Noisy X shape torch.Size([8, 3, 32, 32])

再次强调,请在这里探索使用不同噪声调度和参数的效果。这个视频 非常好地更详细地解释了上面的一些数学知识,并且是对其中一些概念的极好介绍。

第 4 步:定义模型

现在我们来到了核心组件:模型本身。

大多数 diffusion 模型使用的架构都是 U-net 的某种变体,我们这里也将使用它。

简而言之

  • 模型让输入图像通过几个 ResNet 层的块,每个块都将图像尺寸减半
  • 然后通过相同数量的块再次将其上采样。
  • 存在将下采样路径上的特征连接到上采样路径中相应层的跳跃连接。

该模型的一个关键特征是它预测的图像大小与输入相同,这正是我们这里所需要的。

Diffusers 为我们提供了一个方便的 UNet2DModel 类,它可以在 PyTorch 中创建所需的架构。

让我们为我们期望的图像大小创建一个 U-net。请注意,down_block_types 对应于下采样块(上图中的绿色部分),而 up_block_types 是上采样块(图中的红色部分)

from diffusers import UNet2DModel

# Create a model
model = UNet2DModel(
    sample_size=image_size,  # the target image resolution
    in_channels=3,  # the number of input channels, 3 for RGB images
    out_channels=3,  # the number of output channels
    layers_per_block=2,  # how many ResNet layers to use per UNet block
    block_out_channels=(64, 128, 128, 256),  # More channels -> more parameters
    down_block_types=(
        "DownBlock2D",  # a regular ResNet downsampling block
        "DownBlock2D",
        "AttnDownBlock2D",  # a ResNet downsampling block with spatial self-attention
        "AttnDownBlock2D",
    ),
    up_block_types=(
        "AttnUpBlock2D",
        "AttnUpBlock2D",  # a ResNet upsampling block with spatial self-attention
        "UpBlock2D",
        "UpBlock2D",  # a regular ResNet upsampling block
    ),
)
model.to(device)

在处理更高分辨率的输入时,你可能需要使用更多的下采样和上采样块,并将注意力层仅保留在最低分辨率(底部)层,以减少内存使用。我们稍后将讨论如何通过实验找到最适合你用例的设置。

我们可以检查传入一批数据和一些随机时间步是否能产生与输入数据形状相同的输出

with torch.no_grad():
    model_prediction = model(noisy_xb, timesteps).sample
model_prediction.shape

在下一节中,我们将看到如何训练这个模型。

第 5 步:创建训练循环

是时候训练了!下面是 PyTorch 中一个典型的优化循环,我们逐批处理数据,并在每一步使用优化器(在这里是学习率为 0.0004 的 AdamW 优化器)更新模型的参数。

对于每一批数据,我们:

  • 采样一些随机时间步
  • 相应地给数据加噪声
  • 将加噪数据输入模型
  • 使用均方误差作为我们的损失函数,将模型预测与目标(在这里是噪声)进行比较
  • 通过 loss.backward()optimizer.step() 更新模型参数

在此过程中,我们还记录了损失随时间的变化,以便稍后绘图。

注意:此代码运行近 10 分钟——如果你赶时间,可以随意跳过这两个单元格并使用预训练模型。或者,你可以通过上面模型定义减少每层通道数来探索如何加快速度。

官方 diffusers 训练示例 在这个数据集上以更高分辨率训练了一个更大的模型,对于想了解一个不那么简化的训练循环是什么样子的,这是一个很好的参考。

>>> # Set the noise scheduler
>>> noise_scheduler = DDPMScheduler(num_train_timesteps=1000, beta_schedule="squaredcos_cap_v2")

>>> # Training loop
>>> optimizer = torch.optim.AdamW(model.parameters(), lr=4e-4)

>>> losses = []

>>> for epoch in range(30):
...     for step, batch in enumerate(train_dataloader):
...         clean_images = batch["images"].to(device)
...         # Sample noise to add to the images
...         noise = torch.randn(clean_images.shape).to(clean_images.device)
...         bs = clean_images.shape[0]

...         # Sample a random timestep for each image
...         timesteps = torch.randint(0, noise_scheduler.num_train_timesteps, (bs,), device=clean_images.device).long()

...         # Add noise to the clean images according to the noise magnitude at each timestep
...         noisy_images = noise_scheduler.add_noise(clean_images, noise, timesteps)

...         # Get the model prediction
...         noise_pred = model(noisy_images, timesteps, return_dict=False)[0]

...         # Calculate the loss
...         loss = F.mse_loss(noise_pred, noise)
...         loss.backward(loss)
...         losses.append(loss.item())

...         # Update the model parameters with the optimizer
...         optimizer.step()
...         optimizer.zero_grad()

...     if (epoch + 1) % 5 == 0:
...         loss_last_epoch = sum(losses[-len(train_dataloader) :]) / len(train_dataloader)
...         print(f"Epoch:{epoch+1}, loss: {loss_last_epoch}")
Epoch:5, loss: 0.16273280512541533
Epoch:10, loss: 0.11161588924005628
Epoch:15, loss: 0.10206522420048714
Epoch:20, loss: 0.08302505919709802
Epoch:25, loss: 0.07805309211835265
Epoch:30, loss: 0.07474562455900013

绘制损失图,我们看到模型在初期迅速改善,然后以较慢的速度继续变好(如果我们使用对数刻度,如右图所示,则更明显)

>>> fig, axs = plt.subplots(1, 2, figsize=(12, 4))
>>> axs[0].plot(losses)
>>> axs[1].plot(np.log(losses))
>>> plt.show()

作为运行上述训练代码的替代方案,你可以像这样使用 pipeline 中的模型

# Uncomment to instead load the model I trained earlier:
# model = butterfly_pipeline.unet

第 6 步:生成图像

我们如何用这个模型生成图像?

选项 1:创建一个 pipeline:

from diffusers import DDPMPipeline

image_pipe = DDPMPipeline(unet=model, scheduler=noise_scheduler)
>>> pipeline_output = image_pipe()
>>> pipeline_output.images[0]

我们可以像这样将 pipeline 保存到本地文件夹

image_pipe.save_pretrained("my_pipeline")

检查文件夹内容

>>> !ls my_pipeline/
model_index.json  scheduler  unet

schedulerunet 子文件夹包含重新创建这些组件所需的一切。例如,在 unet 文件夹内,你会找到模型权重(diffusion_pytorch_model.bin)以及一个指定 UNet 架构的配置文件。

>>> !ls my_pipeline/unet/
config.json  diffusion_pytorch_model.bin

总而言之,这些文件包含了重新创建 pipeline 所需的一切。你可以手动将它们上传到 hub 与他人分享 pipeline,或者在下一节中查看通过 API 执行此操作的代码。

选项 2:编写采样循环

如果你检查 pipeline 的 forward 方法,你就能看到运行 image_pipe() 时发生了什么

# ??image_pipe.forward

我们从随机噪声开始,按从最多噪声到最少噪声的顺序遍历 scheduler 的时间步,每一步根据模型预测去除少量噪声

>>> # Random starting point (8 random images):
>>> sample = torch.randn(8, 3, 32, 32).to(device)

>>> for i, t in enumerate(noise_scheduler.timesteps):

...     # Get model pred
...     with torch.no_grad():
...         residual = model(sample, t).sample

...     # Update sample with step
...     sample = noise_scheduler.step(residual, t, sample).prev_sample

>>> show_images(sample)

noise_scheduler.step() 函数执行了适当更新 sample 所需的数学运算。有许多采样方法——在下一个单元中,我们将看到如何通过更换不同的采样器来加速现有模型的图像生成,并更多地讨论从 diffusion 模型中采样的理论。

第 7 步:将你的模型推送到 Hub

在上面的例子中,我们将我们的 pipeline 保存到了一个本地文件夹。要将我们的模型推送到 Hub,我们需要一个模型仓库来推送我们的文件。我们将根据我们想给模型的模型 ID 来确定仓库名称(你可以随意用自己的选择替换 model_name;它只需要包含你的用户名,这正是函数 get_full_repo_name() 所做的)

from huggingface_hub import get_full_repo_name

model_name = "sd-class-butterflies-32"
hub_model_id = get_full_repo_name(model_name)
hub_model_id

接下来,在 🤗 Hub 上创建一个模型仓库并推送我们的模型

from huggingface_hub import HfApi, create_repo

create_repo(hub_model_id)
api = HfApi()
api.upload_folder(folder_path="my_pipeline/scheduler", path_in_repo="", repo_id=hub_model_id)
api.upload_folder(folder_path="my_pipeline/unet", path_in_repo="", repo_id=hub_model_id)
api.upload_file(
    path_or_fileobj="my_pipeline/model_index.json",
    path_in_repo="model_index.json",
    repo_id=hub_model_id,
)

最后要做的是创建一个漂亮的模型卡片,这样我们的蝴蝶生成器就能在 Hub 上被轻松找到(随意扩展和编辑描述!)

from huggingface_hub import ModelCard

content = f"""
---
license: mit
tags:
- pytorch
- diffusers
- unconditional-image-generation
- diffusion-models-class
---

# Model Card for Unit 1 of the [Diffusion Models Class 🧨](https://github.com/huggingface/diffusion-models-class)

This model is a diffusion model for unconditional image generation of cute 🦋.

## Usage

```python
from diffusers import DDPMPipeline

pipeline = DDPMPipeline.from_pretrained('{hub_model_id}')
image = pipeline().images[0]
image

"""

card = ModelCard(content) card.push_to_hub(hub_model_id)


Now that the model is on the Hub, you can download it from anywhere by using the `from_pretrained()` method of the `DDPMPipeline` as follows"

```python
>>> from diffusers import DDPMPipeline

>>> image_pipe = DDPMPipeline.from_pretrained(hub_model_id)
>>> pipeline_output = image_pipe()
>>> pipeline_output.images[0]

太好了,它能工作!

使用 🤗 Accelerate 进行扩展

本 notebook 是为了学习目的而制作的,因此我尽量保持代码的最小化和整洁。因此,我们省略了一些你可能需要的东西,比如如果你要尝试在更多数据上训练一个更大的模型,例如多 GPU 支持、进度和示例图像的日志记录、支持更大批量的梯度检查点、自动上传模型等等。幸运的是,大多数这些功能都可以在这里的示例训练脚本中找到。

你可以像这样下载文件

!wget https://github.com/huggingface/diffusers/raw/main/examples/unconditional_image_generation/train_unconditional.py

打开文件,你会看到模型的定义位置以及可用的设置。我用以下命令运行了该脚本

# Let's give our new model a name for the Hub
model_name = "sd-class-butterflies-64"
hub_model_id = get_full_repo_name(model_name)
hub_model_id
!accelerate launch train_unconditional.py \
  --dataset_name="huggan/smithsonian_butterflies_subset" \
  --resolution=64 \
  --output_dir={model_name} \
  --train_batch_size=32 \
  --num_epochs=50 \
  --gradient_accumulation_steps=1 \
  --learning_rate=1e-4 \
  --lr_warmup_steps=500 \
  --mixed_precision="no"

和之前一样,让我们将模型推送到 Hub 并创建一个漂亮的模型卡片(并随意根据你的意愿编辑它!)

create_repo(hub_model_id)
api = HfApi()
api.upload_folder(folder_path=f"{model_name}/scheduler", path_in_repo="", repo_id=hub_model_id)
api.upload_folder(folder_path=f"{model_name}/unet", path_in_repo="", repo_id=hub_model_id)
api.upload_file(
    path_or_fileobj=f"{model_name}/model_index.json",
    path_in_repo="model_index.json",
    repo_id=hub_model_id,
)

content = f"""
---
license: mit
tags:
- pytorch
- diffusers
- unconditional-image-generation
- diffusion-models-class
---

# Model Card for Unit 1 of the [Diffusion Models Class 🧨](https://github.com/huggingface/diffusion-models-class)

This model is a diffusion model for unconditional image generation of cute 🦋.

## Usage

```python
from diffusers import DDPMPipeline

pipeline = DDPMPipeline.from_pretrained('{hub_model_id}')
image = pipeline().images[0]
image

"""

card = ModelCard(content) card.push_to_hub(hub_model_id)


About 45 minutes later, this is the result:

```python
>>> pipeline = DDPMPipeline.from_pretrained(hub_model_id).to(device)
>>> images = pipeline(batch_size=8).images
>>> make_grid(images)

练习: 看看你是否能找到在尽可能短的时间内获得良好结果的训练/模型设置,并与社区分享你的发现。深入研究脚本,看看你是否能理解代码,并对任何看起来令人困惑的地方寻求澄清。

进一步探索的途径

希望这让你体验到了 🤗 Diffusers 库能做什么!一些可能的后续步骤:

  • 尝试在一个新的数据集上训练一个无条件的 diffusion 模型——如果你能自己创建一个就更好了。你可以在 Hub 上的 HugGan 组织中找到一些很棒的图像数据集来完成这个任务。只要确保如果你不想等待很长时间模型训练,就对它们进行下采样!
  • 尝试使用这个 Space这个 notebook 来尝试 DreamBooth,创建你自己的定制化 Stable Diffusion pipeline
  • 修改训练脚本以探索不同的 UNet 超参数(层数、通道数等)、不同的噪声调度等。
  • 查看从零开始实现 Diffusion 模型 notebook,以不同视角了解我们在本单元中涵盖的核心思想

祝你好运,敬请期待第 2 单元!

< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.