当前位置: 首页 > news >正文

【diffusers 极速入门(二)】如何得到扩散去噪的中间结果?Pipeline callbacks 管道回调函数

本文是对 Hugging Face Diffusers 文档中关于回调函数的翻译与总结,:


管道回调函数

在管道的去噪循环中,可以使用callback_on_step_end参数添加自定义回调函数。该回调函数在每一步结束时执行,并修改管道属性和变量,以供下一步使用。这在动态调整某些管道属性或修改张量变量时非常有用。利用回调函数,你可以实现新的功能而无需修改底层代码。

目前,Diffusers 仅支持callback_on_step_end,如果你有其他执行点的回调需求,可以在 github 上提出功能请求。

官方回调函数

官方提供了一些可用于修改去噪循环的回调函数列表:

  • SDCFGCutoffCallback:在一定步数后禁用 CFG。对于 SD 1.5 pipelines 适用, 包括 text-to-image, image-to-image, inpaint, controlnet。
  • SDXLCFGCutoffCallback:在一定步数后禁用 CFG。对于 SDXL pipelines 适用, 包括 text-to-image, image-to-image, inpaint, controlnet。
  • IPAdapterScaleCutoffCallback:在一定步数后禁用 IP Adapter。对所有支持 IP-Adapter 的 pipelines 适用。

要设置回调函数,可以指定cutoff_step_ratiocutoff_step_index参数。

  • cutoff_step_ratio:带有步长比的浮点数。
  • cutoff_step_index:一个整数,包含步数的确切编号。

示例代码

import torch
from diffusers import DPMSolverMultistepScheduler, StableDiffusionXLPipeline
from diffusers.callbacks import SDXLCFGCutoffCallbackcallback = SDXLCFGCutoffCallback(cutoff_step_ratio=0.4)
# 也可以用 cutoff_step_index
# callback = SDXLCFGCutoffCallback(cutoff_step_ratio=None, cutoff_step_index=10)pipeline = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0",torch_dtype=torch.float16,variant="fp16",
).to("cuda")
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config, use_karras_sigmas=True)prompt = "a sports car at the road, best quality, high quality, high detail, 8k resolution"
generator = torch.Generator(device="cpu").manual_seed(2628670641)out = pipeline(prompt=prompt,negative_prompt="",guidance_scale=6.5,num_inference_steps=25,generator=generator,callback_on_step_end=callback,
)out.images[0].save("official_callback.png")

在这里插入图片描述

动态无分类器引导

动态无分类器引导(classifier-free guidance,CFG)允许在一定步数后禁用 CFG,从而节省计算成本。回调函数应包含以下参数:

  • pipeline:访问管道实例属性(如num_timesteps和guidance_scale)。
  • step_indextimestep:当前步骤索引和时间步。在达到num_timesteps的40%后,使用step_index关闭CFG。
  • callback_kwargs:包含在去噪循环中可以修改的张量变量。是一个dict,包含可以在去噪循环中修改的张量变量。
    • 它只包括callback_on_step_end_tensor_inputs参数中指定的变量,该参数被传递给管道的__call__方法。
    • 不同的管道可能使用不同的变量集,因此请检查管道的_callback_tensor_inputs属性以获取可以修改的变量列表。一些常见的变量包括latents和prompt_embeds。
    • 对于此函数,请在将guidance_scale设置为0.0后更改prompt_embeds的批处理大小,以使其正常工作。

示例回调函数:

def callback_dynamic_cfg(pipe, step_index, timestep, callback_kwargs):
# adjust the batch_size of prompt_embeds according to guidance_scaleif step_index == int(pipeline.num_timesteps * 0.4):prompt_embeds = callback_kwargs["prompt_embeds"]prompt_embeds = prompt_embeds.chunk(2)[-1]# update guidance_scale and prompt_embedspipeline._guidance_scale = 0.0callback_kwargs["prompt_embeds"] = prompt_embedsreturn callback_kwargs

每步生成后显示图像(中间结果)

