Diffusers 文件
排程器功能
並獲得增強的文件體驗
開始使用
排程器功能
排程器是任何擴散模型的重要組成部分,因為它控制著整個去噪(或採樣)過程。排程器有很多種型別,有些為速度最佳化,有些為質量最佳化。使用 Diffusers,你可以修改排程器配置,以使用自定義的噪聲排程、sigmas,並重新縮放噪聲排程。改變這些引數可以對推理質量和速度產生深遠的影響。
本指南將演示如何使用這些功能來提高推理質量。
Diffusers 目前僅對部分排程器和 pipeline 支援 timesteps
和 sigmas
引數。如果你希望將這些引數擴充套件到當前不支援的排程器和 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]



時間步間隔
在排程中選擇取樣步長的方式會影響生成影像的質量,特別是與重新縮放噪聲排程結合使用時,這可以使模型生成更亮或更暗的影像。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


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]


重新縮放噪聲排程
在論文 Common Diffusion Noise Schedules and Sample Steps are Flawed 中,作者發現常見的噪聲排程允許一些訊號洩漏到最後一個時間步。這種推理時的訊號洩漏可能導致模型只能生成中等亮度的影像。透過為時間步排程強制執行零信噪比(SNR)並從最後一個時間步開始取樣,可以改進模型以生成非常亮或非常暗的影像。
對於推理,你需要一個使用 v_prediction 訓練過的模型。要用 v_prediction 訓練你自己的模型,請將以下標誌新增到 train_text_to_image.py 或 train_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

