模型处理
任务是阅读模型代码,调整模型使其适应项目目标,指定训练策略。
阅读模型结构
在原来的《mPLUG-Owl: Modularization Empowers Large Language Models with Multimodality》中,mPlug-Owl模型是用来处理图像-文本的大模型,简单来说就是用户提供图像和相关文本,模型根据这些信息做出回复。如下图
模型整体分为预训练的大语言模型模块和视觉抽象模块,语言模型可以使用LLAMA或者BLOOM等,是预训练好的模型,视觉抽象模块是新设计的捕捉图像的高层语义信息(例如,动作、物体等信息)的模块,使用的是ViT-L/14,这是一种视觉Transformer模型,具有24层,隐藏维度为1024,patch大小为14。视觉抽象模块从视觉基础模型中提取的密集特征中总结出若干个可学习的token,以减少计算开销并提高语义表示的质量。
调整模型应用视频任务
由于视频是连续序列帧构成的文件,即视频是一张张连贯性的图片组成的。
原有模型的问题:
由于原有的模型只能一次处理一张图片,这并不符合处理视频的风格。
解决:
视频是一张张图片组成的,一个电影片段的信息是由几张关键帧和一些不太重要的帧组成。因此我们对原有模型的视觉抽象模块做了一些改动,使其能够接受多张视频的关键帧和提供的文本。不选择全部帧的原因是,视频不同于文本,视频计算所占用的显存更大,过多的视频帧会导致爆显存;同时视频频段中也有很多相似的不太重要的帧,这影响模型对电影的理解。
在这个模型中,处理和拼接多张图片的逻辑主要在 MplugOwlForConditionalGeneration
类的 forward
方法中,尤其是以下几部分
1.提取和处理图像特征:
图像特征是通过调用 self.vision_model
提取的,然后通过 self.abstractor
处理。
if pixel_values is not None:
image_embeds = self.vision_model(pixel_values, return_dict=True).last_hidden_state
image_attention_mask = torch.ones(image_embeds.size()[:-1], dtype=torch.long, device=image_embeds.device)
query_tokens = self.query_tokens.expand(image_embeds.shape[0], -1, -1)
temporal_query_tokens = self.temporal_query_tokens.expand(image_embeds.shape[0], -1, -1)
query_features = self.abstractor(
query_embeds=query_tokens,
encoder_hidden_states=image_embeds,
encoder_attention_mask=image_attention_mask,
)["last_hidden_state"]
img_seq_length = query_features.shape[1]
2.处理视频帧特征:
视频帧特征的提取和处理类似于图像特征,只是视频帧需要额外的时间维度处理。
if video_pixel_values is not None:
video_embeds = self.vision_model(video_pixel_values, return_dict=True).last_hidden_state
video_attention_mask = torch.ones(video_embeds.size()[:-1], dtype=torch.long, device=video_embeds.device)
video_attention_mask = einops.rearrange(
video_attention_mask, 'b t n -> b (t n)'
)
query_tokens = self.query_tokens.expand(video_embeds.shape[0], -1, -1)
temporal_query_tokens = self.temporal_query_tokens.expand(video_embeds.shape[0], -1, -1)
video_query_features = self.abstractor(
query_embeds=query_tokens,
temporal_query_embeds=temporal_query_tokens,
encoder_hidden_states=video_embeds,
encoder_attention_mask=video_attention_mask,
)["last_hidden_state"]
vid_seq_length = video_query_features.shape[1]
3.将图像和视频特征插入文本特征中:
最终的输入特征是将提取的图像和视频特征插入到文本特征中。
num_images_per_sample = num_images.long().cpu().tolist()
num_videos_per_sample = num_videos.long().cpu().tolist()
text_chunk_embeds = []
img_idx = 0
for b in range(batch_size):
start = 0
result = []
if len(media_token_indices[b]) > 0:
for i, pos in enumerate(media_token_indices[b]):
if pos > start:
result.append(text_embeds[b, start:pos])
result.append(query_features[img_idx + i])
start = pos + img_seq_length
if start < text_embeds.shape[1]:
result.append(text_embeds[b, start:])
img_idx += num_images_per_sample[b]
text_chunk_embeds.append(torch.cat(result, dim=0))
input_embeds = torch.stack(text_chunk_embeds, dim=0)
在这些步骤中,多帧视频处理并插入到文本特征中。这种设计允许模型能够同时处理和生成基于多模态输入(视频、文本)的输出。
模型介绍图
训练策略设计
我们的训练策略是,首先利用先前处理好的Movie101电影数据集中的解说台词进行模型训练。为了确保模型的准确性和实用性,我们在训练过程中严格按照数据预处理的规范进行操作。接着,我们使用人工标注的五个不同任务的测试集对模型进行推理测试,以评估其性能。这些测试集涵盖了模型需要掌握的不同技能和任务,通过这种全面的测试方法,我们能够更好地了解模型在实际应用中的表现,并进行针对性的优化和改进。