



'''simple docstring'''




import warnings
from typing import Dict

import numpy as np

from ..utils import ExplicitEnum, add_end_docstrings, is_tf_available, is_torch_available
from .base import PIPELINE_INIT_ARGS, GenericTensor, Pipeline


if is_tf_available():
						from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING

if is_torch_available():
						from ..models.auto.modeling_auto import MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING



def 	a			( lowerCamelCase__    ):
			'''simple docstring'''





			return 1.0 / (1.0 + np.exp(-_outputs    ))



def 	a			( lowerCamelCase__    ):
			'''simple docstring'''





			A_	:						Any	=     np.max(_outputs						,      axis=-1						,      keepdims=__snake_case    )
			A_	:						Dict	=     np.exp(_outputs - maxes    )
			return shifted_exp / shifted_exp.sum(axis=-1						,      keepdims=__snake_case    )







class 	_lowerCAmelCase							(			__UpperCAmelCase ):
	__SCREAMING_SNAKE_CASE   :		int					=					'sigmoid'
	__SCREAMING_SNAKE_CASE   :		Dict					=					'softmax'
	__SCREAMING_SNAKE_CASE   :		Dict					=					'none'







@add_end_docstrings(
    __UpperCAmelCase      ,			r'\n        return_all_scores (`bool`, *optional*, defaults to `False`):\n            Whether to return all prediction scores or just the one of the predicted class.\n        function_to_apply (`str`, *optional*, defaults to `"default"`):\n            The function to apply to the model outputs in order to retrieve the scores. Accepts four different values:\n\n            - `"default"`: if the model has a single label, will apply the sigmoid function on the output. If the model\n              has several labels, will apply the softmax function on the output.\n            - `"sigmoid"`: Applies the sigmoid function on the output.\n            - `"softmax"`: Applies the softmax function on the output.\n            - `"none"`: Does not apply any function on the output.\n    '      ,			)
class 	_lowerCAmelCase							(			__UpperCAmelCase ):
	__SCREAMING_SNAKE_CASE   :		str					=					False
	__SCREAMING_SNAKE_CASE   :		Tuple					=					ClassificationFunction.NONE


	def __init__(self       ,      **lowercase							):
				super().__init__(**__a							)

				self.check_model_type(
				    TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING
				    if self.framework == """tf"""
				    else MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING							)


	def     _a	(self       ,      lowercase=None       ,      lowercase=None       ,      lowercase=""       ,      **lowercase							):
				A_	:						Tuple	=     tokenizer_kwargs

				A_	:						Union[str, Any]	=     {}
				if hasattr(self.model.config       ,      """return_all_scores"""							) and return_all_scores is None:
							A_	:						int	=     self.model.config.return_all_scores

				if isinstance(__a       ,      __a							) or top_k is None:
							A_	:						Dict	=     top_k
							A_	:						Union[str, Any]	=     False
				elif return_all_scores is not None:
							warnings.warn(
							    """`return_all_scores` is now deprecated,  if want a similar functionality use `top_k=None` instead of"""
							    """ `return_all_scores=True` or `top_k=1` instead of `return_all_scores=False`."""       ,      __a       ,      )
							if return_all_scores:
										A_	:						Optional[Any]	=     None
							else:
										A_	:						str	=     1

				if isinstance(__a       ,      __a							):
							A_	:						Tuple	=     ClassificationFunction[function_to_apply.upper()]

				if function_to_apply is not None:
							A_	:						List[str]	=     function_to_apply
				return preprocess_params, {}, postprocess_params


	def __call__(self       ,      *lowercase       ,      **lowercase							):
				A_	:						str	=     super().__call__(*__a       ,      **__a							)
				# TODO try and retrieve it in a nicer way from _sanitize_parameters.
				A_	:						Union[str, Any]	=     """top_k""" not in kwargs
				if isinstance(args[0]       ,      __a							) and _legacy:
							# This pipeline is odd, and return a list when single item is run
							return [result]
				else:
							return result


	def     _a	(self       ,      lowercase       ,      **lowercase							):
				A_	:						List[Any]	=     self.framework
				if isinstance(__a       ,      __a							):
							return self.tokenizer(**__a       ,      return_tensors=__a       ,      **__a							)
				elif isinstance(__a       ,      __a							) and len(__a							) == 1 and isinstance(inputs[0]       ,      __a							) and len(inputs[0]							) == 2:
							# It used to be valid to use a list of list of list for text pairs, keeping this path for BC
							return self.tokenizer(
							    text=inputs[0][0]       ,      text_pair=inputs[0][1]       ,      return_tensors=__a       ,      **__a							)
				elif isinstance(__a       ,      __a							):
							# This is likely an invalid usage of the pipeline attempting to pass text pairs.
							raise ValueError(
							    """The pipeline received invalid inputs, if you are trying to send text pairs, you can try to send a"""
							    """ dictionary `{\"text\": \"My text\", \"text_pair\": \"My pair\"}` in order to send a text pair."""							)
				return self.tokenizer(__a       ,      return_tensors=__a       ,      **__a							)


	def     _a	(self       ,      lowercase							):
				return self.model(**__a							)


	def     _a	(self       ,      lowercase       ,      lowercase=None       ,      lowercase=1       ,      lowercase=True							):
				# `_legacy` is used to determine if we're running the naked pipeline and in backward
				# compatibility mode, or if running the pipeline with `pipeline(..., top_k=1)` we're running
				# the more natural result containing the list.
				# Default value before `set_parameters`
				if function_to_apply is None:
							if self.model.config.problem_type == "multi_label_classification" or self.model.config.num_labels == 1:
										A_	:						Optional[Any]	=     ClassificationFunction.SIGMOID
							elif self.model.config.problem_type == "single_label_classification" or self.model.config.num_labels > 1:
										A_	:						Optional[Any]	=     ClassificationFunction.SOFTMAX
							elif hasattr(self.model.config       ,      """function_to_apply"""							) and function_to_apply is None:
										A_	:						int	=     self.model.config.function_to_apply
							else:
										A_	:						Union[str, Any]	=     ClassificationFunction.NONE

				A_	:						Any	=     model_outputs["""logits"""][0]
				A_	:						Tuple	=     outputs.numpy()

				if function_to_apply == ClassificationFunction.SIGMOID:
							A_	:						Union[str, Any]	=     sigmoid(__a							)
				elif function_to_apply == ClassificationFunction.SOFTMAX:
							A_	:						Optional[int]	=     softmax(__a							)
				elif function_to_apply == ClassificationFunction.NONE:
							A_	:						int	=     outputs
				else:
							raise ValueError(F'Unrecognized `function_to_apply` argument: {function_to_apply}'							)

				if top_k == 1 and _legacy:
							return {"label": self.model.config.idalabel[scores.argmax().item()], "score": scores.max().item()}

				A_	:						int	=     [
				    {"""label""": self.model.config.idalabel[i], """score""": score.item()} for i, score in enumerate(__a							)
				]
				if not _legacy:
							dict_scores.sort(key=lambda lowercase							: x["score"]       ,      reverse=__a							)
							if top_k is not None:
										A_	:						Union[str, Any]	=     dict_scores[:top_k]
				return dict_scores

