惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy International News Feed
I
Intezer
T
Tenable Blog
S
Schneier on Security
Project Zero
Project Zero
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
Know Your Adversary
Know Your Adversary
博客园 - 司徒正美
The Cloudflare Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
News and Events Feed by Topic
博客园 - 叶小钗
宝玉的分享
宝玉的分享
L
LINUX DO - 热门话题
aimingoo的专栏
aimingoo的专栏
S
Secure Thoughts
Forbes - Security
Forbes - Security
T
The Exploit Database - CXSecurity.com
D
Darknet – Hacking Tools, Hacker News & Cyber Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
罗磊的独立博客
IT之家
IT之家
H
Hacker News: Front Page
I
InfoQ
云风的 BLOG
云风的 BLOG
S
Security Affairs
M
MIT News - Artificial intelligence
GbyAI
GbyAI
Jina AI
Jina AI
Help Net Security
Help Net Security
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
L
Lohrmann on Cybersecurity
A
About on SuperTechFans
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
V
V2EX
G
Google Developers Blog
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
C
Cybersecurity and Infrastructure Security Agency CISA
J
Java Code Geeks
W
WeLiveSecurity
Cloudbric
Cloudbric
T
Tor Project blog

StudyingLover's Blog

Diffusion Policy笔记 rwkv笔记 act笔记 nanovllm-block_manager opencode多智能体 nanobot-pre-train nanobot-rl nanobot-sft nanobot-checkpoint_manager nanobot-gpt nanobot-mid-train Vision Mamba (Vim)笔记 BPE演示 最后一遍学习Transformer YOLOv5 目标检测笔记 下载根服务器解析记录 Dynaseal A Backend-Controlled LLM API Key Distribution Scheme with Constrained Invocation Parameters 判断链表有环 王道25数据结构勘误 关于perplexity的open-sourcing-r1-1776 AI为什么不像人类一样进行多轮对话 新博客改造日记和功能测试 linuxqq只显示登陆背景图 数字设计和计算机体系结构(机械工业出版社)勘误(自制) Dynaseal:面向未来端侧llm agent的llm api key分发机制 A Definitive Guide to Markdown Style This post is using MDX, Where you can embed JSX and Astro components RT-Patch学习 pydantic实现的LLM ReAct fastapi 和 uvicorn 设置监听 ipv6 pydantic+openai+json 控制大模型输出的最佳范式 解决 Matplotlib Scatter 不支持 Marker 列表的问题:mscatter 实现 roofline model zhipuAI接口兼容openai 在docker部署fastapi宝塔里使用nginx反代套上cloudflare获取请求的真实ip clion搭建libbpf-bootstrap开发环境 coze+coze-discord-proxy+ChatNextWebUI实现AI自由 安卓内核时间使用的是UTC时间 colab运行google最新开源模型Gemma Sora技术报告 视频生成模型作为世界模拟器 笔记 archlinux flutter开发踩坑 fastapi集成google auth登录 linux下NTFS磁盘报错输入输出错误 Venn-Abers 预测器 基于Venn-Abers预测器的系统日志异常检测方法_顾兆军 手机平板远程访问kvm虚拟机的windows phi-2弱智吧测评 poe的gemini pro或是百度开发 google gemini api使用 google gemini api申请 构建用于复杂数据处理的高效UDP服务器和客户端 matplotlib中文字体渲染 TruFor笔记和代码复现 深入分析:GitHub Trending 项目 "multipleWindow3dScene" pua大模型 ggml教程|mnist手写体识别量化推理 xgboost2.0最佳实践 xgboost使用GPU最佳实践 马踏棋盘 cloudlflare推理llama2 docker搭建elasticsearch并使用python连接 FreeU-文字生成图片的免费午餐笔记 使用xgboost的c接口推理模型 Archlinux使用CMake调用xgboost的c接口 m2cgen生成机器学习c语言推理代码 xgboost模型序列化存储并推理 speculative-sampling笔记 prompt2model笔记 RoboTAP笔记 自建obsidian同步服务 MediaPipe即将推出图像生成服务 Dual-Stream Diffusion Net for Text-to-Video Generation笔记 ViT在DDPM取代UNet(DiT) arch4edu搞崩了我的flutter LISA(推理分割)笔记 在终端绘制GPU显存使用曲线 GPTBot介绍 arch蓝牙无法连接 GPU部署llama-cpp-python(llama.cpp通用) 花式求GCD 使用llama构建一个蜜罐(前端) 使用llama构建一个蜜罐(后端) llama-cpp-python快速上手 快速上手llama2.c(更新版) Paper Gestalt笔记 DINO-v2笔记 快速上手llama2.c AnyDoor笔记 Archlinux安装scrcpy加载共享库出错 error while loading shared libraries:libusb-1.0.so.0:wrong ELF class:ELFCLASS32 npc_gzip笔记 python调用c++函数 Filesystem type ntfs3,ntfs not configured in kernel open_clip编码图像和文本 PicGo配置CloudflareR2图片储存 ArchlinuxGnome快捷键打开终端 GroundingDINO安装报错解决 2023华为鲲鹏畅想日暨西安高新国际会议中心零食午饭测评 RoboMaster开源仓库汇总(长期更新) 没有手都可以在腾讯云创建镜像 I3D笔记
clip-interrogator代码解析
About the Author StudyingLover · 2023-06-24 · via StudyingLover's Blog

