Diffusers 文档

加载社区 pipelines 和组件

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

加载社区 pipelines 和组件

社区 pipelines

请查看 GitHub Issue #841 以了解更多关于我们为何添加社区 pipelines 以帮助大家轻松分享工作而不会被拖慢速度的背景信息。

社区 pipelines 是任何与原始论文实现不同的 DiffusionPipeline 类(例如,StableDiffusionControlNetPipeline 对应于 Text-to-Image Generation with ControlNet Conditioning 论文)。它们提供额外的功能或扩展 pipeline 的原始实现。

有很多很棒的社区 pipelines,例如 Marigold Depth EstimationInstantID,您可以在此处找到所有官方社区 pipelines。

社区 pipelines 有两种类型:存储在 Hugging Face Hub 上的和存储在 Diffusers GitHub 仓库中的。Hub pipelines 是完全可定制的(scheduler、模型、pipeline 代码等),而 Diffusers GitHub pipelines 仅限于自定义 pipeline 代码。

GitHub 社区 pipeline HF Hub 社区 pipeline
用法 相同 相同
审核流程 在 GitHub 上打开 Pull Request 并接受 Diffusers 团队的审核流程,然后合并;可能较慢 直接上传到 Hub 仓库,无需任何审核;这是最快的工作流程
可见性 包含在官方 Diffusers 仓库和文档中 包含在您的 HF Hub 个人资料中,并依赖您自己的使用/推广来获得可见性
Hub pipelines
GitHub pipelines

要加载 Hugging Face Hub 社区 pipeline,请将社区 pipeline 的仓库 ID 传递给 custom_pipeline 参数,并将您想要从中加载 pipeline 权重和组件的模型仓库传递给模型仓库。例如,下面的示例从 hf-internal-testing/diffusers-dummy-pipeline 加载一个虚拟 pipeline,并从 google/ddpm-cifar10-32 加载 pipeline 权重和组件

通过从 Hugging Face Hub 加载社区 pipeline,您信任您加载的代码是安全的。在加载并自动运行代码之前,请务必在线检查代码!

from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "google/ddpm-cifar10-32", custom_pipeline="hf-internal-testing/diffusers-dummy-pipeline", use_safetensors=True
)

从本地文件加载

如果您传递文件路径,也可以从本地文件加载社区 pipelines。传递的目录路径必须包含一个 pipeline.py 文件,其中包含 pipeline 类。

pipeline = DiffusionPipeline.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5",
    custom_pipeline="./path/to/pipeline_directory/",
    clip_model=clip_model,
    feature_extractor=feature_extractor,
    use_safetensors=True,
)

从特定版本加载

默认情况下,社区 pipelines 从 Diffusers 的最新稳定版本加载。要从另一个版本加载社区 pipeline,请使用 custom_revision 参数。

main
旧版本

例如,要从 main 分支加载

pipeline = DiffusionPipeline.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5",
    custom_pipeline="clip_guided_stable_diffusion",
    custom_revision="main",
    clip_model=clip_model,
    feature_extractor=feature_extractor,
    use_safetensors=True,
)

使用 from_pipe 加载

社区 pipelines 也可以使用 from_pipe() 方法加载,该方法允许您加载和重用多个 pipelines,而不会产生额外的内存开销(在重用 pipeline 指南中了解更多信息)。内存需求由加载的单个最大 pipeline 决定。

例如,让我们从 Stable Diffusion pipeline 加载一个支持长 prompts 和权重的社区 pipeline。

import torch
from diffusers import DiffusionPipeline

pipe_sd = DiffusionPipeline.from_pretrained("emilianJR/CyberRealistic_V3", torch_dtype=torch.float16)
pipe_sd.to("cuda")
# load long prompt weighting pipeline
pipe_lpw = DiffusionPipeline.from_pipe(
    pipe_sd,
    custom_pipeline="lpw_stable_diffusion",
).to("cuda")

