Stable Diffusion XL on diffusers

Stable Diffusion XL on diffusers

翻译自:https://huggingface.co/docs/diffusers/using-diffusers/sdxl v0.24.0 非逐字翻译

Stable Diffusion XL (SDXL) 是一个强大的图像生成模型,其在上一代 Stable Diffusion 的基础上主要做了如下优化:

  1. 参数量增加:SDXL 中 Unet 的参数量比前一代大了 3 倍,并且 SDXL 还引入了第二个 text-encoder(OpenCLIP ViT-bigG/14),整体参数量大幅增加。
  2. 引入了 size-conditioning 和 crop conditioning,在训练阶段有效利用起低分辨率图像,并在推理对生成的图片是否需要裁剪有更好的控制。
  3. 使用了两阶段的生成过程,除了第一阶段的 base 模型生成之外,还加入了一个 refiner 模型,使得生成图像的细节质量更高(其中 base 模型也可以单独使用,直接生成)

本文将介绍如何使用 diffusers 进行 text-to-image、image-to-image 和 inpainting。

加载模型参数

模型参数分别保存在不同的子目录中,可以使用 from_pretrained 方法来加载:

from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
import torchpipeline = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")refiner = StableDiffusionXLImg2ImgPipeline.from_pretrained("stabilityai/stable-diffusion-xl-refiner-1.0", torch_dtype=torch.float16, use_safetensors=True, variant="fp16"
).to("cuda")

也可以使用 from_single_file 方法来从单个文件 ( .ckpt 或 .safetensors) 中加载:

from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
import torchpipeline = StableDiffusionXLPipeline.from_single_file("https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0.safetensors", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")refiner = StableDiffusionXLImg2ImgPipeline.from_single_file("https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/blob/main/sd_xl_refiner_1.0.safetensors", torch_dtype=torch.float16, use_safetensors=True, variant="fp16"
).to("cuda")

text-to-image

在进行 text-to-image 生成时,需要传入文本 prompt。SDXL 默认生成分辨率为 1024 * 1024,也可以设置为 768 或 512,但不要再低于 512 了:

from diffusers import AutoPipelineForText2Image
import torchpipeline_text2image = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipeline_text2image(prompt=prompt).images[0]
image

在这里插入图片描述

image-to-image

在进行 image-to-image 生成时,SDXL 在 768 - 1024 这个分辨率区间工作的最好。此时需要输入一张原始图像,并给一段文本 prompt:

from diffusers import AutoPipelineForImage2Image
from diffusers.utils import load_image, make_image_grid# 使用 from_pipe,避免在加载 checkpoint 时消耗额外的内存
pipeline = AutoPipelineForImage2Image.from_pipe(pipeline_text2image).to("cuda")url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
init_image = load_image(url)
prompt = "a dog catching a frisbee in the jungle"
image = pipeline(prompt, image=init_image, strength=0.8, guidance_scale=10.5).images[0]
make_image_grid([init_image, image], rows=1, cols=2)

在这里插入图片描述

inpainting

在记性 inpainting 时,需要传入一张原始图片和原始图片中你想要修改部分的 mask 图,并给一个文本 prompt 来描述 mask 区域需要生成什么内容:

from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_gridpipeline = AutoPipelineForInpainting.from_pipe(pipeline_text2image).to("cuda")img_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
mask_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-inpaint-mask.png"init_image = load_image(img_url)
mask_image = load_image(mask_url)prompt = "A deep sea diver floating"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, strength=0.85, guidance_scale=12.5).images[0]
make_image_grid([init_image, mask_image, image], rows=1, cols=3)

在这里插入图片描述

refine image quality

SDXL 相比于之前的 SD 模型,一个很大的差别在于它包含了一个 refiner 模型。refiner 模型 可以接收 base 模型经过几步去噪之后的低噪声图像,并为图像生成更多高质量的细节。有两种使用 refiner 模型的方式:

  1. 同时使用 base 模型和 refiner 模型,来生成高质量图片
  2. 使用 base 模型生成一张图片,然后使用 refiner 模型为图片添加更多的细节(这是 SDXL 训练时的方式)

接下来分别介绍这两种方式的使用。