clip-interrogator代码解析

clip-interrogator 的的主要代码在仓库的./clip-interrogator 文件夹下

.
├── clip_interrogator.py
├── data
│   ├── artists.txt
│   ├── flavors.txt
│   ├── mediums.txt
│   ├── movements.txt
│   └── negative.txt
└── __init__.py

这里主要解析clip-interrogator.py 文件。

init.py

from .clip_interrogator import Config, Interrogator, LabelTable, list_caption_models, list_clip_models, load_list

__version__ = '0.6.0'
__author__ = 'pharmapsychotic'

这个 __init__.py 文件的作用是在包被导入时执行初始化操作,并提供了版本号和作者信息。

clip_interrogator.py

文件的大致结构是这样的

import 需要的库

CAPTION_MODELS = {
'blip-base': 'Salesforce/blip-image-captioning-base', # 990MB
'blip-large': 'Salesforce/blip-image-captioning-large', # 1.9GB
'blip2-2.7b': 'Salesforce/blip2-opt-2.7b', # 15.5GB
'blip2-flan-t5-xl': 'Salesforce/blip2-flan-t5-xl', # 15.77GB
'git-large-coco': 'microsoft/git-large-coco', # 1.58GB
}

CACHE_URL_BASE = 'https://huggingface.co/pharma/ci-preprocess/resolve/main/'

@dataclass
class Config:
    具体实现
    
class Interrogator():
    具体实现
    
class LabelTable():
    具体实现

def _download_file(url: str, filepath: str, chunk_size: int = 4*1024*1024, quiet: bool = False):
    具体实现

def _merge_tables(tables: List[LabelTable], ci: Interrogator) -> LabelTable:
    具体实现

def _prompt_at_max_len(text: str, tokenize) -> bool:
    具体实现

def _truncate_to_fit(text: str, tokenize) -> str:
    具体实现

def list_caption_models() -> List[str]:
    具体实现

def list_clip_models() -> List[str]:
    具体实现

def load_list(data_path: str, filename: Optional[str] = None) -> List[str]:
    具体实现

CAPTION_MODELS 定义了各个所需要的模型在huggingface 地址。CACHE_URL_BASE 是缓存地址

Config class

首先定义了CLIP和BILP模型

caption_model = None
caption_processor = None
clip_model = None
clip_preprocess = None

接下来对BLIP和CLIP进行了详细的设置2

# blip settings
caption_max_length: int = 32
caption_model_name: Optional[str] = 'blip-large' # use a key from CAPTION_MODELS or None
caption_offload: bool = False
  
# clip settings
clip_model_name: str = 'ViT-L-14/openai'
clip_model_path: Optional[str] = None
clip_offload: bool = False

