Diffusers 文件
Stable Diffusion XL
並獲得增強的文件體驗
開始使用
Stable Diffusion XL
Stable Diffusion XL (SDXL) 是一款強大的文字到影像生成模型,它在先前的 Stable Diffusion 模型的基礎上進行了三個關鍵方面的迭代:
- UNet 擴大了 3 倍,並且 SDXL 將第二個文字編碼器 (OpenCLIP ViT-bigG/14) 與原始文字編碼器結合,顯著增加了引數數量
- 引入了尺寸和裁剪條件,以保留訓練資料不被丟棄,並更好地控制生成影像的裁剪方式
- 引入了一個兩階段模型流程;*基礎*模型(也可以作為獨立模型執行)生成一張影像作為*精煉*模型的輸入,精煉模型會新增額外的高質量細節
本指南將向您展示如何使用 SDXL 進行文字到影像、影像到影像和影像修復。
開始之前,請確保已安裝以下庫:
# uncomment to install the necessary libraries in Colab
#!pip install -q diffusers transformers accelerate invisible-watermark>=0.2.0
我們建議安裝 invisible-watermark 庫,以幫助識別生成的影像。如果安裝了 invisible-watermark 庫,它將預設被使用。要停用水印功能:
pipeline = StableDiffusionXLPipeline.from_pretrained(..., add_watermarker=False)
載入模型檢查點
模型權重可能儲存在 Hub 上或本地的單獨子資料夾中,在這種情況下,您應該使用 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() 方法從 Hub 或本地載入以單檔案格式(.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
).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
).to("cuda")
文字到影像
對於文字到影像任務,傳入一個文字提示詞。預設情況下,SDXL 會生成 1024x1024 的影像以獲得最佳效果。您可以嘗試將 height
和 width
引數設定為 768x768 或 512x512,但低於 512x512 的解析度可能無法正常工作。
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

影像到影像
對於影像到影像任務,SDXL 在 768x768 到 1024x1024 之間的影像尺寸上表現尤其出色。傳入一張初始影像和一個文字提示詞來對影像進行條件化。
from diffusers import AutoPipelineForImage2Image
from diffusers.utils import load_image, make_image_grid
# use from_pipe to avoid consuming additional memory when loading a 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)

影像修復
對於影像修復,您需要原始影像和一張掩碼,用於標出您想在原始影像中替換的區域。建立一個提示詞來描述您想用什麼來替換掩碼區域。
from diffusers import AutoPipelineForInpainting
from diffusers.utils import load_image, make_image_grid
# use from_pipe to avoid consuming additional memory when loading a checkpoint
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)

精煉影像質量
SDXL 包含一個精煉模型,專門用於對低噪聲階段的影像進行去噪,從而從基礎模型生成更高質量的影像。有兩種使用精煉模型的方法:
- 將基礎模型和精煉模型一起使用以生成一張精煉影像
- 使用基礎模型生成一張影像,然後使用精煉模型為影像新增更多細節(這是 SDXL 最初的訓練方式)
基礎模型 + 精煉模型
當您將基礎模型和精煉模型一起生成影像時,這被稱為*專家去噪器整合*。與將基礎模型的輸出傳遞給精煉模型相比,專家去噪器整合方法需要的總去噪步驟更少,因此執行速度應該明顯更快。然而,您將無法檢查基礎模型的輸出,因為它仍然包含大量噪聲。
作為專家去噪器整合,基礎模型在高噪聲擴散階段充當專家,而精煉模型在低噪聲擴散階段充當專家。載入基礎模型和精煉模型:
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")
要使用這種方法,您需要定義每個模型在各自階段執行的時間步數。對於基礎模型,這由 denoising_end
引數控制,對於精煉模型,則由 denoising_start
引數控制。
denoising_end
和 denoising_start
引數應該是一個介於 0 和 1 之間的浮點數。這些引數表示為排程器定義的離散時間步的比例。如果您同時使用 strength
引數,它將被忽略,因為去噪步驟的數量由模型訓練時使用的離散時間步和宣告的分數截止值決定。
讓我們設定 denoising_end=0.8
,這樣基礎模型執行前 80% 的**高噪聲**時間步去噪,並設定 denoising_start=0.8
,這樣精煉模型執行後 20% 的**低噪聲**時間步去噪。基礎模型的輸出應為**潛在**空間而不是 PIL 影像。
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 中用於影像修復。
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)
這種專家去噪器整合方法對所有可用的排程器都有效!
基礎模型到精煉模型
SDXL 透過使用精煉模型在影像到影像設定中為基礎模型的完全去噪影像新增額外的高質量細節,從而提升了影像質量。
載入基礎模型和精煉模型:
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")
您可以將 SDXL 精煉模型與其他基礎模型一起使用。例如,您可以使用 Hunyuan-DiT 或 PixArt-Sigma pipeline 來生成具有更好提示詞遵循度的影像。生成影像後,您可以將其傳遞給 SDXL 精煉模型以增強最終生成質量。
從基礎模型生成一張影像,並將模型輸出設定為**潛在**空間。
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = base(prompt=prompt, output_type="latent").images[0]
將生成的影像傳遞給精煉模型。
image = refiner(prompt=prompt, image=image[None, :]).images[0]


