Stable Diffusion XL on diffusers

这篇具有很好参考价值的文章主要介绍了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 torch

pipeline = 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 torch

pipeline = 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 torch

pipeline_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

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

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)

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

inpainting

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

from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid


pipeline = 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)

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

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 torch

base = 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

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

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

from diffusers import StableDiffusionXLInpaintPipeline
from diffusers.utils import load_image, make_image_grid
import torch

base = 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.7

image = 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 torch

base = 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]

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

要进行 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 torch

pipe = 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]

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

crop conditioning

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

from diffusers import StableDiffusionXLPipeline
import torch

pipeline = 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

importerror: cannot import name 'stablediffusionxlpipeline' from 'diffusers,diffusion,stable diffusion,人工智能,深度学习

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

from diffusers import StableDiffusionXLPipeline
import torch

pipe = 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 torch

pipeline = 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 。文章来源地址https://www.toymoban.com/news/detail-839700.html

到了这里,关于Stable Diffusion XL on diffusers的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Stable Diffusion XL搭建

    这里主要介绍如何从0到1搭建Stable Diffusion XL进行AI绘画。 Stable Diffusion XL是Stable Diffusion的优化版本,由Stability AI发布。比起Stable Diffusion,Stable Diffusion XL做了全方位的优化,Rocky相信,Stable Diffusion会是图像生成领域的“YOLO”,而Stable Diffusion XL那就是“YOLOv3”。 零基础使用Co

    2024年02月11日
    浏览(28)
  • Stable Diffusion XL 0.9

    虽然此前CEO曾陷入种种争议,但依然不影响Stability AI登上时代杂志。近日,该公司又发布了Stable Diffusion 的XL 0.9版本,35亿+66亿双模型,搭载最大OpenCLIP,让AI生图质量又有了新的飞跃。 Stable Diffusion又双叒升级了! 最近,Stability AI发布了最新版的Stable Diffusion XL 0.9(SDXL 0.9)。

    2024年02月12日
    浏览(29)
  • Stable Diffusion-XL

    开源、免费的Stable Diffusion就能达到Midjourney水平! 自从Midjourney发布v5之后,在生成图像的人物真实程度、手指细节等方面都有了显著改善,并且在prompt理解的准确性、审美多样性和语言理解方面也都取得了进步。 相比之下,Stable Diffusion虽然免费、开源,但每次都要写一大长

    2024年02月15日
    浏览(30)
  • Stable Diffusion 模型分享:DreamShaper XL(梦想塑造者 XL)

    本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。

    2024年03月24日
    浏览(38)
  • 【已解决cannot import name ‘OrderedDict‘ from ‘typing‘】

    在import tensorflow as tf 时报错no mould tensorflow,自然而然想到pip一下,但是pip一直显示成功,并且不会报任何错 由于我下载的是python3.7版本,tensorflow可能需要下载补丁包,故在网上查询解决方案: 在下载后,将该目录下的function_type.py中的 改为 此时依旧会报错 cannot import name ‘

    2024年02月16日
    浏览(32)
  • Stable Diffusion XL优化终极指南

    如何在自己的显卡上获得SDXL的最佳质量和性能,以及如何选择适当的优化方法和工具,这一让GenAI用户倍感困惑的问题,业内一直没有一份清晰而详尽的评测报告可供参考。直到全栈开发者Félix San出手。 在本文中,Félix介绍了相关SDXL优化的方法论、基础优化、Pipeline优化以

    2024年04月26日
    浏览(27)
  • Stable Diffusion XL训练LoRA

    主要包括SDXL模型结构,从0到1训练SDXL以及LoRA教程,从0到1搭建SDXL推理流程。  【一】SDXL训练初识 Stable Diffusion系列模型的训练主要分成一下几个步骤,Stable Diffusion XL也不例外: 训练集制作:数据质量评估,标签梳理,数据清洗,数据标注,标签清洗,数据增强等。 训练文

    2024年02月07日
    浏览(29)
  • cannot import name ‘_compare_version‘ from ‘torchmetrics.utilities.imports‘

    Traceback (most recent call last): File “/scratch/AzureNfsServer_INPUT1/vc_data/users/willing/home/mQG/src/1_train.py”, line 14, in import pytorch_lightning as pl File “/home/aiscuser/.conda/envs/willing/lib/python3.9/site-packages/pytorch_lightning/ init .py”, line 34, in from pytorch_lightning.callbacks import Callback # noqa: E402 File “/home/ai

    2024年01月16日
    浏览(32)
  • python报错:cannot import name ‘int‘ from ‘numpy‘

    在Python中导入包时出现报错 报错原因是numpy版本不支持该引用,np.int在numpy1.20已经被废弃掉了 在Anaconda Prompt中查看自己所使用的numpy版本 使用以下命令:  我用的numpy版本是1.24.3,出现了报错 解决方法:更换numpy版本 同样在Anaconda Prompt中输入以下命令: 我重新安装的是1.22

    2024年02月09日
    浏览(40)
  • Stable Diffusion XL(SDXL)原理详解

    😘关注公众号 funNLPer 畅读全文😘 技术报告:SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis 官方代码:Stability-AI-generative-models 模型权重:HuggingFace-Stability AI 非官方代码:Linaqruf/kohya-trainer diffuser库:diffusers/pipelines/stable_diffusion_xl

    2024年02月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包