'''simple docstring'''

import uuid
from typing import Any, Dict, List, Optional, Union

from ..utils import add_end_docstrings, is_tf_available, is_torch_available, logging
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_tf_available():
  import tensorflow as tf

if is_torch_available():
  import torch


UpperCamelCase__  :						Dict					=      logging.get_logger(__name__)


class 					_lowercase						:
      '''simple docstring'''


      def __init__(					self       ,lowerCamelCase_ = None       ,lowerCamelCase_ = None       ,lowerCamelCase_=None       ,lowerCamelCase_=None				)      ->      Optional[Any]:



         '''simple docstring'''



         if not conversation_id:
            UpperCAmelCase__				:					Tuple 					=	uuid.uuida()
         if past_user_inputs is None:
            UpperCAmelCase__				:					Any 					=	[]
         if generated_responses is None:
            UpperCAmelCase__				:					Optional[int] 					=	[]

         UpperCAmelCase__				:					uuid.UUID 					=	conversation_id
         UpperCAmelCase__				:					List[str] 					=	past_user_inputs
         UpperCAmelCase__				:					List[str] 					=	generated_responses
         UpperCAmelCase__				:					Optional[str] 					=	text




      def __eq__(					self       ,lowerCamelCase_				)      ->      str:



         '''simple docstring'''



         if not isinstance(lowerCamelCase_       ,lowerCamelCase_				):
            return False
         if self.uuid == other.uuid:
            return True
         return (
             self.new_user_input == other.new_user_input
             and self.past_user_inputs == other.past_user_inputs
             and self.generated_responses == other.generated_responses
         )




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_ = False				)      ->      Optional[int]:



         '''simple docstring'''



         if self.new_user_input:
            if overwrite:
               logger.warning(
                   f'''User input added while unprocessed input was existing: "{self.new_user_input}" was overwritten '''
                   f'''with: "{text}".'''				)
               UpperCAmelCase__				:					Union[str, Any] 					=	text
            else:
               logger.warning(
                   f'''User input added while unprocessed input was existing: "{self.new_user_input}" new input '''
                   f'''ignored: "{text}". Set `overwrite` to True to overwrite unprocessed user input'''				)
         else:
            UpperCAmelCase__				:					Union[str, Any] 					=	text




      def 		lowerCAmelCase__       (					self				)      ->      List[str]:



         '''simple docstring'''



         if self.new_user_input:
            self.past_user_inputs.append(self.new_user_input				)
         UpperCAmelCase__				:					Any 					=	None




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_				)      ->      Dict:



         '''simple docstring'''



         self.generated_responses.append(lowerCamelCase_				)




      def 		lowerCAmelCase__       (					self				)      ->      Optional[Any]:



         '''simple docstring'''



         for user_input, generated_response in zip(self.past_user_inputs       ,self.generated_responses				):
            yield True, user_input
            yield False, generated_response
         if self.new_user_input:
            yield True, self.new_user_input




      def __repr__(					self				)      ->      Dict:



         '''simple docstring'''



         UpperCAmelCase__				:					Any 					=	f'''Conversation id: {self.uuid} \n'''
         for is_user, text in self.iter_texts():
            UpperCAmelCase__				:					str 					=	'''user''' if is_user else '''bot'''
            output += f'''{name} >> {text} \n'''
         return output




@add_end_docstrings(
    lowerCAmelCase		,R'''
        min_length_for_response (`int`, *optional*, defaults to 32):
            The minimum length (in number of tokens) for a response.
        minimum_tokens (`int`, *optional*, defaults to 10):
            The minimum length of tokens to leave for a response.
    '''		,)
