

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

import torch
from torch import nn
from torch.utils.data import DistributedSampler, RandomSampler

from transformers import PreTrainedModel, Trainer, logging
from transformers.integrations import is_fairscale_available
from transformers.models.fsmt.configuration_fsmt import FSMTConfig
from transformers.optimization import (
    Adafactor,
    AdamW,
    get_constant_schedule,
    get_constant_schedule_with_warmup,
    get_cosine_schedule_with_warmup,
    get_cosine_with_hard_restarts_schedule_with_warmup,
    get_linear_schedule_with_warmup,
    get_polynomial_decay_schedule_with_warmup,
)
from transformers.trainer_pt_utils import get_tpu_sampler
from transformers.training_args import ParallelMode
from transformers.utils import is_torch_tpu_available


if is_fairscale_available():
    from fairscale.optim import OSS


__A			:					Union[str, Any]						=			logging.get_logger(__name__)

__A			:					Optional[int]						=			{
    'linear': get_linear_schedule_with_warmup,
    'cosine': get_cosine_schedule_with_warmup,
    'cosine_w_restarts': get_cosine_with_hard_restarts_schedule_with_warmup,
    'polynomial': get_polynomial_decay_schedule_with_warmup,
    'constant': get_constant_schedule,
    'constant_w_warmup': get_constant_schedule_with_warmup,
}





