Project Icon

compel

文本嵌入系统的提示权重调整工具

Compel是一个文本提示权重调整工具,用于transformer类型的文本嵌入系统。通过简洁的语法,用户可以重新分配提示字符串各部分的权重,从而调整生成的嵌入张量。该工具兼容Hugging Face的StableDiffusionPipeline,支持批处理、文本反转和SDXL模型,为AI图像生成提供精细控制。

Compel

一个用于 transformers 类型文本嵌入系统的文本提示权重和混合库,由 @damian0815 开发。

通过灵活直观的语法,您可以重新调整提示字符串不同部分的权重,从而重新调整从字符串生成的嵌入张量的不同部分权重。

经过 Hugging Face 的 StableDiffusionPipeline 测试和开发,但应该适用于任何使用某种 TokenizerText Encoder 的基于 diffusers 的系统。

改编自 InvokeAI 的提示代码(同样由 @damian0815 开发)。

请注意,Compel 目前忽略了交叉注意力控制 .swap(),但您可以通过自行调用 build_conditioning_tensor_for_prompt_object() 并在扩散循环中实现交叉注意力控制来使用它。

安装

pip install compel

文档

文档在这里

演示

参见 compel-demo.ipynb

在 Colab 中打开

快速开始

使用 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)

内存使用/VRAM 泄漏

如果遇到内存问题,请确保在 with torch.no_grad(): 块内运行 compel。

如果这不能解决问题,您可以尝试 @kshieh1 提供的建议:

生成图像后,您应该显式取消引用张量对象(即 prompt_embeds = None)并调用 gc.collect()

更多详情请参见 https://github.com/damian0815/compel/issues/24。感谢 @kshieh1!

更新日志

2.0.3 - 包含贡献的修复 #64、#80,并修复 pyproject.toml/pypi 中的许可证

