Diffusers 文档

文本反演

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始

文本反演

StableDiffusionPipeline 支持文本反演,这项技术使像 Stable Diffusion 这样的模型能够仅从几个示例图像中学习新概念。这使您可以更好地控制生成的图像,并允许您根据特定概念定制模型。您可以在 Stable Diffusion Conceptualizer 中快速开始使用社区创建的概念集合。

本指南将向您展示如何使用 Stable Diffusion Conceptualizer 中预先学习的概念运行文本反演推理。如果您有兴趣使用文本反演教模型新概念,请查看文本反演训练指南。

导入必要的库

import torch
from diffusers import StableDiffusionPipeline
from diffusers.utils import make_image_grid

Stable Diffusion 1 和 2

Stable Diffusion Conceptualizer 中选择一个 Stable Diffusion 检查点和一个预先学习的概念

pretrained_model_name_or_path = "stable-diffusion-v1-5/stable-diffusion-v1-5"
repo_id_embeds = "sd-concepts-library/cat-toy"

现在您可以加载一个 pipeline,并将预先学习的概念传递给它

pipeline = StableDiffusionPipeline.from_pretrained(
    pretrained_model_name_or_path, torch_dtype=torch.float16, use_safetensors=True
).to("cuda")

pipeline.load_textual_inversion(repo_id_embeds)

通过使用特殊的占位符 token <cat-toy>,使用预先学习的概念创建 prompt,并选择您想要生成的图像样本数和行数

prompt = "a grafitti in a favela wall with a <cat-toy> on it"

num_samples_per_row = 2
num_rows = 2

然后运行 pipeline(随意调整参数,例如 num_inference_stepsguidance_scale,以查看它们如何影响图像质量),保存生成的图像并使用您在开始时创建的辅助函数可视化它们

all_images = []
for _ in range(num_rows):
    images = pipeline(prompt, num_images_per_prompt=num_samples_per_row, num_inference_steps=50, guidance_scale=7.5).images
    all_images.extend(images)

grid = make_image_grid(all_images, num_rows, num_samples_per_row)
grid

Stable Diffusion XL

Stable Diffusion XL (SDXL) 也可以使用文本反演向量进行推理。与 Stable Diffusion 1 和 2 相比,SDXL 有两个文本编码器,因此您需要两个文本反演嵌入 - 每个文本编码器模型一个。

让我们下载 SDXL 文本反演嵌入,并仔细看看它的结构

from huggingface_hub import hf_hub_download
from safetensors.torch import load_file

file = hf_hub_download("dn118/unaestheticXL", filename="unaestheticXLv31.safetensors")
state_dict = load_file(file)
state_dict
{'clip_g': tensor([[ 0.0077, -0.0112,  0.0065,  ...,  0.0195,  0.0159,  0.0275],
         ...,
         [-0.0170,  0.0213,  0.0143,  ..., -0.0302, -0.0240, -0.0362]],
 'clip_l': tensor([[ 0.0023,  0.0192,  0.0213,  ..., -0.0385,  0.0048, -0.0011],
         ...,
         [ 0.0475, -0.0508, -0.0145,  ...,  0.0070, -0.0089, -0.0163]],

有两个 tensors,"clip_g""clip_l""clip_g" 对应于 SDXL 中较大的文本编码器,并指向 pipe.text_encoder_2,而 "clip_l" 指向 pipe.text_encoder。

现在您可以分别加载每个 tensor,方法是将它们与正确的文本编码器和分词器一起传递给 load_textual_inversion()

from diffusers import AutoPipelineForText2Image
import torch

pipe = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", variant="fp16", torch_dtype=torch.float16)
pipe.to("cuda")

pipe.load_textual_inversion(state_dict["clip_g"], token="unaestheticXLv31", text_encoder=pipe.text_encoder_2, tokenizer=pipe.tokenizer_2)
pipe.load_textual_inversion(state_dict["clip_l"], token="unaestheticXLv31", text_encoder=pipe.text_encoder, tokenizer=pipe.tokenizer)

# the embedding should be used as a negative embedding, so we pass it as a negative prompt
generator = torch.Generator().manual_seed(33)
image = pipe("a woman standing in front of a mountain", negative_prompt="unaestheticXLv31", generator=generator).images[0]
image
< > 在 GitHub 上更新