| """ |
| @file fflip.py |
| @brief This file contains the code for the multimodal model. It is a modified version of the CLIP model from the huggingface transformers library. |
| @author yutangli |
| """ |
|
|
|
|
| import torch |
| import torch.nn as nn |
| from transformers.modeling_outputs import BaseModelOutputWithPooling |
| from transformers.utils import logging |
| from typing import Optional, Union, Tuple |
| from torch import Tensor, device, dtype, nn |
| from transformers import BertTokenizer |
|
|
| import os |
| from urllib.parse import urlparse |
| from timm.models.hub import download_cached_file |
|
|
| from transformers.modeling_outputs import ( |
| BaseModelOutputWithPastAndCrossAttentions, |
| BaseModelOutputWithPoolingAndCrossAttentions, |
| CausalLMOutputWithCrossAttentions, |
| MaskedLMOutput, |
| MultipleChoiceModelOutput, |
| NextSentencePredictorOutput, |
| QuestionAnsweringModelOutput, |
| SequenceClassifierOutput, |
| TokenClassifierOutput, |
| ) |
|
|
| from models.mm import ( |
| VisionTrainedModel, |
| BertEmbeddings, |
| BertEncoder, |
| BertPreTrainedModel, |
| BertPooler, |
| BertConfig, |
| VisionConfig, |
| VisionTransformer) |
|
|
| logger = logging.get_logger(__name__) |
|
|
|
|
| def init_tokenizer(): |
| tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') |
| tokenizer.add_special_tokens({'bos_token':'[DEC]'}) |
| tokenizer.add_special_tokens({'additional_special_tokens':['[ENC]']}) |
| tokenizer.enc_token_id = tokenizer.additional_special_tokens_ids[0] |
| return tokenizer |
|
|
|
|
| class VisionModel(VisionTrainedModel): |
| config_class = VisionConfig |
| main_input_name = "pixel_values" |
|
|
| def __init__(self, config: VisionConfig): |
| super().__init__(config) |
| self.vision_model = VisionTransformer(config) |
| |
| self.post_init() |
|
|
| def get_input_embeddings(self) -> nn.Module: |
| return self.vision_model.embeddings.patch_embedding |
|
|
| @staticmethod |
| def get_output_channel(model_type): |
| if model_type == 'base': |
| return 768 |
| if model_type == 'large': |
| return 1024 |
| if model_type == 'huge': |
| return 1280 |
|
|
| @staticmethod |
| def get_default_output_indices(model_type): |
| if model_type == 'base': |
| return [3, 5, 7, 11] |
| if model_type == 'large': |
| return [7, 11, 15, 23] |
| if model_type == 'huge': |
| return [8, 14, 20, 31] |
|
|
| def forward( |
| self, |
| pixel_values: Optional[torch.FloatTensor] = None, |
| output_attentions: Optional[bool] = None, |
| output_hidden_states: Optional[bool] = None, |
| return_dict: Optional[bool] = None, |
| intermediate_hidden_state: Optional[bool] = None |
| ) -> Union[Tuple, BaseModelOutputWithPooling]: |
| r""" |
| Returns: |
| |
| Examples: |
| |
| ```python |
| >>> from PIL import Image |
| >>> import requests |
| >>> from transformers import AutoProcessor, CLIPVisionModel |
| |
| >>> model = CLIPVisionModel.from_pretrained("openai/clip-vit-base-patch32") |
| >>> processor = AutoProcessor.from_pretrained("openai/clip-vit-base-patch32") |
| |
| >>> url = "http://images.cocodataset.org/val2017/000000039769.jpg" |
| >>> image = Image.open(requests.get(url, stream=True).raw) |
| |
| >>> inputs = processor(images=image, return_tensors="pt") |
| |
| >>> outputs = model(**inputs) |
| >>> last_hidden_state = outputs.last_hidden_state |
| >>> pooled_output = outputs.pooler_output # pooled CLS states |
| ```""" |
| return_dict = return_dict if return_dict is not None else self.config.use_return_dict |
|
|
| return self.vision_model( |
| pixel_values=pixel_values, |
| output_attentions=output_attentions, |
| output_hidden_states=output_hidden_states, |
| return_dict=return_dict, |
| intermediate_hidden_state=intermediate_hidden_state |
| ) |
|
|
|
|
| class BertModel(BertPreTrainedModel): |
| """ |
| The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of |
| cross-attention is added between the self-attention layers, following the architecture described in `Attention is |
| all you need <https://arxiv.org/abs/1706.03762>`__ by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, |
| Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. |
| argument and :obj:`add_cross_attention` set to :obj:`True`; an :obj:`encoder_hidden_states` is then expected as an |
| input to the forward pass. |
| """ |
|
|
| def __init__(self, config, add_pooling_layer=True): |
| super().__init__(config) |
| self.config = config |
|
|
| self.embeddings = BertEmbeddings(config) |
| |
| self.encoder = BertEncoder(config) |
|
|
| self.pooler = BertPooler(config) if add_pooling_layer else None |
|
|
| self.init_weights() |
| |
|
|
| def get_input_embeddings(self): |
| return self.embeddings.word_embeddings |
|
|
| def set_input_embeddings(self, value): |
| self.embeddings.word_embeddings = value |
|
|
| def _prune_heads(self, heads_to_prune): |
| """ |
| Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base |
| class PreTrainedModel |
| """ |
| for layer, heads in heads_to_prune.items(): |
| self.encoder.layer[layer].attention.prune_heads(heads) |
|
|
| |
| def get_extended_attention_mask(self, attention_mask: Tensor, input_shape: Tuple[int], device: device, is_decoder: bool) -> Tensor: |
| """ |
| Makes broadcastable attention and causal masks so that future and masked tokens are ignored. |
| |
| Arguments: |
| attention_mask (:obj:`torch.Tensor`): |
| Mask with ones indicating tokens to attend to, zeros for tokens to ignore. |
| input_shape (:obj:`Tuple[int]`): |
| The shape of the input to the model. |
| device: (:obj:`torch.device`): |
| The device of the input to the model. |
| |
| Returns: |
| :obj:`torch.Tensor` The extended attention mask, with a the same dtype as :obj:`attention_mask.dtype`. |
| """ |
| |
| |
| if attention_mask.dim() == 3: |
| extended_attention_mask = attention_mask[:, None, :, :] |
| elif attention_mask.dim() == 2: |
| |
| |
| |
| if is_decoder: |
| batch_size, seq_length = input_shape |
|
|
| seq_ids = torch.arange(seq_length, device=device) |
| causal_mask = seq_ids[None, None, :].repeat(batch_size, seq_length, 1) <= seq_ids[None, :, None] |
| |
| |
| causal_mask = causal_mask.to(attention_mask.dtype) |
| |
| if causal_mask.shape[1] < attention_mask.shape[1]: |
| prefix_seq_len = attention_mask.shape[1] - causal_mask.shape[1] |
| causal_mask = torch.cat( |
| [ |
| torch.ones((batch_size, seq_length, prefix_seq_len), device=device, dtype=causal_mask.dtype), |
| causal_mask, |
| ], |
| axis=-1, |
| ) |
|
|
| extended_attention_mask = causal_mask[:, None, :, :] * attention_mask[:, None, None, :] |
| else: |
| extended_attention_mask = attention_mask[:, None, None, :] |
| else: |
| raise ValueError( |
| "Wrong shape for input_ids (shape {}) or attention_mask (shape {})".format( |
| input_shape, attention_mask.shape |
| ) |
| ) |
|
|
| |
| |
| |
| |
| |
| extended_attention_mask = extended_attention_mask.to(dtype=self.dtype) |
| extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0 |
| return extended_attention_mask |
| |
| def forward( |
| self, |
| input_ids=None, |
| attention_mask=None, |
| position_ids=None, |
| head_mask=None, |
| inputs_embeds=None, |
| encoder_embeds=None, |
| encoder_hidden_states=None, |
| encoder_attention_mask=None, |
| past_key_values=None, |
| use_cache=None, |
| output_attentions=None, |
| output_hidden_states=None, |
| return_dict=None, |
| is_decoder=False, |
| mode='multimodal', |
| ): |
| r""" |
| encoder_hidden_states (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length, hidden_size)`, `optional`): |
| Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if |
| the model is configured as a decoder. |
| encoder_attention_mask (:obj:`torch.FloatTensor` of shape :obj:`(batch_size, sequence_length)`, `optional`): |
| Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in |
| the cross-attention if the model is configured as a decoder. Mask values selected in ``[0, 1]``: |
| - 1 for tokens that are **not masked**, |
| - 0 for tokens that are **masked**. |
| past_key_values (:obj:`tuple(tuple(torch.FloatTensor))` of length :obj:`config.n_layers` with each tuple having 4 tensors of shape :obj:`(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): |
| Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. |
| If :obj:`past_key_values` are used, the user can optionally input only the last :obj:`decoder_input_ids` |
| (those that don't have their past key value states given to this model) of shape :obj:`(batch_size, 1)` |
| instead of all :obj:`decoder_input_ids` of shape :obj:`(batch_size, sequence_length)`. |
| use_cache (:obj:`bool`, `optional`): |
| If set to :obj:`True`, :obj:`past_key_values` key value states are returned and can be used to speed up |
| decoding (see :obj:`past_key_values`). |
| """ |
| output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions |
| output_hidden_states = ( |
| output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states |
| ) |
| return_dict = return_dict if return_dict is not None else self.config.use_return_dict |
|
|
| if is_decoder: |
| use_cache = use_cache if use_cache is not None else self.config.use_cache |
| else: |
| use_cache = False |
|
|
| if input_ids is not None and inputs_embeds is not None: |
| raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") |
| elif input_ids is not None: |
| input_shape = input_ids.size() |
| batch_size, seq_length = input_shape |
| device = input_ids.device |
| elif inputs_embeds is not None: |
| input_shape = inputs_embeds.size()[:-1] |
| batch_size, seq_length = input_shape |
| device = inputs_embeds.device |
| elif encoder_embeds is not None: |
| input_shape = encoder_embeds.size()[:-1] |
| batch_size, seq_length = input_shape |
| device = encoder_embeds.device |
| else: |
| raise ValueError("You have to specify either input_ids or inputs_embeds or encoder_embeds") |
|
|
| |
| past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 |
|
|
| if attention_mask is None: |
| attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) |
| |
| |
| |
| extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape, |
| device, is_decoder) |
|
|
| |
| |
| if encoder_hidden_states is not None: |
| if type(encoder_hidden_states) == list: |
| encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states[0].size() |
| else: |
| encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() |
| encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) |
| |
| if type(encoder_attention_mask) == list: |
| encoder_extended_attention_mask = [self.invert_attention_mask(mask) for mask in encoder_attention_mask] |
| elif encoder_attention_mask is None: |
| encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) |
| encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) |
| else: |
| encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) |
| else: |
| encoder_extended_attention_mask = None |
|
|
| |
| |
| |
| |
| |
| head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) |
| |
| if encoder_embeds is None: |
| embedding_output = self.embeddings( |
| input_ids=input_ids, |
| position_ids=position_ids, |
| inputs_embeds=inputs_embeds, |
| past_key_values_length=past_key_values_length, |
| ) |
| else: |
| embedding_output = encoder_embeds |
| |
| encoder_outputs = self.encoder( |
| embedding_output, |
| attention_mask=extended_attention_mask, |
| head_mask=head_mask, |
| encoder_hidden_states=encoder_hidden_states, |
| encoder_attention_mask=encoder_extended_attention_mask, |
| past_key_values=past_key_values, |
| use_cache=use_cache, |
| output_attentions=output_attentions, |
| output_hidden_states=output_hidden_states, |
| return_dict=return_dict, |
| mode=mode, |
| ) |
| sequence_output = encoder_outputs[0] |
| pooled_output = self.pooler(sequence_output) if self.pooler is not None else None |
|
|
| if not return_dict: |
| return (sequence_output, pooled_output) + encoder_outputs[1:] |
|
|
| return BaseModelOutputWithPoolingAndCrossAttentions( |
| last_hidden_state=sequence_output, |
| pooler_output=pooled_output, |
| past_key_values=encoder_outputs.past_key_values, |
| hidden_states=encoder_outputs.hidden_states, |
| attentions=encoder_outputs.attentions, |
| cross_attentions=encoder_outputs.cross_attentions, |
| ) |
| |
|
|
| class MMSEG_UPerHead(nn.Module): |
| """Wraps the UPerHead from mmseg for segmentation. |
| """ |
|
|
| def __init__(self, num_classes: int, |
| in_channels: list = [384, 384, 384, 384], channels: int = 512): |
| super().__init__() |
|
|
| from mmseg.models.decode_heads import UPerHead |
| self.head = UPerHead( |
| in_channels=in_channels, |
| in_index=[0, 1, 2, 3], |
| pool_scales=(1, 2, 3, 6), |
| channels=channels, |
| dropout_ratio=0.1, |
| num_classes=num_classes, |
| norm_cfg=dict(type='SyncBN', requires_grad=True), |
| align_corners=False, |
| loss_decode=dict( |
| type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)) |
|
|
| def forward(self, inputs): |
| return self.head(inputs) |
|
|
|
|
| def _make_fpns(vision_patch_size: int, output_channels: int): |
| if vision_patch_size in {16, 14}: |
| fpn1 = nn.Sequential( |
| nn.ConvTranspose2d(output_channels, output_channels, |
| kernel_size=2, stride=2), |
| nn.SyncBatchNorm(output_channels), |
| nn.GELU(), |
| nn.ConvTranspose2d(output_channels, output_channels, kernel_size=2, stride=2)) |
|
|
| fpn2 = nn.ConvTranspose2d( |
| output_channels, output_channels, kernel_size=2, stride=2) |
| fpn3 = nn.Identity() |
| fpn4 = nn.MaxPool2d(kernel_size=2, stride=2) |
| return nn.ModuleList([fpn1, fpn2, fpn3, fpn4]) |
| |
| elif vision_patch_size == 8: |
| fpn1 = nn.Sequential(nn.ConvTranspose2d( |
| output_channels, output_channels, kernel_size=2, stride=2)) |
| fpn2 = nn.Identity() |
| fpn3 = nn.MaxPool2d(kernel_size=2, stride=2) |
| fpn4 = nn.MaxPool2d(kernel_size=4, stride=4) |
| return nn.ModuleList([fpn1, fpn2, fpn3, fpn4]) |
| else: |
| raise NotImplementedError() |
|
|
|
|
| def is_url(url_or_filename): |
| parsed = urlparse(url_or_filename) |
| return parsed.scheme in ("http", "https") |
|
|
|
|
| def interpolate_pos_embed(pos_embed_checkpoint, visual_encoder): |
| |
| embedding_size = pos_embed_checkpoint.shape[-1] |
| num_patches = visual_encoder.vision_model.embeddings.num_patches |
| num_extra_tokens = visual_encoder.vision_model.embeddings.position_embedding.weight.shape[-2] - num_patches |
| |
| orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5) |
| |
| new_size = int(num_patches ** 0.5) |
|
|
| if orig_size!=new_size: |
| |
| extra_tokens = pos_embed_checkpoint[:num_extra_tokens, :] |
| |
| pos_tokens = pos_embed_checkpoint[num_extra_tokens:, :] |
| pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2) |
| pos_tokens = torch.nn.functional.interpolate( |
| pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False) |
| pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2).squeeze(0) |
| new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=0) |
| print('reshape position embedding from %d to %d'%(orig_size ** 2, new_size ** 2)) |
| return new_pos_embed |
| else: |
| return pos_embed_checkpoint |
|
|
|
|
| def load_checkpoint(model,url_or_filename): |
| if is_url(url_or_filename): |
| cached_file = download_cached_file(url_or_filename, check_hash=False, progress=True) |
| checkpoint = torch.load(cached_file, map_location='cpu') |
| elif os.path.isfile(url_or_filename): |
| checkpoint = torch.load(url_or_filename, map_location='cpu') |
| else: |
| raise RuntimeError('checkpoint url or path is invalid') |
| |
| state_dict = checkpoint['model'] |
| |
| state_dict['visual_encoder.vision_model.embeddings.position_embedding.weight'] = interpolate_pos_embed(state_dict['visual_encoder.vision_model.embeddings.position_embedding.weight'], model.visual_encoder) |
| if hasattr(model, " visual_encoder_m") and 'visual_encoder.vision_model.embeddings.position_embedding.weight' in model.state_dict().keys(): |
| state_dict['visual_encoder.vision_model.embeddings.position_embedding.weight'] = interpolate_pos_embed(state_dict['visual_encoder.vision_model.embeddings.position_embedding.weight'], |
| model.visual_encoder_m) |
| for key in model.state_dict().keys(): |
| if key in state_dict.keys(): |
| if state_dict[key].shape!=model.state_dict()[key].shape: |
| del state_dict[key] |
| |
| msg = model.load_state_dict(state_dict,strict=False) |
| print('load checkpoint from %s'%url_or_filename) |
| return model, msg |