Diffusers 文件

快速教程

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

快速教程

擴散模型透過逐步去噪隨機高斯噪聲來生成感興趣的樣本,例如影像或音訊。這在生成式人工智慧領域引起了巨大興趣,您可能已經在網際網路上看到過擴散生成的影像示例。🧨 Diffusers 是一個旨在讓所有人都能廣泛使用擴散模型的庫。

無論您是開發人員還是日常使用者,本快速教程都將向您介紹 🧨 Diffusers 並幫助您快速開始生成!該庫有三個主要元件需要了解:

  • DiffusionPipeline 是一個高階的端到端類,旨在快速從預訓練擴散模型生成樣本以進行推理。
  • 流行的預訓練模型架構和模組,可用作構建擴散系統的構建塊。
  • 許多不同的排程器 - 控制訓練時如何新增噪聲以及推理時如何生成去噪影像的演算法。

快速教程將向您展示如何使用DiffusionPipeline進行推理,然後引導您瞭解如何組合模型和排程器以複製DiffusionPipeline內部發生的事情。

快速教程是 🧨 Diffusers 入門notebook 的簡化版本,可幫助您快速入門。如果您想了解更多關於 🧨 Diffusers 的目標、設計理念及其核心 API 的其他詳細資訊,請檢視該 notebook!

在開始之前,請確保您已安裝所有必要的庫

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

DiffusionPipeline

DiffusionPipeline 是使用預訓練擴散系統進行推理的最簡單方法。它是一個包含模型和排程器的端到端系統。您可以開箱即用DiffusionPipeline來完成許多工。請查看下錶以瞭解一些受支援的任務,有關受支援任務的完整列表,請檢視🧨 Diffusers 摘要表。

任務 描述 流水線
無條件影像生成 從高斯噪聲生成影像 無條件影像生成
文字引導影像生成 根據文字提示生成影像 條件影像生成
文字引導影像到影像翻譯 根據文字提示調整影像 影像到影像
文字引導影像修復 給定影像、遮罩和文字提示,填充影像的遮罩部分 影像修復
文字引導深度到影像翻譯 根據文字提示調整影像部分,同時透過深度估計保持結構 深度到影像

首先建立DiffusionPipeline的例項,並指定要下載的管道檢查點。您可以將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 管道由UNet2DConditionModelPNDMScheduler等組成

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

我們強烈建議在 GPU 上執行管道,因為該模型包含大約 14 億個引數。您可以像在 PyTorch 中一樣將生成器物件移動到 GPU。

>>> pipeline.to("cuda")

現在您可以將文字提示傳遞給pipeline以生成影像,然後訪問去噪影像。預設情況下,影像輸出被包裝在PIL.Image物件中。

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

透過呼叫save儲存影像

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

本地管道

您也可以在本地使用該管道。唯一的區別是您需要先下載權重

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

然後將儲存的權重載入到管道中

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

現在,您可以像上一節中那樣執行管道。

更換排程器

不同的排程器具有不同的去噪速度和質量權衡。找出最適合您的方法是嘗試它們!🧨 Diffusers 的主要功能之一是讓您可以輕鬆地在排程器之間切換。例如,要用EulerDiscreteScheduler替換預設的PNDMScheduler,請使用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)

嘗試使用新的排程器生成影像,看看您是否注意到差異!

在下一節中,您將仔細研究構成DiffusionPipeline的元件——模型和排程器——並學習如何使用這些元件生成貓的影像。

模型

大多數模型接收一個帶噪聲的樣本,並在每個時間步預測*噪聲殘差*(其他模型學習直接預測之前的樣本或速度或v-prediction),即噪聲較少的影像與輸入影像之間的差異。您可以混合搭配模型來建立其他擴散系統。

模型透過from_pretrained()方法進行初始化,該方法也會在本地快取模型權重,以便下次載入模型時更快。在本快速教程中,您將載入UNet2DModel,這是一個基於貓影像訓練的檢查點的基本無條件影像生成模型。

>>> from diffusers import UNet2DModel

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

如果您不確定要使用哪個模型類,可以使用AutoModel API 自動選擇模型類。

要訪問模型引數,請呼叫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

但是,要生成實際示例,您需要一個排程器來指導去噪過程。在下一節中,您將學習如何將模型與排程器結合使用。

排程器

排程器根據模型輸出(在本例中為`noisy_residual`)管理從帶噪聲樣本到噪聲較少樣本的過程。

🧨 Diffusers 是一個用於構建擴散系統的工具箱。雖然DiffusionPipeline是開始使用預構建擴散系統的便捷方法,但您也可以單獨選擇自己的模型和排程器元件來構建自定義擴散系統。

對於快速教程,您將使用其from_config()方法例項化DDPMScheduler

>>> 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 上更新

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