这段代码是Config类中与Interrogator类相关的配置参数。

接下来定义了interrogator的相关设置

cache_path: str = 'cache' # 存储缓存的文本嵌入的路径
download_cache: bool = True # 是否从huggingface下载缓存的嵌入向量
chunk_size: int = 2048 # CLIP的批处理大小
data_path: str = os.path.join(os.path.dirname(__file__), 'data')# 数据文件的路径
device: str = ("mps" if torch.backends.mps.is_available() else "cuda" if torch.cuda.is_available() else "cpu")
flavor_intermediate_count: int = 2048
quiet: bool = False # 是否显示进度条

apply_low_vram_defaults方法,用于将配置参数设置为适合低显存设备的默认值。在该方法中,将一些参数设置为较小的值,以减少显存的使用。

Interrogator class

def __init__(self, config: Config):
	self.config = config
	self.device = config.device
	self.dtype = torch.float16 if self.device == 'cuda' else torch.float32
	self.caption_offloaded = True
	self.clip_offloaded = True
	self.load_caption_model()
	self.load_clip_model()

继承了Config 类中的一些配置。

load_caption_model

这个方法用于加载图像描述模型。首先判断配置中是否直接传入了图像描述模型对象,并且是否指定了图像描述模型名称。如果没有直接传入模型对象并且指定了模型名称,则根据模型名称加载对应的模型。加载过程中根据模型名称的不同选择不同的加载方式。加载完成后,将模型设置为eval模式,并根据配置决定是否将模型移动到指定的设备上

load_clip_model

这个方法用于加载CLIP模型。首先根据配置中指定的CLIP模型名称解析出模型名称和预训练模型名称。然后判断配置中是否直接传入了CLIP模型对象。如果没有直接传入模型对象,则根据模型名称和预训练模型名称加载模型。加载过程中会调用open_clip.create_model_and_transforms()方法创建模型和预处理函数,并设置模型为eval模式。加载完成后,将模型和预处理函数保存到对应的属性中。

接下来,根据配置中的数据路径加载一些标签数据,并创建LabelTable对象。LabelTable类用于管理标签和对应的嵌入向量。这里创建了artists、flavors、mediums、movements、trendings和negative等LabelTable对象。

最后,打印加载CLIP模型和数据所花费的时间。

chain

这个方法用于它用于在一组短语中选择最佳的短语,以构建一个完整的提示。

首先调用_prepare_clip()方法,准备CLIP模型。

然后,将短语列表转换为一个集合,方便操作。如果没有指定最佳提示,则通过调用rank_top()方法选择当前短语列表中与图像特征最相似的短语作为最佳提示,并计算其相似度。然后从短语集合中移除最佳提示。

接下来,使用curr_prompt和curr_sim变量保存当前的提示和相似度。

定义了一个名为check的内部函数,用于检查给定的附加短语是否应该成为当前提示的一部分。该函数会根据相似度比较结果更新最佳提示和最佳相似度,并判断是否需要更新当前提示。

使用一个循环遍历max_count次,每次迭代中选择当前短语列表中与当前提示加上附加短语后最相似的短语作为最佳短语。然后将该短语的一部分(从curr_prompt的长度加2开始)作为附加短语。调用check()函数进行相似度比较和更新。

在循环过程中,如果当前提示已经达到了最大长度,则停止迭代。最后,返回最佳提示。

generate_caption

使用BILP生成图像的描述。它首先对图像进行预处理,然后使用图像描述模型生成描述的tokens,最后将tokens解码为文本描述。

image_to_features

使用CLIP的图像编码器将图片转换成torch格式的特征

interrogate

interrogate_classic 首先生成一个标准格式的提示,描述图像,然后列出艺术家、趋势、风格和口味等文本修饰符。它使用了mediums、artists、trendings、movements和flavors等LabelTable对象来选择相应的修饰符。

interrogate_fast 在生成的描述后面简单地添加排名靠前的词语。它通常比经典模式产生更好的生成提示和图像之间的相似度,但提示的可读性较差。它使用了artists、flavors、mediums、movements和trendings等LabelTable对象来选择排名靠前的词语。

