SDXL总结

SDXL base部分的权重:https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main

diffusers库中的SDXL代码pipelines:

https://github.com/huggingface/diffusers/tree/main/src/diffusers/pipelines/stable_diffusion_xl

参考:深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识 - 知乎 (zhihu.com)


 Stable Diffusion XL是一个二阶段的级联扩散模型(Latent Diffusion Model),包括Base模型和Refiner模型。其中Base模型的主要工作和Stable Diffusion 1.x-2.x一致,具备文生图(txt2img)、图生图(img2img)、图像inpainting等能力。在Base模型之后,级联了Refiner模型,对Base模型生成的图像Latent特征进行精细化提升,其本质上是在做图生图的工作

SDXL Base模型由U-Net、VAE以及CLIP Text Encoder(两个)三个模块组成

SDXL Refiner模型同样由U-Net、VAE和CLIP Text Encoder(一个)三个模块

1.VAE

VAE Encoder与VAE Decoder结构图 

VAE官方开源权重:https://huggingface.co/stabilityai/sdxl-vae

Stable Diffusion XL VAE模型与之前的Stable Diffusion系列并不兼容。如果在SDXL上使用之前系列的VAE,会生成充满噪声的图片。

Stable Diffusion XL VAE采用FP16精度时会出现数值溢出成NaNs的情况,导致重建的图像是一个黑图,所以必须使用FP32精度进行推理重建。

import cv2
import torch
import numpy as np
from diffusers import AutoencoderKL# 加载SDXL VAE模型: SDXL VAE模型可以通过指定subfolder文件来单独加载。
# SDXL VAE模型权重百度云网盘:关注Rocky的公众号WeThinkIn,后台回复:SDXL模型,即可获得资源链接
VAE = AutoencoderKL.from_pretrained("/本地路径/sdxl-vae")
VAE.to("cuda") # 用OpenCV读取和调整图像大小
raw_image = cv2.imread("test_vae.png")
raw_image = cv2.cvtColor(raw_image, cv2.COLOR_BGR2RGB)
raw_image = cv2.resize(raw_image, (1024, 1024))# 将图像数据转换为浮点数并归一化
image = raw_image.astype(np.float32) / 127.5 - 1.0# 调整数组维度以匹配PyTorch的格式 (N, C, H, W)
image = image.transpose(2, 0, 1)
image = image[None, :, :, :]# 转换为PyTorch张量
image = torch.from_numpy(image).to("cuda")# 压缩图像为Latent特征并重建
with torch.inference_mode():# 使用SDXL VAE进行压缩和重建latent = VAE.encode(image).latent_dist.sample()rec_image = VAE.decode(latent).sample# 后处理rec_image = (rec_image / 2 + 0.5).clamp(0, 1)rec_image = rec_image.cpu().permute(0, 2, 3, 1).numpy()# 反归一化rec_image = (rec_image * 255).round().astype("uint8")rec_image = rec_image[0]# 保存重建后图像cv2.imwrite("reconstructed_sdxl.png", cv2.cvtColor(rec_image, cv2.COLOR_RGB2BGR))

 2.Unet

SDXL Base部分的 U-Net的完整结构图

 Stable Diffusion XL中的Text Condition信息由两个Text Encoder提供(OpenCLIP ViT-bigG和OpenAI CLIP ViT-L),将两个Text Encoder提取的Token Embedding进行Contact,通过Cross Attention组件嵌入,作为K Matrix和V Matrix。与此同时,图片的Latent Feature作为Q Matrix

3.Text Encoder模型

Stable Diffusion XL分别提取两个Text Encoder的倒数第二层特征,并进行concat操作作为文本条件(Text Conditioning)。其中OpenCLIP ViT-bigG的特征维度为77x1280,而OpenAI CLIP ViT-L/14的特征维度是77x768,所以输入总的特征维度是77x2048(77是最大的token数,2048是SDXL的context dim),再通过Cross Attention模块将文本信息传入Stable Diffusion XL的训练过程与推理过程中。

Stable Diffusion XL与之前的系列相比使用了两个CLIP Text Encoder,分别是OpenCLIP ViT-bigG(694M)和OpenAI CLIP ViT-L/14(123.65M),从而大大增强了Stable Diffusion XL对文本的提取和理解能力,同时提高了输入文本和生成图片的一致性

