【深度学习】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; 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

跟着Kimi Chat学习提示工程Prompt Engineering!让AI更高效地给你打工!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识…

【JavaWeb】百度地图API SDK导入

百度地图开放平台 | 百度地图API SDK | 地图开发 (baidu.com) 登录注册,创建应用,获取AK 地理编码 | 百度地图API SDK (baidu.com) 需要的接口一:获取店铺/用户 所在地址的经纬度坐标 轻量级路线规划 | 百度地图API SDK (baidu.com) 需要的…

Fastjson 1.2.47 远程命令执行漏洞复现分析环境

Fastjson 1.2.47 远程命令执行漏洞 1、靶机环境安装 1.1、虚机机linux环境参数 1、操作系统:CentOS Linux release 7.4.1708 (Core) 2、IP:192.168.127.1321.1、docker与docker compose安装 1.2、下载https://github.com/vulhub/vulhub/tree/master/…

Golang | Leetcode Golang题解之第8题字符串转换整数atoi

题目&#xff1a; 题解&#xff1a; func myAtoi(s string) int {abs, sign, i, n : 0, 1, 0, len(s)//丢弃无用的前导空格for i < n && s[i] {i}//标记正负号if i < n {if s[i] - {sign -1i} else if s[i] {sign 1i}}for i < n && s[i] >…

java数据结构与算法刷题-----LeetCode417. 太平洋大西洋水流问题

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 深度优先遍历 深度优先遍历 解题思路&#xff1a;时间复杂度O( …

【计算机视觉】四篇基于Gaussian Splatting的SLAM论文对比

本文对比四篇论文&#xff1a; [1] Gaussian Splatting SLAM [2] SplaTAM: Splat, Track & Map 3D Gaussians for Dense RGB-D SLAM [3] Gaussian-SLAM: Photo-realistic Dense SLAM with Gaussian Splatting [4] GS-SLAM: Dense Visual SLAM with 3D Gaussian Splatting …

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

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

element-ui collapse 组件源码分享

今日简单分享 collapse 组件的源码实现&#xff0c;主要分为四个方面&#xff1a; 1、collapse 组件页面结构 2、collapse 组件属性 3、collapse 组件事件 4、collapse item 组件属性 一、collapse 组件页面结构 二、collapse 组件属性 2.1 value/v-model 属性&#xff0…

Linux终端人性化vimrc编辑配置

目录 vim常用操作 扩展之批量注释 扩展之批量替换 .vimrc pyhon代码补全功能安装 效果预览 .bashrc 终端命令行预览时间 vim常用操作 常用的操作有很多&#xff0c;基本上总会用到的例如 x 删除当前字母 dd 删除正行 i 当前光标插入数据 a 当前位置后插入数据 …

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

安装Python第三方库Schedule 我的环境&#xff1a;Window10&#xff0c;Python3.7&#xff0c;Anaconda3&#xff0c;Pycharm2023.1.3 Schedule库 Schedule 是一个轻量级、功能强大而灵活的任务调度工具库&#xff0c;用于在指定的时间间隔内执行任务。为用户提供了简单易用的…

标题:探索AI绘画:使用深度学习生成艺术

正文&#xff1a; 随着计算机技术的发展&#xff0c;人工智能在各个领域取得了显著的成果。通过训练深度学习模型&#xff0c;AI可以学习大量的艺术作品&#xff0c;从而生成具有独特风格和创意的新作品。 本文将介绍如何使用Python和TensorFlow实现一个简单的AI绘画程序。 二、…

云原生:应用敏捷,华为视角下的应用现代化

Gartner 也提出&#xff0c;到 2023 年&#xff0c;新应用新服务的数量将达到 5 亿&#xff0c;也即是说&#xff1a;“每个企业都正在成为软件企业”。据IDC 预测&#xff0c;到 2025 年三分之二的企业将成为多产的“软件企业”&#xff0c;每天都会发布软件版本。越来越多的企…

AI绘图:Stable Diffusion WEB UI 详细操作介绍:基础篇

接上一篇《AI绘图体验&#xff1a;Stable Diffusion本地化部署详细步骤》本地部署完了SD后&#xff0c;大家肯定想知道怎么用&#xff0c;接下来补一篇Stable Diffusion WEB UI 详细操作&#xff0c;如果大家还没有完成SD的部署&#xff0c;请参考上一篇文章进行本地化的部署。…

vue2+element-ui 实现OSS分片上传+取消上传

遇到问题&#xff1a;项目中需要上传500MB以上的视频。一开始使用上传组件el-upload&#xff0c;调用后台接口&#xff0c;但是出现了onprogress显示百分百后接口一直pending&#xff0c;过了很多秒后接口才通&#xff0c;如果遇到大文件的话&#xff0c;接口就会报超时。 解决…

【javaScript】DOM编程入门

一、什么是DOM编程 概念&#xff1a;DOM(Document Object Model)编程就是使用document对象的API完成对网页HTML文档进行动态修改&#xff0c;以实现网页数据和样式动态变化的编程 为什么要由DOM编程来动态修改呢&#xff1f;我们就得先理解网页的运行原理&#xff1a; 如上图&a…

机器学习每周挑战——信用卡申请用户数据分析

数据集的截图 # 字段 说明 # Ind_ID 客户ID # Gender 性别信息 # Car_owner 是否有车 # Propert_owner 是否有房产 # Children 子女数量 # Annual_income 年收入 # Type_Income 收入类型 # Education 教育程度 # Marital_status 婚姻状况 # Housing_type 居住…

C_C++数据的在内存中的分布

C/C内存分布 在编程世界中&#xff0c;C和C语言一直以其强大的性能和灵活性著称。然而&#xff0c;这种强大和灵活的背后&#xff0c;离不开对内存分布的深入理解和熟练掌握。本文将详细介绍C/C程序中的内存分布&#xff0c;包括栈、堆和全局变量的存储区域。下面是c/c中&…

如何在本地搭建集成大语言模型Llama 2的聊天机器人并实现无公网IP远程访问

文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛&#xff0c;包括聊天机…

x-cmd-pkg | broot 是基于 Rust 开发的一个终端文件管理器

简介 broot 是基于 Rust 开发的一个终端文件管理器&#xff0c;它设计用于帮助用户在终端中更轻松地管理文件和目录&#xff0c;使用树状视图探索文件层次结构、操作文件、启动操作以及定义您自己的快捷方式。 同时它还集成了 ls, tree, find, grep, du, fzf 等工具的常用功能…

Python爬虫之分布式爬虫

分布式爬虫 1.详情介绍 分布式爬虫是指将一个爬虫任务分解成多个子任务&#xff0c;在多个机器上同时执行&#xff0c;从而加快数据的抓取速度和提高系统的可靠性和容错性的技术。 传统的爬虫是在单台机器上运行&#xff0c;一次只能处理一个URL&#xff0c;而分布式爬虫通过将…