源码分析之blip2的ITC和ITM的具体实现

引言:很久之前读blip2,对ITC和ITM大致有个印象,一个对比学习,一个图文匹配的二分类,咋一听好像没什么难理解的,最近好好看了一下源码,觉得实现上很巧妙,值得与诸君共享

这里小编没有一句一句分析,直接源码+注释,觉得这样看比较方便,因为只分析ITC和ITM,所以这里只放了blip2里面的Blip2Qformer的forward函数内容,如有出入,还请各位小伙伴留言斧正!

Image-text Contrastive

###============== Image-text Contrastive ===================###
    
    """
    因为在多张卡上训练,所以这里需要将所有卡上的图像特征收集起来,维度为[batch_size*num_gpu, num_query_tokens, embed_dim],
    其中,num_query_tokens是视觉tokens数量,embed_dim是维度
    """
    image_feats_all = concat_all_gather(
        image_feats
    )  # [batch_size*num_gpu, num_query_tokens, embed_dim]

    # 文本这一步操作与上述同理
    text_feat_all = concat_all_gather(text_feat)  # [batch_size*num_gpu, embed_dim]

    """
    求图像与所有文本的相似度
    这里image_feats.unsqueeze(1)之后的维度是[batch_size,1, num_query_tokens, embed_dim]
    text_feat_all.unsqueeze(-1)之后的维度是[batch_size*num_gpu, embed_dim,1]
    为了求每个图像跟所有文本的相似度,图像特征[batch_size,1, num_query_tokens, embed_dim]第2个维度会被广播到batch_size*num_gpu变成[batch_size*,batch_size*num_gpu, num_query_tokens, embed_dim]
    然后矩阵乘法会沿着image_feats和text_feat_all最后两个维度进行相乘,embed_dim维度相乘消失,所以得到的结果为[batch_size,batch_size*num_gpu, num_query_tokens,1]
    相乘之后的结果再squeeze()就得到了[batch_size,batch_size*num_gpu, num_query_tokens]
    """
    sim_q2t = torch.matmul(
        image_feats.unsqueeze(1), text_feat_all.unsqueeze(-1)
    ).squeeze()  # [batch_size, batch_size*num_gpu, num_query_tokens]

    """
    max(-1)表示在最后一个维度上,寻找最大值
    也就是说,对每个图像到文本的相似度,选取所有num_query_tokens中的最大值,sim_i2t最终的维度为[batch_size, batch_size*num_gpu]
    """
    sim_i2t, _ = sim_q2t.max(-1)

    # 通过温度参数self.temp进行相似度的缩放控制
    sim_i2t = sim_i2t / self.temp

    """
    求文本与所有图像的相似度
    text_feat.unsqueeze(1).unsqueeze(1)之后的维度为[batch_size,1,1,embed_dim]
    image_feats_all.permute(0, 2, 1)交换后面两个维度之后的特征维度为[batch_size*num_gpu, embed_dim, num_query_token]
    同理,文本特征[batch_size,1,1,embed_dim]会广播第2个维度到batch_size*num_gpu,变成[batch_size,batch_size*num_gpu,1,embed_dim]
    然后最后两个维度做矩阵乘法得到[batch_size,batch_size*num_gpu,1,num_query_token]
    squeeze()之后的特征为[batch_size,batch_size*num_gpu,num_query_token]
    """
    sim_t2q = torch.matmul(
        text_feat.unsqueeze(1).unsqueeze(1), image_feats_all.permute(0, 2, 1)
    ).squeeze()

    # 对每个文本到图像的相似度,选取所有num_query_tokens中的最大值,sim_i2t最终的维度为[batch_size, batch_size*num_gpu]
    sim_t2i, _ = sim_t2q.max(-1)
    sim_t2i = sim_t2i / self.temp

    rank = dist.get_rank()
    bs = image.size(0)

    """
    torch.linspace(start, end, steps, dtype=int)的作用是生成从 start 
### BLIP2 CLIP 的区别、特性及应用场景 #### 特性功能对比 BLIP2 是一种多模态预训练模型,专注于图像文本之间的交互能力。它通过引入外部视觉语言模型(VLM)作为冻结的上下文编码器来提升其性能[^1]。这种设计使得 BLIP2 能够更好地理解复杂的场景并生成高质量的描述。相比之下,CLIP 则是一种由 OpenAI 开发的双塔架构模型,主要目标是学习跨模态表示以便于执行零样本分类任务。CLIP 使用大量的互联网数据集进行训练,在多种下游任务上表现出强大的泛化能力[^2]。 #### 数据处理方式 在数据处理方面,BLIP2 更加注重对齐特定领域内的图文配对关系,从而实现更精确的任务导向型表现;而 CLIP 倾向于采用广泛分布的数据源来进行大规模无监督或者弱监督的学习过程。这样的差异决定了两者各自擅长的应用范围有所不同。 #### 应用案例分析 对于实际应用而言,如果需要构建一个能够实时响应复杂查询请求并且具备一定推理能力的产品,则可以选择基于 BLIP2 构建解决方案,因为它提供了更强的语言理解生成能力。另一方面,当面临资源受限情况下的快速原型开发需求时,由于 CLIP 已经经过充分优化且易于部署,因此可能成为更好的选项之一。 ```python import torch from transformers import Blip2Processor, Blip2ForConditionalGeneration processor = Blip2Processor.from_pretrained("Salesforce/blip2-opt-2.7b") model = Blip2ForConditionalGeneration.from_pretrained("Salesforce/blip2-opt-2.7b", torch_dtype=torch.float16) url = "http://images.cocodataset.org/val2017/000000039769.jpg" raw_image = Image.open(requests.get(url, stream=True).raw).convert('RGB') inputs = processor(raw_image, return_tensors="pt").to("cuda", torch.float16) generated_ids = model.generate(**inputs, max_new_tokens=20) print(processor.decode(generated_ids[0], skip_special_tokens=True)) ``` 上述代码展示了如何使用 BLIP2 来生成给定图片的文字说明。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的小强呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值