base + refiner model

当使用第一种方式,即同时使用 base 模型和 refiner 模型来生成图片时,称为 ensemble of expert denoisers。这种方式相比于第二种将 base 模型的输出给 refiner 模型中的方式来说,整体需要的去噪步数更少,因此会快很多。但这种方式我们看到的 base 模型的输出是带有一些噪声的。

在第一种方式中,base 模型负责高噪声阶段的去噪,refiner 模型负责低噪声阶段的去噪。首先加载 base 模型和 refiner 模型:

from diffusers import DiffusionPipeline
import torchbase = DiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")refiner = DiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-xl-refiner-1.0",text_encoder_2=base.text_encoder_2,vae=base.vae,torch_dtype=torch.float16,use_safetensors=True,variant="fp16",
).to("cuda")

在使用 ensemble of expert denoisers 这种方式时,我们需要定义不同的模型在他们各自阶段的去噪步数。对于 base 模型,需要 denoising_end 参数,对于 refiner 模型,需要 denoising_start 参数。

denoising_startdenoising_end 参数都时 0-1 之间的一个小数,用于表示当前 schduler 下步数的比例。如果同时还传入了 strength 参数,它将被忽略,因为去噪步骤的数量是由模型训练的离散时间步长和声明的比例截止值决定的。

这里,我们设置 denoising_end 为 0.8,从而 base 模型会负责前 80% 的高噪声阶段的降噪,并设置 denoising_start 为 0.8,从而 refiner 模型会负责后 20% 的低噪声阶段的降噪。注意 base 模型的输出是在隐层 latent 空间的,而非可见的图片。

prompt = "A majestic lion jumping from a big stone at night"image = base(prompt=prompt,num_inference_steps=40,denoising_end=0.8,output_type="latent",
).images
image = refiner(prompt=prompt,num_inference_steps=40,denoising_start=0.8,image=image,
).images[0]
image

在这里插入图片描述

在 StableDiffusionXLInpaintPipeline 中,refiner 模型也可以用于进行 inpainting:

from diffusers import StableDiffusionXLInpaintPipeline
from diffusers.utils import load_image, make_image_grid
import torchbase = StableDiffusionXLInpaintPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")refiner = StableDiffusionXLInpaintPipeline.from_pretrained("stabilityai/stable-diffusion-xl-refiner-1.0",text_encoder_2=base.text_encoder_2,vae=base.vae,torch_dtype=torch.float16,use_safetensors=True,variant="fp16",
).to("cuda")img_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo.png"
mask_url = "https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo_mask.png"init_image = load_image(img_url)
mask_image = load_image(mask_url)prompt = "A majestic tiger sitting on a bench"
num_inference_steps = 75
high_noise_frac = 0.7image = base(prompt=prompt,image=init_image,mask_image=mask_image,num_inference_steps=num_inference_steps,denoising_end=high_noise_frac,output_type="latent",
).images
image = refiner(prompt=prompt,image=image,mask_image=mask_image,num_inference_steps=num_inference_steps,denoising_start=high_noise_frac,
).images[0]
make_image_grid([init_image, mask_image, image.resize((512, 512))], rows=1, cols=3)

这种 ensemble of expert denoisers 的方式对于所有 scheduler 都可用。

base to refiner model

第二种方式通过 base 模型先生成一张完全去噪的图片,然后使用 refiner 模型以 image-to-image 的形式,为图片添加更多的高质量细节,这使得 SDXL 的生成质量有了极大的提高。首先加载 base 和 refiner 模型:

from diffusers import DiffusionPipeline
import torchbase = DiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")refiner = DiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-xl-refiner-1.0",text_encoder_2=base.text_encoder_2,vae=base.vae,torch_dtype=torch.float16,use_safetensors=True,variant="fp16",
).to("cuda")

先使用 base 模型生成一张图片,注意将输出形式设置为 latent:

prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"image = base(prompt=prompt, output_type="latent").images[0]

将生成的图片输入到 refiner 模型中:

image = refiner(prompt=prompt, image=image[None, :]).images[0]

在这里插入图片描述