class 			_SCREAMING_SNAKE_CASE (   __snake_case		):







   '''simple docstring'''




   def __init__(       self					:			List[str]     , __lowerCamelCase					:			List[str]=None     , __lowerCamelCase					:			str=None     , *__lowerCamelCase					:			Dict     , **__lowerCamelCase					:			List[Any]			):
       super().__init__(*_lowercase     , **_lowercase			)

       if config is None:
           assert isinstance(self.model     , _lowercase			), (
               "If no `config` is passed the model to be trained has to be of type `PreTrainedModel`, but is"
               f" {self.model.__class__}"
           )
           SCREAMING_SNAKE_CASE										=   self.model.config
       else:
           SCREAMING_SNAKE_CASE										=   config

       SCREAMING_SNAKE_CASE										=   data_args
       SCREAMING_SNAKE_CASE										=   self.config.tgt_vocab_size if isinstance(self.config     , _lowercase			) else self.config.vocab_size

       if self.args.label_smoothing != 0 or (self.data_args is not None and self.data_args.ignore_pad_token_for_loss):
           assert self.config.pad_token_id is not None, (
               "Make sure that `config.pad_token_id` is correcly defined when ignoring `pad_token` for loss"
               " calculation or doing label smoothing."
           )

       if self.config.pad_token_id is None and self.config.eos_token_id is not None:
           logger.warning(
               f"The `config.pad_token_id` is `None`. Using `config.eos_token_id` = {self.config.eos_token_id} for"
               " padding.."			)

       if self.args.label_smoothing == 0:
           SCREAMING_SNAKE_CASE										=   torch.nn.CrossEntropyLoss(ignore_index=self.config.pad_token_id			)
       else:
           # dynamically import label_smoothed_nll_loss
           from utils import label_smoothed_nll_loss

           SCREAMING_SNAKE_CASE										=   label_smoothed_nll_loss





   def      _snake_case		(       self					:			Any     , __lowerCamelCase					:			int			):
       if self.optimizer is None:
           SCREAMING_SNAKE_CASE										=   ["bias", "LayerNorm.weight"]
           SCREAMING_SNAKE_CASE										=   [
               {
                   "params": [p for n, p in self.model.named_parameters() if not any(nd in n for nd in no_decay			)],
                   "weight_decay": self.args.weight_decay,
               },
               {
                   "params": [p for n, p in self.model.named_parameters() if any(nd in n for nd in no_decay			)],
                   "weight_decay": 0.0,
               },
           ]
           SCREAMING_SNAKE_CASE										=   Adafactor if self.args.adafactor else AdamW
           if self.args.adafactor:
               SCREAMING_SNAKE_CASE										=   Adafactor
               SCREAMING_SNAKE_CASE										=   {"scale_parameter": False, "relative_step": False}
           else:
               SCREAMING_SNAKE_CASE										=   AdamW
               SCREAMING_SNAKE_CASE										=   {
                   "betas": (self.args.adam_betaa, self.args.adam_betaa),
                   "eps": self.args.adam_epsilon,
               }
           SCREAMING_SNAKE_CASE										=   self.args.learning_rate
           if self.sharded_ddp:
               SCREAMING_SNAKE_CASE										=   OSS(
                   params=_lowercase     , optim=_lowercase     , **_lowercase     , )
           else:
               SCREAMING_SNAKE_CASE										=   optimizer_cls(_lowercase     , **_lowercase			)

       if self.lr_scheduler is None:
           SCREAMING_SNAKE_CASE										=   self._get_lr_scheduler(_lowercase			)
       else:  # ignoring --lr_scheduler
           logger.warning("scheduler is passed to `Seq2SeqTrainer`, `--lr_scheduler` arg is ignored."			)





   def      _snake_case		(       self					:			Optional[Any]     , __lowerCamelCase					:			Optional[int]			):
       SCREAMING_SNAKE_CASE										=   arg_to_scheduler[self.args.lr_scheduler]
       if self.args.lr_scheduler == "constant":
           SCREAMING_SNAKE_CASE										=   schedule_func(self.optimizer			)
       elif self.args.lr_scheduler == "constant_w_warmup":
           SCREAMING_SNAKE_CASE										=   schedule_func(self.optimizer     , num_warmup_steps=self.args.warmup_steps			)
       else:
           SCREAMING_SNAKE_CASE										=   schedule_func(
               self.optimizer     , num_warmup_steps=self.args.warmup_steps     , num_training_steps=_lowercase			)
       return scheduler





   def      _snake_case		(       self					:			str			):
       if isinstance(self.train_dataset     , torch.utils.data.IterableDataset			):
           return None
       elif is_torch_tpu_available():
           return get_tpu_sampler(self.train_dataset			)
       else:
           if self.args.sortish_sampler:
               self.train_dataset.make_sortish_sampler(
                   self.args.per_device_train_batch_size     , distributed=(self.args.parallel_mode == ParallelMode.DISTRIBUTED)     , )

           return (
               RandomSampler(self.train_dataset			)
               if self.args.local_rank == -1
               else DistributedSampler(self.train_dataset			)
           )





   def      _snake_case		(       self					:			str     , __lowerCamelCase					:			str     , __lowerCamelCase					:			List[Any]     , __lowerCamelCase					:			Dict			):
       if self.args.label_smoothing == 0:
           if self.data_args is not None and self.data_args.ignore_pad_token_for_loss:
               # force training to ignore pad token
               SCREAMING_SNAKE_CASE										=   model(**_lowercase     , use_cache=_lowercase			)[0]
               SCREAMING_SNAKE_CASE										=   self.loss_fn(logits.view(-1     , logits.shape[-1]			)     , labels.view(-1			)			)
           else:
               # compute usual loss via models
               SCREAMING_SNAKE_CASE							,	SCREAMING_SNAKE_CASE										=   model(**_lowercase     , labels=_lowercase     , use_cache=_lowercase			)[:2]
       else:
           # compute label smoothed loss
           SCREAMING_SNAKE_CASE										=   model(**_lowercase     , use_cache=_lowercase			)[0]
           SCREAMING_SNAKE_CASE										=   torch.nn.functional.log_softmax(_lowercase     , dim=-1			)
           SCREAMING_SNAKE_CASE							,	SCREAMING_SNAKE_CASE										=   self.loss_fn(_lowercase     , _lowercase     , self.args.label_smoothing     , ignore_index=self.config.pad_token_id			)
       return loss, logits





   def      _snake_case		(       self					:			List[Any]     , __lowerCamelCase					:			Dict     , __lowerCamelCase					:			Tuple			):
       SCREAMING_SNAKE_CASE										=   inputs.pop("labels"			)
       SCREAMING_SNAKE_CASE							,	SCREAMING_SNAKE_CASE										=   self._compute_loss(_lowercase     , _lowercase     , _lowercase			)
       return loss





   def      _snake_case		(       self					:			Optional[Any]     , __lowerCamelCase					:			nn.Module     , __lowerCamelCase					:			Dict[str, Union[torch.Tensor, Any]]     , __lowerCamelCase					:			bool     , __lowerCamelCase					:			Optional[List[str]] = None     , ):
       SCREAMING_SNAKE_CASE										=   self._prepare_inputs(_lowercase			)

       SCREAMING_SNAKE_CASE										=   {
           "max_length": self.data_args.val_max_target_length
           if self.data_args is not None
           else self.config.max_length,
           "num_beams": self.data_args.eval_beams if self.data_args is not None else self.config.num_beams,
       }

       if self.args.predict_with_generate and not self.args.prediction_loss_only:
           SCREAMING_SNAKE_CASE										=   self.model.generate(
               inputs["input_ids"]     , attention_mask=inputs["attention_mask"]     , **_lowercase     , )
           # in case the batch is shorter than max length, the output should be padded
           if generated_tokens.shape[-1] < gen_kwargs["max_length"]:
               SCREAMING_SNAKE_CASE										=   self._pad_tensors_to_max_len(_lowercase     , gen_kwargs["max_length"]			)

       SCREAMING_SNAKE_CASE										=   inputs.pop("labels"			)
       with torch.no_grad():
           # compute loss on predict data
           SCREAMING_SNAKE_CASE							,	SCREAMING_SNAKE_CASE										=   self._compute_loss(_lowercase     , _lowercase     , _lowercase			)

       SCREAMING_SNAKE_CASE										=   loss.mean().detach()
       if self.args.prediction_loss_only:
           return (loss, None, None)

       SCREAMING_SNAKE_CASE										=   generated_tokens if self.args.predict_with_generate else logits

       if labels.shape[-1] < gen_kwargs["max_length"]:
           SCREAMING_SNAKE_CASE										=   self._pad_tensors_to_max_len(_lowercase     , gen_kwargs["max_length"]			)

       return (loss, logits, labels)





   def      _snake_case		(       self					:			List[str]     , __lowerCamelCase					:			Any     , __lowerCamelCase					:			int			):
       # If PAD token is not defined at least EOS token has to be defined
       SCREAMING_SNAKE_CASE										=   self.config.pad_token_id if self.config.pad_token_id is not None else self.config.eos_token_id

       if pad_token_id is None:
           raise ValueError(
               "Make sure that either `config.pad_token_id` or `config.eos_token_id` is defined if tensor has to be"
               f" padded to `max_length`={max_length}"			)

       SCREAMING_SNAKE_CASE										=   pad_token_id * torch.ones(
           (tensor.shape[0], max_length)     , dtype=tensor.dtype     , device=tensor.device			)
       SCREAMING_SNAKE_CASE										=   tensor
       return padded_tensor