通过访问并转换潜在空间,可以在每步生成后显示图像。以下函数将 SDXL 的潜在空间(4 通道)转换为 RGB 张量(3 通道)。

  1. 使用以下函数将SDXL潜伏时间(4个通道)转换为RGB张量(3个通道)
def latents_to_rgb(latents):weights = ((60, -60, 25, -70),(60,  -5, 15, -50),(60,  10, -5, -35))weights_tensor = torch.t(torch.tensor(weights, dtype=latents.dtype).to(latents.device))biases_tensor = torch.tensor((150, 140, 130), dtype=latents.dtype).to(latents.device)rgb_tensor = torch.einsum("...lxy,lr -> ...rxy", latents, weights_tensor) + biases_tensor.unsqueeze(-1).unsqueeze(-1)image_array = rgb_tensor.clamp(0, 255)[0].byte().cpu().numpy()image_array = image_array.transpose(1, 2, 0)return Image.fromarray(image_array)
  1. 使用该函数在每步生成后解码并保存潜在空间为图像。
def decode_tensors(pipe, step, timestep, callback_kwargs):latents = callback_kwargs["latents"]image = latents_to_rgb(latents)image.save(f"{step}.png")return callback_kwargs
  1. decode_tensors函数传递给callback_on_step_end参数,以在每一步之后对张量进行解码。还需要在callback_on_step_end_tensor_inputs参数中指定要修改的内容,在本例中为 latents。
from diffusers import AutoPipelineForText2Image
import torch
from PIL import Imagepipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0",torch_dtype=torch.float16,variant="fp16",use_safetensors=True
).to("cuda")image = pipeline(prompt="A croissant shaped like a cute bear.",negative_prompt="Deformed, ugly, bad anatomy",callback_on_step_end=decode_tensors,callback_on_step_end_tensor_inputs=["latents"],
).images[0]

在这里插入图片描述

详细内容请参见Hugging Face Diffusers 官方文档。

相关文章:

  • 移植案例与原理 - HDF驱动框架-驱动配置(2)
  • Linux常用操作大全(下)
  • Google 广告VS Facebook广告:哪个更适合我?2024全维度区别详解
  • 中国500米分辨率年平均LAI数据集(2000-2020)
  • PLC模拟量和数字量到底有什么区别?
  • 【Liunx】基础开发工具的使用介绍-- yum / vim / gcc / gdb / make
  • Vue CLI,Vue Router,Vuex
  • 浅谈疫情后IT业的挑战和机会
  • 【计算机网络体系结构】计算机网络体系结构实验-DNS模拟器实验
  • 第四篇:精通Docker构建:Dockerfile的艺术与策略
  • springboot mybatis mysql新增后返回id(ai生成)
  • 【宠粉赠书】科技图表绘制:R语言数据可视化
  • Cesium中实现SPH流体模拟
  • 虚拟现实环境下的远程教育和智能评估系统(十)
  • 微信小程序学习(八):behaviors代码复用
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 11111111
  • canvas 高仿 Apple Watch 表盘
  • JavaScript类型识别
  • PHP 7 修改了什么呢 -- 2
  • Spring核心 Bean的高级装配
  • vue 配置sass、scss全局变量
  • vue.js框架原理浅析
  • zookeeper系列(七)实战分布式命名服务
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 当SetTimeout遇到了字符串
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 爬虫模拟登陆 SegmentFault
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 手写双向链表LinkedList的几个常用功能
  • 数据科学 第 3 章 11 字符串处理
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 我的zsh配置, 2019最新方案
  • 追踪解析 FutureTask 源码
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • ​力扣解法汇总946-验证栈序列
  • ‌Excel VBA进行间比法设计
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • ${ }的特别功能
  • (2)空速传感器
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (C语言)fgets与fputs函数详解
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (Note)C++中的继承方式
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (回溯) LeetCode 78. 子集
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .cn根服务器被攻击之后
  • .gitignore文件设置了忽略但不生效
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET和.COM和.CN域名区别