DiffusionPipeline
有一种简便的方法用于推理是至关重要的。扩散系统通常由多个组件组成,如parameterized model
、tokenizers
和schedulers
等,它们以复杂的方式进行交互。这就是为什么我们设计了DiffusionPipeline
,将整个扩散系统的复杂性包装成易于使用的API,同时保持足够的灵活性,以适应其他用例,例如将每个组件单独加载作为构建块来组装自己的扩散系统。
作为所有Diffusion模型Pipeline的基类,DiffusionPipeline
主要负责完成模型的加载与注册等一系列前置工作。将下载的权重加载到正确的Pipeline类(从文件model_index.json
中检索)中,并返回该类的实例,并自动将model移动到对应的device
上(注意:DiffusionPipeline将device
和dtype
注册为property method
,是在from_pretrained
中初始化的)。
除了基类DiffusionPipeline
,其他用于特定任务的Piepline叫做Community pipelines
:如StableDiffusionControlNetPipeline
对应于使用 ControlNet 调节生成文本到图像的Pipeline。
1. from_pretrained
1.1 简单使用
DiffusionPipeline 类是从 Hub 加载最新趋势扩散模型的最简单、最通用的方法。DiffusionPipeline.from_pretrained()
方法自动从检查点检测正确的Pipeline类,下载并缓存所有必需的配置和权重文件,并返回准备进行推理的管道实例。而且当 from_pretrained()
方法检测到本地路径时,它不会从 Hub 下载任何文件,但这也意味着它不会下载和缓存检查点的最新更改。
from diffusers import DiffusionPipeline
repo_id = "runwayml/stable-diffusion-v1-5"
pipe = DiffusionPipeline.from_pretrained(repo_id, use_safetensors=True)
还可以加载具有特定Community pipelines类的检查点。上面的示例加载了一个稳定扩散模型;若要获得相同的结果,请使用 StableDiffusionPipeline 类:
from diffusers import StableDiffusionPipeline
repo_id = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionPipeline.from_pretrained(repo_id, use_safetensors=True)
也可以直接使用其相应的特定于任务的Community pipelines类加载它:
from diffusers import StableDiffusionImg2ImgPipeline
repo_id = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(repo_id)
除了直接从diffusers导入对应的Community pipelines类
,我们还可以直接使用DiffusionPipeline导入,只需要指定custom_pipeline
参数即可:若要在 Hub 上加载任何社区管道,请将Community pipelines的存储库 ID 传递给custom_pipeline。
如果Pipeline中包含 Diffusers库 尚不支持的自定义组件,则需要手动将其实现,然后导入。这些自定义组件可以是 VAE、UNet 、TextEncoder、调度器等。
例如,以下示例从 showlab/show-1-base
加载Community Pipeline,手动加载
加载pipeline权重和组件传入Pipeline:
pipe_id = "showlab/show-1-base"
# 1. 从 Transformer 导入并加载文本编码器:
from transformers import T5Tokenizer, T5EncoderModel
tokenizer = T5Tokenizer.from_pretrained(pipe_id, subfolder="tokenizer")
text_encoder = T5EncoderModel.from_pretrained(pipe_id, subfolder="text_encoder")
# 2. 加载调度程序:
from diffusers import DPMSolverMultistepScheduler
scheduler = DPMSolverMultistepScheduler.from_pretrained(pipe_id, subfolder="scheduler")
# 3. 加载图像处理器:
from transformers import CLIPFeatureExtractor
feature_extractor = CLIPFeatureExtractor.from_pretrained(pipe_id, subfolder="feature_extractor")
# 4. 加载一个自定义 UNet(为方便起见,假设该 UNet3DConditionModel 已在showone_unet_3d_condition.py脚本中实现)
from showone_unet_3d_condition import ShowOneUNet3DConditionModel
unet = ShowOneUNet3DConditionModel.from_pretrained(pipe_id, subfolder="unet")
# 5. 加载自定义管道 Pipeline同样假设已经在pipeline_t2v_base_pixel.py脚本中实现)
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,我们可以将其推送到Huggingace社区,方便以后直接用DiffusionPipeline进行加载,push_to_hub()
将每个组件保存到存储库中的子文件夹中,权重默认保存为.safetensors
,配置参数默认保存为config.json
:
pipeline.push_to_hub("custom-t2v-pipeline") # 设置pipeline的id_name
成功推送管道后,只需要进行一些更改:
- 将
model_index.json
中的_class_name
属性更改为"pipeline_t2v_base_pixel"
和"TextToVideoIFPipeline"
。 - 上传
showone_unet_3d_condition.py
脚本到unet目录。 - 上传
pipeline_t2v_base_pixel.py
脚本到pipeline基目录。
要再次运行推理,只需在初始化管道时添加参数trust_remote_code
,即可在幕后处理所有操作。
from diffusers import DiffusionPipeline
import torch
pipeline = DiffusionPipeline.from_pretrained(
"your-namespace/custom-t2v-pipeline", 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
1.2 from_pretrained加载原理
- Pipeline根据
model_index.json
进行加载各个子文件夹的组件类; - 各个组件类根据子文件夹中的
config.json
加载对应类的实例;
当我们打印普通的StableDiffusionPipeline
:将看到 pipeline 是 StableDiffusionPipeline 的一个实例,它由七个组件组成:
- “feature_extractor”:来自 Transformer 的 🤗 - CLIPImageProcessor。
- “safety_checker”:用于筛选有害内容的组件。
- “scheduler”:PNDMScheduler 的实例。
- “text_encoder”:来自 Transformer 的 🤗 CLIPTextModel。
- “tokenizer”:来自变形金刚的 🤗 CLIPTokenizer。
- “unet”:UNet2DConditionModel 的实例。
- “vae”:AutoencoderKL的实例。
StableDiffusionPipeline {
"feature_extractor": [
"transformers",
"CLIPImageProcessor"
],
"safety_checker": [
"stable_diffusion",
"StableDiffusionSafetyChecker"
],
"scheduler": [
"diffusers",
"PNDMScheduler"
],
"text_encoder": [
"transformers",
"CLIPTextModel"
],
"tokenizer": [
"transformers",
"CLIPTokenizer"
],
"unet": [
"diffusers",
"UNet2DConditionModel"
],
"vae": [
"diffusers",
"AutoencoderKL"
]
}
将管道实例的组件与 runwayml/stable-diffusion-v1-5 文件夹结构
进行比较,您将看到存储库中的每个组件都有一个单独的文件夹:
.
├── feature_extractor
│ └── preprocessor_config.json
├── model_index.json
├── safety_checker
│ ├── config.json
| ├── model.fp16.safetensors
│ ├── model.safetensors
│ ├── pytorch_model.bin
| └── pytorch_model.fp16.bin
├── scheduler
│ └── scheduler_config.json
├── text_encoder
│ ├── config.json
| ├── model.fp16.safetensors
│ ├── model.safetensors
│ |── pytorch_model.bin
| └── pytorch_model.fp16.bin
├── tokenizer
│ ├── merges.txt
│ ├── special_tokens_map.json
│ ├── tokenizer_config.json
│ └── vocab.json
├── unet
│ ├── config.json
│ ├── diffusion_pytorch_model.bin
| |── diffusion_pytorch_model.fp16.bin
│ |── diffusion_pytorch_model.f16.safetensors
│ |── diffusion_pytorch_model.non_ema.bin
│ |── diffusion_pytorch_model.non_ema.safetensors
│ └── diffusion_pytorch_model.safetensors
|── vae
. ├── config.json
. ├── diffusion_pytorch_model.bin
├── diffusion_pytorch_model.fp16.bin
├── diffusion_pytorch_model.fp16.safetensors
└── diffusion_pytorch_model.safetensors
每个Pipeline都需要一个 model_index.json
文件,该文件告诉 DiffusionPipeline
:
- 要从哪个Pipeline类,加载
_class_name
- 哪个版本的diffusers🧨,用于创建模型
_diffusers_version
- 子文件夹中存储了哪些库中的组件(对应于组件和子文件夹名称,对应于要从中加载类的库的名称,对应于类名称)
name: [library, class]
如下是runwayml/stable-diffusion-v1-5
的model_index.json
文件:
{
"_class_name": "StableDiffusionPipeline",
"_diffusers_version": "0.6.0",
"feature_extractor": [
"transformers",
"CLIPImageProcessor"
],
"safety_checker": [
"stable_diffusion",
"StableDiffusionSafetyChecker"
],
"scheduler": [
"diffusers",
"PNDMScheduler"
],
"text_encoder": [
"transformers",
"CLIPTextModel"
],
"tokenizer": [
"transformers"