「BLIP 微调指南」以 Image-Text Captioning 任务为例

本文介绍了如何对BLIP模型进行微调,以适应Image-TextCaptioning任务。通过解析BLIP的开源代码,定位关键文件和函数,特别是`blip_decoder`,并详细说明了模型参数的设定,如`pretrained`、`image_size`和`prompt`等。在训练和测试阶段,展示了如何使用BLIPModel进行前向传播和生成文本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:近日需要用到 BLIP 微调下游任务,搜索发觉如今并无 BLIP 微调教程,下面就以 Image-Text Captioning 任务为例,演示如何完成 BLIP 模型在自己数据集上的微调。


1. BLIP 介绍

相关论文BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation (ICML, 2022)

演示地址https://huggingface.co/spaces/Salesforce/BLIP

开源代码https://github.com/salesforce/BLIP

在开源代码的 README.md 介绍中,可以看到

在这里插入图片描述
可知 BLIP 可以完成 Image-Text Captioning、VQA 以及 NLVR2 这几个下游任务。


2. 关键代码定位

下图是 github 仓库中的文件构成:

在这里插入图片描述
首先通过 https://github.com/salesforce/BLIP/blob/main/train_caption.py 文件,了解 BLIP 如何用于 captioning 场景中。

相关参数定义在 https://github.com/salesforce/BLIP/blob/main/configs/caption_coco.yaml 文件中。

发现模型通过如下方式定义:

在这里插入图片描述

根据 from models.blip import blip_decoder 的得知,blip_decoder 函数定义于 models.blip 文件中,于是转到https://github.com/salesforce/BLIP/blob/main/models/blip.py 文件。微调过程中,主要使用的是该文件中的 blip_decoder() 函数以及 BLIP_Decoder 类。

  • blip_decoder() 函数定义如下,参数列表包括 pretrained 模型的地址以及 BLIP_Decoder 类的参数列表。

    def blip_decoder(pretrained='',**kwargs):
        model = BLIP_Decoder(**kwargs)
        if pretrained:
            model,msg = load_checkpoint(model,pretrained)
            assert(len(msg.missing_keys)==0)
        return model    
    
  • BLIP_Decoder 类的初始化函数参数列表如下:

    class BLIP_Decoder(nn.Module):
        def __init__(self,                 
                     med_config = 'configs/med_config.json',  
                     image_size = 384,
                     vit = 'base',
                     vit_grad_ckpt = False,
                     vit_ckpt_layer = 0,
                     prompt = 'a picture of ',
                     ):
    

    其中,med_config 对应的 json 文件路径为 https://github.com/salesforce/BLIP/blob/main/configs/med_config.json
    image_size 为模型接收到的图像尺寸;
    vit 为 image encoder 的规模,可选 base 或 large;
    vit_grad_ckpt 是梯度检查点,如果设置为 True,训练时就会节省显存;反之,占用显存更多。详见此篇文章
    vit_ckpt_layer 为使用梯度检查点的层(个人理解);
    prompt 为 BLIP 使用的提示文本,以字符串形式的自然语言文本给出。

PyTorch的 gradient checkpoint 是通过torch.utils.checkpoint.checkpoint(function, *args, **kwargs)函数实现的。Gradient Checkpoint是通过以更长的计算时间为代价,换取更少的显存占用。相比于原本需要存储所有中间变量以供反向传播使用,使用 checkpoint 的部分不存储中间变量,而是在反向传播过程中重新计算这些中间变量。模型中的任何部分都可以使用 gradient checkpoint.

3. 关键参数赋值

  • blip_decoder() 的 pretrained 这一参数的值是在 https://github.com/salesforce/BLIP/blob/main/configs/caption_coco.yaml 文件中找到的;
  • image_size 的值要与自己的数据集中图像尺寸对应,我这里将其修改为 224;
  • prompt 修改为自己需要的自然语言提示文本,注意以字符串形式给出;
  • 其他参数保持不变即可。

4. 模型定义&使用

