Diffusers 文件

排程器功能

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

排程器功能

排程器是任何擴散模型的重要組成部分,因為它控制著整個去噪(或採樣)過程。排程器有很多種型別,有些為速度最佳化,有些為質量最佳化。使用 Diffusers,你可以修改排程器配置,以使用自定義的噪聲排程、sigmas,並重新縮放噪聲排程。改變這些引數可以對推理質量和速度產生深遠的影響。

本指南將演示如何使用這些功能來提高推理質量。

Diffusers 目前僅對部分排程器和 pipeline 支援 timestepssigmas 引數。如果你希望將這些引數擴充套件到當前不支援的排程器和 pipeline,歡迎隨時提出功能請求

時間步排程

時間步或噪聲排程決定了每個取樣步驟中的噪聲量。排程器使用它在每個步驟生成具有相應噪聲量的影像。時間步排程是根據排程器的預設配置生成的,但你可以自定義排程器以使用新的、最佳化的取樣排程,即使這些排程尚未在 Diffusers 中提供。

例如,Align Your Steps (AYS) 是一種最佳化取樣排程的方法,可以在短短 10 個步驟內生成高質量的影像。針對 Stable Diffusion XL 的最佳 10 步排程

from diffusers.schedulers import AysSchedules

sampling_schedule = AysSchedules["StableDiffusionXLTimesteps"]
print(sampling_schedule)
"[999, 845, 730, 587, 443, 310, 193, 116, 53, 13]"

你可以透過將 AYS 取樣排程傳遞給 timesteps 引數,在 pipeline 中使用它。

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "SG161222/RealVisXL_V4.0",
    torch_dtype=torch.float16,
    variant="fp16",
).to("cuda")
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, algorithm_type="sde-dpmsolver++")

prompt = "A cinematic shot of a cute little rabbit wearing a jacket and doing a thumbs up"
generator = torch.Generator(device="cpu").manual_seed(2487854446)
image = pipeline(
    prompt=prompt,
    negative_prompt="",
    generator=generator,
    timesteps=sampling_schedule,
).images[0]
AYS 10 步時間步排程
線性間隔 10 步時間步排程
線性間隔 25 步時間步排程

時間步間隔

在排程中選擇取樣步長的方式會影響生成影像的質量,特別是與重新縮放噪聲排程結合使用時,這可以使模型生成更亮或更暗的影像。Diffusers 提供了三種時間步間隔方法

  • leading 建立均勻間隔的步長
  • linspace 包含第一步和最後一步,並均勻選擇剩餘的中間步長
  • trailing 只包含最後一步,並從末尾開始均勻選擇剩餘的中間步長

建議使用 trailing 間隔方法,因為在取樣步長較少時,它能生成質量更高、細節更豐富的影像。但對於更標準的取樣步長值,質量差異不那麼明顯。

import torch
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "SG161222/RealVisXL_V4.0",
    torch_dtype=torch.float16,
    variant="fp16",
).to("cuda")
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, timestep_spacing="trailing")

prompt = "A cinematic shot of a cute little black cat sitting on a pumpkin at night"
generator = torch.Generator(device="cpu").manual_seed(2487854446)
image = pipeline(
    prompt=prompt,
    negative_prompt="",
    generator=generator,
    num_inference_steps=5,
).images[0]
image
5 步後的 trailing 間隔
5 步後的 leading 間隔

Sigmas

sigmas 引數是根據時間步排程在每個時間步新增的噪聲量。與 timesteps 引數類似,你可以自定義 sigmas 引數來控制每一步新增多少噪聲。當你使用自定義的 sigmas 值時,timesteps 會根據自定義的 sigmas 值計算,而預設的排程器配置將被忽略。

例如,你可以手動將類似之前 10 步 AYS 排程的 sigmas 傳遞給 pipeline。

import torch

from diffusers import DiffusionPipeline, EulerDiscreteScheduler

model_id = "stabilityai/stable-diffusion-xl-base-1.0"
pipeline = DiffusionPipeline.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0",
  torch_dtype=torch.float16,
  variant="fp16",
).to("cuda")
pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)

