【深度学习】sdwebui的token_counter,update_token_counter,如何超出77个token的限制?对提示词加权的底层实现

news2024/11/24 9:53:43

文章目录

  • 前言
  • 关于token_counter
  • 关于class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing)
  • 如何超出77个token的限制?
  • 对提示词加权的底层实现
  • Overcoming the 77 token limit in diffusers
    • 方法1 手动拼
    • 方法2 compel
  • 问询、帮助请看:

前言

CLIP的输出是77*768的特征,现在基本上一个图像的prompt提示词的token数肯定是很高,会超过77,那超出的时候是如何计算的呢?

sdwebui输入的文本token是自动更新计算的,如何做到的呢?
在这里插入图片描述

关于token_counter

追溯一下代码:
在这里插入图片描述
然后追到js:

在这里插入图片描述

然后追到更新逻辑:

在这里插入图片描述

重要的是这个函数:
在这里插入图片描述
可以看到是clip的分词器在统计token数量:
在这里插入图片描述
估计是要算上开始符号结束符号:
在这里插入图片描述

如何使用这个token,继续追这里的代码:

在这里插入图片描述

写得很抽象:processed = modules.scripts.scripts_txt2img.run(p, *p.script_args)

生图任务,生图参数,给到了scripts_txt2img: ScriptRunner 去跑,除了基础的文生图,还需要考虑各个插件的回调。

如 before_process_batch()、process_batch()、postprocess_batch() 等,它们在批量化生成图像的不同阶段被调用,以便在生成过程中插入自定义逻辑。

关于class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing)

生图的逻辑在这里:

在这里插入图片描述

当我进一步研究这里的代码的时候,我对python的**kwargs 感到恐怖,强大的灵活性的代价就是追踪代码更难了,我不得不打开断点调试来继续。

运行webui.py

运行参数:

--enable-insecure-extension-access         --skip-python-version-check         --skip-torch-cuda-test         --skip-install         --timeout-keep-alive 300         --ckpt ./models/Stable-diffusion/majicmixRealistic_v7.safetensors         --port 7867         --no-download-sd-model         --api  --listen

对于我给的np:worst quality, low quality, low res, blurry, cropped image, jpeg artifacts, error, ugly, out of frame, deformed, poorly drawn, mutilated, mangled, bad proportions, long neck, missing limb, floating limbs, disconnected limbs, long body, missing arms, malformed limbs, missing legs, extra arms, extra legs, poorly drawn face, cloned face, deformed iris, deformed pupils, deformed hands, twisted fingers, malformed hands, poorly drawn hands, mutated hands, mutilated hands, extra fingers, fused fingers, too many fingers, duplicate, multiple heads, extra limb, duplicate artifacts

在这里插入图片描述
在这里就已经拼接为2个77,即是(154,768)的形状。

在这里插入图片描述
定位到这里

在这里插入图片描述

跟到这里就是已经在采样预测噪声去噪了:

在这里插入图片描述

如何超出77个token的限制?

靠纯补,只要是77的倍数就行。

对提示词加权的底层实现

在这里插入图片描述

这段代码实现了一个文本提示权重加权的功能,它将自然语言提示转换为具有权重的token序列。当prompt中包含如(a cute girl: 2)这样的权重信息时,程序通过以下步骤处理:

  1. 首先,prompt_parser.parse_prompt_attention(line)会解析prompt,提取出带有权重的部分。

  2. tokenize_line方法中,针对每个带权重的文本片段(例如:text, weight),将其token化并按照权重分配到PromptChunk对象中。对于权重部分,它会被相应地添加到chunk.multipliers列表中,这个列表与chunk.tokens一一对应,表示每个token的权重。

  3. 当遇到需要添加到Embedding的特殊标记时,使用PromptChunkFix记录下在PromptChunk中的偏移量和对应的Embedding信息,以便稍后应用到模型的嵌入层。

  4. 最后,在调用forward函数时,根据这些权重对tokens进行处理,并在传递给transformer网络之前,将权重与token的嵌入向量相乘(或以其他方式结合权重)。这样就实现了对prompt中括号内指定权重的加权处理。

程序通过解析prompt文本,提取出权重值,并在生成token嵌入向量时将权重应用到相应的token上,从而实现了对prompt中括号内权重的加权功能。