https://github.com/salesforce/BLIP/blob/main/models/ 目录下的 blip.py, vit.py 以及 med.py 文件下载到自己项目的同一目录下。

在主文件中,通过使用如下命令使用 BLIP model:

BLIPModel = blip_decoder(pretrained=args['pretrained'], image_size=args['image_size'], vit=args['vit'], vit_grad_ckpt=args['vit_grad_ckpt'], vit_ckpt_layer=args['vit_ckpt_layer'], prompt=args['prompt']).to(device)
  • 训练时,使用代码 loss = BLIPModel(imgs, texts) ,调用 Blip_Decoder 类中的 forward() 函数,会得到当前 batch 数据对应的 loss,然后按照关惯常操作进行反向传播;

  • 测试时,使用下述代码
    generated_texts = BLIPModel.generate(imgs, sample=True, num_beams=3, max_length=30, min_length=5, top_p=0.95, repetition_penalty=1.0)
    调用 Blip_Decoder 类中的 generate() 函数,会得到模型对当前 batch 数据生成的自然语言文本。


参考资料

  1. https://github.com/salesforce/BLIP
  2. Pytorch Gradient Checkpoint使用示例_森尼嫩豆腐的博客-CSDN博客
  3. https://pytorch.org/docs/stable/checkpoint.html
### Blip2 模型的指令微调方法 Blip2 是一种强大的多模态模型,其通过两阶段预训练策略实现了高效的视觉-语言理解能力[^3]。为了进一步增强该模型任务适应性和泛化性能,可以对其进行指令微调(Instruction Tuning),使其能够更好地完成特定任务。 #### 1. 指令微调的核心概念 指令微调是一种针对下游任务优化模型的技术,旨在使模型具备更强的理解能力和执行复杂任务的能力。对于 Blip2 而言,可以通过引入专门设计的数据集和调整架构中的 Q-Former 结构来实现这一目标[^2]。具体来说: - **数据准备**:构建高质量的指令-响应对数据集,这些数据应覆盖多种场景,如图像描述、视觉问答等。 - **架构调整**:相较于原始版本,Blip2 的指令微调通常会修改 Querying Transformer 部分的设计,以支持更灵活的上下文建模。 #### 2. 实现步骤详解 以下是基于 Blip2 进行指令微调的主要流程: ```python from transformers import AutoTokenizer, Blip2ForConditionalGeneration import torch # 加载基础模型与 tokenizer model_name_or_path = "Salesforce/blip2-opt" tokenizer = AutoTokenizer.from_pretrained(model_name_or_path) model = Blip2ForConditionalGeneration.from_pretrained( model_name_or_path, load_in_8bit=True, device_map="auto", ) # 准备输入数据 (假设有一个图片路径 img_path 和对应的文本 prompt) img_path = "example_image.jpg" prompt = "Describe the image." processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32") image = processor(images=img_path, return_tensors="pt").pixel_values.to('cuda') inputs = tokenizer(prompt, return_tensors='pt').to('cuda') input_ids = inputs.input_ids # 微调配置 optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5) criterion = torch.nn.CrossEntropyLoss() for epoch in range(epochs): # 定义迭代次数 epochs outputs = model(input_ids=input_ids, pixel_values=image, labels=input_ids) loss = outputs.loss optimizer.zero_grad() loss.backward() optimizer.step() print(f"Training Loss: {loss.item()}") ``` 上述代码展示了如何加载 Blip2 并对其参数进行更新的过程。注意,在实际应用中可能还需要加入更多的超参数调节以及验证机制。 #### 3. 关键注意事项 - 数据质量直接影响最终效果,因此建议收集多样化的标注样本并仔细清洗噪声。 - 训练过程中需监控 GPU 显存占用情况,必要时可启用混合精度训练或梯度累积等方式缓解资源压力。 - 如果希望保持部分模块固定不变,则可通过设置 `requires_grad=False` 来冻结相应层权重。 ---
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Meilinger_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值