当前位置: 首页 > news >正文

从Debug中学习MiniGPT4

一、代码及配置

话不多说,先附上我用的代码:

import osos.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
os.environ['TRANSFORMERS_OFFLINE'] = '1'import argparse
import os
import randomimport numpy as np
import torch
import torch.backends.cudnn as cudnn
import gradio as grfrom transformers import StoppingCriteriaListfrom minigpt4.common.config import Config
from minigpt4.common.dist_utils import get_rank
from minigpt4.common.registry import registry
from minigpt4.conversation.conversation import Chat, CONV_VISION_Vicuna0, CONV_VISION_LLama2, StoppingCriteriaSub# imports modules for registration
from minigpt4.datasets.builders import *
from minigpt4.models import *
from minigpt4.processors import *
from minigpt4.runners import *
from minigpt4.tasks import *def parse_args():parser = argparse.ArgumentParser(description="Demo")parser.add_argument("--cfg-path", required=True, help="path to configuration file.")parser.add_argument("--gpu-id", type=int, default=0, help="specify the gpu to load the model.")parser.add_argument("--options",nargs="+",help="override some settings in the used config, the key-value pair ""in xxx=yyy format will be merged into config file (deprecate), ""change to --cfg-options instead.",)args = parser.parse_args()return argsdef setup_seeds(config):seed = config.run_cfg.seed + get_rank()random.seed(seed)np.random.seed(seed)torch.manual_seed(seed)cudnn.benchmark = Falsecudnn.deterministic = True# ========================================
#             Model Initialization
# ========================================conv_dict = {'pretrain_vicuna0': CONV_VISION_Vicuna0,'pretrain_llama2': CONV_VISION_LLama2}print('Initializing Chat')
args = parse_args()
cfg = Config(args)model_config = cfg.model_cfg
model_config.device_8bit = args.gpu_id
model_cls = registry.get_model_class(model_config.arch)
model = model_cls.from_config(model_config).to('cuda:{}'.format(args.gpu_id))CONV_VISION = conv_dict[model_config.model_type]vis_processor_cfg = cfg.datasets_cfg.cc_sbu_align.vis_processor.train
vis_processor = registry.get_processor_class(vis_processor_cfg.name).from_config(vis_processor_cfg)stop_words_ids = [[835], [2277, 29937]]
stop_words_ids = [torch.tensor(ids).to(device='cuda:{}'.format(args.gpu_id)) for ids in stop_words_ids]
stopping_criteria = StoppingCriteriaList([StoppingCriteriaSub(stops=stop_words_ids)])chat = Chat(model, vis_processor, device='cuda:{}'.format(args.gpu_id), stopping_criteria=stopping_criteria)
print('Initialization Finished')USER_ANS_FORMAT = ''
# 新代码
# 上传图片
# 图片地址
gr_img = "F:\PKUMultimodal\MiniGPT4main\example1.png"
chat_state = CONV_VISION.copy()
img_list = []
# user_message = '[grounding] describe this image in detail'
USER_PROMPT_CUB_NOVEL = 'describe this image in detail'
user_message = '[grounding]' + USER_ANS_FORMAT + USER_PROMPT_CUB_NOVEL"""chat.upload_img(gr_img, chat_state, img_list)# 问问题
chat.ask(user_message, chat_state)
chat.encode_img(img_list)# 得到回答
llm_message = chat.answer(conv=chat_state,img_list=img_list,temperature=1.5,max_new_tokens=1000,max_length=2000)[0]
print(llm_message)"""from PIL import Image# === 图像预处理 ===
img_path = r"F:\PKUMultimodal\MiniGPT4main\example1.png"
raw_image = Image.open(img_path).convert("RGB")
image_tensor = vis_processor(raw_image).unsqueeze(0).to(model.device)# === 设置 prompt 和 answer ===
user_message = "[grounding] describe this image in detail"
gt_answer = "A detailed description of the image goes here."  # 真实回答越贴近越好# === 伪造 chat state 和 img_list ===
chat_state = CONV_VISION.copy()
img_list = []# === 使用 Chat 模块封装输入 ===
chat.upload_img(raw_image, chat_state, img_list)
chat.encode_img(img_list)
chat.ask(user_message, chat_state)# === 这里我们手动构造符合模型 forward 要求的 samples ===
samples = {"image": image_tensor,"instruction_input": [chat_state.get_prompt()],"answer": [gt_answer],
}# === 模型推理并打印 loss ===
model.eval()
with torch.no_grad():outputs = model(samples)print("Loss:", outputs["loss"].item())

