[CLIP-VIT-L + Qwen] 多模态大模型源码阅读 - 视觉模型篇

news/2024/11/15 4:46:53/

[CLIP-VIT-L + Qwen] 多模态大模型学习笔记 - 5

  • 前情提要
  • 源码解读(visualModel类)
    • init函数
      • 整体含义
      • 逐行解读
    • get_image_features函数(重构)
      • 整体含义
      • 逐行解读
    • main函数
      • 整体含义
      • 逐行解读

参考repo:WatchTower-Liu/VLM-learning; url: VLLM-BASE

前情提要

有关多模态大模型架构中的语言模型部分(MQwen.py)的代码请看(多模态大模型源码阅读 - 1、 多模态大模型源码阅读 - 2, 多模态大模型源码阅读 - 3,多模态大模型源码阅读 - 4)
本节中将阅读视觉模型部分,即重构后的visual-encoder的源码,位于文件夹visual下的CLIP_VIT.py文件,模型选择的是clip-vit-large-patch14。

源码解读(visualModel类)

init函数

python">class visualModel(CLIPModel):def __init__(self, config: CLIPConfig):super().__init__(config)

整体含义

利用传入的通用配置模型参数初始化父类。

逐行解读

python">class visualModel(CLIPModel):def __init__(self, config: CLIPConfig):super().__init__(config)

定义一个继承CLIPModel成员变量和成员方法的visualModel类,在python3.5之后,可以对传递参数的类型进行注解,这里的CLIPModel是一个特定的自定义参数类型,用于指定传入的config参数是CLIPConfig类型,并使用传递的一般配置参数初始化父类。

get_image_features函数(重构)

python">    @add_start_docstrings_to_model_forward(CLIP_VISION_INPUTS_DOCSTRING)def get_image_features(self,pixel_values: Optional[torch.FloatTensor] = None,output_attentions: Optional[bool] = None,output_hidden_states: Optional[bool] = None,return_dict: Optional[bool] = None,) -> torch.FloatTensor:# Use CLIP model's config for some fields (if specified) instead of those of vision & text components.output_attentions = output_attentions if output_attentions is not None else self.config.output_attentionsoutput_hidden_states = (output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states)return_dict = return_dict if return_dict is not None else self.config.use_return_dictvision_outputs = self.vision_model(pixel_values=pixel_values,output_attentions=output_attentions,output_hidden_states=output_hidden_states,return_dict=return_dict,)pooled_output = vision_outputs.last_hidden_state  # pooled_output# print(pooled_output.shape)return pooled_output

整体含义

经典的特征提取函数,对传入的像素值进行特征提取,并用于后续进一步的处理。重构的目的在于让操作更灵活,可以使用自定义输入和直接获取池化输出。

逐行解读

python">    @add_start_docstrings_to_model_forward(CLIP_VISION_INPUTS_DOCSTRING)def get_image_features(self,pixel_values: Optional[torch.FloatTensor] = None,output_attentions: Optional[bool] = None,output_hidden_states: Optional[bool] = None,return_dict: Optional[bool] = None,) -> torch.FloatTensor:

这里的装饰器是为了给函数添加文档字符串,其中CLIP_VISION_INPUTS_DOCSTRING从transformers.models.clip.modeling_clip导入,这个装饰器可有可无,不必在意。
pixel_values:一个包含图像像素值的浮点数张量
其余的三个参数结尾bool值类型参数,分别代表是否输出注意力权重,是否输出每一层的隐藏层状态,返回值形式是否为字典类型。

python">    # Use CLIP model's config for some fields (if specified) instead of those of vision & text components.output_attentions = output_attentions if output_attentions is not None else self.config.output_attentionsoutput_hidden_states = (output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states)return_dict = return_dict if return_dict is not None else self.config.use_return_dict

这段代码主要判断是使用传入的参数还是使用配置中的默认参数,保证既可以自定义参数,也可以和配置参数保持一致。

python">        vision_outputs = self.vision_model(pixel_values=pixel_values,output_attentions=output_attentions,output_hidden_states=output_hidden_states,return_dict=return_dict,)

调用成员变量vision_model处理像素信息,并输出包含多个返回值的vision_outputs,传递入的参数在前文已经说明,这里不再赘述。

python">        pooled_output = vision_outputs.last_hidden_state  # pooled_output# print(pooled_output.shape)return pooled_output

获取最后一个时间步的隐藏层状态作为池化输出,并将其返回。这个隐藏层状态包含了模型对输入图像的压缩表示或汇总特征。