prompt = "cat, hiding in the leaves, ((rain)), zazie rainyday, beautiful eyes, macro shot, colorful details, natural lighting, amazing composition, subsurface scattering, amazing textures, filmic, soft light, ultra-detailed eyes, intricate details, detailed texture, light source contrast, dramatic shadows, cinematic light, depth of field, film grain, noise, dark background, hyperrealistic dslr film still, dim volumetric cinematic lighting"
neg_prompt = "(deformed iris, deformed pupils, semi-realistic, cgi, 3d, render, sketch, cartoon, drawing, anime, mutated hands and fingers:1.4), (deformed, distorted, disfigured:1.3), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, disconnected limbs, mutation, mutated, ugly, disgusting, amputation"
generator = torch.Generator(device="cpu").manual_seed(20)
out_lpw = pipe_lpw(
    prompt,
    negative_prompt=neg_prompt,
    width=512,
    height=512,
    max_embeddings_multiples=3,
    num_inference_steps=50,
    generator=generator,
    ).images[0]
out_lpw
具有长 prompt 权重的 Stable Diffusion
Stable Diffusion

社区 pipeline 示例

社区 pipelines 是一种非常有趣和富有创意的方式,可以通过新的和独特的功能来扩展原始 pipeline 的功能。您可以在 diffusers/examples/community 文件夹中找到所有社区 pipelines,其中包含关于如何使用它们的推理和训练示例。

本节展示了几个社区 pipelines,希望能激发您创建自己的 pipeline(欢迎为您的社区 pipeline 打开 PR 并 ping 我们进行审核)!

from_pipe() 方法对于加载社区 pipelines 特别有用,因为许多社区 pipelines 没有预训练权重,并且在现有 pipeline(如 Stable Diffusion 或 Stable Diffusion XL)之上添加了功能。您可以在 使用 from_pipe 加载 部分了解更多关于 from_pipe() 方法的信息。

Marigold
HD-Painter

Marigold 是一种深度估计扩散 pipeline,它利用扩散模型中丰富的现有和内在视觉知识。它接收输入图像,并对其进行去噪和解码,生成深度图。即使对于以前未见过的图像,Marigold 也表现良好。

import torch
from PIL import Image
from diffusers import DiffusionPipeline
from diffusers.utils import load_image

pipeline = DiffusionPipeline.from_pretrained(
    "prs-eth/marigold-lcm-v1-0",
    custom_pipeline="marigold_depth_estimation",
    torch_dtype=torch.float16,
    variant="fp16",
)

pipeline.to("cuda")
image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/community-marigold.png")
output = pipeline(
    image,
    denoising_steps=4,
    ensemble_size=5,
    processing_res=768,
    match_input_res=True,
    batch_size=0,
    seed=33,
    color_map="Spectral",
    show_progress_bar=True,
)
depth_colored: Image.Image = output.depth_colored
depth_colored.save("./depth_colored.png")
原始图像
彩色深度图像

社区组件

社区组件允许用户构建可能具有自定义组件的 pipelines,这些组件不是 Diffusers 的一部分。如果您的 pipeline 具有 Diffusers 尚不支持的自定义组件,则需要以 Python 模块的形式提供它们的实现。这些自定义组件可以是 VAE、UNet 和 scheduler。在大多数情况下,文本编码器是从 Transformers 库导入的。pipeline 代码本身也可以自定义。

本节展示了用户应如何使用社区组件来构建社区 pipeline。

您将使用 showlab/show-1-base pipeline 检查点作为示例。

  1. 从 Transformers 导入并加载文本编码器
from transformers import T5Tokenizer, T5EncoderModel

pipe_id = "showlab/show-1-base"
tokenizer = T5Tokenizer.from_pretrained(pipe_id, subfolder="tokenizer")
text_encoder = T5EncoderModel.from_pretrained(pipe_id, subfolder="text_encoder")
  1. 加载 scheduler
