文本嵌入系统的提示权重调整工具
Compel是一个文本提示权重调整工具,用于transformer类型的文本嵌入系统。通过简洁的语法,用户可以重新分配提示字符串各部分的权重,从而调整生成的嵌入张量。该工具兼容Hugging Face的StableDiffusionPipeline,支持批处理、文本反转和SDXL模型,为AI图像生成提供精细控制。
一个用于 transformers 类型文本嵌入系统的文本提示权重和混合库,由 @damian0815 开发。
通过灵活直观的语法,您可以重新调整提示字符串不同部分的权重,从而重新调整从字符串生成的嵌入张量的不同部分权重。
经过 Hugging Face 的 StableDiffusionPipeline
测试和开发,但应该适用于任何使用某种 Tokenizer
和 Text Encoder
的基于 diffusers 的系统。
改编自 InvokeAI 的提示代码(同样由 @damian0815 开发)。
请注意,Compel 目前忽略了交叉注意力控制 .swap()
,但您可以通过自行调用 build_conditioning_tensor_for_prompt_object()
并在扩散循环中实现交叉注意力控制来使用它。
pip install compel
文档在这里。
使用 Hugging Face diffusers >=0.12:
from diffusers import StableDiffusionPipeline from compel import Compel pipeline = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5") compel = Compel(tokenizer=pipeline.tokenizer, text_encoder=pipeline.text_encoder) # 提高 "ball" 的权重 prompt = "a cat playing with a ball++ in the forest" conditioning = compel.build_conditioning_tensor(prompt) # 或者:conditioning = compel([prompt]) # 生成图像 images = pipeline(prompt_embeds=conditioning, num_inference_steps=20).images images[0].save("image.jpg")
对 于批处理输入,使用 compel 的 call 接口:
from diffusers import StableDiffusionPipeline from compel import Compel pipeline = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5") compel = Compel(tokenizer=pipeline.tokenizer, text_encoder=pipeline.text_encoder) prompts = ["a cat playing with a ball++ in the forest", "a dog playing with a ball in the forest"] prompt_embeds = compel(prompts) images = pipeline(prompt_embeds=prompt_embeds).images images[0].save("image0.jpg") images[1].save("image1.jpg")
如果您想使用 🤗diffusers 文本反转功能,请实例化一个 DiffusersTextualInversionManager
并在 Compel 初始化时传递:
pipeline = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
textual_inversion_manager = DiffusersTextualInversionManager(pipeline)
compel = Compel(tokenizer=pipeline.tokenizer, text_encoder=pipeline.text_encoder,
textual_inversion_manager=textual_inversion_manager)
如果遇到内存问题,请确保在 with torch.no_grad():
块内运行 compel。
如果这不能解决问题,您可以尝试 @kshieh1 提供的建议:
生成图像后,您应该显式取消引用张量对象(即 prompt_embeds = None)并调用 gc.collect()
更多详情请参见 https://github.com/damian0815/compel/issues/24。感谢 @kshieh1!
pipeline.enable_sequential_cpu_offloading()
的问题(您需要在 compel 初始化时传递 device='cuda'
).and()
的填充问题非常感谢 Hugging Face 的 Patrick von Platen 提供的拉取请求,Compel 现在支持 SDXL。使用方法如下:
from compel import Compel, ReturnedEmbeddingsType from diffusers import DiffusionPipeline import torch pipeline = DiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", variant="fp16", use_safetensors=True, torch_dtype=torch.float16).to("cuda") compel = Compel(tokenizer=[pipeline.tokenizer, pipeline.tokenizer_2] , text_encoder=[pipeline.text_encoder, pipeline.text_encoder_2], returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED, requires_pooled=[False, True]) # 提高 "ball" 的权重 prompt = "a cat playing with a ball++ in the forest" conditioning, pooled = compel(prompt) # 生成图像 image = pipeline(prompt_embeds=conditioning, pooled_prompt_embeds=pooled, num_inference_steps=30).images[0]
请注意,如果您一直在使用 clip skip,这是一个重大变更:旧的布尔参数 use_penultimate_clip_layer
已被替换为枚举 ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NORMALIZED
。
.and()
权重.and()
连接嵌入对于 Stable Diffusion 2.1,我一直在尝试一个新功能:连接嵌入。我注意到,例如,对于更复杂的提示,当提示被分成多个部分并分别输入到 OpenCLIP 时,图像生成质量会大幅提高。
简而言之:您现在可以尝试将提示分成多个段落,这似乎可以改善 SD2.1 生成的图像。语法是 ("提示部分 1", "提示部分 2").and()
。您可以有多个部分,也可以为它们分配权重,例如 ("一个人吃苹果", "坐在车顶上", "高质量,艺术站热门,8K UHD").and(1, 0.5, 0.5)
,这将为