# Copyright 2023 Haotian Liu # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import math import random from abc import ABC, abstractmethod import torch import torch.nn as nn import torch.nn.functional as F from longvu.constants import ( DEFAULT_IM_END_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IMAGE_PATCH_TOKEN, IGNORE_INDEX, IMAGE_TOKEN_INDEX, ) from .multimodal_encoder.builder import build_vision_tower_aux_list from .multimodal_projector.builder import build_vision_projector from .vision_sampler import VisionTokenSampler IS_XLA_AVAILABLE = False class CambrianMetaModel: def __init__(self, config): super(CambrianMetaModel, self).__init__(config) if hasattr(config, "mm_vision_tower_aux_list"): projector_type = getattr(config, "mm_projector_type", "linear") if projector_type == "sva": vision_hidden_size = config.vision_hidden_size num_query_group = config.num_query_group query_num_list = config.query_num_list connector_only = config.connector_only connector_depth = config.connector_depth self.vision_tower_aux_list = build_vision_tower_aux_list( config, delay_load=True ) self.mm_projector = nn.Sequential( nn.Linear(vision_hidden_size * num_query_group, config.hidden_size), nn.GELU(), nn.Linear(config.hidden_size, config.hidden_size), ) image_token_len = config.image_token_len vision_tower_aux_token_len_list = ( self.config.mm_vision_tower_aux_token_len_list ) cross_att_token_len_list = [ int(vision_tower_aux_token_len**0.5) // int(image_token_len**0.5) for vision_tower_aux_token_len in vision_tower_aux_token_len_list ] for aux_i, vision_tower_aux in enumerate(self.vision_tower_aux_list): setattr( self, "mm_projector_aux_{}".format(aux_i), nn.Sequential( nn.Linear(vision_tower_aux.hidden_size, vision_hidden_size), nn.GELU(), nn.Linear(vision_hidden_size, vision_hidden_size), nn.LayerNorm(vision_hidden_size), ), ) for query_group_i in range(num_query_group): cross_att_token_len_list = [ int(vision_tower_aux_token_len**0.5) // int(query_num_list[query_group_i] ** 0.5) for vision_tower_aux_token_len in vision_tower_aux_token_len_list ] setattr( self, "vision_sampler_{}".format(query_group_i), VisionTokenSampler( vision_hidden_size, vision_hidden_size, [vision_hidden_size] * len(self.vision_tower_aux_list), cross_att_token_len_list, vision_hidden_size, connector_depth, ), ) if not connector_only: num_of_vision_sampler_layers = ( config.num_of_vision_sampler_layers ) = config.num_of_vision_sampler_layers config.start_of_vision_sampler_layers = ( config.start_of_vision_sampler_layers ) config.stride_of_vision_sampler_layers = ( config.stride_of_vision_sampler_layers ) cross_att_token_len_list = [ int(vision_tower_aux_token_len**0.5) // int(image_token_len**0.5) for vision_tower_aux_token_len in vision_tower_aux_token_len_list ] self.vision_sampler_layers = nn.ModuleList( [ VisionTokenSampler( config.hidden_size, vision_hidden_size, [vision_hidden_size] * len(self.vision_tower_aux_list), cross_att_token_len_list, vision_hidden_size, 1, ) for layer_idx in range(0, num_of_vision_sampler_layers) ] ) self.vision_query = nn.Parameter( torch.randn((num_query_group, vision_hidden_size), dtype=self.dtype) ) self.image_newline = nn.Parameter( torch.empty(config.hidden_size, dtype=self.dtype) ) self.frame_pos = torch.stack( [ 1 / torch.pow( torch.tensor(10000), torch.tensor(2 * (hid_j // 2) / config.hidden_size), ) for hid_j in range(config.hidden_size) ] ) else: self.vision_tower_aux_list = build_vision_tower_aux_list( config, delay_load=True ) config.mm_hidden_size = sum( [ vision_tower_aux.hidden_size for vision_tower_aux in self.vision_tower_aux_list ] ) self.mm_projector = build_vision_projector(config) self.image_newline = nn.Parameter( torch.empty(config.hidden_size, dtype=self.dtype) ) def get_frame_pos(self, time_range): frame_pos = self.frame_pos.reshape(1, -1) * time_range.reshape(-1, 1).to( self.frame_pos.device ) frame_pos[:, 0::2] = torch.sin(frame_pos[:, 0::2]) frame_pos[:, 1::2] = torch.cos(frame_pos[:, 0::2]) frame_pos = frame_pos.unsqueeze(1) return frame_pos # def get_vision_tower(self): # vision_tower = getattr(self, 'vision_tower', None) # if type(vision_tower) is list: # vision_tower = vision_tower[0] # return vision_tower def get_vision_tower_aux_list(self): vision_tower_aux_list = getattr(self, "vision_tower_aux_list", None) return vision_tower_aux_list def initialize_vision_modules(self, model_args, fsdp=None): # vision_tower = model_args.vision_tower num_query_group = model_args.num_query_group query_num_list = model_args.query_num_list vision_hidden_size = model_args.vision_hidden_size vision_tower_aux_list = model_args.vision_tower_aux_list vision_tower_aux_token_len_list = model_args.vision_tower_aux_token_len_list image_token_len = model_args.image_token_len mm_vision_select_layer = model_args.mm_vision_select_layer mm_vision_select_feature = model_args.mm_vision_select_feature pretrain_mm_mlp_adapter = model_args.pretrain_mm_mlp_adapter connector_only = model_args.connector_only connector_depth = model_args.connector_depth # self.config.mm_vision_tower = vision_tower self.config.image_token_len = image_token_len self.config.num_query_group = num_query_group self.config.query_num_list = query_num_list assert num_query_group == len(query_num_list) self.config.connector_depth = connector_depth self.config.mm_vision_tower_aux_list = vision_tower_aux_list self.config.mm_vision_tower_aux_token_len_list = vision_tower_aux_token_len_list self.config.connector_only = connector_only self.config.highres_connect = model_args.highres_connect self.config.highres = model_args.highres self.config.frame_pos = model_args.frame_pos self.config.lowres_token = model_args.lowres_token self.config.connect_layer = model_args.connect_layer self.config.dino_threshold = getattr(model_args, "dino_threshold", 0.83) self.config.drop_threshold = getattr(model_args, "drop_threshold", 0.6) self.config.is_image_newline = getattr(model_args, "is_image_newline", True) if self.get_vision_tower_aux_list() is None: vision_tower_aux_list = build_vision_tower_aux_list(model_args) if model_args.unfreeze_mm_vision_tower: self.vision_tower_aux_list = nn.ModuleList(vision_tower_aux_list) else: self.vision_tower_aux_list = vision_tower_aux_list else: vision_tower_aux_list = self.vision_tower_aux_list for vision_tower_aux in vision_tower_aux_list: vision_tower_aux.load_model() self.config.use_mm_proj = True self.config.mm_projector_type = getattr( model_args, "mm_projector_type", "linear" ) self.config.vision_hidden_size = vision_hidden_size self.config.mm_vision_select_layer = mm_vision_select_layer self.config.mm_vision_select_feature = mm_vision_select_feature if getattr(self, "mm_projector", None) is None: if self.config.mm_projector_type == "sva": self.mm_projector = nn.Sequential( nn.Linear( vision_hidden_size * num_query_group, self.config.hidden_size ), nn.GELU(), nn.Linear(self.config.hidden_size, self.config.hidden_size), ) for aux_i, vision_tower_aux in enumerate(vision_tower_aux_list): setattr( self, "mm_projector_aux_{}".format(aux_i), nn.Sequential( nn.Linear(vision_tower_aux.hidden_size, vision_hidden_size), nn.GELU(), nn.Linear(vision_hidden_size, vision_hidden_size), nn.LayerNorm(vision_hidden_size), ), ) # vision sampler for each group of query as the connector before the LLM for query_group_i in range(num_query_group): cross_att_token_len_list = [ int(vision_tower_aux_token_len**0.5) // int(query_num_list[query_group_i] ** 0.5) for vision_tower_aux_token_len in vision_tower_aux_token_len_list ] setattr( self, "vision_sampler_{}".format(query_group_i), VisionTokenSampler( vision_hidden_size, vision_hidden_size, [vision_hidden_size] * len(vision_tower_aux_list), cross_att_token_len_list, vision_hidden_size, connector_depth, ), ) # sampler layers within LLM if not connector_only: num_of_vision_sampler_layers = ( self.config.num_of_vision_sampler_layers ) = model_args.num_of_vision_sampler_layers self.config.start_of_vision_sampler_layers = ( model_args.start_of_vision_sampler_layers ) self.config.stride_of_vision_sampler_layers = ( model_args.stride_of_vision_sampler_layers ) cross_att_token_len_list = [ int(vision_tower_aux_token_len**0.5) // int(image_token_len**0.5) for vision_tower_aux_token_len in vision_tower_aux_token_len_list ] self.vision_sampler_layers = nn.ModuleList( [ VisionTokenSampler( self.config.hidden_size, vision_hidden_size, [vision_hidden_size] * len(vision_tower_aux_list), cross_att_token_len_list, vision_hidden_size, 1, ) for layer_idx in range(0, num_of_vision_sampler_layers) ] ) vision_embed_std = 1 / torch.sqrt( torch.tensor(vision_hidden_size, dtype=self.dtype) ) self.vision_query = nn.Parameter( torch.randn((num_query_group, vision_hidden_size), dtype=self.dtype) * vision_embed_std ) embed_std = 1 / torch.sqrt( torch.tensor(self.config.hidden_size, dtype=self.dtype) ) self.image_newline = nn.Parameter( torch.randn(self.config.hidden_size, dtype=self.dtype) * embed_std ) else: self.config.mm_hidden_size = sum( [ vision_tower_aux.hidden_size for vision_tower_aux in vision_tower_aux_list ] ) self.mm_projector = build_vision_projector(self.config) embed_std = 1 / torch.sqrt( torch.tensor(self.config.hidden_size, dtype=self.dtype) ) self.image_newline = nn.Parameter( torch.randn(self.config.hidden_size, dtype=self.dtype) * embed_std ) else: # In case it is frozen by LoRA for p in self.mm_projector.parameters(): p.requires_grad = True if pretrain_mm_mlp_adapter is not None: mm_projector_weights = torch.load( pretrain_mm_mlp_adapter, map_location="cpu" ) def get_w(weights, keyword): return { k.split(keyword + ".")[1]: v for k, v in weights.items() if keyword + "." in k } self.mm_projector.load_state_dict( get_w(mm_projector_weights, "mm_projector"), strict=True ) if self.config.mm_projector_type == "sva": for aux_i in range(len(vision_tower_aux_list)): getattr(self, "mm_projector_aux_{}".format(aux_i)).load_state_dict( get_w( mm_projector_weights, "mm_projector_aux_{}".format(aux_i) ), strict=True, ) for query_group_i in range(num_query_group): getattr( self, "vision_sampler_{}".format(query_group_i) ).load_state_dict( get_w( mm_projector_weights, "vision_sampler_{}".format(query_group_i), ), strict=True, ) if not connector_only: self.vision_sampler_layers.load_state_dict( get_w(mm_projector_weights, "vision_sampler_layers"), strict=True, ) self.vision_query.data = mm_projector_weights["model.vision_query"] self.image_newline.data = mm_projector_weights["model.image_newline"] def unmask_attention_mask(mask, original_size): original_w, original_h = original_size cur_h, cur_w = mask.shape[1:3] original_aspect_ratio = original_w / original_h current_aspect_ratio = cur_w / cur_h if original_aspect_ratio > current_aspect_ratio: scale_factor = cur_w / original_w new_height = int(original_h * scale_factor) padding = (cur_h - new_height) // 2 if padding > 0: mask[:, :padding, :] = 0 mask[:, -padding:, :] = 0 return mask else: scale_factor = cur_h / original_h new_width = int(original_w * scale_factor) padding = (cur_w - new_width) // 2 if padding > 0: mask[:, :, :padding] = 0 mask[:, :, -padding:] = 0 return mask def unpad_image(tensor, original_size): """ Unpads a PyTorch tensor of a padded and resized image. Args: tensor (torch.Tensor): The image tensor, assumed to be in CxHxW format. original_size (tuple): The original size of the image (height, width). Returns: torch.Tensor: The unpadded image tensor. """ original_width, original_height = original_size current_height, current_width = tensor.shape[1:3] original_aspect_ratio = original_width / original_height current_aspect_ratio = current_width / current_height if original_aspect_ratio > current_aspect_ratio: scale_factor = current_width / original_width new_height = int(original_height * scale_factor) padding = (current_height - new_height) // 2 unpadded_tensor = tensor[:, padding : current_height - padding, :] # if 0 in unpadded_tensor.shape: # print(f"scale_factor: {scale_factor}, new_height: {new_height}, padding: {padding}, original_width: {original_width}, original_height: {original_height}") else: scale_factor = current_height / original_height new_width = int(original_width * scale_factor) padding = (current_width - new_width) // 2 unpadded_tensor = tensor[:, :, padding : current_width - padding] # if 0 in unpadded_tensor.shape: # print(f"scale_factor: {scale_factor}, new_width: {new_width}, padding: {padding}, original_width: {original_width}, original_height: {original_height}") return unpadded_tensor class CambrianMetaForCausalLM(ABC): @abstractmethod def get_model(self): pass # def get_vision_tower(self): # return self.get_model().get_vision_tower() def get_vision_tower_aux_list(self): return self.get_model().get_vision_tower_aux_list() def rearrange_vision_tower_features_train( self, vision_tower_aux_feature_list, vision_tower_aux_attention_masks_list, query_side_len, ): vision_tower_aux_feature_rearranged_list = [] vision_tower_aux_attention_masks_rearranged_list = [] bs = vision_tower_aux_feature_list[0].shape[0] for vision_tower_aux_feature, vision_tower_aux_attention_masks in zip( vision_tower_aux_feature_list, vision_tower_aux_attention_masks_list ): aux_height = aux_width = int(vision_tower_aux_feature.shape[1] ** 0.5) assert (aux_height // query_side_len) * query_side_len == aux_height reduce_factor = aux_height // query_side_len vision_tower_aux_feature_rearranged = vision_tower_aux_feature.view( bs, query_side_len, reduce_factor, query_side_len, reduce_factor, -1 ) vision_tower_aux_feature_rearranged = ( vision_tower_aux_feature_rearranged.permute(0, 1, 3, 2, 4, 5) .contiguous() .flatten(0, 2) .flatten(1, 2) ) vision_tower_aux_attention_masks_rearranged = ( vision_tower_aux_attention_masks.view( bs * query_side_len * query_side_len, reduce_factor * reduce_factor ) ) vision_tower_aux_feature_rearranged_list.append( vision_tower_aux_feature_rearranged ) vision_tower_aux_attention_masks_rearranged_list.append( vision_tower_aux_attention_masks_rearranged ) return ( vision_tower_aux_feature_rearranged_list, vision_tower_aux_attention_masks_rearranged_list, ) def rearrange_vision_tower_features_inference( self, vision_tower_aux_feature_list, query_side_len, image_sizes, unpad=False ): vision_tower_aux_feature_rearranged_list = [] vision_tower_aux_attention_masks_rearranged_list = [] bs = vision_tower_aux_feature_list[0].shape[0] for vision_tower_aux_feature in vision_tower_aux_feature_list: aux_height = aux_width = int(vision_tower_aux_feature.shape[1] ** 0.5) assert (aux_height // query_side_len) * query_side_len == aux_height reduce_factor = aux_height // query_side_len vision_tower_aux_feature_rearranged = [] vision_tower_aux_attention_masks_rearranged = [] for batch_i in range(bs): image_size = image_sizes[batch_i] cur_vision_tower_aux_feature = vision_tower_aux_feature[batch_i] cur_vision_tower_aux_attention_masks_rearranged = torch.ones( (1, aux_height, aux_width), dtype=torch.bool, device=cur_vision_tower_aux_feature.device, ) cur_vision_tower_aux_feature_rearranged = ( cur_vision_tower_aux_feature.view( 1, query_side_len, reduce_factor, query_side_len, reduce_factor, -1, ) ) cur_vision_tower_aux_feature_rearranged = ( cur_vision_tower_aux_feature_rearranged.permute( 0, 1, 3, 2, 4, 5 ).contiguous() ) if unpad: cur_vision_tower_aux_feature_rearranged = unpad_image( cur_vision_tower_aux_feature_rearranged, image_size ) cur_vision_tower_aux_feature_rearranged = ( cur_vision_tower_aux_feature_rearranged.flatten(0, 2).flatten(1, 2) ) # query_side_len*query_side_len X reduce_factor*reduce_factor X C cur_vision_tower_aux_attention_masks_rearranged = unmask_attention_mask( cur_vision_tower_aux_attention_masks_rearranged, image_size ) cur_vision_tower_aux_attention_masks_rearranged = ( cur_vision_tower_aux_attention_masks_rearranged.view( 1, query_side_len, reduce_factor, query_side_len, reduce_factor ) .permute(0, 1, 3, 2, 4) .contiguous() ) if unpad: cur_vision_tower_aux_attention_masks_rearranged = unpad_image( cur_vision_tower_aux_attention_masks_rearranged, image_size ) cur_vision_tower_aux_attention_masks_rearranged = ( cur_vision_tower_aux_attention_masks_rearranged.flatten( 0, 2 ).flatten(1, 2) ) cur_vision_tower_aux_attention_masks_rearranged[ cur_vision_tower_aux_attention_masks_rearranged.sum(-1) == 0 ] = True vision_tower_aux_feature_rearranged.append( cur_vision_tower_aux_feature_rearranged ) vision_tower_aux_attention_masks_rearranged.append( cur_vision_tower_aux_attention_masks_rearranged ) vision_tower_aux_feature_rearranged = torch.cat( vision_tower_aux_feature_rearranged, 0 ) vision_tower_aux_attention_masks_rearranged = torch.cat( vision_tower_aux_attention_masks_rearranged, 0 ) vision_tower_aux_feature_rearranged_list.append( vision_tower_aux_feature_rearranged ) vision_tower_aux_attention_masks_rearranged_list.append( vision_tower_aux_attention_masks_rearranged ) return ( vision_tower_aux_feature_rearranged_list, vision_tower_aux_attention_masks_rearranged_list, ) def encode_images(self, image_aux_list, encode_type=None): vision_tower_aux_list = self.get_model().get_vision_tower_aux_list() image_aux_features_list = [] chunk_size = 64 if encode_type == "dino": image_aux = image_aux_list[-1] vision_tower_aux = vision_tower_aux_list[-1] if image_aux.shape[0] > chunk_size: image_aux_features_chunks = [] for start_idx in range(0, image_aux.shape[0], chunk_size): end_idx = min(start_idx + chunk_size, image_aux.shape[0]) chunk = image_aux[start_idx:end_idx] image_aux_features_chunk = vision_tower_aux(chunk) image_aux_features_chunks.append(image_aux_features_chunk) image_aux_features = torch.cat(image_aux_features_chunks, dim=0) else: image_aux_features = vision_tower_aux(image_aux) return image_aux_features elif encode_type == "siglip": image_aux = image_aux_list[0] vision_tower_aux = vision_tower_aux_list[0] if image_aux.shape[0] > chunk_size: image_aux_features_chunks = [] for start_idx in range(0, image_aux.shape[0], chunk_size): end_idx = min(start_idx + chunk_size, image_aux.shape[0]) chunk = image_aux[start_idx:end_idx] image_aux_features_chunk = vision_tower_aux(chunk) image_aux_features_chunks.append(image_aux_features_chunk) image_aux_features = torch.cat(image_aux_features_chunks, dim=0) else: image_aux_features = vision_tower_aux(image_aux) return image_aux_features else: for image_aux, vision_tower_aux in zip( image_aux_list, vision_tower_aux_list ): if image_aux.shape[0] > chunk_size: image_aux_features_chunks = [] for start_idx in range(0, image_aux.shape[0], chunk_size): end_idx = min(start_idx + chunk_size, image_aux.shape[0]) chunk = image_aux[start_idx:end_idx] image_aux_features_chunk = vision_tower_aux(chunk) image_aux_features_chunks.append(image_aux_features_chunk) image_aux_features = torch.cat(image_aux_features_chunks, dim=0) else: image_aux_features = vision_tower_aux(image_aux) image_aux_features_list.append(image_aux_features) return image_aux_features_list def select_frame( self, feature_list, split_sizes, input_ids, new_image_aux_list, image_sizes, window_size=16, threshold=0.83, ): dino_features_batch = torch.split(feature_list, split_sizes, dim=0) new_image_aux_batch_0 = torch.split(new_image_aux_list[0], split_sizes, dim=0) new_image_aux_batch_1 = torch.split(new_image_aux_list[1], split_sizes, dim=0) new_split_sizes = [] selected_frames_all_0 = [] selected_frames_all_1 = [] selected_frames_feature_all = [] selected_frame_indices_all = [] for i_batch, frame_features in enumerate(dino_features_batch): try: if "llama" in self.get_model().config.model_type: text_len = torch.where(input_ids[i_batch] == 128002)[-1][0] else: text_len = torch.where(input_ids[i_batch] == 151643)[-1][0] except: text_len = len(input_ids[i_batch]) original_width, original_height = image_sizes[i_batch] if getattr(self.get_model().config, "highres", False): token_per_frame = self.get_model().config.lowres_token ** 2 else: token_per_frame = self.get_model().config.image_token_len # current_height, current_width = token_per_side, token_per_side # original_aspect_ratio = original_width / original_height # current_aspect_ratio = current_width / current_height # if original_aspect_ratio > current_aspect_ratio: # scale_factor = current_width / original_width # new_height = int(original_height * scale_factor) # padding = math.ceil((current_height - new_height) / 2.0) # token_per_frame = ( # current_height - padding * 2 # ) * token_per_side + token_per_side # else: # scale_factor = current_height / original_height # new_width = int(original_width * scale_factor) # padding = math.ceil((current_width - new_width) / 2.0) # token_per_frame = (current_width - padding * 2) * token_per_side + ( # current_width - padding * 2 # ) # token_per_frame = ( # token_per_side**2 if token_per_frame < 1 else token_per_frame # ) max_num_frames = max( 1, ( self.get_model().config.tokenizer_model_max_length - text_len - getattr(self.get_model().config, "inference_max_length", 16) ) // token_per_frame, ) if len(frame_features) < max_num_frames: selected_frames_all_0.append(new_image_aux_batch_0[i_batch]) selected_frames_all_1.append(new_image_aux_batch_1[i_batch]) selected_frames_feature_all.append(frame_features) new_split_sizes.append(len(frame_features)) selected_frame_indices_all.append(torch.arange(len(frame_features))) continue num_segments = len(frame_features) // window_size if num_segments == 0: query_feature = frame_features.flatten(1, 2) query_feature = query_feature / torch.norm( (query_feature), dim=1, keepdim=True ) similarities = torch.mean(query_feature @ query_feature.T, dim=1) similarities[len(frame_features) // 2] = 0 indices = torch.where(similarities < threshold)[0] selected_frame_indices_all.append(indices) selected_frames_all_0.append(new_image_aux_batch_0[i_batch][indices]) selected_frames_all_1.append(new_image_aux_batch_1[i_batch][indices]) selected_frames_feature_all.append(frame_features[indices]) new_split_sizes.append(len(indices)) continue segments_frames_0 = [] segments_frames_1 = [] segments_features = [] for start_idx in range(0, len(frame_features), window_size): end_idx = min(start_idx + window_size, len(frame_features)) segments_frames_0.append( new_image_aux_batch_0[i_batch][start_idx:end_idx] ) segments_frames_1.append( new_image_aux_batch_1[i_batch][start_idx:end_idx] ) segments_features.append(frame_features[start_idx:end_idx]) selected_frames_0 = [] selected_frames_1 = [] selected_features = [] selected_frame_indices = [] for i, segment in enumerate(segments_features): query_feature = segment.flatten(1, 2) query_feature = query_feature / torch.norm( (query_feature), dim=1, keepdim=True ) similarities = torch.mean(query_feature @ query_feature.T, dim=1) similarities[len(segment) // 2] = 0 indices = torch.where(similarities < threshold)[0] selected_frames_0.append(segments_frames_0[i][indices]) selected_frames_1.append(segments_frames_1[i][indices]) selected_features.append(segment[indices]) selected_frame_indices.extend(indices + i * window_size) selected_frames_0 = torch.cat(selected_frames_0, dim=0) selected_frames_1 = torch.cat(selected_frames_1, dim=0) selected_features = torch.cat(selected_features, dim=0) selected_frame_indices = torch.tensor(selected_frame_indices) # ablation max_num_frames = 400 # in case of OOM if len(selected_frames_0) > max_num_frames: interval = len(selected_frames_0) / float(max_num_frames) indices = [int(interval * i) for i in range(max_num_frames)] new_split_sizes.append(len(indices)) selected_frames_all_0.append(selected_frames_0[indices]) selected_frames_all_1.append(selected_frames_1[indices]) selected_frames_feature_all.append(selected_features[indices]) selected_frame_indices = selected_frame_indices[indices] else: new_split_sizes.append(len(selected_frames_0)) selected_frames_all_0.append(selected_frames_0) selected_frames_all_1.append(selected_frames_1) selected_frames_feature_all.append(selected_features) selected_frame_indices_all.append(selected_frame_indices) selected_frames_all_0 = torch.cat(selected_frames_all_0, dim=0) selected_frames_all_1 = torch.cat(selected_frames_all_1, dim=0) selected_frames_feature_all = torch.cat(selected_frames_feature_all, dim=0) return ( selected_frames_feature_all, new_split_sizes, [selected_frames_all_0, selected_frames_all_1], selected_frame_indices_all, ) def prepare_inputs_labels_for_multimodal( self, input_ids, position_ids, attention_mask, past_key_values, labels, images, image_aux_attention_masks_list=None, image_sizes=None, ): # vision_tower = self.get_vision_tower() vision_tower_aux_list = self.get_model().get_vision_tower_aux_list() if vision_tower_aux_list is None or images is None or input_ids.shape[1] == 1: return ( input_ids, position_ids, attention_mask, past_key_values, None, labels, None, None, None, None, ) image_aux_list = images split_sizes = None if type(image_aux_list[0]) is list or image_aux_list[0].ndim == 5: split_sizes_ori = [ 1 if image.ndim == 3 else image.shape[0] for image in image_aux_list[0] ] new_image_aux_list = [] for image_aux in image_aux_list: if type(image_aux) is list: image_aux = [ x.unsqueeze(0) if x.ndim == 3 else x for x in image_aux ] concat_image_aux = torch.cat([image for image in image_aux], dim=0) new_image_aux_list.append(concat_image_aux) image_aux_features_dino = self.encode_images( new_image_aux_list, encode_type="dino" ) ( image_aux_features_dino, split_sizes, new_image_aux_list, selected_frame_indices_all, ) = self.select_frame( image_aux_features_dino, split_sizes_ori, input_ids, new_image_aux_list, image_sizes, threshold=getattr(self.get_model().config, "dino_threshold", 0.83), ) image_aux_features_siglip = self.encode_images( new_image_aux_list, encode_type="siglip" ) image_aux_features_list = [ image_aux_features_siglip, image_aux_features_dino, ] bs = image_aux_features_list[0].shape[0] dtype = new_image_aux_list[0].dtype frame_sizes = [] for i in range(len(image_sizes)): for j in range(split_sizes[i]): frame_sizes.append(image_sizes[i]) image_sizes = frame_sizes else: image_aux_features_list = self.encode_images(image_aux_list) bs = image_aux_list[0].shape[0] dtype = image_aux_list[0].dtype image_token_len = self.get_model().config.image_token_len query_num_list = self.get_model().config.query_num_list final_height = final_width = int(image_token_len**0.5) final_image_features_list = [] final_image_features_down_list = [] # only needed for sva vision_tower_aux_feature_list_final = None vision_tower_aux_attention_masks_list_final = None global_context_feature_final = None if self.get_model().config.mm_projector_type == "sva": vision_tower_aux_feature_list = [] vision_tower_aux_attention_masks_list = [] # get vision tokens from each vision tower for aux_i in range(len(vision_tower_aux_list)): image_aux_features = image_aux_features_list[aux_i] image_aux_features = getattr( self.get_model(), "mm_projector_aux_{}".format(aux_i) )(image_aux_features).to(dtype) if aux_i == 0: global_context_feature = image_aux_features.mean(1).view( bs, 1, 1, -1 ) vision_tower_aux_feature_list.append(image_aux_features) input_mix_res = True input_high_res = True # perform vision sampling for each query group for query_group_i, query_num in enumerate(query_num_list): query_features_i = ( self.get_model() .vision_query[query_group_i, :] .view(1, 1, 1, -1) .expand(bs, query_num, -1, -1) ) global_context_feature_i = global_context_feature.expand( -1, query_num, 1, -1 ).flatten(0, 1) query_side_len = int(query_num**0.5) if IS_XLA_AVAILABLE: ( vision_tower_aux_feature_list_i, vision_tower_aux_attention_masks_list_i, ) = self.rearrange_vision_tower_features_train( vision_tower_aux_feature_list, image_aux_attention_masks_list, query_side_len, ) else: ( vision_tower_aux_feature_list_i, vision_tower_aux_attention_masks_list_i, ) = self.rearrange_vision_tower_features_inference( vision_tower_aux_feature_list, query_side_len, image_sizes ) query_features_i = getattr( self.get_model(), "vision_sampler_{}".format(query_group_i) )( query_features_i.flatten(0, 1), global_context_feature_i, *vision_tower_aux_feature_list_i, *vision_tower_aux_attention_masks_list_i, ) query_features_i = query_features_i.view(bs, query_num, -1) if split_sizes is not None: try: if "llama" in self.get_model().config.model_type: text_len = torch.where(input_ids[0] == 128002)[-1][0] else: text_len = torch.where(input_ids[0] == 151643)[-1][0] except: text_len = len(input_ids[0]) max_visual_len = ( self.get_model().config.tokenizer_model_max_length - text_len - getattr(self.get_model().config, "inference_max_length", 16) ) max_num_frames = max( 1, math.floor(max_visual_len // (final_height * final_width)), ) max_num_frames_low = max( 1, math.floor( max_visual_len // (self.get_model().config.lowres_token ** 2) ), ) if split_sizes[0] < max_num_frames: input_mix_res = False elif split_sizes[0] > max_num_frames_low: input_mix_res = False input_high_res = False # input_mix_res = False # ablation if (getattr(self.config, "highres", False)) and input_mix_res: _query_features_i = ( query_features_i.permute(0, 2, 1) .contiguous() .view(bs, -1, query_side_len, query_side_len) ) _query_features_i = F.interpolate( _query_features_i.float(), size=( self.get_model().config.lowres_token, self.get_model().config.lowres_token, ), mode="bilinear", align_corners=False, ).to(dtype=query_features_i.dtype) _query_features_i = ( _query_features_i.permute(0, 2, 3, 1).contiguous().flatten(1, 2) ) final_image_features_down_list.append(_query_features_i) # interpolate to the final target size if query_side_len != final_height: query_features_i = ( query_features_i.permute(0, 2, 1) .contiguous() .view(bs, -1, query_side_len, query_side_len) ) if input_high_res: query_features_i = F.interpolate( query_features_i.float(), size=(final_height, final_width), mode="bilinear", align_corners=False, ).to(dtype=query_features_i.dtype) else: query_features_i = F.interpolate( query_features_i.float(), size=(8, 8), mode="bilinear", align_corners=False, ).to(dtype=query_features_i.dtype) query_features_i = ( query_features_i.permute(0, 2, 3, 1).contiguous().flatten(1, 2) ) final_image_features_list.append(query_features_i) if IS_XLA_AVAILABLE: ( vision_tower_aux_feature_list_final, vision_tower_aux_attention_masks_list_final, ) = self.rearrange_vision_tower_features_train( vision_tower_aux_feature_list, image_aux_attention_masks_list, final_height, ) global_context_feature_final = global_context_feature.expand( -1, final_height * final_width, 1, -1 ).flatten(0, 1) else: final_image_features_list = image_aux_features_list image_features = torch.cat(final_image_features_list, -1) image_features = self.get_model().mm_projector(image_features).to(dtype) if (getattr(self.config, "highres", False)) and input_mix_res: image_features_down = torch.cat(final_image_features_down_list, -1) image_features_down = ( self.get_model().mm_projector(image_features_down).to(dtype) ) if IS_XLA_AVAILABLE: image_features = image_features.view( image_features.shape[0], final_height, final_width, -1 ) image_features = torch.cat( ( image_features, self.model.image_newline[None, None, None, :].expand( image_features.shape[0], final_height, 1, -1 ), ), dim=2, ) image_features = image_features.flatten(1, 2) final_size = [(final_height, final_width)] * bs else: image_features = image_features.view(bs, final_height, final_width, -1) if (getattr(self.config, "highres", False)) and input_mix_res: image_features_down = image_features_down.view( bs, self.get_model().config.lowres_token, self.get_model().config.lowres_token, -1, ) image_features_unpadded = [] image_features_downsample = [] final_size = [] if self.get_model().config.mm_projector_type == "sva": ( vision_tower_aux_feature_list_final, vision_tower_aux_attention_masks_list_final, ) = self.rearrange_vision_tower_features_inference( vision_tower_aux_feature_list, final_height, image_sizes, unpad=True ) global_context_feature_final = [] for batch_i in range(bs): cur_image_feature = image_features[batch_i] image_size = image_sizes[batch_i] cur_image_feature = unpad_image( cur_image_feature.unsqueeze(0), image_size ) cur_h, cur_w = cur_image_feature.shape[1:3] try: # fix bug for some invalid image cur_image_feature = cur_image_feature.view(1, cur_h, cur_w, -1) final_size.append((cur_h, cur_w)) except: # print(f"invalid after unpad {image_features[batch_i].shape}, {image_sizes[batch_i]}", flush=True) cur_image_feature = image_features[batch_i].unsqueeze(0) image_size = image_sizes[batch_i] cur_h, cur_w = cur_image_feature.shape[1:3] cur_image_feature = cur_image_feature.view(1, cur_h, cur_w, -1) final_size.append((cur_h, cur_w)) if (getattr(self.config, "highres", False)) and input_mix_res: cur_image_feature_down = unpad_image( image_features_down[batch_i].unsqueeze(0), ( int( image_size[0] / ( image_token_len**0.5 / self.get_model().config.lowres_token ) ), int( image_size[1] / ( image_token_len**0.5 / self.get_model().config.lowres_token ) ), ), ) _cur_h, _cur_w = cur_image_feature_down.shape[1:3] try: # fix bug for some invalid image cur_image_feature_down = cur_image_feature_down.view( 1, _cur_h, _cur_w, -1 ) except: print("invalid after unpad", flush=True) cur_image_feature_down = image_features_down[batch_i].unsqueeze( 0 ) _cur_h, _cur_w = cur_image_feature_down.shape[1:3] cur_image_feature_down = cur_image_feature_down.view( 1, _cur_h, _cur_w, -1 ) cur_image_feature_down = torch.cat( ( cur_image_feature_down, self.model.image_newline.view(1, 1, 1, -1) .expand(1, _cur_h, 1, -1) .to(cur_image_feature_down.device), ), dim=2, ).flatten(1, 2) if split_sizes is None and getattr(self.config, "frame_pos", False): frame_pos = ( self.get_model() .get_frame_pos(torch.arange(1)) .to(cur_image_feature_down.device) .to(cur_image_feature_down.dtype) ) cur_image_feature_down += frame_pos image_features_downsample.append(cur_image_feature_down.squeeze(0)) cur_image_feature = torch.cat( ( cur_image_feature, self.model.image_newline.view(1, 1, 1, -1) .expand(1, cur_h, 1, -1) .to(cur_image_feature.device), ), dim=2, ) if split_sizes is None and getattr(self.config, "frame_pos", False): frame_pos = ( self.get_model() .get_frame_pos(torch.arange(1)) .to(cur_image_feature.device) .to(cur_image_feature.dtype) ) cur_image_feature += frame_pos cur_image_feature = cur_image_feature.flatten(1, 2) image_features_unpadded.append(cur_image_feature.squeeze(0)) if self.get_model().config.mm_projector_type == "sva": cur_global_context_feature = global_context_feature[batch_i].expand( cur_h * cur_w, 1, -1 ) global_context_feature_final.append(cur_global_context_feature) if self.get_model().config.mm_projector_type == "sva": global_context_feature_final = torch.cat( global_context_feature_final, 0 ) if (getattr(self.config, "highres", False)) and input_mix_res: image_features = image_features_downsample else: image_features = image_features_unpadded # TODO: image start / end is not implemented here to support pretraining. if getattr(self.config, "tune_mm_mlp_adapter", False) and getattr( self.config, "mm_use_im_start_end", False ): raise NotImplementedError split_image_features_unpadded = None frame_split_sizes = None if split_sizes is not None: split_image_features = [] split_image_features_unpadded = ( [] if (getattr(self.config, "highres", False)) and input_mix_res else None ) start_idx = 0 for split_batch_idx, split_size in enumerate(split_sizes): if isinstance(image_features[start_idx : start_idx + split_size], list): if getattr(self.config, "frame_pos", False): frame_feature = torch.cat( image_features[start_idx : start_idx + split_size], dim=0 ).reshape(split_size, -1, image_features[0].shape[-1]) frame_pos = ( self.get_model() .get_frame_pos(selected_frame_indices_all[split_batch_idx]) .to(frame_feature.device) .to(frame_feature.dtype) ) frame_feature += frame_pos split_image_features.append( frame_feature.reshape(-1, image_features[0].shape[-1]) ) else: split_image_features.append( torch.cat( image_features[start_idx : start_idx + split_size], dim=0, ) ) if (getattr(self.config, "highres", False)) and input_mix_res: if getattr(self.config, "frame_pos", False): frame_feature = torch.cat( image_features_unpadded[ start_idx : start_idx + split_size ], dim=0, ).reshape(split_size, -1, image_features[0].shape[-1]) frame_pos = ( self.get_model() .get_frame_pos( selected_frame_indices_all[split_batch_idx] ) .to(frame_feature.device) .to(frame_feature.dtype) ) frame_feature += frame_pos split_image_features_unpadded.append( frame_feature.reshape(-1, image_features[0].shape[-1]) ) else: split_image_features_unpadded.append( torch.cat( image_features_unpadded[ start_idx : start_idx + split_size ], dim=0, ) ) else: if getattr(self.config, "frame_pos", False): frame_feature = image_features[ start_idx : start_idx + split_size ].reshape(split_size, -1, image_features[0].shape[-1]) frame_pos = ( self.get_model() .get_frame_pos(selected_frame_indices_all[split_batch_idx]) .to(frame_feature.device) .to(frame_feature.dtype) ) frame_feature += frame_pos split_image_features.append( frame_feature.reshape(-1, image_features[0].shape[-1]) ) else: split_image_features.append( image_features[start_idx : start_idx + split_size] ) if (getattr(self.config, "highres", False)) and input_mix_res: if getattr(self.config, "frame_pos", False): frame_feature = image_features_unpadded[ start_idx : start_idx + split_size ] frame_pos = ( self.get_model() .get_frame_pos( selected_frame_indices_all[split_batch_idx] ) .to(frame_feature.device) .to(frame_feature.dtype) ) frame_feature += frame_pos split_image_features_unpadded.append( frame_feature.reshape(-1, image_features[0].shape[-1]) ) else: split_image_features_unpadded.append( image_features_unpadded[ start_idx : start_idx + split_size ] ) start_idx += split_size image_features = split_image_features frame_split_sizes = split_sizes _labels = labels _position_ids = position_ids _attention_mask = attention_mask if attention_mask is None: attention_mask = torch.ones_like(input_ids, dtype=torch.bool) else: attention_mask = attention_mask.bool() if position_ids is None: position_ids = torch.arange( 0, input_ids.shape[1], dtype=torch.long, device=input_ids.device ) if labels is None: labels = torch.full_like(input_ids, IGNORE_INDEX) # remove the padding using attention_mask -- FIXME _input_ids = input_ids attention_mask = attention_mask | (input_ids == IMAGE_TOKEN_INDEX) input_ids = [ cur_input_ids[cur_attention_mask] for cur_input_ids, cur_attention_mask in zip(input_ids, attention_mask) ] labels = [ cur_labels[cur_attention_mask] for cur_labels, cur_attention_mask in zip(labels, attention_mask) ] new_input_embeds = [] new_labels = [] image_token_indices_batch = [] cur_image_idx = 0 for batch_idx, cur_input_ids in enumerate(input_ids): num_images = (cur_input_ids == IMAGE_TOKEN_INDEX).sum() if num_images == 0: cur_image_features = image_features[cur_image_idx] cur_input_embeds_1 = self.get_model().embed_tokens(cur_input_ids) cur_input_embeds = torch.cat( [cur_input_embeds_1, cur_image_features[0:0]], dim=0 ) new_input_embeds.append(cur_input_embeds) new_labels.append(labels[batch_idx]) cur_image_idx += 1 continue image_token_indices = ( [-1] + torch.where(cur_input_ids == IMAGE_TOKEN_INDEX)[0].tolist() + [cur_input_ids.shape[0]] ) image_token_indices_batch.append( torch.where(cur_input_ids == IMAGE_TOKEN_INDEX)[0].tolist()[0] ) cur_input_ids_noim = [] cur_labels = labels[batch_idx] cur_labels_noim = [] for i in range(len(image_token_indices) - 1): cur_input_ids_noim.append( cur_input_ids[ image_token_indices[i] + 1 : image_token_indices[i + 1] ] ) cur_labels_noim.append( cur_labels[image_token_indices[i] + 1 : image_token_indices[i + 1]] ) split_sizes = [x.shape[0] for x in cur_labels_noim] cur_input_embeds = self.get_model().embed_tokens( torch.cat(cur_input_ids_noim) ) cur_input_embeds_no_im = torch.split(cur_input_embeds, split_sizes, dim=0) cur_new_input_embeds = [] cur_new_labels = [] text_len = sum([x.shape[0] for x in cur_input_embeds_no_im]) visual_len = len(image_features[cur_image_idx]) max_visual_len = ( self.get_model().config.tokenizer_model_max_length - getattr(self.get_model().config, "inference_max_length", 16) - text_len ) mix_token = False # ablation mix if ( input_mix_res and ( self.get_model().config.image_token_len > getattr(self.get_model().config, "lowres_token", 8) ** 2 ) and frame_split_sizes is not None and getattr(self.config, "highres", False) ): if max_visual_len > visual_len: visual_emb = image_features[cur_image_idx] text_emb = cur_input_embeds_no_im[-1] highres_num = math.floor( (max_visual_len - visual_len) / ( split_image_features_unpadded[cur_image_idx].shape[0] // frame_split_sizes[cur_image_idx] - visual_emb.shape[0] // frame_split_sizes[cur_image_idx] ) ) if highres_num >= 1: mix_token = True sim = torch.matmul(visual_emb, text_emb.transpose(0, 1)).mean( dim=-1 ) sim_frame = sim.reshape( frame_split_sizes[cur_image_idx], -1 ).mean(dim=-1) highres_num = min(highres_num, sim_frame.shape[0]) top_values, top_indices = torch.topk(sim_frame, highres_num) if len(top_indices) > 0: sorted_indices = torch.sort(top_indices)[1] top_indices = top_indices[sorted_indices] visual_emb_frame = image_features[cur_image_idx].reshape( frame_split_sizes[cur_image_idx], -1, image_features[cur_image_idx].shape[-1], ) visual_emb_frame_highres = split_image_features_unpadded[ cur_image_idx ].reshape( frame_split_sizes[cur_image_idx], -1, split_image_features_unpadded[cur_image_idx].shape[-1], ) current_point = 0 mix_visual_emb_frame = [] for frame_i in range(len(visual_emb_frame)): if current_point > len(top_indices) - 1: mix_visual_emb_frame.append( visual_emb_frame[frame_i] ) continue if frame_i == top_indices[current_point]: mix_visual_emb_frame.append( visual_emb_frame_highres[frame_i] ) current_point += 1 else: mix_visual_emb_frame.append( visual_emb_frame[frame_i] ) image_features[cur_image_idx] = torch.cat( mix_visual_emb_frame, dim=0 ) # ablation drop if ( max_visual_len < visual_len and frame_split_sizes is not None and not mix_token ): visual_emb_frame = image_features[cur_image_idx].reshape( frame_split_sizes[cur_image_idx], -1, image_features[cur_image_idx].shape[-1], ) sim = F.cosine_similarity( visual_emb_frame[:-1], visual_emb_frame[1:], dim=-1, ) new_visual_emb_frames = [] for start_idx in range(0, len(visual_emb_frame), 8): end_idx = min(start_idx + 8, len(visual_emb_frame)) chunk_feature = visual_emb_frame[start_idx:end_idx] # 8, HW, C if len(chunk_feature) == 1: new_visual_emb_frames.append(chunk_feature[0]) continue sim = F.cosine_similarity( chunk_feature[0] .unsqueeze(0) .repeat_interleave(len(chunk_feature[1:]), dim=0), chunk_feature[1:], dim=-1, ) new_visual_emb_frame = torch.cat( [ chunk_feature[0], chunk_feature[1:].flatten(0, 1)[ sim.flatten(0, 1) < getattr( self.get_model().config, "drop_threshold", 0.7 ) ], ], dim=0, ) new_visual_emb_frames.append(new_visual_emb_frame) reduced_visual_len = sum([x.shape[0] for x in new_visual_emb_frames]) if reduced_visual_len > max_visual_len: force_remove = math.ceil( (reduced_visual_len - max_visual_len) / len(new_visual_emb_frames) ) for chunk_i in range(len(new_visual_emb_frames)): new_visual_emb_frames[chunk_i] = new_visual_emb_frames[chunk_i][ :-force_remove ] new_visual_emb_frames = torch.cat(new_visual_emb_frames, dim=0) else: new_visual_emb_frames = torch.cat(new_visual_emb_frames, dim=0) image_features[cur_image_idx] = new_visual_emb_frames[:max_visual_len] for i in range(num_images + 1): cur_new_input_embeds.append(cur_input_embeds_no_im[i]) cur_new_labels.append(cur_labels_noim[i]) if i < num_images: cur_image_features = image_features[cur_image_idx] cur_image_idx += 1 cur_new_input_embeds.append(cur_image_features) cur_new_labels.append( torch.full( (cur_image_features.shape[0],), IGNORE_INDEX, device=cur_labels.device, dtype=cur_labels.dtype, ) ) cur_new_input_embeds = [x.to(self.device) for x in cur_new_input_embeds] cur_new_input_embeds = torch.cat(cur_new_input_embeds) cur_new_labels = torch.cat(cur_new_labels) new_input_embeds.append(cur_new_input_embeds) new_labels.append(cur_new_labels) # Truncate sequences to max length as image embeddings can make the sequence longer tokenizer_model_max_length = getattr( self.config, "tokenizer_model_max_length", None ) if tokenizer_model_max_length is not None: new_input_embeds = [ x[:tokenizer_model_max_length] for x in new_input_embeds ] new_labels = [x[:tokenizer_model_max_length] for x in new_labels] # Combine them max_len = max(x.shape[0] for x in new_input_embeds) batch_size = len(new_input_embeds) new_input_embeds_padded = [] new_labels_padded = torch.full( (batch_size, max_len), IGNORE_INDEX, dtype=new_labels[0].dtype, device=new_labels[0].device, ) attention_mask = torch.zeros( (batch_size, max_len), dtype=attention_mask.dtype, device=attention_mask.device, ) position_ids = torch.zeros( (batch_size, max_len), dtype=position_ids.dtype, device=position_ids.device, ) for i, (cur_new_embed, cur_new_labels) in enumerate( zip(new_input_embeds, new_labels) ): cur_len = cur_new_embed.shape[0] if getattr(self.config, "tokenizer_padding_side", "right") == "left": new_input_embeds_padded.append( torch.cat( ( torch.zeros( (max_len - cur_len, cur_new_embed.shape[1]), dtype=cur_new_embed.dtype, device=cur_new_embed.device, ), cur_new_embed, ), dim=0, ) ) if cur_len > 0: new_labels_padded[i, -cur_len:] = cur_new_labels attention_mask[i, -cur_len:] = True position_ids[i, -cur_len:] = torch.arange( 0, cur_len, dtype=position_ids.dtype, device=position_ids.device, ) else: new_input_embeds_padded.append( torch.cat( ( cur_new_embed, torch.zeros( (max_len - cur_len, cur_new_embed.shape[1]), dtype=cur_new_embed.dtype, device=cur_new_embed.device, ), ), dim=0, ) ) if cur_len > 0: new_labels_padded[i, :cur_len] = cur_new_labels attention_mask[i, :cur_len] = True position_ids[i, :cur_len] = torch.arange( 0, cur_len, dtype=position_ids.dtype, device=position_ids.device, ) new_input_embeds = torch.stack(new_input_embeds_padded, dim=0) if _labels is None: new_labels = None else: new_labels = new_labels_padded if _attention_mask is None: attention_mask = None else: attention_mask = attention_mask.to(dtype=_attention_mask.dtype) if _position_ids is None: position_ids = None return ( None, position_ids, attention_mask, past_key_values, new_input_embeds, new_labels, vision_tower_aux_feature_list_final, vision_tower_aux_attention_masks_list_final, final_size, global_context_feature_final, ) def initialize_vision_tokenizer(self, model_args, tokenizer): if model_args.mm_use_im_patch_token: tokenizer.add_tokens([DEFAULT_IMAGE_PATCH_TOKEN], special_tokens=True) self.resize_token_embeddings(len(tokenizer)) if model_args.mm_use_im_start_end: num_new_tokens = tokenizer.add_tokens( [DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN], special_tokens=True ) self.resize_token_embeddings(len(tokenizer)) if num_new_tokens > 0: input_embeddings = self.get_input_embeddings().weight.data output_embeddings = self.get_output_embeddings().weight.data input_embeddings_avg = input_embeddings[:-num_new_tokens].mean( dim=0, keepdim=True ) output_embeddings_avg = output_embeddings[:-num_new_tokens].mean( dim=0, keepdim=True ) input_embeddings[-num_new_tokens:] = input_embeddings_avg output_embeddings[-num_new_tokens:] = output_embeddings_avg if model_args.tune_mm_mlp_adapter: for p in self.get_input_embeddings().parameters(): p.requires_grad = True for p in self.get_output_embeddings().parameters(): p.requires_grad = False if model_args.pretrain_mm_mlp_adapter: mm_projector_weights = torch.load( model_args.pretrain_mm_mlp_adapter, map_location="cpu" ) embed_tokens_weight = mm_projector_weights["model.embed_tokens.weight"] assert num_new_tokens == 2 if input_embeddings.shape == embed_tokens_weight.shape: input_embeddings[-num_new_tokens:] = embed_tokens_weight[ -num_new_tokens: ] elif embed_tokens_weight.shape[0] == num_new_tokens: input_embeddings[-num_new_tokens:] = embed_tokens_weight else: raise ValueError( f"Unexpected embed_tokens_weight shape. Pretrained: {embed_tokens_weight.shape}. Current: {input_embeddings.shape}. Numer of new tokens: {num_new_tokens}." ) elif model_args.mm_use_im_patch_token: if model_args.tune_mm_mlp_adapter: for p in self.get_input_embeddings().parameters(): p.requires_grad = False for p in self.get_output_embeddings().parameters(): p.requires_grad = False