對於影像修復,在 StableDiffusionXLInpaintPipeline 中載入基礎模型和精煉模型,移除 denoising_end
和 denoising_start
引數,併為精煉模型選擇較少的推理步數。
微條件
SDXL 訓練涉及幾種額外的條件化技術,這些技術被稱為*微條件*。其中包括原始影像尺寸、目標影像尺寸和裁剪引數。這些微條件可以在推理時用於建立高質量、居中的影像。
由於無分類器引導,您可以使用微條件和負微條件引數。它們在 StableDiffusionXLPipeline、StableDiffusionXLImg2ImgPipeline、StableDiffusionXLInpaintPipeline 和 StableDiffusionXLControlNetPipeline 中均可用。
尺寸條件
有兩種型別的尺寸條件:
original_size
條件來自訓練批次中的上取樣影像(因為丟棄佔總訓練資料近 40% 的較小影像會造成浪費)。透過這種方式,SDXL 學會了高解析度影像中不應出現上取樣偽影。在推理期間,您可以使用original_size
來指示原始影像解析度。使用預設值(1024, 1024)
會產生更高質量的影像,類似於資料集中的 1024x1024 影像。如果您選擇使用較低的解析度,例如(256, 256)
,模型仍會生成 1024x1024 的影像,但它們看起來會像資料集中的低解析度影像(更簡單的圖案、模糊)。target_size
條件來自對 SDXL 進行微調以支援不同的影像寬高比。在推理期間,如果您使用預設值(1024, 1024)
,您將得到一張類似於資料集中方形影像構圖的影像。我們建議為target_size
和original_size
使用相同的值,但歡迎嘗試其他選項!
🤗 Diffusers 還允許您指定關於影像尺寸的負條件,以引導生成遠離某些影像解析度:
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]

裁剪條件
先前 Stable Diffusion 模型生成的影像有時可能看起來被裁剪過。這是因為在訓練過程中,影像實際上會被裁剪,以使批次中的所有影像都具有相同的大小。透過對裁剪座標進行條件化,SDXL *學會*了無裁剪——座標 `(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

您還可以指定負裁剪座標,以引導生成遠離某些裁剪引數。
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
為每個文字編碼器使用不同的提示詞
SDXL 使用兩個文字編碼器,因此可以為每個文字編碼器傳遞不同的提示詞,這可以提高質量。將您的原始提示詞傳遞給 `prompt`,第二個提示詞傳遞給 `prompt_2`(如果您使用負提示詞,則使用 `negative_prompt` 和 `negative_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 文字反演 部分中的說明單獨載入。
最佳化
SDXL 是一個大型模型,您可能需要最佳化記憶體才能在您的硬體上執行它。以下是一些節省記憶體和加速推理的技巧。
- 使用 enable_model_cpu_offload() 將模型解除安裝到 CPU,以解決記憶體不足的錯誤。
- base.to("cuda")
- refiner.to("cuda")
+ base.enable_model_cpu_offload()
+ refiner.enable_model_cpu_offload()
- 使用 `torch.compile` 可獲得約 20% 的速度提升(您需要 `torch>=2.0`)。
+ base.unet = torch.compile(base.unet, mode="reduce-overhead", fullgraph=True)
+ refiner.unet = torch.compile(refiner.unet, mode="reduce-overhead", fullgraph=True)
- 如果 `torch<2.0`,請啟用 xFormers 來執行 SDXL。
+ base.enable_xformers_memory_efficient_attention()
+ refiner.enable_xformers_memory_efficient_attention()
其他資源
如果您有興趣嘗試 SDXL 中使用的 UNet2DConditionModel 的簡化版本,請檢視 minSDXL 實現,該實現使用 PyTorch 編寫,並與 🤗 Diffusers 直接相容。
< > 在 GitHub 上更新