"""simple docstring"""





from typing import List, Union

import numpy as np

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, logging
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline


_a														=		logging.get_logger(__name__)






class     _UpperCAmelCase(    lowerCamelCase	):



		def 						UpperCAmelCase							(					self				,		__a)       ->       Tuple:






							'''simple docstring'''
							if isinstance(__a				,		__a):
												_UpperCamelCase							 =  [label.strip() for label in labels.split(''',''') if label.strip()]
							return labels




		def __call__(					self				,		__a				,		__a				,		__a)       ->       Optional[int]:






							'''simple docstring'''
							if len(__a) == 0 or len(__a) == 0:
												raise ValueError('''You must include at least one label and at least one sequence.''')
							if hypothesis_template.format(labels[0]) == hypothesis_template:
												raise ValueError(
												    (
												        '''The provided hypothesis_template "{}" was not able to be formatted with the target labels. '''
												        '''Make sure the passed template includes formatting syntax such as {{}} where the label should go.'''
												    ).format(__a))

							if isinstance(__a				,		__a):
												_UpperCamelCase							 =  [sequences]

							_UpperCamelCase							 =  []
							for sequence in sequences:
												sequence_pairs.extend([[sequence, hypothesis_template.format(__a)] for label in labels])

							return sequence_pairs, sequences