from diffusers import DPMSolverMultistepScheduler

scheduler = DPMSolverMultistepScheduler.from_pretrained(pipe_id, subfolder="scheduler")
  1. 加载图像处理器
from transformers import CLIPImageProcessor

feature_extractor = CLIPImageProcessor.from_pretrained(pipe_id, subfolder="feature_extractor")

在步骤 4 和 5 中,自定义 UNet 和 pipeline 实现必须与它们的文件中显示的格式匹配,此示例才能正常工作。

  1. 现在您将加载一个自定义 UNet,在本示例中,为了方便起见,它已在 showone_unet_3d_condition.py 中实现。您会注意到 UNet3DConditionModel 类名已更改为 ShowOneUNet3DConditionModel,因为 UNet3DConditionModel 已存在于 Diffusers 中。ShowOneUNet3DConditionModel 类所需的任何组件都应放在 showone_unet_3d_condition.py 中。

    完成此操作后,您可以初始化 UNet

    from showone_unet_3d_condition import ShowOneUNet3DConditionModel
    
    unet = ShowOneUNet3DConditionModel.from_pretrained(pipe_id, subfolder="unet")
  2. 最后,您将加载自定义 pipeline 代码。对于本示例,它已在 pipeline_t2v_base_pixel.py 中为您创建。此脚本包含一个自定义 TextToVideoIFPipeline 类,用于从文本生成视频。与自定义 UNet 一样,自定义 pipeline 工作所需的任何代码都应放在 pipeline_t2v_base_pixel.py 中。

一切就绪后,您可以使用 ShowOneUNet3DConditionModel 初始化 TextToVideoIFPipeline

from pipeline_t2v_base_pixel import TextToVideoIFPipeline
import torch

pipeline = TextToVideoIFPipeline(
    unet=unet,
    text_encoder=text_encoder,
    tokenizer=tokenizer,
    scheduler=scheduler,
    feature_extractor=feature_extractor
)
pipeline = pipeline.to(device="cuda")
pipeline.torch_dtype = torch.float16

将 pipeline 推送到 Hub 以与社区分享!

pipeline.push_to_hub("custom-t2v-pipeline")

pipeline 成功推送后,您需要进行一些更改

  1. model_index.json 中的 _class_name 属性更改为 "pipeline_t2v_base_pixel""TextToVideoIFPipeline"
  2. showone_unet_3d_condition.py 上传到 unet 子文件夹。
  3. pipeline_t2v_base_pixel.py 上传到 pipeline 仓库

要运行推理,请在初始化 pipeline 时添加 trust_remote_code 参数,以处理幕后所有的“魔术”。

作为使用 trust_remote_code=True 的额外预防措施,我们强烈建议您将 commit 哈希传递给 from_pretrained() 中的 revision 参数,以确保代码没有被恶意的新代码行更新(除非您完全信任模型所有者)。

from diffusers import DiffusionPipeline
import torch

pipeline = DiffusionPipeline.from_pretrained(
    "<change-username>/<change-id>", trust_remote_code=True, torch_dtype=torch.float16
).to("cuda")

prompt = "hello"

# Text embeds
prompt_embeds, negative_embeds = pipeline.encode_prompt(prompt)

# Keyframes generation (8x64x40, 2fps)
video_frames = pipeline(
    prompt_embeds=prompt_embeds,
    negative_prompt_embeds=negative_embeds,
    num_frames=8,
    height=40,
    width=64,
    num_inference_steps=2,
    guidance_scale=9.0,
    output_type="pt"
).frames

作为额外的参考,请查看 stabilityai/japanese-stable-diffusion-xl 的仓库结构,它也使用了 trust_remote_code 功能。

from diffusers import DiffusionPipeline
import torch

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/japanese-stable-diffusion-xl", trust_remote_code=True
)
pipeline.to("cuda")
< > 在 GitHub 上更新