Diffusers 文件
載入排程器和模型
並獲得增強的文件體驗
開始使用
載入排程器和模型
擴散流水線是可互換的排程器和模型的集合,可以混合搭配以針對特定用例定製流水線。排程器封裝了整個去噪過程,例如去噪步數和查詢去噪樣本的演算法。排程器不進行引數化或訓練,因此它們不佔用太多記憶體。模型通常只關注從噪聲輸入到較少噪聲樣本的前向傳遞。
本指南將向您展示如何載入排程器和模型以定製流水線。您將在本指南中始終使用 stable-diffusion-v1-5/stable-diffusion-v1-5 檢查點,所以我們先載入它。
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True
).to("cuda")
您可以使用 `pipeline.scheduler` 屬性檢視此流水線使用的排程器。
pipeline.scheduler
PNDMScheduler {
"_class_name": "PNDMScheduler",
"_diffusers_version": "0.21.4",
"beta_end": 0.012,
"beta_schedule": "scaled_linear",
"beta_start": 0.00085,
"clip_sample": false,
"num_train_timesteps": 1000,
"set_alpha_to_one": false,
"skip_prk_steps": true,
"steps_offset": 1,
"timestep_spacing": "leading",
"trained_betas": null
}
載入排程器
排程器由一個配置檔案定義,該檔案可以由各種排程器使用。使用 SchedulerMixin.from_pretrained() 方法載入排程器,並指定 `subfolder` 引數將配置檔案載入到流水線倉庫的正確子資料夾中。
例如,要載入 DDIMScheduler
from diffusers import DDIMScheduler, DiffusionPipeline
ddim = DDIMScheduler.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", subfolder="scheduler")
然後您可以將新載入的排程器傳遞給流水線。
pipeline = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5", scheduler=ddim, torch_dtype=torch.float16, use_safetensors=True
).to("cuda")
比較排程器
排程器有其獨特的優缺點,這使得很難定量比較哪個排程器對流水線最有效。您通常不得不在去噪速度和去噪質量之間進行權衡。我們建議嘗試不同的排程器以找到最適合您用例的排程器。呼叫 `pipeline.scheduler.compatibles` 屬性以檢視哪些排程器與流水線相容。
讓我們在以下提示和種子下比較 LMSDiscreteScheduler、EulerDiscreteScheduler、EulerAncestralDiscreteScheduler 和 DPMSolverMultistepScheduler。
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True
).to("cuda")
prompt = "A photograph of an astronaut riding a horse on Mars, high resolution, high definition."
generator = torch.Generator(device="cuda").manual_seed(8)
要更改流水線排程器,請使用 from_config() 方法將不同調度器的 `pipeline.scheduler.config` 載入到流水線中。
LMSDiscreteScheduler 通常比預設排程器生成更高質量的影像。
from diffusers import LMSDiscreteScheduler
pipeline.scheduler = LMSDiscreteScheduler.from_config(pipeline.scheduler.config)
image = pipeline(prompt, generator=generator).images[0]
image




大多數影像看起來非常相似,並且質量相當。同樣,這通常取決於您的特定用例,因此一個好的方法是執行多種不同的排程器並比較結果。
Flax 排程器
要比較 Flax 排程器,您需要額外將排程器狀態載入到模型引數中。例如,讓我們更改 FlaxStableDiffusionPipeline 中的預設排程器,以使用超快的 `FlaxDPMSolverMultistepScheduler`。
`FlaxLMSDiscreteScheduler` 和 `FlaxDDPMScheduler` 尚未與 FlaxStableDiffusionPipeline 相容。
import jax
import numpy as np
from flax.jax_utils import replicate
from flax.training.common_utils import shard
from diffusers import FlaxStableDiffusionPipeline, FlaxDPMSolverMultistepScheduler
scheduler, scheduler_state = FlaxDPMSolverMultistepScheduler.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
subfolder="scheduler"
)
pipeline, params = FlaxStableDiffusionPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
scheduler=scheduler,
variant="bf16",
dtype=jax.numpy.bfloat16,
)
params["scheduler"] = scheduler_state
然後您可以利用 Flax 與 TPU 的相容性來並行生成多個影像。您需要為每個可用裝置複製模型引數,然後將輸入拆分到它們之間以生成所需數量的影像。
# Generate 1 image per parallel device (8 on TPUv2-8 or TPUv3-8)
prompt = "A photograph of an astronaut riding a horse on Mars, high resolution, high definition."
num_samples = jax.device_count()
prompt_ids = pipeline.prepare_inputs([prompt] * num_samples)
prng_seed = jax.random.PRNGKey(0)
num_inference_steps = 25
# shard inputs and rng
params = replicate(params)
prng_seed = jax.random.split(prng_seed, jax.device_count())
prompt_ids = shard(prompt_ids)
images = pipeline(prompt_ids, params, prng_seed, num_inference_steps, jit=True).images
images = pipeline.numpy_to_pil(np.asarray(images.reshape((num_samples,) + images.shape[-3:])))
模型
模型從 ModelMixin.from_pretrained() 方法載入,該方法下載並快取最新版本的模型權重和配置。如果最新檔案在本地快取中可用,from_pretrained() 會重用快取中的檔案,而不是重新下載它們。
模型可以從子資料夾載入,使用 `subfolder` 引數。例如,stable-diffusion-v1-5/stable-diffusion-v1-5 的模型權重儲存在 unet 子資料夾中。
from diffusers import UNet2DConditionModel
unet = UNet2DConditionModel.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", subfolder="unet", use_safetensors=True)
它們也可以直接從 倉庫 載入。
from diffusers import UNet2DModel
unet = UNet2DModel.from_pretrained("google/ddpm-cifar10-32", use_safetensors=True)
要載入和儲存模型變體,請在 ModelMixin.from_pretrained() 和 ModelMixin.save_pretrained() 中指定 `variant` 引數。
from diffusers import UNet2DConditionModel
unet = UNet2DConditionModel.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5", subfolder="unet", variant="non_ema", use_safetensors=True
)
unet.save_pretrained("./local-unet", variant="non_ema")