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

文章目录

  • 前言
  • 关于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; usuallythere 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 multipliercorresponds 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_padz = self.encode_with_transformers(tokens)pooled = getattr(z, 'pooled', None)emphasis = sd_emphasis.get_current_option(opts.emphasis)()emphasis.tokens = remade_batch_tokensemphasis.multipliers = torch.asarray(batch_multipliers).to(devices.device)emphasis.z = zemphasis.after_transformers()z = emphasis.zif pooled is not None:z.pooled = pooledreturn 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 StableDiffusionPipelinepipe = 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.mzph.cn/news/791276.shtml

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

相关文章

动规训练2

一、最小路径和 1、题目解析 就是一个人从左上往做下走,每次只能往右或者往下,求他到终点时,路径上数字和最小,返回最小值 2、算法原理 a状态表示方程 小技巧:经验题目要求 用一个二维数组表示,创建一个…

Flask Python:数据库多条件查询,flask中模型关联

前言 在上一篇Flask Python:模糊查询filter和filter_by,数据库多条件查询中,已经分享了几种常用的数据库操作,这次就来看看模型的关联关系是怎么定义的,先说基础的关联哈。在分享之前,先分享官方文档,点击查看 从文档…

FreeRTOS中断管理以及实验

FreeRTOS中断管理以及实验 继续记录学习FreeRTOS的博客,参照正点原子FreeRTOS的视频。 ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器 , STM32寄存器中并且这个寄存器只使用[7:4]&#xff0c…

RTX RTOS 操作实例分析之---线程(thread)

0 Preface/Foreword 1 线程(thread) 1.1 线程定义 1.1.1 USE_BASIC_THREADS(宏定义) 经过以上步骤(makefile包含),USE_BASIC_THREADS在编译阶段被定义到相应的模块中。 1.1.2 定义线程ID变量…

安装Pillow库的方法最终解答!_Python第三方库

安装Python第三方库Pillow 我的环境:Window10,Python3.7,Anaconda3,Pycharm2023.1.3 pillow库 Pillow库是一个非常强大的图像处理库。它提供了广泛的图像处理功能,让我们可以轻松地读取和保存图像、创建缩略图和合并到…

欧拉路径欧拉回路

欧拉回路,指遍历图时通过图中每条边且仅通过一次,最终回到起点的一条闭合回路,适用于有向图与无向图,如果不强制要求回到起点,则被称为欧拉路径。 欧拉图:具备欧拉回路的图 无向图:图的所有顶…

37-巩固练习(一)

37-1 if语句等 1、问&#xff1a;输出结果 int main() {int i 0;for (i 0; i < 10; i){if (i 5){printf("%d\n", i);}return 0;} } 答&#xff1a;一直输出5&#xff0c;死循环 解析&#xff1a;i5是赋值语句&#xff0c;不是判断语句&#xff0c;每一次循…

路径规划——曲线拟合详解(一):多项式轨迹与QP优化(minimum-snap算法核心部分)

前言 历经一个多星期时间&#xff0c;我们在路径规划——搜索算法部分讲解了7种常见的路径搜索算法&#xff0c;每一种算法的链接放在下面了&#xff0c;有需要的朋友点击跳转即可&#xff1a; 路径规划——搜索算法详解&#xff08;一&#xff09;&#xff1a;Dijkstra算法详…

由平行公设的不同而来三种几何学浅谈

由平行公设的不同而来三种几何学浅谈 欧几里德的《几何原本》 欧几里德的《几何原本》一开始就给出了23个定义&#xff0c;5个公设&#xff0c;5个公理。 23个定义(部分)&#xff1a; 点是没有部分的东西。 线是没有宽度的长度。 线的端点是点。 直线是各点都在同一方向上…

GraalVM运行模式和企业级应用

文章目录 GraalVM运行模式JIT模式AOT模式 GraalVM的问题和解决方案GraalVM企业级应用传统架构的问题Serverless架构函数计算Serverless应用场景Serverless应用 GraalVM内存参数 GraalVM运行模式 JIT模式 JIT&#xff08; Just-In-Time &#xff09;模式 &#xff0c;即时编译模…

Ruby 之交租阶段信息生成

题目 我看了一下&#xff0c;这个题目应该不是什么机密&#xff0c;所以先放上来了。大概意思是根据合同信息生成交租阶段信息。 解答 要求是要使用 Ruby 生成交租阶段信息&#xff0c;由于时间比较仓促&#xff0c;变量名那些就用得随意了些。要点主要有下面这些&#xff1a…

【介绍什么是DDOS】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

Qt 的发展历史、现状与启示

Qt 最早在1991年由挪威的两位程序员 Eirik Chambe-Eng 和 Haavard Nord 开发&#xff0c;他们在1994年创立 Trolltech 公司&#xff08;奇趣科技&#xff09;正式经营软件业务。Qt 的第一个公众预览版于1995年面世&#xff0c;之后在2008年被诺基亚收购&#xff1b;2011年到201…

Go——函数

一. 函数定义 1.1 特点 无需声明原型支持不定变参支持多返回值支持命名返回参数支持匿名函数和闭包函数也是一种类型&#xff0c;一种函数可以赋值给变量不支持嵌套&#xff0c;一个包不能有两个名字一样的函数不支持重载不支持默认参数 1.2 函数声明 函数声明包含一个函数名&…

备战蓝桥杯---DP刷题2

1.树形DP&#xff1a; 即问那几个点在树的直径上&#xff0c;类似ROAD那题&#xff0c;我们先求一下每一个子树根的子树的最大值与次大值用d1,d2表示&#xff0c;直径就是d1d2的最大值&#xff0c;那么我们如何判断是否在最大路径上&#xff0c;其实就是看一下从某一点出发的所…

还得是抖音,字节推出竖屏视频理解数据集,入选CVPR2024

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 短视频在当下社交媒体逐渐成为主导的视频格式。传统视频处理技术和研究一般都专注于横屏视频…

58商铺全新UI试客试用平台网站php源码

探索未来商铺新纪元&#xff0c;58商铺全新UI试客试用平台网站PHP源码完整版震撼来袭&#xff01; 在这个数字化飞速发展的时代&#xff0c;58商铺一直致力于为商家和消费者打造更加便捷、高效的交易平台。今天&#xff0c;我们荣幸地推出全新UI试客试用平台网站PHP源码完整版…

C/C++ 项目:分别用精密星历和广播星历计算卫星坐标

文章目录 Part.I IntroductionChap.I rinex.hChap.II gmain_body.h Part.II 使用方法扩展阅读 Part.I Introduction 本文将介绍一个小项目的使用方法&#xff0c;此项目可用精密星历和广播星历计算卫星位置&#xff0c;并将两者结果做差&#xff0c;输出至文件。 其实 『分别…

SWM341系列应用(上位机应用)

SWM341系列之上位机应用 1、分级图像和PNG、JPG的应用 现象&#xff1a;客户使用SWM34SVET6HMI_0.4.1版本上位机进行UI界面布局&#xff0c;反馈在模拟运行时&#xff08;PC端&#xff09;流畅&#xff0c;在Demo平台&#xff08;设备端&#xff09;运行卡顿。 分析及解决&…

【fastadmin】脚本模式下,日志钩子函数执行出现死循环,导致内存溢出奔溃

问题出现原因是想对项目中error级别的日志&#xff0c;接入钉钉告警&#xff0c;方便查看 于是使用钩子方法&#xff0c;日志写入完成后&#xff0c;自动调用自定义的告警方法中 1、在application/tags.php 中添加log_write_done > [app\\common\\behavior\\Common, ],2、在…