main函数

python">def main():modle_path = "F:/huggingface_model/clip-vit-large-patch14"model = visualModel.from_pretrained(modle_path)processor = CLIPProcessor.from_pretrained(modle_path)test_img = Image.open("D:/code/multimodal/data/000000391895.jpg")P_input = processor(images=test_img, return_tensors="pt")print(model.get_image_features(**P_input).shape)

整体含义

一个完整的测试流程,加载图像后利用processer预处理图像获得像素信息,并用视觉模型根据传入的像素信息提取图片特征。

逐行解读

python">def main():modle_path = "huggingface_model/clip-vit-large-patch14"model = visualModel.from_pretrained(modle_path)processor = CLIPProcessor.from_pretrained(modle_path)test_img = Image.open("D:/code/multimodal/data/000000391895.jpg")P_input = processor(images=test_img, return_tensors="pt")print(model.get_image_features(**P_input).shape)

这里的model_path可以是自己下载的文件夹,也可以直接从huggingface上加载(需要魔法),使用模型地址加载processor和model,加载测试图片后用processor获取图片像素信息,之后会重构后的模型提取池化特征输出表示。
至此,visual_model中的CLIP-VIT源码阅读完毕,有关项目中的另一个视觉模型SIGLIP模型有兴趣的童鞋可以自行阅读。


http://www.ppmy.cn/news/1513927.html

相关文章

004快速排序-python实现

插入排序原理讲解(以升序为例) 每一轮选取一个参考点,通常为序列的第一个元素或者是序列的最后一个元素,我们此处选取序列的第一个元素作为参考点,将其存入key中,接下来 用key表示参考点的元素。每一轮中&a…

某211电子硕,为什么选择学fpga?

据国海证券发布的快速崛起的国内FPGA龙头报告。 FPGA 作为半定制化、可编程的集成电路,具备高度灵活性,下游主要应用于通信、工业等领域,二者合计占比超七成。国内FPGA市场规模全球占比约为38%,是FPGA主要的消费国。 从人才结构来…

十四、模拟实现 list 类

Ⅰ . list 基本框架的实现 01 结点的建立 为了实现链表&#xff0c;我们首先要做的应该是建立结点 为了和真正的 list 进行区分&#xff0c;我们仍然在自己的命名空间内实现 代码实现&#xff1a; namespace yxt {// 建立结点template<class T>struct ListNode{T _d…

每日一问:深入理解MySQL中的锁机制

每日一问&#xff1a;深入理解MySQL中的锁机制 MySQL作为最流行的关系型数据库管理系统之一&#xff0c;其锁机制在保证数据一致性和并发性方面发挥了关键作用。MySQL的锁机制复杂且多样&#xff0c;涵盖了表级锁、行级锁、共享锁、排他锁、意向锁等多个层面。理解这些锁及其互…

CSS的:required和:optional伪类:提升表单可访问性与用户体验

在Web表单设计中&#xff0c;清晰地指示哪些字段是必填的&#xff0c;哪些是可选的&#xff0c;对于提升用户体验和表单的可访问性至关重要。CSS提供了两个非常有用的伪类&#xff1a;:required和:optional&#xff0c;它们允许开发者为必填和非必填的表单输入字段应用特定的样…

达梦表字段、字段类型,精度比对及更改字段SQL生成

达梦表字段、字段类型&#xff0c;精度比对及更改字段SQL生成&#xff1a; 依赖 <!-- 达梦 Connector --><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.3.62</version>&l…

JavaEE:http请求 | 同步与异步请求 | 跨域问题 | axios框架 有这一篇就够!

前言 HTTP请求是现代Web开发中前后端沟通的基础。在开发过程中&#xff0c;开发者面临同步与异步请求的选择、跨域问题的挑战以及选择合适的HTTP库等问题。同步请求简单却往往阻塞用户界面&#xff0c;而异步请求能提高效率但增加复杂性。跨域问题则源自浏览器的同源政策&…

大模型,读论文,提示词:让任何人,任何时间,读懂,任何领域,任何论文

大模型&#xff0c;读论文&#xff0c;提示词&#xff1a;让任何人&#xff0c;任何时间&#xff0c;读懂&#xff0c;任何领域&#xff0c;任何论文 为什么要读论文&#xff1f;使用装备秒懂大纲提出背景结构化分析问题解法拆解到点全流程分析画出分析性关联图理解数学公式创意…