






from __future__ import absolute_import, division, print_function, unicode_literals

from torch import nn
from torch.nn import CrossEntropyLoss, MSELoss

from transformers import RobertaConfig
from transformers.file_utils import add_start_docstrings, add_start_docstrings_to_model_forward
from transformers.models.roberta.modeling_roberta import (
    ROBERTA_INPUTS_DOCSTRING,
    ROBERTA_START_DOCSTRING,
    RobertaEmbeddings,
)

from .modeling_highway_bert import BertPreTrainedModel, DeeBertModel, HighwayException, entropy







@add_start_docstrings(
    '''The RoBERTa Model transformer with early exiting (DeeRoBERTa). '''	,				UpperCAmelCase_	,				)
class 		_A						( UpperCAmelCase_ ):
  lowercase_						:			str						=					RobertaConfig
  lowercase_						:			Union[str, Any]						=					'''roberta'''

  def __init__(    self						:	Tuple   ,				lowerCamelCase__						:	List[str]			):
     """simple docstring"""

     super().__init__(lowerCamelCase__			)

     __UpperCamelCase	:			Dict					=					RobertaEmbeddings(lowerCamelCase__			)
     self.init_weights()







@add_start_docstrings(
    '''RoBERTa Model (with early exiting - DeeRoBERTa) with a classifier on top,
    also takes care of multi-layer training. '''	,				UpperCAmelCase_	,				)
class 		_A						( UpperCAmelCase_ ):
  lowercase_						:			List[str]						=					RobertaConfig
  lowercase_						:			int						=					'''roberta'''

  def __init__(    self						:	Union[str, Any]   ,				lowerCamelCase__						:	Optional[Any]			):
     """simple docstring"""

     super().__init__(lowerCamelCase__			)
     __UpperCamelCase	:			List[str]					=					config.num_labels
     __UpperCamelCase	:			int					=					config.num_hidden_layers

     __UpperCamelCase	:			int					=					DeeRobertaModel(lowerCamelCase__			)
     __UpperCamelCase	:			List[str]					=					nn.Dropout(config.hidden_dropout_prob			)
     __UpperCamelCase	:			Dict					=					nn.Linear(config.hidden_size   ,				self.config.num_labels			)

  @add_start_docstrings_to_model_forward(lowerCamelCase__			)
  def    a					(    self						:	str   ,				lowerCamelCase__						:	Optional[Any]=None   ,				lowerCamelCase__						:	int=None   ,				lowerCamelCase__						:	Tuple=None   ,				lowerCamelCase__						:	Optional[int]=None   ,				lowerCamelCase__						:	Union[str, Any]=None   ,				lowerCamelCase__						:	Optional[Any]=None   ,				lowerCamelCase__						:	List[str]=None   ,				lowerCamelCase__						:	int=-1   ,				lowerCamelCase__						:	List[Any]=False   ,				):
     """simple docstring"""

     __UpperCamelCase	:			Dict					=					self.num_layers
     try:
        __UpperCamelCase	:			Optional[int]					=					self.roberta(
            lowerCamelCase__   ,				attention_mask=lowerCamelCase__   ,				token_type_ids=lowerCamelCase__   ,				position_ids=lowerCamelCase__   ,				head_mask=lowerCamelCase__   ,				inputs_embeds=lowerCamelCase__   ,				)

        __UpperCamelCase	:			int					=					outputs[1]

        __UpperCamelCase	:			str					=					self.dropout(lowerCamelCase__			)
        __UpperCamelCase	:			Optional[int]					=					self.classifier(lowerCamelCase__			)
        __UpperCamelCase	:			List[Any]					=					(logits,) + outputs[2:]  # add hidden states and attention if they are here
     except HighwayException as e:
        __UpperCamelCase	:			List[Any]					=					e.message
        __UpperCamelCase	:			Optional[Any]					=					e.exit_layer
        __UpperCamelCase	:			Optional[Any]					=					outputs[0]

     if not self.training:
        __UpperCamelCase	:			List[str]					=					entropy(lowerCamelCase__			)
        __UpperCamelCase	:			List[str]					=					[]
        __UpperCamelCase	:			Union[str, Any]					=					[]
     if labels is not None:
        if self.num_labels == 1:
           #  We are doing regression
           __UpperCamelCase	:			Dict					=					MSELoss()
           __UpperCamelCase	:			Union[str, Any]					=					loss_fct(logits.view(-1			)   ,				labels.view(-1			)			)
        else:
           __UpperCamelCase	:			Tuple					=					CrossEntropyLoss()
           __UpperCamelCase	:			str					=					loss_fct(logits.view(-1   ,				self.num_labels			)   ,				labels.view(-1			)			)

        # work with highway exits
        __UpperCamelCase	:			Tuple					=					[]
        for highway_exit in outputs[-1]:
           __UpperCamelCase	:			Optional[Any]					=					highway_exit[0]
           if not self.training:
              highway_logits_all.append(lowerCamelCase__			)
              highway_entropy.append(highway_exit[2]			)
           if self.num_labels == 1:
              #  We are doing regression
              __UpperCamelCase	:			List[Any]					=					MSELoss()
              __UpperCamelCase	:			Optional[int]					=					loss_fct(highway_logits.view(-1			)   ,				labels.view(-1			)			)
           else:
              __UpperCamelCase	:			str					=					CrossEntropyLoss()
              __UpperCamelCase	:			Optional[Any]					=					loss_fct(highway_logits.view(-1   ,				self.num_labels			)   ,				labels.view(-1			)			)
           highway_losses.append(lowerCamelCase__			)

        if train_highway:
           __UpperCamelCase	:			Dict					=					(sum(highway_losses[:-1]			),) + outputs
           # exclude the final highway, of course
        else:
           __UpperCamelCase	:			int					=					(loss,) + outputs
     if not self.training:
        __UpperCamelCase	:			List[Any]					=					outputs + ((original_entropy, highway_entropy), exit_layer)
        if output_layer >= 0:
           __UpperCamelCase	:			Optional[int]					=					(
               (outputs[0],) + (highway_logits_all[output_layer],) + outputs[2:]
           )  # use the highway of the last layer

     return outputs  # (loss), logits, (hidden_states), (attentions), entropy