把命令行参数加入到Pycharm的步骤

这个还是要用命令行参数:

  1. 打开 PyCharm,打开你的项目。

  2. 在右上角,找到 Run/Debug Configurations 的下拉框(通常显示你当前运行的脚本名或者 <no configurations>)。

  3. 点击下拉箭头,选择 Edit Configurations...

  4. 在弹出的 Run/Debug Configurations 窗口,点击左上角的 + 号,选择 Python

  5. 填写配置内容:

  • Name:给这个配置起个名字,比如 Run MiniGPT4
  • Script path:点击右侧的文件夹图标,选择你的 Python 脚本文件,比如 test.py
  • Python interpreter:确保选择的是你对应的 conda 虚拟环境里的 Python 解释器(比如 minigptv
  • Parameters:这里填写你的命令行参数,比如
  • css
  • 复制编辑
  • --cfg-path eval_configs/minigpt4_eval.yaml --gpu-id 0
  • Working directory:一般默认是项目根目录,可以确认一下。然后点击APPLY和OK就好了

二、Debug过程中对代码的深入理解

1. 关于parse的相关用法

parse, 中文意思是“分析(字符串、句子、数据)以便理解和处理”。如parse a sentence, parse aa JSON, parse arguments,用来表达“分析并转成结构化形式”。

这这里用于解析命令行参数

def parse_args():parser = argparse.ArgumentParser(description="Demo")parser.add_argument("--cfg-path", required=True, help="path to configuration file.")parser.add_argument("--gpu-id", type=int, default=0, help="specify the gpu to load the model.")parser.add_argument("--options",nargs="+",help="override some settings in the used config, the key-value pair ""in xxx=yyy format will be merged into config file (deprecate), ""change to --cfg-options instead.",)args = parser.parse_args()return args

2.这里的config配置

model:arch: minigpt4model_type: pretrain_llama2max_txt_len: 160end_sym: "</s>"low_resource: Trueprompt_template: '[INST] {} [/INST] 'ckpt: "F:\\PKUMultimodal\\MiniGPT4main\\pretrained_minigpt4_llama2_7b.pth"datasets:cc_sbu_align:vis_processor:train:name: "blip2_image_eval"image_size: 224text_processor:train:name: "blip_caption"run:task: image_text_pretrain

这里记一下,以防后面用到的时候还要找

3.初始化

(1)config初始化配置

这里的config是runner_config, model_config, dataset_config,evaluation_dataset_config, user_config五个的结合

配置名作用描述控制内容示例
runner_config控制训练/测试主流程epochs, amp, output_dir, logging
model_config控制模型结构和预训练权重加载arch, pretrained, precision
dataset_config控制训练数据集加载数据集名称、路径、预处理方式
evaluation_dataset_config控制推理/验证时使用的数据集image path, vis_processor, text_proc
user_config用户自定义覆盖参数(命令行等)比如 model.precision=fp16
①OmegaConnf

它的作用是比 Python 的字典更灵活地管理配置文件,尤其是 .yaml 格式的深层嵌套配置。

它返回的是DictConfig类型,支持点号访问

cfg = OmegaConf.load("config.yaml")
print(cfg.model.name)  # 相当于 cfg["model"]["name"]
②_build_opt_list

把嵌套的字典结构转换为“点式路径”(default一般是默认的意思)

    def _build_opt_list(self, opts):opts_dot_list = self._convert_to_dot_list(opts)return OmegaConf.from_dotlist(opts_dot_list)

如: 

opts = {"model": {"precision": "fp16","pretrained": True}
}
# 转换成:
opts_dot_list = ["model.precision=fp16","model.pretrained=True"
]

(2)Model初始化配置

①初始化所用的三个模型——vit、Qformer、llama
        vit_model = cfg.get("vit_model", "eva_clip_g")q_former_model = cfg.get("q_former_model", "https://storage.googleapis.com/sfr-vision-language-research/LAVIS/models/BLIP2/blip2_pretrained_flant5xxl.pth")img_size = cfg.get("image_size")num_query_token = cfg.get("num_query_token")llama_model = cfg.get("llama_model")

checkpoint:

 ②interpolate
interpolate是指插值从而使位置嵌入与输入数据大小相同,内部依赖于torch.nn.functional.interpolate函数,它主要是用于对多维向量做上采样或下采样操作,形状一般为(N,C,H,W),这就要求orig_size和new_size要相匹配,否则会报错。
③用到的数据集构建方式
名称含义
cc_sbu_align是两个大规模图文对齐数据集 Conceptual Captions(CC) 和 SBU Captions 的组合(用于预训练的图文对齐)。MiniGPT-4 的训练数据就是这两个数据集拼接而来的版本。
minigpt4/datasets/builders/cc_sbu_align_builder.py有定义如何构建该数据集类,包括图像路径、文本内容、预处理方式等。

4.model运行过程

①EncoderImage

vit:transform(形状变为3*224*224)

->x = self.proj(x).flatten(2).transpose(1, 2)(把图像划分为固定大小的patch(通过设置卷积核和步长大小相等),并把每个patch由三通道嵌入到embed_dim个通道,通过卷积实现)(1,256,1408)

#init
self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)
#forward
x = self.proj(x).flatten(2).transpose(1, 2)