class 					_lowercase						(   lowerCAmelCase ):
      '''simple docstring'''


      def __init__(					self       ,*lowerCamelCase_       ,**lowerCamelCase_				)      ->      List[str]:



         '''simple docstring'''



         super().__init__(*lowerCamelCase_       ,**lowerCamelCase_				)
         if self.tokenizer.pad_token_id is None:
            UpperCAmelCase__				:					Union[str, Any] 					=	self.tokenizer.eos_token




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,**lowerCamelCase_				)      ->      Tuple:



         '''simple docstring'''



         UpperCAmelCase__				:					int 					=	{}
         UpperCAmelCase__				:					Tuple 					=	{}
         UpperCAmelCase__				:					str 					=	{}

         if min_length_for_response is not None:
            UpperCAmelCase__				:					str 					=	min_length_for_response
         if minimum_tokens is not None:
            UpperCAmelCase__				:					List[Any] 					=	minimum_tokens

         if "max_length" in generate_kwargs:
            UpperCAmelCase__				:					Dict 					=	generate_kwargs['''max_length''']
            # self.max_length = generate_kwargs.get("max_length", self.model.config.max_length)
         if clean_up_tokenization_spaces is not None:
            UpperCAmelCase__				:					Any 					=	clean_up_tokenization_spaces

         if generate_kwargs:
            forward_params.update(lowerCamelCase_				)
         return preprocess_params, forward_params, postprocess_params




      def __call__(					self       ,lowerCamelCase_       ,lowerCamelCase_=0       ,**lowerCamelCase_				)      ->      Tuple:



         '''simple docstring'''



         UpperCAmelCase__				:					List[str] 					=	super().__call__(lowerCamelCase_       ,num_workers=lowerCamelCase_       ,**lowerCamelCase_				)
         if isinstance(lowerCamelCase_       ,lowerCamelCase_				) and len(lowerCamelCase_				) == 1:
            return outputs[0]
         return outputs




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_=32				)      ->      Dict[str, Any]:



         '''simple docstring'''



         if not isinstance(lowerCamelCase_       ,lowerCamelCase_				):
            raise ValueError('''ConversationalPipeline, expects Conversation as inputs'''				)
         if conversation.new_user_input is None:
            raise ValueError(
                f'''Conversation with UUID {type(conversation.uuid				)} does not contain new user input to process. '''
                '''Add user inputs with the conversation\'s `add_user_input` method'''				)
         if hasattr(self.tokenizer       ,'''_build_conversation_input_ids'''				):
            UpperCAmelCase__				:					List[Any] 					=	self.tokenizer._build_conversation_input_ids(lowerCamelCase_				)
         else:
            # If the tokenizer cannot handle conversations, we default to only the old version
            UpperCAmelCase__				:					Dict 					=	self._legacy_parse_and_tokenize(lowerCamelCase_				)

         if self.framework == "pt":
            UpperCAmelCase__				:					List[str] 					=	torch.LongTensor([input_ids]				)
         elif self.framework == "tf":
            UpperCAmelCase__				:					str 					=	tf.constant([input_ids]				)
         return {"input_ids": input_ids, "conversation": conversation}




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_=10       ,**lowerCamelCase_				)      ->      Dict:



         '''simple docstring'''



         UpperCAmelCase__				:					Union[str, Any] 					=	generate_kwargs.get('''max_length'''       ,self.model.config.max_length				)

         UpperCAmelCase__				:					Tuple 					=	model_inputs['''input_ids'''].shape[1]
         if max_length - minimum_tokens < n:
            logger.warning(f'''Conversation input is to long ({n}), trimming it to ({max_length} - {minimum_tokens})'''				)
            UpperCAmelCase__				:					Tuple 					=	max_length - minimum_tokens
            UpperCAmelCase__				:					Dict 					=	model_inputs['''input_ids'''][:, -trim:]
            if "attention_mask" in model_inputs:
               UpperCAmelCase__				:					List[Any] 					=	model_inputs['''attention_mask'''][:, -trim:]
         UpperCAmelCase__				:					Optional[int] 					=	model_inputs.pop('''conversation'''				)
         UpperCAmelCase__				:					List[str] 					=	max_length
         UpperCAmelCase__				:					List[str] 					=	self.model.generate(**lowerCamelCase_       ,**lowerCamelCase_				)
         if self.model.config.is_encoder_decoder:
            UpperCAmelCase__				:					str 					=	1
         else:
            UpperCAmelCase__				:					List[str] 					=	n
         return {"output_ids": output_ids[:, start_position:], "conversation": conversation}




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_       ,lowerCamelCase_=True				)      ->      Union[str, Any]:



         '''simple docstring'''



         UpperCAmelCase__				:					List[str] 					=	model_outputs['''output_ids''']
         UpperCAmelCase__				:					Tuple 					=	self.tokenizer.decode(
             output_ids[0]       ,skip_special_tokens=lowerCamelCase_       ,clean_up_tokenization_spaces=lowerCamelCase_       ,)
         UpperCAmelCase__				:					str 					=	model_outputs['''conversation''']
         conversation.mark_processed()
         conversation.append_response(lowerCamelCase_				)
         return conversation




      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_				)      ->      Dict:



         '''simple docstring'''



         UpperCAmelCase__				:					Tuple 					=	self.tokenizer.eos_token_id
         UpperCAmelCase__				:					List[str] 					=	[]
         for is_user, text in conversation.iter_texts():
            if eos_token_id is not None:
               input_ids.extend(self.tokenizer.encode(lowerCamelCase_       ,add_special_tokens=lowerCamelCase_				) + [eos_token_id]				)
            else:
               input_ids.extend(self.tokenizer.encode(lowerCamelCase_       ,add_special_tokens=lowerCamelCase_				)				)

         if len(lowerCamelCase_				) > self.tokenizer.model_max_length:
            UpperCAmelCase__				:					Optional[Any] 					=	input_ids[-self.tokenizer.model_max_length :]
         return input_ids