'''simple docstring'''
from collections import UserDict
from typing import List, Union

from ..utils import (
    add_end_docstrings,
    is_tf_available,
    is_torch_available,
    is_vision_available,
    logging,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_vision_available():
							from PIL import Image

							from ..image_utils import load_image

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

if is_tf_available():
							from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING
							from ..tf_utils import stable_softmax

_SCREAMING_SNAKE_CASE			=						logging.get_logger(__name__)
@add_end_docstrings(lowerCAmelCase				)
class   __UpperCAmelCase				(     lowerCAmelCase				):



					'''simple docstring'''





					def __init__(	self     :						int      ,       **_lowercase     :						List[Any])    ->							Union[str, Any]:
								super().__init__(**_lowercase)

								requires_backends(self      ,       'vision')
								self.check_model_type(
								    TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING
								    if self.framework == 'tf'
								    else MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING)



					def __call__(	self     :						Optional[Any]      ,       _lowercase     :						Union[str, List[str], "Image", List["Image"]]      ,       **_lowercase     :						List[Any])    ->							Any:
								return super().__call__(_lowercase      ,       **_lowercase)



					def     __snake_case						(	self     :						int      ,       **_lowercase     :						Union[str, Any])    ->							Any:
								A_									= {}
								if "candidate_labels" in kwargs:
											A_									= kwargs['candidate_labels']
								if "hypothesis_template" in kwargs:
											A_									= kwargs['hypothesis_template']

								return preprocess_params, {}, {}



					def     __snake_case						(	self     :						List[str]      ,       _lowercase     :						Tuple      ,       _lowercase     :						Any=None      ,       _lowercase     :						Optional[int]="This is a photo of {}.")    ->							Union[str, Any]:
								A_									= load_image(_lowercase)
								A_									= self.image_processor(images=[image]      ,       return_tensors=self.framework)
								A_									= candidate_labels
								A_									= [hypothesis_template.format(_lowercase) for x in candidate_labels]
								A_									= self.tokenizer(_lowercase      ,       return_tensors=self.framework      ,       padding=_lowercase)
								A_									= [text_inputs]
								return inputs



					def     __snake_case						(	self     :						Optional[int]      ,       _lowercase     :						Tuple)    ->							Optional[int]:
								A_									= model_inputs.pop('candidate_labels')
								A_									= model_inputs.pop('text_inputs')
								if isinstance(text_inputs[0]      ,       _lowercase):
											A_									= text_inputs[0]
								else:
											# Batching case.
											A_									= text_inputs[0][0]

								A_									= self.model(**_lowercase      ,       **_lowercase)

								A_									= {
								    'candidate_labels': candidate_labels,
								    'logits': outputs.logits_per_image,
								}
								return model_outputs



					def     __snake_case						(	self     :						List[str]      ,       _lowercase     :						int)    ->							Optional[int]:
								A_									= model_outputs.pop('candidate_labels')
								A_									= model_outputs['logits'][0]
								if self.framework == "pt":
											A_									= logits.softmax(dim=-1).squeeze(-1)
											A_									= probs.tolist()
											if not isinstance(_lowercase      ,       _lowercase):
														A_									= [scores]
								elif self.framework == "tf":
											A_									= stable_softmax(_lowercase      ,       axis=-1)
											A_									= probs.numpy().tolist()
								else:
											raise ValueError(F'Unsupported framework: {self.framework}')

								A_									= [
								    {'score': score, 'label': candidate_label}
								    for score, candidate_label in sorted(zip(_lowercase      ,       _lowercase)      ,       key=lambda _lowercase: -x[0])
								]
								return result