这段代码在这里:


    def process_tokens(self, remade_batch_tokens, batch_multipliers):
        """
        sends one single prompt chunk to be encoded by transformers neural network.
        remade_batch_tokens is a batch of tokens - a list, where every element is a list of tokens; usually
        there are exactly 77 tokens in the list. batch_multipliers is the same but for multipliers instead of tokens.
        Multipliers are used to give more or less weight to the outputs of transformers network. Each multiplier
        corresponds to one token.
        """
        tokens = torch.asarray(remade_batch_tokens).to(devices.device)

        # this is for SD2: SD1 uses the same token for padding and end of text, while SD2 uses different ones.
        if self.id_end != self.id_pad:
            for batch_pos in range(len(remade_batch_tokens)):
                index = remade_batch_tokens[batch_pos].index(self.id_end)
                tokens[batch_pos, index+1:tokens.shape[1]] = self.id_pad

        z = self.encode_with_transformers(tokens)

        pooled = getattr(z, 'pooled', None)

        emphasis = sd_emphasis.get_current_option(opts.emphasis)()
        emphasis.tokens = remade_batch_tokens
        emphasis.multipliers = torch.asarray(batch_multipliers).to(devices.device)
        emphasis.z = z

        emphasis.after_transformers()

        z = emphasis.z

        if pooled is not None:
            z.pooled = pooled

        return z

这段代码定义了一个名为process_tokens的方法,它属于一个继承自FrozenCLIPEmbedderWithCustomWordsBase的类,并且主要功能是对一组带有权重的tokens进行预处理并经过transformers神经网络编码。

  1. 方法接受两个参数:

    • remade_batch_tokens:这是经过重构的批次级别的tokens列表,其中每个元素也是一个包含多个tokens的列表,通常每个列表长度为77个tokens。
    • batch_multipliers:与tokens对应的权重列表,结构同tokens列表一致,每个权重值对应于一个token,用于调整transformers网络输出的权重。
  2. 首先,将remade_batch_tokens转换为PyTorch张量,并移动到当前设备上(devices.device)。

  3. 对于SD2情况(一种假设的变体),如果结束符id (self.id_end) 和填充符id (self.id_pad) 不相同,则会将每个样本中结束符之后的所有位置替换为填充符id。

  4. 使用self.encode_with_transformers方法对调整后的tokens张量进行编码,得到编码后的向量z

  5. 获取编码后向量z中的pooling结果(如果有)。

  6. 创建一个名为emphasis的对象,该对象应该是某种策略类,用于处理强调(权重分配)。设置其属性为传入的tokens和multipliers,以及刚刚经过transformers编码的结果z

  7. 调用emphasis.after_transformers()方法来应用权重强调策略。

  8. 更新z为强调策略处理后的编码结果。

  9. 如果有pooling结果,则将其重新赋给更新后的z.pooled属性。

  10. 最后返回经过整个处理流程后的编码结果z

通过这段代码可以看出,权重的确是在emphasis对象的相关方法中使用的,可能是通过某种方式改变z的某些部分(比如self-attention中的权重分布或是最终的输出向量),以便在模型计算中体现不同token的重要性差异。

Overcoming the 77 token limit in diffusers

在sdwebui这些知名库,都不用diffusers,因为diffusers定制化能力太弱,比如这个需求Overcoming the 77 token limit in diffusers,diffusers一年了都不好好写个文档解决:

有人提过这个问题:

https://github.com/huggingface/diffusers/issues/2136

方法1 手动拼

也就是下面这个代码可以用,但其实未使用77的倍数这个规则,这让我对unet中的交叉注意力如何接收clip出来的特征有很大的兴趣,改天换个文章介绍。

import torch
from diffusers import StableDiffusionPipeline

pipe = StableDiffusionPipeline.from_pretrained(
    "/ssd/xiedong/src_data/eff_train/Stable-diffusion/majicmixRealistic_v7_diffusers", torch_dtype=torch.float16)
pipe = pipe.to("cuda")


# 2. Forward embeddings and negative embeddings through text encoder
prompt = 25 * "a photo of an astronaut riding a horse on mars"
max_length = pipe.tokenizer.model_max_length
print(max_length)

input_ids = pipe.tokenizer(prompt, return_tensors="pt").input_ids
input_ids = input_ids.to("cuda")

