Diffusers 文件

載入排程器和模型

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

載入排程器和模型

擴散流水線是可互換的排程器和模型的集合,可以混合搭配以針對特定用例定製流水線。排程器封裝了整個去噪過程,例如去噪步數和查詢去噪樣本的演算法。排程器不進行引數化或訓練,因此它們不佔用太多記憶體。模型通常只關注從噪聲輸入到較少噪聲樣本的前向傳遞。

本指南將向您展示如何載入排程器和模型以定製流水線。您將在本指南中始終使用 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` 屬性以檢視哪些排程器與流水線相容。

讓我們在以下提示和種子下比較 LMSDiscreteSchedulerEulerDiscreteSchedulerEulerAncestralDiscreteSchedulerDPMSolverMultistepScheduler

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
EulerDiscreteScheduler
EulerAncestralDiscreteScheduler
DPMSolverMultistepScheduler

LMSDiscreteScheduler 通常比預設排程器生成更高質量的影像。

from diffusers import LMSDiscreteScheduler

pipeline.scheduler = LMSDiscreteScheduler.from_config(pipeline.scheduler.config)
image = pipeline(prompt, generator=generator).images[0]
image
LMSDiscreteScheduler
EulerDiscreteScheduler
EulerAncestralDiscreteScheduler
DPMSolverMultistepScheduler

大多數影像看起來非常相似,並且質量相當。同樣,這通常取決於您的特定用例,因此一個好的方法是執行多種不同的排程器並比較結果。

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")
< > 在 GitHub 上更新

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