SDXL OpenCLIP ViT-bigG的完整结构图

SDXL OpenCLIP ViT-bigG的文本编码过程:

from transformers import CLIPTextModel, CLIPTokenizer# 加载 OpenCLIP ViT-bigG Text Encoder模型和Tokenizer
# SDXL模型权重百度云网盘:关注Rocky的公众号WeThinkIn,后台回复:SDXL模型,即可获得资源链接
text_encoder = CLIPTextModel.from_pretrained("/本地路径/stable-diffusion-xl-base-1.0", subfolder="text_encoder_2").to("cuda")
text_tokenizer = CLIPTokenizer.from_pretrained("/本地路径/stable-diffusion-xl-base-1.0", subfolder="tokenizer_2")# 将输入SDXL模型的prompt进行tokenize,得到对应的token ids特征
prompt = "1girl,beautiful"
text_token_ids = text_tokenizer(prompt,padding="max_length",max_length=text_tokenizer.model_max_length,truncation=True,return_tensors="pt"
).input_idsprint("text_token_ids' shape:",text_token_ids.shape)
print("text_token_ids:",text_token_ids)# 将token ids特征输入OpenCLIP ViT-bigG Text Encoder模型中输出77x1280的Text Embeddings特征
text_embeddings = text_encoder(text_token_ids.to("cuda"))[0] # 由于Text Encoder模型输出的是一个元组,所以需要[0]对77x1280的Text Embeddings特征进行提取
print("text_embeddings' shape:",text_embeddings.shape)
print(text_embeddings)---------------- 运行结果 ----------------
text_token_ids' shape: torch.Size([1, 77])
text_token_ids: tensor([[49406,   272,  1611,   267,  1215, 49407,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0,     0,     0,     0,0,     0,     0,     0,     0,     0,     0]])
text_embeddings' shape: torch.Size([1, 77, 1280])
tensor([[[-0.1025, -0.3104,  0.1660,  ..., -0.1596, -0.0680, -0.0180],[ 0.7724,  0.3004,  0.5225,  ...,  0.4482,  0.8743, -1.0429],[-0.3963,  0.0041, -0.3626,  ...,  0.1841,  0.2224, -1.9317],...,[-0.8887, -0.2579,  1.3508,  ..., -0.4421,  0.2193,  1.2736],[-0.9659, -0.0447,  1.4424,  ..., -0.4350, -0.1186,  1.2042],[-0.5213, -0.0255,  1.8161,  ..., -0.7231, -0.3752,  1.0876]]],device='cuda:0', grad_fn=<NativeLayerNormBackward0>)

SDXL OpenAI CLIP ViT-L/14的完整结构图 

SDXL OpenAI CLIP ViT-L/14的文本编码过程: 

from transformers import CLIPTextModel, CLIPTokenizer# 加载 OpenAI CLIP ViT-L/14 Text Encoder模型和Tokenizer
# SDXL模型权重百度云网盘:关注Rocky的公众号WeThinkIn,后台回复:SDXL模型,即可获得资源链接
text_encoder = CLIPTextModel.from_pretrained("/本地路径/stable-diffusion-xl-base-1.0", subfolder="text_encoder").to("cuda")
text_tokenizer = CLIPTokenizer.from_pretrained("/本地路径/stable-diffusion-xl-base-1.0", subfolder="tokenizer")# 将输入SDXL模型的prompt进行tokenize,得到对应的token ids特征
prompt = "1girl,beautiful"
text_token_ids = text_tokenizer(prompt,padding="max_length",max_length=text_tokenizer.model_max_length,truncation=True,return_tensors="pt"
).input_idsprint("text_token_ids' shape:",text_token_ids.shape)
print("text_token_ids:",text_token_ids)# 将token ids特征输入OpenAI CLIP ViT-L/14 Text Encoder模型中输出77x768的Text Embeddings特征
text_embeddings = text_encoder(text_token_ids.to("cuda"))[0] # 由于Text Encoder模型输出的是一个元组,所以需要[0]对77x768的Text Embeddings特征进行提取
print("text_embeddings' shape:",text_embeddings.shape)
print(text_embeddings)---------------- 运行结果 ----------------
text_token_ids' shape: torch.Size([1, 77])
text_token_ids: tensor([[49406,   272,  1611,   267,  1215, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407, 49407,49407, 49407, 49407, 49407, 49407, 49407, 49407]])
text_embeddings' shape: torch.Size([1, 77, 768])
tensor([[[-0.3885,  0.0230, -0.0521,  ..., -0.4901, -0.3065,  0.0674],[-0.8424, -1.1387,  1.2767,  ..., -0.2598,  1.6289, -0.7855],[ 0.1751, -0.9847,  0.1881,  ...,  0.0657, -1.4940, -1.2612],...,[ 0.2039, -0.7298, -0.3206,  ...,  0.6751, -0.5814, -0.7320],[ 0.1921, -0.7345, -0.3039,  ...,  0.6806, -0.5852, -0.7228],[ 0.2112, -0.6438, -0.3042,  ...,  0.6628, -0.5576, -0.7583]]],device='cuda:0', grad_fn=<NativeLayerNormBackward0>)

 以上都为SDXL的base模型


 4.Refiner模型