'''simple docstring'''

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). '''		,lowerCAmelCase		,)
class 					_lowercase						(   lowerCAmelCase ):
      '''simple docstring'''


      UpperCAmelCase_   :   int   				= RobertaConfig
      UpperCAmelCase_   :   Tuple   				= '''roberta'''




      def __init__(					self       ,lowerCamelCase_				)      ->      List[Any]:



         '''simple docstring'''



         super().__init__(lowerCamelCase_				)

         UpperCAmelCase__				:					Optional[Any] 					=	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. '''		,lowerCAmelCase		,)
class 					_lowercase						(   lowerCAmelCase ):
      '''simple docstring'''


      UpperCAmelCase_   :   Tuple   				= RobertaConfig
      UpperCAmelCase_   :   Optional[Any]   				= '''roberta'''




      def __init__(					self       ,lowerCamelCase_				)      ->      str:



         '''simple docstring'''



         super().__init__(lowerCamelCase_				)
         UpperCAmelCase__				:					Any 					=	config.num_labels
         UpperCAmelCase__				:					Union[str, Any] 					=	config.num_hidden_layers

         UpperCAmelCase__				:					str 					=	DeeRobertaModel(lowerCamelCase_				)
         UpperCAmelCase__				:					Optional[int] 					=	nn.Dropout(config.hidden_dropout_prob				)
         UpperCAmelCase__				:					Union[str, Any] 					=	nn.Linear(config.hidden_size       ,self.config.num_labels				)




      @add_start_docstrings_to_model_forward(lowerCamelCase_				)
      def 		lowerCAmelCase__       (					self       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=None       ,lowerCamelCase_=-1       ,lowerCamelCase_=False       ,)      ->      Optional[Any]:



         '''simple docstring'''



         UpperCAmelCase__				:					Tuple 					=	self.num_layers
         try:
            UpperCAmelCase__				:					Union[str, Any] 					=	self.roberta(
                lowerCamelCase_       ,attention_mask=lowerCamelCase_       ,token_type_ids=lowerCamelCase_       ,position_ids=lowerCamelCase_       ,head_mask=lowerCamelCase_       ,inputs_embeds=lowerCamelCase_       ,)

            UpperCAmelCase__				:					List[Any] 					=	outputs[1]

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

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

            # work with highway exits
            UpperCAmelCase__				:					List[str] 					=	[]
            for highway_exit in outputs[-1]:
               UpperCAmelCase__				:					Optional[int] 					=	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__				:					Any 					=	MSELoss()
                  UpperCAmelCase__				:					Optional[Any] 					=	loss_fct(highway_logits.view(-1				)       ,labels.view(-1				)				)
               else:
                  UpperCAmelCase__				:					Any 					=	CrossEntropyLoss()
                  UpperCAmelCase__				:					int 					=	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__				:					Dict 					=	(loss,) + outputs
         if not self.training:
            UpperCAmelCase__				:					Tuple 					=	outputs + ((original_entropy, highway_entropy), exit_layer)
            if output_layer >= 0:
               UpperCAmelCase__				:					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