2.0.2 - 修复 SDXL 模型使用 pipeline.enable_sequential_cpu_offloading() 的问题(您需要在 compel 初始化时传递 device='cuda'

2.0.1 - 修复 #45 SDXL 非截断提示和 .and() 的填充问题

2.0.0 - SDXL 支持

非常感谢 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

1.2.1 - 实际应用 .and() 权重

1.2.0 - 使用 .and() 连接嵌入

对于 Stable Diffusion 2.1,我一直在尝试一个新功能:连接嵌入。我注意到,例如,对于更复杂的提示,当提示被分成多个部分并分别输入到 OpenCLIP 时,图像生成质量会大幅提高。

简而言之:您现在可以尝试将提示分成多个段落,这似乎可以改善 SD2.1 生成的图像。语法是 ("提示部分 1", "提示部分 2").and()。您可以有多个部分,也可以为它们分配权重,例如 ("一个人吃苹果", "坐在车顶上", "高质量,艺术站热门,8K UHD").and(1, 0.5, 0.5),这将为 一个人吃苹果 分配权重 1,为 坐在车顶上高质量,艺术站热门,8K UHD 分配权重 0.5

这里有一个来自 InvokeAI discord #garbage-bin 频道的无意义示例,由 gogurt enjoyer 的令人难以置信的噩梦提示生成器创建:

一个潮湿黏腻的 pindlesackboy 邋遢的 hamblin' bogomadong,Clem Fandango 很生气,背景是 Wario's Woods,发出 ga-woink-a 的声音

直接将这个输入到 SD2.1 中,我们得到了这个真的不太好的图像:

然而,如果将提示分成几个部分,分别输入到 OpenCLIP 中作为四个独立的提示,然后连接起来:

一个潮湿黏腻的 pindlesackboy 邋遢的 hamblin' bogomadong

Clem Fandango 很生气

背景是 Wario's Woods

发出 ga-woink-a 的声音

然后使用相同的种子生成的输出图像好多了

在新的 .and() 语法中,您可以这样提示:

("一个潮湿黏腻的 pindlesackboy 邋遢的 hamblin' bogomadong", "Clem Fandango 很生气", "背景是 Wario's Woods", "发出 ga-woink-a 的声音").and()

效果可能或多或少有所不同。例如,这里是

卡斯帕·大卫·弗里德里希绘制的遥远星系之梦,哑光绘画,艺术站热门,高质量

将其分为两部分:

卡斯帕·大卫·弗里德里希绘制的遥远星系之梦,哑光绘画

艺术站热门,高质量

这个 Compel 提示是:

("卡斯帕·大卫·弗里德里希绘制的遥远星系之梦,哑光绘画", "艺术站热门,高质量").and()

1.1.6 - 杂项小修复

  • 添加 DiffusersTextualInversionManager(感谢 @pdoane)
  • 修复截断/非截断提示长度的批量嵌入生成问题(#18,感谢 @abassino)
  • 添加关于内存泄漏的说明(参考 #24,感谢 @kshieh1)
  • 修复逗号后没有空格时的错误解析(#34,感谢 @moono)

1.1.5 - 修复compel将括号内文本中的数字转换为浮点数的问题

1.1.4 - 修复 #23(顺序卸载)和 InvokeAI 问题 #3442(允许LoRA名称中使用连字符)

1.1.3 - 启用获取倒数第二个CLIP隐藏层(又称"clip skip")

使用时,在初始化 Compel 实例时传递 use_penultimate_clip_layer=True。注意,对于SD2.0/SD2.1,无需传递此标志,因为diffusers在加载SD2.0+文本编码器时已经舍弃了最后一个隐藏层。

1.1.2 - 修复 #21(启用截断时解析长提示词导致崩溃,如果截断边界之外存在加权片段)

1.1.1 - 修复 #22(括号内解析 . 字符的问题)

1.1.0 - 支持在 parse_prompt_string() 中解析 withLora/useLora

  • Compel.parse_prompt_string() 现在返回一个 Conjunction
  • 提示词字符串中任何出现的 withLora(name[, weight])useLora(name[, weight]) 将被解析为 LoraWeight 实例,并在 parse_prompt_string() 返回的最外层 Conjunction 中返回。

1.0.5 - 修复传递无效(auto1111)语法中包含浮点数时的错误解析

同时修复默认交换参数的测试用例

1.0.4 - 修复禁用截断时空交换目标的嵌入(例如 cat.swap("")

1.0.3 - 改进 .swap 的默认值(https://github.com/damian0815/compel/issues/8)

1.0.2 - 修复非截断批量嵌入的填充(https://github.com/damian0815/compel/issues/9)

1.0.1 - 修复 InvokeAI 的 --free_gpu_mem 选项

1.0.0 - 新的降权算法

降权现在通过应用注意力掩码来移除降权的标记,而不是直接从序列中删除它们。这是默认行为,但可以通过在初始化 Compel 实例时传递 downweight_mode=DownweightMode.REMOVE 来启用旧行为。

以前,降权标记的工作方式是既乘以标记嵌入的权重,又与移除了降权标记的标记序列副本进行反向加权混合。直觉上,随着权重接近零,被降权的标记应该实际从序列中移除。然而,移除标记导致所有下游标记的位置变得混乱。混合最终混合了远超预期的标记。

从 v1.0.0 开始,采纳了 @keturn 和 @bonlime 的建议(https://github.com/damian0815/compel/issues/7),默认程序有所不同。降权仍然涉及混合,但混合的是一个掩蔽了降权标记的标记序列版本,而不是移除它们。这正确地保留了其他标记的位置嵌入。

还有一个错误修复:修复权重为 0 时的黑色图像问题(https://github.com/invoke-ai/InvokeAI/issues/2832)

0.1.10 - 添加对超过模型最大标记长度的提示词的支持

要启用,请在初始化 Compel 时使用 truncate_long_prompts=False(默认为 True)。长度超过模型 max_token_length 的提示词将被分块并填充到 max_token_length 的整数倍。

请注意,即使你不使用负面提示词,你也需要为至少一个 "" 的负面提示词构建条件张量,并使用 compel.pad_conditioning_tensors_to_same_length(),否则你会收到条件张量长度不匹配的错误:

compel = Compel(..., truncate_long_prompts=False)
prompt = "一只猫在森林里玩球++,令人惊叹,精致,惊人,杰作,熟练,强大,难以置信,惊人,在gregstation上流行,greg,greggy,greggs greggson,greggy mcgregface,..." # 非常长的提示词
conditioning = compel.build_conditioning_tensor(prompt)
negative_prompt = "" # 必须创建一个空提示词 - 如果需要,它也可以很长
negative_conditioning = compel.build_conditioning_tensor(negative_prompt)
[conditioning, negative_conditioning] = compel.pad_conditioning_tensors_to_same_length([conditioning, negative_conditioning])

0.1.9 - 已损坏

0.1.8 - 将 Python 最低版本降至 3.7

0.1.7 - InvokeAI 兼容性

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号