from typing import List, Optional, Union

from ...image_utils import ImageInput
from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding, PaddingStrategy, PreTokenizedInput, TextInput, TruncationStrategy
from ...utils import TensorType







class 		_A						( UpperCAmelCase_ ):
  lowercase_						:			Tuple						=					['''image_processor''', '''tokenizer''']
  lowercase_						:			str						=					'''BlipImageProcessor'''
  lowercase_						:			str						=					('''BertTokenizer''', '''BertTokenizerFast''')

  def __init__(    self						:	List[str]   ,				lowerCamelCase__						:	str   ,				lowerCamelCase__						:	Union[str, Any]			):
     """simple docstring"""

     __UpperCamelCase	:			Optional[int]					=					False
     super().__init__(lowerCamelCase__   ,				lowerCamelCase__			)
     __UpperCamelCase	:			Tuple					=					self.image_processor

  def __call__(    self						:	Optional[Any]   ,				lowerCamelCase__						:	ImageInput = None   ,				lowerCamelCase__						:	Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None   ,				lowerCamelCase__						:	bool = True   ,				lowerCamelCase__						:	Union[bool, str, PaddingStrategy] = False   ,				lowerCamelCase__						:	Union[bool, str, TruncationStrategy] = None   ,				lowerCamelCase__						:	Optional[int] = None   ,				lowerCamelCase__						:	int = 0   ,				lowerCamelCase__						:	Optional[int] = None   ,				lowerCamelCase__						:	Optional[bool] = None   ,				lowerCamelCase__						:	bool = False   ,				lowerCamelCase__						:	bool = False   ,				lowerCamelCase__						:	bool = False   ,				lowerCamelCase__						:	bool = False   ,				lowerCamelCase__						:	bool = False   ,				lowerCamelCase__						:	bool = True   ,				lowerCamelCase__						:	Optional[Union[str, TensorType]] = None   ,				**lowerCamelCase__						:	int   ,				):
     """simple docstring"""

     if images is None and text is None:
        raise ValueError("""You have to specify either images or text."""			)

     # Get only text
     if images is None:
        __UpperCamelCase	:			Optional[int]					=					self.tokenizer
        __UpperCamelCase	:			Dict					=					self.tokenizer(
            text=lowerCamelCase__   ,				add_special_tokens=lowerCamelCase__   ,				padding=lowerCamelCase__   ,				truncation=lowerCamelCase__   ,				max_length=lowerCamelCase__   ,				stride=lowerCamelCase__   ,				pad_to_multiple_of=lowerCamelCase__   ,				return_attention_mask=lowerCamelCase__   ,				return_overflowing_tokens=lowerCamelCase__   ,				return_special_tokens_mask=lowerCamelCase__   ,				return_offsets_mapping=lowerCamelCase__   ,				return_token_type_ids=lowerCamelCase__   ,				return_length=lowerCamelCase__   ,				verbose=lowerCamelCase__   ,				return_tensors=lowerCamelCase__   ,				**lowerCamelCase__   ,				)
        return text_encoding

     # add pixel_values
     __UpperCamelCase	:			str					=					self.image_processor(lowerCamelCase__   ,				return_tensors=lowerCamelCase__			)

     if text is not None:
        __UpperCamelCase	:			Optional[int]					=					self.tokenizer(
            text=lowerCamelCase__   ,				add_special_tokens=lowerCamelCase__   ,				padding=lowerCamelCase__   ,				truncation=lowerCamelCase__   ,				max_length=lowerCamelCase__   ,				stride=lowerCamelCase__   ,				pad_to_multiple_of=lowerCamelCase__   ,				return_attention_mask=lowerCamelCase__   ,				return_overflowing_tokens=lowerCamelCase__   ,				return_special_tokens_mask=lowerCamelCase__   ,				return_offsets_mapping=lowerCamelCase__   ,				return_token_type_ids=lowerCamelCase__   ,				return_length=lowerCamelCase__   ,				verbose=lowerCamelCase__   ,				return_tensors=lowerCamelCase__   ,				**lowerCamelCase__   ,				)
     else:
        __UpperCamelCase	:			Optional[Any]					=					None

     if text_encoding is not None:
        encoding_image_processor.update(lowerCamelCase__			)

     return encoding_image_processor

  def    a					(    self						:	List[str]   ,				*lowerCamelCase__						:	Any   ,				**lowerCamelCase__						:	List[Any]			):
     """simple docstring"""

     return self.tokenizer.batch_decode(*lowerCamelCase__   ,				**lowerCamelCase__			)

  def    a					(    self						:	List[str]   ,				*lowerCamelCase__						:	int   ,				**lowerCamelCase__						:	Tuple			):
     """simple docstring"""

     return self.tokenizer.decode(*lowerCamelCase__   ,				**lowerCamelCase__			)

  @property
  def    a					(    self						:	Any			):
     """simple docstring"""

     __UpperCamelCase	:			str					=					self.tokenizer.model_input_names
     __UpperCamelCase	:			str					=					self.image_processor.model_input_names
     return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names			)			)