要进行 inpainting,在 StableDiffusionXLInpaintPipeline 中加载 base 和 refiner 模型,去掉 denoising_enddenoising_start 参数,并为 refiner 模型设置一个较小的步数。

micro-conditioning

SDXL 训练时使用了许多额外的条件方式,即 micro-conditioning,包括 original_image_size、target_image_size 和 cropping parameters。在推理阶段,合理地使用 micro-conditioning 可以生成高质量的、居中的图片。

由于 classfier-free guidance 的存在,可以在 SDXL 相关的 pipeline 中使用 micro-conditioning 和 negative micro-conditioning 参数。

size conditioning

size conditioning 有两种:

  1. original size conditioning。训练集中有许多图片的分辨率是较低的,但又不能直接不用这些低分辨率图像(占比达 40%,丢了太浪费了),因此通常会对这些图像进行 resize,从而得到高分辨率的图像。在这个过程中,不可避免得会引入插值这种人工合成的模糊痕迹,被 SDXL 学到,而在真正的高分辨率图像中,是不该有这些痕迹的。因此训练时会告诉模型,这张图片实际是多少分辨率的,作为条件。

    在推理阶段,我们可以指定 original_size 来表示图像的原始尺寸。使用默认的 1024,能生成出与原始数据集中高分辨率图像类似的高质量图像。而如果将这个值设得很低,如 256,模型还是会生成分辨率为 1024 的图像,但就会带有低分辨率图像的特征(如模糊、模式简单等)。

  2. target size conditioning。SDXL 训练时支持多种不同的长宽比。

    推理时,如果使用默认的值 1024,生成的图像会看起来像方形图像(长宽比1:1)。这里建议将 target_size 和 original_size 设置为相同的值,但你也可以调一调这些参数实验一下看看。

在 diffusers 中,我们还可以指定有关图像大小的 negative 条件,从而引导生成远离某些图像分辨率:

from diffusers import StableDiffusionXLPipeline
import torchpipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipe(prompt=prompt,negative_original_size=(512, 512),negative_target_size=(1024, 1024),
).images[0]

在这里插入图片描述

crop conditioning

SDXL 之前的 SD 模型的生成结果有时会看起来像是被裁剪过得。这是因为为了保证训练时每个 batch 内的尺寸一致,输入的训练数据确实有很多是裁剪过的。因此训练时,裁剪坐标也会作为条件给到模型。从而,在推理时,我们将裁剪坐标指定为 (0, 0) (也是 diffusers 默认值),就可以生成非裁剪的图片了。你也可以试着调一下裁剪坐标这个参数,看模型的生成结果会是什么样子,应该可以得到非居中的构图。

from diffusers import StableDiffusionXLPipeline
import torchpipeline = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipeline(prompt=prompt, crops_coords_top_left=(256, 0)).images[0]
image

在这里插入图片描述

同样可以指定 negative 裁剪坐标以引导生成远离某些裁剪参数:

from diffusers import StableDiffusionXLPipeline
import torchpipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipe(prompt=prompt,negative_original_size=(512, 512),negative_crops_coords_top_left=(0, 0),negative_target_size=(1024, 1024),
).images[0]
image

Use a different prompt for each text-encoder

SDXL 有两个 text encoder,所以给两个 text encoder 传入不同的文本 prompt 是可能的,这可以提高生成质量(参考)。将原本的 prompt 传到 prompt 中,另一个 prompt 传到 prompt_2 中。如果使用 negative prompt 也是类似的,分别传到 negative_promptnegative_prompt_2

from diffusers import StableDiffusionXLPipeline
import torchpipeline = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16", use_safetensors=True
).to("cuda")# prompt is passed to OAI CLIP-ViT/L-14
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
# prompt_2 is passed to OpenCLIP-ViT/bigG-14
prompt_2 = "Van Gogh painting"
image = pipeline(prompt=prompt, prompt_2=prompt_2).images[0]
image

SDXL 的双 text encoder 同样支持 textual inversion embeddings,需要分别加载,详情见:SDXL textual inversion 。

Optimizations

