Diffusers 快速上手指南:用 DiffusionPipeline 与「模型 + 调度器」组合生成图像
【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers
本文是 🧨 Diffusers 官方 Quicktour(韩文版docs/source/ko/quicktour.md)的技术导读。你将首先学会用最高层级的DiffusionPipeline一条命令完成文生图推理,再深入拆解 pipeline 内部,亲手用UNet2DModel与DDPMScheduler两个独立组件复刻完整的去噪(denoising)循环,从零生成一张猫的图片。读完后,你既能在几分钟内跑通端到端生成,也能理解 diffusion 推理的底层调用链,为后续自定义 pipeline 与训练打基础。
Diffusion 模型与 Diffusers 的三大核心组件
扩散(diffusion)模型通过「逐步去除随机高斯噪声」来生成图像、音频等目标样本:训练时模型学会把噪声一步步还原为干净数据,推理时则从纯噪声出发,沿着这条逆过程重建出内容。这就是你在互联网上看到的各类 AI 生成图像的底层原理。🧨 Diffusers 的目标,就是让任何人都能方便地使用这些扩散模型。
整个库由三大核心组件构成,本仓库的源码结构与文档分层也严格对应这三者:
DiffusionPipeline:面向推理的高层端到端类,把「模型 + 调度器 + 其他组件」打包成一个可直接调用的对象,用于从预训练扩散模型中快速采样。- 模型(Models):广泛使用的预训练模型架构与模块,如 UNet、Diffusion Transformer(DiT)、VAE 等,是搭建扩散系统的积木。
- 调度器(Schedulers):控制「训练时如何添加噪声」以及「推理时如何从噪声样本一步步去噪」的算法。
以标准的文生图(text-to-image)模型为例,推理时各组件各司其职:文本编码器把提示词转为引导去噪的嵌入向量;调度器承载逐步去噪的算法细节(不同调度器影响生成速度与质量);UNet 或 DiT 在每个时间步执行去噪预测;最后 VAE 负责把压缩的潜空间(latents)解码回像素图像。DiffusionPipeline正是把上述所有组件封装进单一类的产物。
与多数框架「只给成品」不同,Diffusers 的定位是构建扩散系统的工具箱:既可以用
DiffusionPipeline快速使用现成系统,也可以单独挑选模型与调度器组件,自由组合出自定义扩散系统。
安装与环境准备
动手前请确保依赖库已安装。在 Colab 中可直接取消注释执行:
# 주석 풀어서 Colab에 필요한 라이브러리 설치하기. #!pip install --upgrade diffusers accelerate transformers- 🤗 Accelerate:加速推理与训练时的模型加载。
- 🤗 Transformers:运行 Stable Diffusion 这类最流行扩散模型所必需。
安装完成后,按顺序阅读 安装指南 可了解 PyTorch 版本、可选依赖(如diffusers[torch])等更多细节。
DiffusionPipeline:端到端文生图
DiffusionPipeline是使用预训练扩散系统进行推理最简单的方式——它是一个包含模型与调度器的完整端到端系统,可直接用于多种任务。下表列出部分内置任务(完整清单见 🧨 Diffusers Summary 一览表):
| 任务 | 说明 | Pipeline 文档 |
|---|---|---|
| 无条件图像生成 | 从高斯噪声直接生成图像 | unconditional_image_generation |
| 文本引导图像生成 | 根据文本提示词生成图像 | conditional_image_generation |
| 文本引导图生图 | 在文本提示词引导下改造一张图像 | img2img |
| 文本引导图像修复 | 根据图像、掩码与文本提示词填充图像被遮罩的区域 | inpaint |
| 文本引导深度图生图 | 在保持结构(借助深度估计)的同时按提示词改造图像 | depth2img |
加载 pipeline 并生成图像
首先实例化DiffusionPipeline,并指定要下载的 pipeline 检查点(checkpoint)。只要是 Hugging Face Hub 上以 diffusers 格式保存的检查点都可以直接加载。本例以文生图领域的经典检查点stable-diffusion-v1-5/stable-diffusion-v1-5为例:
>>> from diffusers import DiffusionPipeline >>> pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5")[!WARNING] 使用 Stable Diffusion 模型前,请先仔细阅读其模型许可协议。Diffusers 在
safety_checker中实现了安全检测以避免生成冒犯性或有害内容,但由于模型本身强大的图像生成能力,仍可能产生潜在有害内容,请合理合规使用。
from_pretrained会把该 pipeline 的全部建模、分词、调度组件下载并缓存到本地。从源码看,DiffusionPipeline以model_index.json(类属性config_name,见 pipeline_utils.py)记录各组件,并通过register_modules(pipeline_utils.py)把组件注册进配置并绑定为 pipeline 属性。打印 pipeline 即可看到 Stable Diffusion 的组件构成,其中包含UNet2DConditionModel与PNDMScheduler等:
>>> pipeline StableDiffusionPipeline { "_class_name": "StableDiffusionPipeline", "_diffusers_version": "0.13.1", ..., "scheduler": [ "diffusers", "PNDMScheduler" ], ..., "unet": [ "diffusers", "UNet2DConditionModel" ], "vae": [ "diffusers", "AutoencoderKL" ] }该模型约含 14 亿参数,强烈建议在 GPU 上运行。与 PyTorch 一致,把 pipeline 移到 GPU:
>>> pipeline.to("cuda")把文本提示词传入pipeline即可生成图像,去噪完成的图像默认包装为PIL.Image对象,通过.images[0]访问:
>>> image = pipeline("An image of a squirrel in Picasso style").images[0] >>> image调用save保存图像:
>>> image.save("image_of_squirrel_painting.png")使用本地 pipeline
pipeline 也可以完全在本地使用,唯一区别是需要先把权重下载到本地。用 Git LFS 克隆检查点:
!git lfs install !git clone https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5然后把保存的权重加载进 pipeline:
>>> pipeline = DiffusionPipeline.from_pretrained("./stable-diffusion-v1-5")之后的使用方式与上文完全一致。
更换调度器
不同调度器的去噪速度与输出质量各不相同,找到最适合自己的调度器最好的方式就是亲自试一试。Diffusers 的核心特性之一就是可以轻松在调度器之间切换。例如把默认的PNDMScheduler换成EulerDiscreteScheduler,只需用ConfigMixin.from_config从原调度器配置中重建即可:
>>> from diffusers import EulerDiscreteScheduler >>> pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5") >>> pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)之所以能无缝替换,是因为调度器统一继承自SchedulerMixin与ConfigMixin(如 scheduling_euler_discrete.py),配置结构一致。EulerDiscreteScheduler还支持prediction_type("epsilon"/"sample"/"v_prediction")与use_karras_sigmas等参数,详见 调度器使用指南。换上新调度器再生成一次,对比两张图的差异吧。
模型:UNet2DModel 与去噪残差预测
接下来拆解 pipeline 内部的组件。大多数扩散模型接收带噪样本,预测「噪声残差」——即每个时间间隔上,输入图像与更少噪声图像之间的差异(也有模型直接预测前一步样本、或预测速度 /v-prediction)。模型可以任意混搭(mix and match),组合出不同的扩散系统。
模型通过ModelMixin.from_pretrained加载,权重会被缓存到本地,下次加载更快。本例加载基于猫图像训练的无条件图像生成模型UNet2DModel:
>>> from diffusers import UNet2DModel >>> repo_id = "google/ddpm-cat-256" >>> model = UNet2DModel.from_pretrained(repo_id)访问model.config可以查看模型参数:
>>> model.config模型配置是一个「冻结」的字典:模型创建后其参数不可更改。这是有意设计——定义模型架构的参数保持不变,其余参数留给推理时调节。其中最重要的参数有:
sample_size:输入样本的高、宽尺寸;in_channels:输入样本的通道数;down_block_types与up_block_types:构建 UNet 架构所用的下采样 / 上采样块类型;block_out_channels:下采样块的输出通道数(也按倒序用作上采样块的输入通道数);layers_per_block:每个 UNet 块中包含的 ResNet 块数量。
从源码看,UNet2DModel(unet_2d.py)的forward方法签名正是接收sample(带噪输入,形状(batch, channel, height, width))与timestep(去噪时间步),并返回模型输出(unet_2d.py)。推理前,先构造一个与图像形状一致的高斯随机噪声张量。模型支持 batch 推理,因此张量需要包含 batch 轴、对应输入通道数的 channel 轴、以及表示图像高宽的sample_size轴:
>>> import torch >>> torch.manual_seed(0) >>> noisy_sample = torch.randn(1, model.config.in_channels, model.config.sample_size, model.config.sample_size) >>> noisy_sample.shape torch.Size([1, 3, 256, 256])把带噪图像与timestep一起传给模型做一次前向。timestep表示输入图像的噪声程度:开始时噪声更多、结束时噪声更少,模型据此判断自己处于扩散过程的起始还是末尾。用sample方法取得模型输出(这里取timestep=2):
>>> with torch.no_grad(): ... noisy_residual = model(sample=noisy_sample, timestep=2).sample不过,要真正生成一张图,还需要调度器来引导整个去噪过程——这正是下一节的内容。
调度器:DDPMScheduler 与单步去噪
调度器负责在给定模型输出的情况下,把带噪样本推进为噪声更少的样本——这里的模型输出就是上文的noisy_residual。本例用ConfigMixin.from_config实例化DDPMScheduler:
>>> from diffusers import DDPMScheduler >>> scheduler = DDPMScheduler.from_config(repo_id) >>> scheduler DDPMScheduler { "_class_name": "DDPMScheduler", "_diffusers_version": "0.13.1", "beta_end": 0.02, "beta_schedule": "linear", "beta_start": 0.0001, "clip_sample": true, "clip_sample_range": 1.0, "num_train_timesteps": 1000, "prediction_type": "epsilon", "trained_betas": null, "variance_type": "fixed_small" }[!TIP] 注意调度器是从配置实例化的:与模型不同,调度器没有可学习权重,也没有参数!
最重要的参数:
num_train_timesteps:去噪过程的长度,即把随机高斯噪声处理成数据样本所需的 timestep 数量(默认 1000);beta_schedule:训练与推理使用的噪声调度类型(如"linear");beta_start与beta_end:噪声调度的起始与结束噪声值(默认0.0001与0.02)。
对应源码 scheduling_ddpm.py 中,beta_schedule为linear时用torch.linspace(beta_start, beta_end, num_train_timesteps)生成 betas;variance_type支持fixed_small、fixed_large、learned等取值(scheduling_ddpm.py);clip_sample会把预测样本裁剪到clip_sample_range(默认 ±1.0)范围内,防止数值发散。
把模型输出、timestep、当前sample传入调度器的step方法(scheduling_ddpm.py),即可得到噪声更少的样本:
>>> less_noisy_sample = scheduler.step(model_output=noisy_residual, timestep=2, sample=noisy_sample).prev_sample >>> less_noisy_sample.shape把less_noisy_sample作为下一次迭代的输入继续传给下一个timestep,噪声就会越来越少!step内部会先计算alpha_prod_t/alpha_prod_t_prev等累积参数,再按公式反推上一步样本prev_sample(scheduling_ddpm.py)。
组装完整去噪循环:从噪声到猫
把所有环节串起来,可视化完整的去噪过程。首先写一个把去噪样本后处理成PIL.Image的展示函数:
>>> import PIL.Image >>> import numpy as np >>> def display_sample(sample, i): ... image_processed = sample.cpu().permute(0, 2, 3, 1) ... image_processed = (image_processed + 1.0) * 127.5 ... image_processed = image_processed.numpy().astype(np.uint8) ... image_pil = PIL.Image.fromarray(image_processed[0]) ... display(f"Image at step {i}") ... display(image_pil)为加快去噪速度,把输入与模型都移到 GPU:
>>> model.to("cuda") >>> noisy_sample = noisy_sample.to("cuda")现在构建去噪循环:每一步先用模型预测噪声更少样本的残差,再用调度器计算噪声更少的样本,并沿scheduler.timesteps逐时间步推进:
>>> import tqdm >>> sample = noisy_sample >>> for i, t in enumerate(tqdm.tqdm(scheduler.timesteps)): ... # 1. predict noise residual ... with torch.no_grad(): ... residual = model(sample, t).sample ... # 2. compute less noisy image and set x_t -> x_t-1 ... sample = scheduler.step(residual, t, sample).prev_sample ... # 3. optionally look at image ... if (i + 1) % 50 == 0: ... display_sample(sample, i + 1)这个循环与DiffusionPipeline内部的__call__核心逻辑在原理上完全一致:模型负责「预测噪声残差」(对应UNet2DModel.forward),调度器负责「由残差反推上一步样本」(对应DDPMScheduler.step),两者交替执行直至噪声被完全去除。静静观察,一只猫从纯噪声中逐渐浮现。
下一步学习路径
至此你已经用 Diffusers 完成了图像生成,并理解了 pipeline 的底层原理。接下来可以:
- 在 basic_training 训练教程 中训练或微调模型,生成属于自己的图像;
- 参考官方与社区的训练 / 微调脚本示例(如
examples/dreambooth、examples/text_to_image等目录下的完整脚本)覆盖更多使用场景; - 在 调度器使用指南 中了解调度器的加载、访问、更换与对比;
- 阅读 Stable Diffusion 指南,学习提示词工程、速度与内存优化、高质量图像生成技巧;
- 通过 GPU 上的 PyTorch 优化(fp16)、Apple Silicon(M1/M2)上的 Stable Diffusion(mps) 与 ONNX Runtime 推理 等指南,进一步为 Diffusers 推理提速。
附:本文涉及的仓库源码与文档路径
- 核心 Pipeline 基类:src/diffusers/pipelines/pipeline_utils.py(
DiffusionPipeline、from_pretrained、register_modules) - 无条件图像生成模型:src/diffusers/models/unets/unet_2d.py(
UNet2DModel及其forward) - DDPM 调度器:src/diffusers/schedulers/scheduling_ddpm.py(
DDPMScheduler.step) - PNDM 调度器:src/diffusers/schedulers/scheduling_pndm.py
- Euler 调度器:src/diffusers/schedulers/scheduling_euler_discrete.py
- 安全检测器:src/diffusers/pipelines/stable_diffusion/safety_checker.py
- 英文版 Quicktour 及扩展内容:docs/source/en/quicktour.md(含 LoRA、量化、显存/速度优化示例)
【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考