sigmas = [14.615, 6.315, 3.771, 2.181, 1.342, 0.862, 0.555, 0.380, 0.234, 0.113, 0.0]
prompt = "anthropomorphic capybara wearing a suit and working with a computer"
generator = torch.Generator(device='cuda').manual_seed(123)
image = pipeline(
    prompt=prompt,
    num_inference_steps=10,
    sigmas=sigmas,
    generator=generator
).images[0]

當你檢視排程器的 timesteps 引數時,你會發現它與 AYS 時間步排程相同,因為 timestep 排程是根據 sigmas 計算的。

print(f" timesteps: {pipe.scheduler.timesteps}")
"timesteps: tensor([999., 845., 730., 587., 443., 310., 193., 116.,  53.,  13.], device='cuda:0')"

Karras sigmas

請參考排程器 API 概覽,檢視支援 Karras sigmas 的排程器列表。

Karras sigmas 不應用於未經其訓練的模型。例如,基礎的 Stable Diffusion XL 模型不應使用 Karras sigmas,但 DreamShaperXL 模型可以使用,因為它們是使用 Karras sigmas 訓練的。

Karras 排程器使用來自論文 Elucidating the Design Space of Diffusion-Based Generative Models 的時間步排程和 sigmas。與其他排程器相比,此排程器變體在接近取樣過程結束時每步應用的噪聲量更少,並且可以增加生成影像的細節水平。

透過在排程器中設定 use_karras_sigmas=True 來啟用 Karras sigmas。

import torch
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler

pipeline = StableDiffusionXLPipeline.from_pretrained(
    "SG161222/RealVisXL_V4.0",
    torch_dtype=torch.float16,
    variant="fp16",
).to("cuda")
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, algorithm_type="sde-dpmsolver++", use_karras_sigmas=True)

prompt = "A cinematic shot of a cute little rabbit wearing a jacket and doing a thumbs up"
generator = torch.Generator(device="cpu").manual_seed(2487854446)
image = pipeline(
    prompt=prompt,
    negative_prompt="",
    generator=generator,
).images[0]
啟用 Karras sigmas
停用 Karras sigmas

重新縮放噪聲排程

在論文 Common Diffusion Noise Schedules and Sample Steps are Flawed 中,作者發現常見的噪聲排程允許一些訊號洩漏到最後一個時間步。這種推理時的訊號洩漏可能導致模型只能生成中等亮度的影像。透過為時間步排程強制執行零信噪比(SNR)並從最後一個時間步開始取樣,可以改進模型以生成非常亮或非常暗的影像。

對於推理,你需要一個使用 v_prediction 訓練過的模型。要用 v_prediction 訓練你自己的模型,請將以下標誌新增到 train_text_to_image.pytrain_text_to_image_lora.py 指令碼中。

--prediction_type="v_prediction"

例如,載入使用 v_prediction 訓練的 ptx0/pseudo-journey-v2 checkpoint 和 DDIMScheduler。在 DDIMScheduler 中配置以下引數

  • rescale_betas_zero_snr=True 將噪聲排程重新縮放到零信噪比
  • timestep_spacing="trailing" 從最後一個時間步開始取樣

在 pipeline 中設定 guidance_rescale 以防止過度曝光。較低的值會增加亮度,但一些細節可能會顯得褪色。

from diffusers import DiffusionPipeline, DDIMScheduler

pipeline = DiffusionPipeline.from_pretrained("ptx0/pseudo-journey-v2", use_safetensors=True)

pipeline.scheduler = DDIMScheduler.from_config(
    pipeline.scheduler.config, rescale_betas_zero_snr=True, timestep_spacing="trailing"
)
pipeline.to("cuda")
prompt = "cinematic photo of a snowy mountain at night with the northern lights aurora borealis overhead, 35mm photograph, film, professional, 4k, highly detailed"
generator = torch.Generator(device="cpu").manual_seed(23)
image = pipeline(prompt, guidance_rescale=0.7, generator=generator).images[0]
image
預設 Stable Diffusion v2-1 影像
啟用了零信噪比和 trailing 時間步間隔的影像
< > 在 GitHub 上更新

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