SDXL 的模型还是很大的,可能在一些设备上运行会比较吃力,以下是一些节约内存和提高推理速度的技巧。

  1. 如果显存不够,可以临时将模型 offload 到内存中

    # base.to("cuda")
    # refiner.to("cuda")
    base.enable_model_cpu_offload()
    refiner.enable_model_cpu_offload()
    
  2. 如果你使用的 torch 版本 > 2.0,那么使用 torch.cmpile 可以提速约 20%

    base.unet = torch.compile(base.unet, mode="reduce-overhead", fullgraph=True)
    refiner.unet = torch.compile(refiner.unet, mode="reduce-overhead", fullgraph=True)
    
  3. 如果你使用的 torch 版本 < 2.0,记得要用 xFormers 来提供 flash attention

    base.enable_xformers_memory_efficient_attention()
    refiner.enable_xformers_memory_efficient_attention()
    

Other resources

如果你想要研究下 SDXL 中 UNet2DConditionModel 的最小版本,可参考minSDXL 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/207135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生产上线需要注意的安全漏洞

一、关闭swagger 1、关闭swagger v3 # 需同时设置auto-startupfalse&#xff0c;否则/v3/api-docs等接口仍能继续访问 springfox:documentation:enabled: falseauto-startup: falseswagger-ui:enabled: false 2、关闭swagger v2 # 只要不是true就不启用 swagger:enable: fa…

代立冬:基于Apache Doris+SeaTunnel 实现多源实时数据仓库解决方案探索实践

大家好&#xff0c;我是白鲸开源的联合创始人代立冬&#xff0c;同时担任 Apache DolphinScheduler 的 PMC chair 和 SeaTunnel 的 PMC。作为 Apache Foundation 的成员和孵化器导师&#xff0c;我积极参与推动多个开源项目的发展&#xff0c;帮助它们通过孵化器成长为 Apache …

某度旋转验证码v2 逆向分析

v2主要依据是核心 JS 文件mkd_v2.js 版本&#xff0c;如下图所示&#xff1a; 第一次 https://passport.baidu.com/cap/init 接口&#xff0c;请求的 ak 是固定值&#xff0c;当然不同场景不同网站是不一样的&#xff0c;_ 时间戳&#xff0c;ver1&#xff0c;返回值 as、tk 都…

android项目实战之使用框架 集成多图片、视频的上传

效果图 实现方式&#xff0c;本功能使用PictureSelector 第三方库 。作者项目地址&#xff1a;https://github.com/LuckSiege/PictureSelector 1. builder.gradle 增加 implementation io.github.lucksiege:pictureselector:v3.11.1implementation com.tbruyelle.rxpermissio…

线性回归实战

3.1 使用正规方程进行求解 3.1.1 简单线性回归 公式 &#xff1a; y w x b y wx b ywxb 一元一次方程&#xff0c;在机器学习中一元表示一个特征&#xff0c;b表示截距&#xff0c;y表示目标值。 使用代码进行实现&#xff1a; 导入包 import numpy as np import matp…

中缀表达式转后缀表达式与后缀表达式计算(详解)

**中缀表达式转后缀表达式的一般步骤如下&#xff1a; 1&#xff1a;创建一个空的栈和一个空的输出列表。 2&#xff1a;从左到右扫描中缀表达式的每个字符。 3&#xff1a;如果当前字符是操作数&#xff0c;则直接将其加入到输出列表中。 4&#xff1a;如果当前字符是运算符&a…

Linux 常用命令汇总

1 linux定时任务 查看定时任务&#xff1a;crontab -l 每晚一点半执行定时任务&#xff1a; 30 1 * * * sh /var/lib/pgsql/pg_db_backup.sh >> /var/lib/pgsql/pg_db_backup.log 2>&1 配置定时任务&#xff1a;crontab -e 2 linux 内核版本查询 cat /etc/r…

我有才打造私域流量的知识付费小程序平台

在当今数字化时代&#xff0c;知识付费市场正在迅速崛起&#xff0c;而私域流量的概念也日益受到重视。私域流量指的是企业通过自有渠道获取的、能够自由支配的流量&#xff0c;这种流量具有更高的用户粘性和转化率。因此&#xff0c;打造一个基于私域流量的知识付费小程序平台…

实现:切换页面切换标题,扩展 vue-router 的类型