negative_ids = pipe.tokenizer("", truncation=False, padding="max_length", max_length=input_ids.shape[-1], return_tensors="pt").input_ids
negative_ids = negative_ids.to("cuda")

concat_embeds = []
neg_embeds = []
for i in range(0, input_ids.shape[-1], max_length):
    concat_embeds.append(pipe.text_encoder(input_ids[:, i: i + max_length])[0])
    neg_embeds.append(pipe.text_encoder(negative_ids[:, i: i + max_length])[0])

prompt_embeds = torch.cat(concat_embeds, dim=1)
negative_prompt_embeds = torch.cat(neg_embeds, dim=1)

# 3. Forward
image = pipe(prompt_embeds=prompt_embeds, negative_prompt_embeds=negative_prompt_embeds).images[0]
image.save("astronaut_rides_horse.png")

方法2 compel

对提示词里做各种各样的加强操作,这个库还是挺6的:

https://github.com/damian0815/compel#compel

diffuers官方也喜欢这个库,有一段说明:

https://huggingface.co/docs/diffusers/main/en/using-diffusers/weighted_prompts

问询、帮助请看:

https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1566095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[已解决] slam_gmapping: undefined symbol: _ZN8GMapping14sampleGaussianEdm问题

之前用的好好的gampping建图功能包,今天突然不能用了,运行报错如下: /opt/ros/noetic/lib/gmapping/slam_gmapping: symbol lookup error: /opt/ros/noetic/lib/gmapping/slam_gmapping: undefined symbol: _ZN8GMapping14sampleGaussianEdm …

首场直播,就在4月11日!

2024年的第一场直播,我们把目光聚焦到“大会员”。 这一次我们想聊聊,当大会员遇上泛零售企业,会产生怎样的“火花”。泛零售企业突破增长压力的机会在哪里?又有哪些挑战必须直面? 本次直播将结合泛零售企业“多业态、…

双机 Cartogtapher 建图文件配置

双机cartogtapher建图 最近在做硕士毕设的最后一个实验,其中涉及到多机建图,经过调研最终采用cartographer建图算法,其中配置多机建图的文件有些麻烦,特此博客以记录 非常感谢我的同门 ”叶少“ 山上的稻草人-CSDN博客的帮助&am…

Chrome 设置在新窗口中打开链接(已登录google账号版)

Chrome的链接默认是在原标签页中打开的,如果要在新窗口中打开,需要自己自行设置,在此,针对已经登录google账号的chrome浏览器怎么进行设置进行说明。 一、点击登录图标->更多设置 二、选择其他设置->在新窗口中打开搜索结果…

Linux上管理文件系统

Linux上管理文件系统 机械硬盘 机械硬盘由多块盘片组成,它们都绕着主轴旋转。每块盘片上下方都有读写磁头悬浮在盘片上下方,它们与盘片的距离极小。在每次读写数据时盘片旋转,读写磁头被磁臂控制着不断的移动来读取其中的数据。 所有的盘片…

一套C#自主版权+应用案例的手麻系统源码

手术麻醉信息管理系统源码,自主版权应用案例的手麻系统源码 手术麻醉信息管理系统包含了患者从预约申请手术到术前、术中、术后的流程控制。手术麻醉信息管理系统主要是由监护设备数据采集子系统和麻醉临床系统两个子部分组成。包括从手术申请到手术分配&#xff0c…

SSM框架学习——JSP语法入门

JSP语法入门 前提 在前一节中我们已经写过JSP的代码了,这一节将单独介绍JSP一些基础语法。当然,你可以跳过这一节,当后面有代码不太理解的时候再回来阅读。 中文编码问题 如果中文乱码,看看JSP是否是以UTF8的方式编码&#xf…

mysql建表必须知道的18个重点(荣耀典藏版)

大家好,我是月夜枫,又和大家见面了!!!! 目录 前言 1.名字 1.1 见名知意 1.2 大小写 1.3 分隔符 1.4 表名 1.5 字段名称 1.6 索引名 2.字段类型 3.字段长度 4.字段个数 5. 主键 6.存储引擎 7.…

计算机网络:数据链路层 - 点对点协议PPP