由于已经有U-Net(Base)模型生成了图像的Latent特征,所以Refiner模型的主要工作是在Latent特征进行小噪声去除和细节质量提升

Refiner模型和Base模型一样是基于Latent的扩散模型,也采用了Encoder-Decoder结构,和U-Net兼容同一个VAE模型。不过在Text Encoder部分,Refiner模型只使用了OpenCLIP ViT-bigG的Text Encoder,同样提取了倒数第二层特征以及进行了pooled text embedding的嵌入。

refine模型中的Unet结构:

 单独使用Stable Diffusion XL中的Base模型来生成图像: 

# 加载diffusers和torch依赖库
from diffusers import DiffusionPipeline
import torch# 加载Stable Diffusion XL Base模型(stable-diffusion-xl-base-1.0或stable-diffusion-xl-base-0.9)
pipe = DiffusionPipeline.from_pretrained("/本地路径/stable-diffusion-xl-base-1.0",torch_dtype=torch.float16, variant="fp16")
# "/本地路径/stable-diffusion-xl-base-1.0"表示我们需要加载的Stable Diffusion XL Base模型路径
# 大家可以关注Rocky的公众号WeThinkIn,后台回复:SDXL模型,即可获得SDXL模型权重资源链接
# "fp16"代表启动fp16精度。比起fp32,fp16可以使模型显存占用减半# 使用GPU进行Pipeline的推理
pipe.to("cuda")# 输入提示词
prompt = "Watercolor painting of a desert landscape, with sand dunes, mountains, and a blazing sun, soft and delicate brushstrokes, warm and vibrant colors"# 输入负向提示词,表示我们不想要生成的特征
negative_prompt = "(EasyNegative),(watermark), (signature), (sketch by bad-artist), (signature), (worst quality), (low quality), (bad anatomy), NSFW, nude, (normal quality)"# 设置seed,可以固定生成图像中的构图
seed = torch.Generator("cuda").manual_seed(42)# SDXL Base Pipeline进行推理
image = pipe(prompt, negative_prompt=negative_prompt,generator=seed).images[0]
# Pipeline生成的images包含在一个list中:[<PIL.Image.Image image mode=RGB size=1024x1024>]
#所以需要使用images[0]来获取list中的PIL图像# 保存生成图像
image.save("SDXL-Base.png")

将SDXL Base模型和SDXL Refiner模型级联来生成图像: 