interrogate_negative 主要生成负面词汇,将与图像最不相似的词语连接在一起。它可以用于构建与正面提示相对应的负面提示,并且通常可以改善生成图像的结果,特别是在使用稳定扩散2(Stable Diffusion 2)时。它使用了flavors和negative等LabelTable对象来选择最不相似的词语。

interrogate 会生成一个完整的提示。首先生成一个基于图像的描述,然后根据图像特征和LabelTable对象生成一组修饰符。然后使用chain方法选择最佳的修饰符,并根据相似度和一些条件选择最佳提示。最后,根据生成的多个提示的相似度,选择最终的生成提示。

_prepare_caption

用于加载BLIP模型。

_prepare_clip

用于加载CLIP模型。

rank_top

这个方法用于对文本进行排名,并返回排名最高的文本。

首先加载CLIP模型。使用tokenize方法将文本数组转换为文本tokens,并将其移动到设备上。

然后,使用clip_modelencode_text方法对文本tokens进行编码,得到文本的特征向量。对特征向量进行归一化处理,使其长度为1。接着,计算文本特征向量与图像特征向量之间的相似度。通过计算特征向量的点积得到相似度。如果reverseTrue,则将相似度取负,以实现按相似度降序排列。最后,返回排名最高的文本,即相似度最大的文本。

similarity和similarities

通过计算点积的方式计算了相似度

LabelTable class

这个类创建标签,并对标签进行排名

init

def __init__(self, labels:List[str], desc:str, ci: Interrogator):
clip_model, config = ci.clip_model, ci.config
self.chunk_size = config.chunk_size
self.config = config
self.device = config.device
self.embeds = []
self.labels = labels
self.tokenize = ci.tokenize
  
hash = hashlib.sha256(",".join(labels).encode()).hexdigest()
sanitized_name = self.config.clip_model_name.replace('/', '_').replace('@', '_')
self._load_cached(desc, hash, sanitized_name)
  
if len(self.labels) != len(self.embeds):
self.embeds = []
chunks = np.array_split(self.labels, max(1, len(self.labels)/config.chunk_size))
for chunk in tqdm(chunks, desc=f"Preprocessing {desc}" if desc else None, disable=self.config.quiet):
text_tokens = self.tokenize(chunk).to(self.device)
with torch.no_grad(), torch.cuda.amp.autocast():
text_features = clip_model.encode_text(text_tokens)
text_features /= text_features.norm(dim=-1, keepdim=True)
text_features = text_features.half().cpu().numpy()
for i in range(text_features.shape[0]):
self.embeds.append(text_features[i])
  
if desc and self.config.cache_path:
os.makedirs(self.config.cache_path, exist_ok=True)
cache_filepath = os.path.join(self.config.cache_path, f"{sanitized_name}_{desc}.safetensors")
tensors = {
"embeds": np.stack(self.embeds),
"hash": np.array([ord(c) for c in hash], dtype=np.int8)
}
save_file(tensors, cache_filepath)
  
if self.device == 'cpu' or self.device == torch.device('cpu'):
self.embeds = [e.astype(np.float32) for e in self.embeds]

继承了Interrogator 中的一些内容,同时对embeds 做了预处理。

_load_cached

用于加载缓存的嵌入向量。

_rank和rank

用于对图像特征和文本嵌入向量进行排名。_rank方法计算图像特征与文本嵌入向量之间的相似度,并返回排名最高的文本索引。rank方法根据chunk_size的大小,将文本嵌入向量分成多个批次进行排名,然后返回排名最高的文本标签。

data

存储了常用的文字生成图片的prompt

clip-interrogator究竟做了什么

首先,clip-interrogator会使用BILP生成一段对图片的自然语言描述。

接下来会根据四种模式,从data文件夹下的txt文件中组合出文字生成图片常用的prompt,通过CLIP进行编码,然后将图片也用CLIP进行编码,计算出相似度最大的一组prompt,和BILP生成的prompt拼接到一起,就得到了一组prompt。