@add_end_docstrings(lowerCamelCase	)
class     _UpperCAmelCase(    lowerCamelCase	):



		def __init__(					self				,		__a=ZeroShotClassificationArgumentHandler()				,		*__a				,		**__a)       ->       List[str]:






							'''simple docstring'''
							_UpperCamelCase							 =  args_parser
							super().__init__(*__a				,		**__a)
							if self.entailment_id == -1:
												logger.warning(
												    '''Failed to determine \'entailment\' label id from the label2id mapping in the model config. Setting to '''
												    '''-1. Define a descriptive label2id mapping in the model config to ensure correct outputs.''')



		@property
		def 						UpperCAmelCase							(					self)       ->       List[str]:






							'''simple docstring'''
							for label, ind in self.model.config.labelaid.items():
												if label.lower().startswith('''entail'''):
																	return ind
							return -1



		def 						UpperCAmelCase							(					self				,		__a				,		__a=True				,		__a=True				,		__a=TruncationStrategy.ONLY_FIRST				,		**__a)       ->       List[Any]:






							'''simple docstring'''
							_UpperCamelCase							 =  self.framework
							if self.tokenizer.pad_token is None:
												# Override for tokenizers not supporting padding
												logger.error(
												    '''Tokenizer was not supporting padding necessary for zero-shot, attempting to use '''
												    ''' `pad_token=eos_token`''')
												_UpperCamelCase							 =  self.tokenizer.eos_token
							try:
												_UpperCamelCase							 =  self.tokenizer(
												    __a				,		add_special_tokens=__a				,		return_tensors=__a				,		padding=__a				,		truncation=__a				,		)
							except Exception as e:
												if "too short" in str(__a):
																	# tokenizers might yell that we want to truncate
																	# to a value that is not even reached by the input.
																	# In that case we don't want to truncate.
																	# It seems there's not a really better way to catch that
																	# exception.

																	_UpperCamelCase							 =  self.tokenizer(
																	    __a				,		add_special_tokens=__a				,		return_tensors=__a				,		padding=__a				,		truncation=TruncationStrategy.DO_NOT_TRUNCATE				,		)
												else:
																	raise e

							return inputs



		def 						UpperCAmelCase							(					self				,		**__a)       ->       Any:






							'''simple docstring'''
							if kwargs.get('''multi_class'''				,		__a) is not None:
												_UpperCamelCase							 =  kwargs['''multi_class''']
												logger.warning(
												    '''The `multi_class` argument has been deprecated and renamed to `multi_label`. '''
												    '''`multi_class` will be removed in a future version of Transformers.''')
							_UpperCamelCase							 =  {}
							if "candidate_labels" in kwargs:
												_UpperCamelCase							 =  self._args_parser._parse_labels(kwargs['''candidate_labels'''])
							if "hypothesis_template" in kwargs:
												_UpperCamelCase							 =  kwargs['''hypothesis_template''']

							_UpperCamelCase							 =  {}
							if "multi_label" in kwargs:
												_UpperCamelCase							 =  kwargs['''multi_label''']
							return preprocess_params, {}, postprocess_params



		def __call__(					self				,		__a				,		*__a				,		**__a				,		)       ->       int:






							'''simple docstring'''
							if len(__a) == 0:
												pass
							elif len(__a) == 1 and "candidate_labels" not in kwargs:
												_UpperCamelCase							 =  args[0]
							else:
												raise ValueError(F'''Unable to understand extra arguments {args}''')

							return super().__call__(__a				,		**__a)



		def 						UpperCAmelCase							(					self				,		__a				,		__a=None				,		__a="This example is {}.")       ->       Dict:






							'''simple docstring'''
							_UpperCamelCase ,  _UpperCamelCase							 =  self._args_parser(__a				,		__a				,		__a)

							for i, (candidate_label, sequence_pair) in enumerate(zip(__a				,		__a)):
												_UpperCamelCase							 =  self._parse_and_tokenize([sequence_pair])

												yield {
												    "candidate_label": candidate_label,
												    "sequence": sequences[0],
												    "is_last": i == len(__a) - 1,
												    **model_input,
												}



		def 						UpperCAmelCase							(					self				,		__a)       ->       List[Any]:






							'''simple docstring'''
							_UpperCamelCase							 =  inputs['''candidate_label''']
							_UpperCamelCase							 =  inputs['''sequence''']
							_UpperCamelCase							 =  {k: inputs[k] for k in self.tokenizer.model_input_names}
							_UpperCamelCase							 =  self.model(**__a)

							_UpperCamelCase							 =  {
							    '''candidate_label''': candidate_label,
							    '''sequence''': sequence,
							    '''is_last''': inputs['''is_last'''],
							    **outputs,
							}
							return model_outputs




		def 						UpperCAmelCase							(					self				,		__a				,		__a=False)       ->       Dict:






							'''simple docstring'''
							_UpperCamelCase							 =  [outputs['''candidate_label'''] for outputs in model_outputs]
							_UpperCamelCase							 =  [outputs['''sequence'''] for outputs in model_outputs]
							_UpperCamelCase							 =  np.concatenate([output['''logits'''].numpy() for output in model_outputs])
							_UpperCamelCase							 =  logits.shape[0]
							_UpperCamelCase							 =  len(__a)
							_UpperCamelCase							 =  N // n
							_UpperCamelCase							 =  logits.reshape((num_sequences, n, -1))

							if multi_label or len(__a) == 1:
												# softmax over the entailment vs. contradiction dim for each label independently
												_UpperCamelCase							 =  self.entailment_id
												_UpperCamelCase							 =  -1 if entailment_id == 0 else 0
												_UpperCamelCase							 =  reshaped_outputs[..., [contradiction_id, entailment_id]]
												_UpperCamelCase							 =  np.exp(__a) / np.exp(__a).sum(-1				,		keepdims=__a)
												_UpperCamelCase							 =  scores[..., 1]
							else:
												# softmax the "entailment" logits over all candidate labels
												_UpperCamelCase							 =  reshaped_outputs[..., self.entailment_id]
												_UpperCamelCase							 =  np.exp(__a) / np.exp(__a).sum(-1				,		keepdims=__a)

							_UpperCamelCase							 =  list(reversed(scores[0].argsort()))
							return {
							    "sequence": sequences[0],
							    "labels": [candidate_labels[i] for i in top_inds],
							    "scores": scores[0, top_inds].tolist(),
							}