计算机网络:数据链路层 - 点对点协议PPP PPP协议的帧格式透明传输字节填充法零比特填充法 差错检测循环冗余校验 对于点对点链路,PPP协议是目前使用最广泛的数据链路层协议。比如说,当用户想要接入互联网,就需要通过因特网服务提供…

vulnhub靶机: DC-9

dc-9靶机下载 将靶机设置为NAT模式,本次实验使用的内网网段为192.168.198.0/24,kali的ip为192.168.198.172 信息搜集 ip主机扫描: nmap -sP 192.168.198.0/24 确定靶机ip为192.168.198.171 主机端口扫描: nmap -T4 -A -v 192…

【JVM】如何定位、解决内存泄漏和溢出

目录 1.概述 2.堆溢出、内存泄定位及解决办法 2.1.示例代码 2.2.抓堆快照 2.3.分析堆快照 1.概述 常见的几种JVM内存溢出的场景如下: Java堆溢出: 错误信息: java.lang.OutOfMemoryError: Java heap space 原因:Java对象实例在运行时持…

简单聊聊冯诺伊曼体系结构

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系结构。 简单聊一下,我们所认识的计算机,都是有一个个的硬件组件组成 中央处理器(CPU): a.运算器 :算数运算…

配置code-server和texlive实现网页写tex

使用overleaf太卡了,有云服务器或者nas小主机,配置自己的code-servertexlive,来写论文。 之前用服务器配置过自己的overleaf,感觉不是很好用,缺少东西。 一、思路 使用docker先安装一个ubuntu,用dockerfil…

施耐德 Unity Pro PLC 编程软件介绍

Unity Pro 软件基本介绍 Unity Pro 是施耐德中大型 PLC 的编程软件&#xff08;<–> 对应西门子 Step7&#xff09; 支持的 PLC&#xff1a;施耐德中大型 PLC 中型 PLC&#xff1a;Premium、M340&#xff08;<–> 对应西门子 S7-300、S7-1200&#xff09;大型 PL…

制作一个一键运行的10多M的go-cqhttp最简docker镜像

一直有个想自己部署一个QQ机器人&#xff0c;虽然成功完成在Windows环境下基于 go-cqhttp 的搭建工作。但考虑到我有一台常年在线的群晖 NAS&#xff0c;并且已经配置并启用了 Docke r服务&#xff0c;可否将go-cqhttp 迁移至 NAS 上的 Docker 容器中运行吗呢&#xff1f;同时&…

SSTI模板注入(jinja2)

前面学习了SSTI中的smarty类型&#xff0c;今天学习了Jinja2&#xff0c;两种类型都是flask框架的&#xff0c;但是在注入的语法上还是有不同 SSTI&#xff1a;服务器端模板注入&#xff0c;也属于一种注入类型。与sql注入类似&#xff0c;也是通过凭借进行命令的执行&#xff…

短袖有什么牌子可以推荐?五款每个人都必备的短袖分享

最近天气逐渐升温&#xff0c;大家都在挑选夏季的短袖了&#xff0c;但是因为市面上的短袖质量参差不齐&#xff0c;甚至有一些使用劣质面料&#xff0c;不仅不耐穿不耐洗&#xff0c;而且穿着还十分闷热。相信大家心里都非常想知道现在有哪些短袖品牌是可靠的&#xff0c;所以…

鸿蒙TypeScript入门学习第8天:【TypeScript 函数】

1、TypeScript 函数 函数是一组一起执行一个任务的语句。 您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的&#xff0c;但在逻辑上&#xff0c;划分通常是根据每个函数执行一个特定的任务来进行的。 函数声明告诉编译器函数的名称、返回类型和参…

2.2.1.2-网格交易(python网格交易附实战交易记录)

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1、投资&技术   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas   1.2 金融数据处理   1.3 金融数据可视化 2、投资方法论   2.1.1 预期年化收益率   2.1.2 一个关于yaxb的…

源浩流体设备与您相约2024年第13届生物发酵展

参展企业介绍 温州源浩流体设备科技有限公司是一家集设计、开发、制造、销售、服务于一体的高科技企业&#xff0c;公司主要生产各种不锈钢阀门、管件、卫生级流体设备(卫生级换向阀,卫生级减压阀,卫生级罐底阀)等。现为温州市泵阀协会会员&#xff0c;ISO9000 2008版质量质量…