from diffusers import DiffusionPipeline
import torch# 下面的五行代码不变
pipe = DiffusionPipeline.from_pretrained("/本地路径/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, variant="fp16")pipe.to("cuda")prompt = "Watercolor painting of a desert landscape, with sand dunes, mountains, and a blazing sun, soft and delicate brushstrokes, warm and vibrant colors"negative_prompt = "(EasyNegative),(watermark), (signature), (sketch by bad-artist), (signature), (worst quality), (low quality), (bad anatomy), NSFW, nude, (normal quality)"seed = torch.Generator("cuda").manual_seed(42)# 运行SDXL Base模型的Pipeline,设置输出格式为output_type="latent"
image = pipe(prompt=prompt, negative_prompt=negative_prompt, generator=seed, output_type="latent").images# 加载Stable Diffusion XL Refiner模型(stable-diffusion-xl-refiner-1.0或stable-diffusion-xl-refiner-0.9)
pipe = DiffusionPipeline.from_pretrained("/本地路径/stable-diffusion-xl-refiner-1.0", torch_dtype=torch.float16, variant="fp16")
# "本地路径/stable-diffusion-xl-refiner-1.0"表示我们需要加载的Stable Diffusion XL Refiner模型,
# 大家可以关注Rocky的公众号WeThinkIn,后台回复:SDXL模型,即可获得SDXL模型权重资源链接pipe.to("cuda")# SDXL Refiner Pipeline进行推理
images = pipe(prompt=prompt, negative_prompt=negative_prompt, generator=seed, image=image).images# 保存生成图像
images[0].save("SDXL-Base-Refiner.png")

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

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

相关文章

目标跟踪那些事

目标跟踪那些事 跟踪与检测的区别 目标跟踪和目标检测是计算机视觉中的两个重要概念&#xff0c;但它们的目的和方法是不同的。 目标检测(object Detection)&#xff1a;是指在图像或视频帧中识别并定位一个或多个感兴趣的目标对象的过程 。 目标跟踪(object Tracking)&…

力扣爆刷第169天之TOP200五连刷111-115(课程表、单词搜索、归并)

力扣爆刷第169天之TOP200五连刷111-115&#xff08;课程表、单词搜索、归并&#xff09; 文章目录 力扣爆刷第169天之TOP200五连刷111-115&#xff08;课程表、单词搜索、归并&#xff09;一、207. 课程表二、LCR 125. 图书整理 II三、402. 移掉 K 位数字四、79. 单词搜索五、9…

设计模式:详细拆解策略模式

策略模式 既然是详解&#xff0c;就不以案例开头了&#xff0c;直奔主题&#xff0c;先来看看什么是策略模式。 模式定义 定义一系列的算法&#xff0c;把它们一个个封装起来&#xff0c;并且使它们可相互替换。本模式 使得算法可独立于使用它的客户而变化。 结构 Strategy&a…

C++ | Leetcode C++题解之第318题最大单词长度乘积

题目&#xff1a; 题解&#xff1a; class Solution { public:int maxProduct(vector<string>& words) {unordered_map<int,int> map;int length words.size();for (int i 0; i < length; i) {int mask 0;string word words[i];int wordLength word.s…

深入解析Java虚拟机(JVM)内存模型-全面掌握JVM内存管理

Java虚拟机(JVM)的内存模型是Java开发者必须掌握的核心知识之一。无论你是刚入门的新手,还是经验丰富的老手,深入理解JVM内存模型都能帮助你写出更高效、更稳定的Java程序。本文将带你全面剖析JVM内存模型的各个组成部分,深入探讨其工作原理,并通过实例讲解如何进行内存优化。让…

C#-读取测序数据的ABI文件并绘制svg格式峰图

本地环境&#xff1a;win10&#xff0c;visual studio 2022 community 目录 前言问题描述实现效果解决思路实现要点ABI文件的组织方式svg绘制问题变色碱基值 动态设置svg图像宽度 前言 本文是在已有的代码基础上进行的开发&#xff0c;前期已经实现&#xff1a; ABI文件的解析…

【从零搭建SpringBoot3.x 项目脚手架】- 1. 工程初始化

为什么会有这个系列文章 在项目开发中&#xff0c;大多项目依旧沿用的是 JDK 8 Spring Boot 2.x 系列的技术栈&#xff0c;没有Spring Boot 3.x 的上手实践机会。在个人学习探索 Spring Boot 3.x 的过程中&#xff0c;遇到多数第三方框架集成和问题排查的技术问题&#xff0c…

[极客大挑战 2019]Secret File-web

打开题目 查看源码 直接访问Archive_room.php 第二个页面是个点击框&#xff0c;这里bp抓包确认&#xff1b;若是直接SECRET&#xff0c;会跳到end.php 直接访问secr3t.php 代码审计一下 playload&#xff1a;secr3t.php?fileflag.php 改为php协议读取权限 secr3t.php?f…

[图解]SysML建模电磁轨道炮-01块定义图

1 00:00:00,490 --> 00:00:04,000 我们是用EA复刻一个网络上的案例 2 00:00:06,370 --> 00:00:09,240 电磁轨道炮&#xff0c;它的原理很简单 3 00:00:09,490 --> 00:00:10,960 初中物理就可以理解 4 00:00:11,670 --> 00:00:14,010 首先&#xff0c;电流形成磁…

polyfit曲线拟合

一、简介 polyfit函数是matlab中用于进行曲线拟合的一个函数。其数学基础是最小二乘法曲线拟合原理。曲线拟合&#xff1a;已知离散点上的数据集&#xff0c;即已知在点集上的函数值&#xff0c;构造一个解析函数&#xff08;其图形为一曲线&#xff09;使在原离散点上尽可能接…

快讯 | 苹果携手OpenAI,ChatGPT即将登陆iOS 18

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

【反序列化漏洞】serial靶机详解

一、安装靶机 首先创建新的虚拟机。 然后选择客户机版本为Ubuntu 64位。 然后选择使用现有磁盘&#xff0c;选择下载的vmdk磁盘文件即可。剩下的都是默认 二、信息收集 发现主机192.168.204.143 访问 扫描端口nmap -A 192.168.204.143 -p-&#xff0c;发现只有ssh:22和http:8…

Java:线程安全

引子 首先来看一段代码: private static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(()->{for (int i 0; i < 50000; i) {count;}});Thread t2 new Thread(()->{for (int i 0; i < 50000; i) {…

如何解决C#字典的线程安全问题

前言 我们在上位机软件开发过程中经常需要使用字典这个数据结构&#xff0c;并且经常会在多线程环境中使用字典&#xff0c;如果使用常规的Dictionary就会出现各种异常&#xff0c;本文就是详细介绍如何在多线程环境中使用字典来解决线程安全问题。 1、非线程安全举例 Dictio…

Vue+live2d实现虚拟人物互动(一次体验叙述)

目录 故事的开头&#xff1a; 最终的实现效果&#xff1a; 实现步骤&#xff1a; 第一步&#xff1a;下载重要文件 第二步&#xff1a;创建vue项目文件&#xff0c;将刚下载文件拷贝到public目录下 第三步&#xff1a;在index.html文件中引入js 第四步&#xff1a;使用&…

【数据结构算法经典题目刨析(c语言)】顺序表和链表的区别(图文详解)

&#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏&#xff1a;数据结构经典题目刨析(c语言) 目录 顺序表和链表的区别 一、底层存储空间 二、插入和删除操作 三、随机访问 四、空间利用率 五、应用场景 六、高速缓存 为什么顺序表的缓存利用率高于链表呢…

设计界的新宠:5款热门UI在线设计软件评测

随着用户界面设计行业的蓬勃发展&#xff0c;越来越多的设计师进入用户界面设计。选择一个方便的用户界面设计工具尤为重要&#xff01;除了传统的用户界面设计工具&#xff0c;在线用户界面设计工具也受到越来越多设计师的青睐。这种不受时间、地点、计算机配置限制的工作方法…

OpenCV||超详细的图像边缘检测

一、基本概念 1.图像边缘检测目的 特征提取&#xff1a;边缘是图像中亮度变化最显著的部分&#xff0c;它们通常对应于物体的轮廓、不同区域的边界等。通过边缘检测&#xff0c;可以从图像中提取出这些重要的特征信息&#xff0c;为后续处理如图像分割、目标识别等提供基础。 …

webfunny埋点系统如何进行部署?

hello 大家webfunny埋点系统做了不少功能更新&#xff0c;平常给大家分享比较多的是**webfunny前端监控系统**&#xff0c;最近有不少技术同学来了解webfunny埋点系统&#xff0c;今天主要给大家分享下webfunny埋点系统部署&#xff0c;分为本地部署和线上部署。 还没有试用和…

字节一面面经

1.redis了解吗&#xff0c;是解决什么问题的&#xff0c;redis的应用&#xff1f; Redis 是一种基于内存的数据库&#xff0c;常用的数据结构有string、hash、list、set、zset这五种&#xff0c;对数据的读写操作都是在内存中完成。因此读写速度非常快&#xff0c;常用于缓存&…