解除diffusers库的prompt长度限制(SDXL版)

2025-5-21 注:本文只提供思路,没有解决"权重识别"、"BREAK"问题。

要想实现与webui一样的绘图效果与无限prompt,可参考diffusers/examples/community/lpw_stable_diffusion_xl.py

1、上代码

python 复制代码
from diffusers import StableDiffusionXLPipeline,EulerAncestralDiscreteScheduler

# 1. 加载模型
config_path = "anime_illust_diffusion_xl"
model_id="anime_illust_diffusion_xl/animeIllustDiffusion_v08.safetensors"
pipe = StableDiffusionXLPipeline.from_single_file(
    model_id, 
    dtype=torch.bfloat16,
    config=config_path,
    local_files_only=True)

pipe = pipe.to("cuda") 

# 2. 准备输入图像和提示词
#======================================
clip_skip = 1

prompt = 40 * "1girl, solo, black background,(best quality:1.5)" # 超出77长度限制
negative_prompt = "worst quality, low quality, multi views"

max_length = pipe.tokenizer.model_max_length
tokenizers = [pipe.tokenizer,pipe.tokenizer_2]
text_encoders = [pipe.text_encoder,pipe.text_encoder_2]
prompts = [prompt,prompt]
negative_prompts = [negative_prompt,negative_prompt]

prompt_embeds_list = []
negative_prompt_embeds_list= []

for prompt,negative_prompt, tokenizer, text_encoder in zip(prompts,negative_prompts, tokenizers, text_encoders):
    input_ids = tokenizer(prompt, return_tensors="pt").input_ids
    input_ids = input_ids.to("cuda")
    negative_ids =tokenizer(negative_prompt, truncation=False, padding="max_length", max_length=input_ids.shape[-1], return_tensors="pt").input_ids                                                                                                     
    negative_ids = negative_ids.to("cuda")
    
    # 分段处理prompt
    concat_embeds = [] 
    neg_embeds = []
    for i in range(0, input_ids.shape[-1], max_length):
        embeds_1 = text_encoder(input_ids[:, i: i + max_length], output_hidden_states=True)
        pooled_prompt_embeds = embeds_1[0]
        concat_embeds.append(embeds_1.hidden_states[-(clip_skip+2)])
        
        embeds_2 = text_encoder(negative_ids[:, i: i + max_length],output_hidden_states=True)
        negative_pooled_prompt_embeds = embeds_2[0]
        neg_embeds.append(embeds_2.hidden_states[-2])
        

    # 拼接text_encoder结果
    # 例:(1,77,768)+(1,22,768) = (1,99,768)
    prompt_embeds = torch.cat(concat_embeds, dim=1)
    negative_prompt_embeds = torch.cat(neg_embeds, dim=1)
    
    prompt_embeds_list.append(prompt_embeds)
    negative_prompt_embeds_list.append(negative_prompt_embeds)

# 拼接两个text_encoder的特征
# 例:(1,99,768)+(1,99,1280) = (1,99,2048)
prompt_embeds = torch.concat(prompt_embeds_list, dim=-1)
negative_prompt_embeds = torch.concat(negative_prompt_embeds_list, dim=-1)

#=====================================

# 3. 设置生成参数
num_inference_steps = 28  # 推理步数,可根据需要调整
guidance_scale = 7     # 引导比例,控制生成图像与提示的匹配程度
generator = torch.Generator("cuda").manual_seed(31)
 


# 4. 执行生成
with torch.no_grad():
    images = pipe(
        #prompt=prompt,
        #negative_prompt=negative_prompt,
        prompt_embeds = prompt_embeds, 
        pooled_prompt_embeds = pooled_prompt_embeds,
        negative_prompt_embeds = negative_prompt_embeds, 
        negative_pooled_prompt_embeds = negative_pooled_prompt_embeds,
        height = 1216,
        width= 832,
        num_inference_steps=num_inference_steps,
        guidance_scale=guidance_scale,
        clip_skip=clip_skip,
        num_images_per_prompt=2,
        generator = generator
    ).images

print(type(images))
# 5. 保存结果
for id in range(len(images)):
    images[id].save(f"output_image_{id}.png")

2、分析

需要准备下面四样东西:

prompt_embeds # 正向提示词编码

pooled_prompt_embeds # 正向提示词编码的全局池化

negative_prompt_embeds # 负向提示词编码

negative_pooled_prompt_embeds # 负向提示词的全局池化

前置知识:

  1. sdxl有两个text_encoder,不妨设为t1,t2:

将prompt输入t1,得到768维的数据;输入t2,得到1280维的数据

最后送入Unet进行cross_attention的,是拼接后2048维的数据

t1、t2的输入限制了大小,最大为77

2. pooled_prompt_embeds,这玩意的原理我不懂,不过生成方式在上面代码里有写

解决方案

把长度为99的prompt,拆分为77+22,分别输入text_encoder,然后将结果拼接

相关推荐
小鸡吃米…21 小时前
机器学习 - K - 中心聚类
人工智能·机器学习·聚类
好奇龙猫1 天前
【AI学习-comfyUI学习-第三十节-第三十一节-FLUX-SD放大工作流+FLUX图生图工作流-各个部分学习】
人工智能·学习
沈浩(种子思维作者)1 天前
真的能精准医疗吗?癌症能提前发现吗?
人工智能·python·网络安全·健康医疗·量子计算
minhuan1 天前
大模型应用:大模型越大越好?模型参数量与效果的边际效益分析.51
人工智能·大模型参数评估·边际效益分析·大模型参数选择
Cherry的跨界思维1 天前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS1 天前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
ASF1231415sd1 天前
【基于YOLOv10n-CSP-PTB的大豆花朵检测与识别系统详解】
人工智能·yolo·目标跟踪
水如烟1 天前
孤能子视角:“意识“的阶段性回顾,“感质“假说
人工智能
Carl_奕然1 天前
【数据挖掘】数据挖掘必会技能之:A/B测试
人工智能·python·数据挖掘·数据分析
旅途中的宽~1 天前
《European Radiology》:2024血管瘤分割—基于MRI T1序列的分割算法
人工智能·计算机视觉·mri·sci一区top·血管瘤·t1