->添加cls_token(涵盖图片全局信息)+添加位置信息+dropout(1,257,1408)

cls_tokens = self.cls_token.expand(batch_size, -1, -1)  # stole cls_tokens impl from Phil Wang, thanks
if self.pos_embed is not None:x = x + self.pos_embed
#位置初始化使用了截断的正态分布(Truncated Normal Distribution)来填充给定的 tensor。
#也就是说,和普通的正态分布不一样,它会将值 限制在区间 [a, b] 内,超出范围的会被重新采样。
#注意:这里的位置编码知识一个可学习的参数矩阵初始值,并不是像句子那样明确arange的位置,所以这么初始化没有问题

->进入block(block结构看上一篇)

值得注意的是这里虽然没有直接加位置参数,但是使用了相对位置索引,从而添加了位置感知信息的能力

        if self.relative_position_bias_table is not None:relative_position_bias = \self.relative_position_bias_table[self.relative_position_index.view(-1)].view(self.window_size[0] * self.window_size[1] + 1,self.window_size[0] * self.window_size[1] + 1, -1)  # Wh*Ww,Wh*Ww,nH#从可学习的 relative_position_bias_table 中,# 根据每对 token 的相对位置索引,取出偏置,并加到注意力矩阵中,用于增强模型的空间结构感知能力。relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Wwattn = attn + relative_position_bias.unsqueeze(0)

LN

Qformer(训练的时候有,但是这里没有)

(注意,到目前位置没有经过llama,图像处理只经过了Vit+Qformer)

里面新学到的参数的意思:num_beams用于控制beam_search的宽度,决定模型每一步保留多少个候选序列(类似于topk中的k),stopping_criteria定义什么时候停止生成过程,除了eos_tojen_id外还能增加更多复杂判断。

②LLama模型

将得到的文本特征+图片特征输入到LLama模型中进行生成,因为这个它调用的是LlamaForCausalLMOrig进行的是简单的生成函数,就不再过多介绍。

http://www.dtcms.com/a/272679.html

相关文章:

  • 在Vue中如何对组件进行销毁在进行挂载
  • 模型训练之数据标注-Labelme的使用教程
  • 5款工具高效制作插图,PPT设计新选择!
  • 货车车架和悬架设计cad【7张】+设计说明书
  • leetcode 3440. 重新安排会议得到最多空余时间 II 中等
  • 《PyQt6-3D:开启Python 3D编程新世界 2》
  • 【TCP/IP】8. 传输层协议
  • hive小文件问题
  • 二层环路避免-STP技术
  • Linux【大数据运维】下制作Redis绿色免安装包(一)
  • 企业网络安全的“金字塔”策略:构建全方位防护体系的核心思路
  • upload-labs靶场通关详解:第20关 /.绕过
  • 以下哪种类型在Golang中不是内置类型?
  • zookeeper etcd区别
  • Keepalived+LVS实现LNMP网站的高可用部署
  • 登录为图片验证时,selenium通过token直接进入页面操作
  • Java 导出word 实现饼状图导出--可编辑数据
  • CIEDE2000 色差公式C++及MATLAB实现
  • 【零基础学AI】第35讲:策略梯度方法 - 连续控制任务实战
  • Swift 图论实战:DFS 算法解锁 LeetCode 323 连通分量个数
  • 快速搭建服务器,fetch请求从服务器获取数据
  • ReentrantLock 与 Synchronized 的区别
  • 给MySQL做定时备份,一天3次
  • method_name字段是什么
  • 单片机基础(STM32-DAY2(GPIO))
  • Linux驱动06 --- UDP
  • 飞书AI技术体系
  • web 系统对接飞书三方登录完整步骤实战使用示例
  • 低温冷启动 高温热启动
  • OpenCV 图像进阶处理:特征提取与车牌识别深度解析