布局容器-页面标题 网址&#xff1a;https://router.vuejs.org/zh/guide/advanced/meta 给每一个路由添加 元信息 数据 router/index.ts const router createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{ path: /login, component: () > im…

第一启富金:新添澳大利亚(ASIC)牌照

第一启富金&#xff1a;澳大利亞證券及投資委員會&#xff08;ASIC&#xff09; GOLDWELL GLOBAL PTY LTD 是 WHOLESALE INVESTOR SERVICES PTY LTD&#xff08;CAR 編號 001304943&#xff09;的企業授權代表開發澳大利亞客戶&#xff0c;WHOLESALE INVESTOR SERVICES PTY LT…

XML是什么

XML是是什么&#xff1f; XML&#xff08;Extensible Markup Language&#xff09;&#xff0c;中文是可扩展标记语言&#xff0c;是标准通用标记语言的子集。它是一种标记语言&#xff0c;用于标记电子文档&#xff0c;使其结构化。 XML可以用来标记数据&#xff0c;定义数据…

【软件推荐】文本转语音,语音转wav,导入ue5

文字转语音 在线免费文字转语音 - TTSMaker官网 | 马克配音https://ttsmaker.cn/ 文件转换器 语音转wav Convertio — 文件转换器https://convertio.co/zh/

HarmonyOS应用程序框架——UIAbility实操

UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。 每一个UIAbility实例&#xff0c;都对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&…

Leetcode—901.股票价格跨度【中等】

2023每日刷题&#xff08;五十二&#xff09; Leetcode—901.股票价格跨度 算法思想 实现代码 class StockSpanner { public:stack<pair<int, int>> st;int curday -1;StockSpanner() {st.emplace(-1, INT_MAX);}int next(int price) {while(price > st.top(…

油猴(Tampermonkey)浏览器插件简单自定义脚本开发

介绍 浏览器插件&#xff0c;包括油猴插件和其他插件&#xff0c;通过它们可以实现浏览器网页的定制化与功能增强。 其他插件一般只有某种具体的功能&#xff0c;且已经写死而不能更改&#xff0c;比如Adblock插件只用于去广告。 油猴插件是一款用于管理用户脚本的插件&…

使用Rust 构建C 组件

协议解析&#xff0c;这不就很快了&#xff0c;而且原生的标准库红黑树和avl 树支持&#xff0c;异步tokio 这些库&#xff0c;编写应用组件就很快了 rust 标准库不支持 unix 的消息队列&#xff0c;但是支持 shm 和 uds&#xff0c;后者从多方面考虑都比&#xff0c;消息队列更…

教育类直播介绍

教育类直播是一种在线教育形式&#xff0c;它允许学生和教师通过实时视频通话进行互动学习。这种学习方式可以为学生提供更灵活的学习时间和地点&#xff0c;同时也可以帮助教师更好地与学生进行互动和指导。 在教育类直播中&#xff0c;学生可以通过网络与教师和其他学生进行…

c/c++中一些不常用但有用的知识

1.变长数组 bool fun(int cnt) {unsigned char data[cnt];return true; } 在 C 语言中&#xff0c;变长数组&#xff08;Variable Length Arrays&#xff0c;VLA&#xff09;是 C99 标准引入的特性&#xff0c;允许使用变量来定义数组的长度。因此&#xff0c;在 C 版本的代码…

快速在VMware虚拟机上运行Kali Linux(保姆级教程)

本期将演示如何在VMware虚拟机上快速、轻松地安装Kali Linux。Kali Linux是一款专为渗透测试和网络安全而设计的操作系统&#xff0c;拥有很多强大的工具和功能。 在运行任何虚拟机之前&#xff0c;一定要先确保已经打开主板BIOS上的虚拟化支持。 下载VMware 接着来到vmware的…

vue 一直运行 /sockjs-node/info?及 /sockjs-node/info报错解决办法

sockjs-node介绍 sockjs-node 是一个JavaScript库&#xff0c;提供跨浏览器JavaScript的API&#xff0c;创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。 服务端&#xff1a;sockjs-node&#xff08;https://github.com/sockjs/sockjs-node&#xff09; 客户端&a…