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.pswp.cn/news/207135.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/207135.shtml
英文地址,請注明出處:http://en.pswp.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…

深度解讀:淘客返利機器人無限制與免費版的差異

深度解讀:淘客返利機器人無限制與免費版的差異 在數字時代&#xff0c;人工智能和大數據技術的飛速發展正在改變我們的生活方式&#xff0c;尤其在購物領域&#xff0c;各種優惠工具如雨后春筍般涌現。其中&#xff0c;淘客返利機器人和微賺淘客系統以其獨特的優勢&#xff0c…

Python核心編程之序列下篇

目錄 十二、列表 如何創建列表類型數據并給它賦值 如何訪問列表中的值

代立冬:基于Apache Doris+SeaTunnel 實現多源實時數據倉庫解決方案探索實踐

大家好&#xff0c;我是白鯨開源的聯合創始人代立冬&#xff0c;同時擔任 Apache DolphinScheduler 的 PMC chair 和 SeaTunnel 的 PMC。作為 Apache Foundation 的成員和孵化器導師&#xff0c;我積極參與推動多個開源項目的發展&#xff0c;幫助它們通過孵化器成長為 Apache …

如何訪問內部網絡做內網穿透

項目&#xff1a;https://github.com/ehang-io/nps 有個公網服務器&#xff0c;搭建服務端。 然后客戶端使用&#xff1a; -server是服務端的訪問方式。-vkey是秘鑰。 ./npc -server192.227.19.12:8024 -vkeyoies8gq3wml -typetcp然后在服務端配置TCP隧道即可。

某度旋轉驗證碼v2 逆向分析

v2主要依據是核心 JS 文件mkd_v2.js 版本&#xff0c;如下圖所示&#xff1a; 第一次 https://passport.baidu.com/cap/init 接口&#xff0c;請求的 ak 是固定值&#xff0c;當然不同場景不同網站是不一樣的&#xff0c;_ 時間戳&#xff0c;ver1&#xff0c;返回值 as、tk 都…

大數據的技術棧-逐步完善

目錄 1.hadoop a.HDFS分布式文件系統 b.Yarn集群資源管理器 c.MapReduce sql引擎 d.Impala sql引擎 e.工具概觀 2.數據倉庫知識 a.Hive數據庫 1)Hive Sql 2)數據庫結構 b.Doris數據庫 3.混合處理框架SPARK a.Spark b.集群架構 4.數倉模型知識 5.開發工具 a.Dbeaver b.Idea…

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…

QNX usleep測試

QNX usleep測試 結論 usleep時間在QNX上沒有ubuntu上運行準確&#xff0c;但是10ms以上誤差不大。 測試代碼 testsleep.cpp的代碼如下&#xff1a; #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <time.h>double usleep_…

sklearn 筆記:neighbors.NearestNeighbors 自定義metric

1 數據 假設我們有這樣的一個數據tst_lst&#xff0c;表示的是5條軌跡的墨卡托坐標&#xff0c;我們希望算出逐點的曼哈頓距離之和&#xff0c;作為兩條軌跡的距離 [array([[11549759.51313693, 148744.89246911],[11549751.49813359, 148732.97804463],[11549757.620705…

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…

P5744 【深基7.習9】培訓

題目描述 某培訓機構的學員有如下信息&#xff1a; 姓名&#xff08;字符串&#xff09;年齡&#xff08;周歲&#xff0c;整數&#xff09;去年 NOIP 成績&#xff08;整數&#xff0c;且保證是 5 5 5 的倍數&#xff09; 經過為期一年的培訓&#xff0c;所有同學的成績都…

學習-java多線程

線程的創建 *繼承Tread,重寫run *實現Runnable接口,重寫run() [匿名內部類] *實現callable接口(有結果返回) 線程的常用方法 調用join保證這個方法先執行完成, 線程安全 并發編程 進程&#xff1a;就相當一個程序的實例線程&#xff1a;就是指令流&#xff08;一個進程包含多…

無重復字符的最長子串-中等

leetcode地址 給定一個字符串 s &#xff0c;請你找出其中不含有重復字符的 最長子串 的長度。 示例 1:輸入: s "abcabcbb" 輸出: 3 解釋: 因為無重復字符的最長子串是 "abc"&#xff0c;所以其長度為 3。 示例 2:輸入: s "bbbbb" 輸出: 1 …

我有才打造私域流量的知識付費小程序平臺

在當今數字化時代&#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…

問題:數組對象去重

問題&#xff1a;數組對象去重 var arr [{name: ‘a’,id: 1}, {name: ‘a’,id: 2}, {name: ‘b’,id: 3}, {name: ‘c’,id: 4}, {name: ‘c’,id: 6}, {name: ‘b’,id: 6}, {name: ‘d’,id: 7}]; 對數組對象name進行去重處理&#xff0c; 結果顯示為&#xff1a; [{name…

第一啟富金:新添澳大利亞(ASIC)牌照

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