

"""simple docstring"""


import logging
import os
from dataclasses import dataclass, field
from typing import Dict, Optional

import numpy as np
from utils_multiple_choice import MultipleChoiceDataset, Split, processors

import transformers
from transformers import (
    AutoConfig,
    AutoModelForMultipleChoice,
    AutoTokenizer,
    DataCollatorWithPadding,
    EvalPrediction,
    HfArgumentParser,
    Trainer,
    TrainingArguments,
    set_seed,
)
from transformers.trainer_utils import is_main_process


UpperCAmelCase													=logging.getLogger(__name__)



def   _A					(	_a	:						Optional[Any]     ,   _a	:						Any				):



      """simple docstring"""






      return (preds == labels).mean()





@dataclass
class lowerCamelCase__   :



    '''simple docstring'''




    _lowerCamelCase					=   field(
        metadata={'''help''': '''Path to pretrained model or model identifier from huggingface.co/models'''}    )
    _lowerCamelCase					=   field(
        default=SCREAMING_SNAKE_CASE     ,   metadata={'''help''': '''Pretrained config name or path if not the same as model_name'''}    )
    _lowerCamelCase					=   field(
        default=SCREAMING_SNAKE_CASE     ,   metadata={'''help''': '''Pretrained tokenizer name or path if not the same as model_name'''}    )
    _lowerCamelCase					=   field(
        default=SCREAMING_SNAKE_CASE     ,   metadata={'''help''': '''Where do you want to store the pretrained models downloaded from huggingface.co'''}     ,   )





@dataclass
class lowerCamelCase__   :



    '''simple docstring'''




    _lowerCamelCase					=   field(metadata={'''help''': '''The name of the task to train on: ''' + ''', '''.join(processors.keys()    )}    )
    _lowerCamelCase					=   field(metadata={'''help''': '''Should contain the data files for the task.'''}    )
    _lowerCamelCase					=   field(
        default=128     ,   metadata={
            '''help''': (
                '''The maximum total input sequence length after tokenization. Sequences longer '''
                '''than this will be truncated, sequences shorter will be padded.'''
            )
        }     ,   )
    _lowerCamelCase					=   field(
        default=SCREAMING_SNAKE_CASE     ,   metadata={'''help''': '''Overwrite the cached training and evaluation sets'''}    )




def   _A					(	):



      """simple docstring"""






      A				  =		HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments)				)
      A  ,			A  ,			A				  =		parser.parse_args_into_dataclasses()

      if (
          os.path.exists(training_args.output_dir				)
          and os.listdir(training_args.output_dir				)
          and training_args.do_train
          and not training_args.overwrite_output_dir
      ):
            raise ValueError(
                f'Output directory ({training_args.output_dir}) already exists and is not empty. Use'
                """ --overwrite_output_dir to overcome."""				)

      # Setup logging
      logging.basicConfig(
          format="""%(asctime)s - %(levelname)s - %(name)s - %(message)s"""     ,   datefmt="""%m/%d/%Y %H:%M:%S"""     ,   level=logging.INFO if training_args.local_rank in [-1, 0] else logging.WARN     ,   )
      logger.warning(
          """Process rank: %s, device: %s, n_gpu: %s, distributed training: %s, 16-bits training: %s"""     ,   training_args.local_rank     ,   training_args.device     ,   training_args.n_gpu     ,   bool(training_args.local_rank != -1				)     ,   training_args.fpaa     ,   )
      # Set the verbosity to info of the Transformers logger (on main process only):
      if is_main_process(training_args.local_rank				):
            transformers.utils.logging.set_verbosity_info()
            transformers.utils.logging.enable_default_handler()
            transformers.utils.logging.enable_explicit_format()
      logger.info("""Training/evaluation parameters %s"""     ,   _a				)

      # Set seed
      set_seed(training_args.seed				)

      try:
            A				  =		processors[data_args.task_name]()
            A				  =		processor.get_labels()
            A				  =		len(_a				)
      except KeyError:
            raise ValueError("""Task not found: %s""" % (data_args.task_name)				)

      # Load pretrained model and tokenizer
      #
      # Distributed training:
      # The .from_pretrained methods guarantee that only one local process can concurrently
      # download model & vocab.

      A				  =		AutoConfig.from_pretrained(
          model_args.config_name if model_args.config_name else model_args.model_name_or_path     ,   num_labels=_a     ,   finetuning_task=data_args.task_name     ,   cache_dir=model_args.cache_dir     ,   )
      A				  =		AutoTokenizer.from_pretrained(
          model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path     ,   cache_dir=model_args.cache_dir     ,   )
      A				  =		AutoModelForMultipleChoice.from_pretrained(
          model_args.model_name_or_path     ,   from_tf=bool(""".ckpt""" in model_args.model_name_or_path				)     ,   config=_a     ,   cache_dir=model_args.cache_dir     ,   )

      # Get datasets
      A				  =		(
          MultipleChoiceDataset(
              data_dir=data_args.data_dir     ,   tokenizer=_a     ,   task=data_args.task_name     ,   max_seq_length=data_args.max_seq_length     ,   overwrite_cache=data_args.overwrite_cache     ,   mode=Split.train     ,   )
          if training_args.do_train
          else None
      )
      A				  =		(
          MultipleChoiceDataset(
              data_dir=data_args.data_dir     ,   tokenizer=_a     ,   task=data_args.task_name     ,   max_seq_length=data_args.max_seq_length     ,   overwrite_cache=data_args.overwrite_cache     ,   mode=Split.dev     ,   )
          if training_args.do_eval
          else None
      )

      def compute_metrics(_a	:						EvalPrediction				) -> Dict:
            A				  =		np.argmax(p.predictions     ,   axis=1				)
            return {"acc": simple_accuracy(_a     ,   p.label_ids				)}

      # Data collator
      A				  =		DataCollatorWithPadding(_a     ,   pad_to_multiple_of=8				) if training_args.fpaa else None

      # Initialize our Trainer
      A				  =		Trainer(
          model=_a     ,   args=_a     ,   train_dataset=_a     ,   eval_dataset=_a     ,   compute_metrics=_a     ,   data_collator=_a     ,   )

      # Training
      if training_args.do_train:
            trainer.train(
                model_path=model_args.model_name_or_path if os.path.isdir(model_args.model_name_or_path				) else None				)
            trainer.save_model()
            # For convenience, we also re-save the tokenizer to the same directory,
            # so that you can share your model easily on huggingface.co/models =)
            if trainer.is_world_master():
                  tokenizer.save_pretrained(training_args.output_dir				)

    # Evaluation
      A				  =		{}
      if training_args.do_eval:
            logger.info("""*** Evaluate ***"""				)

            A				  =		trainer.evaluate()

            A				  =		os.path.join(training_args.output_dir     ,   """eval_results.txt"""				)
            if trainer.is_world_master():
                  with open(_a     ,   """w"""				) as writer:
                        logger.info("""***** Eval results *****"""				)
                        for key, value in result.items():
                              logger.info("""  %s = %s"""     ,   _a     ,   _a				)
                              writer.write("""%s = %s\n""" % (key, value)				)

                        results.update(_a				)

      return results



def   _A					(	_a	:						List[Any]				):



      """simple docstring"""






      main()


if __name__ == "__main__":
  main()







"""simple docstring"""


from typing import Union

from ..utils import add_end_docstrings, is_torch_available, is_vision_available, logging
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_VISUAL_QUESTION_ANSWERING_MAPPING

UpperCAmelCase													=logging.get_logger(__name__)





@add_end_docstrings(SCREAMING_SNAKE_CASE    )
class lowerCamelCase__   (				SCREAMING_SNAKE_CASE    ):



    '''simple docstring'''




    def __init__( self ,*lowerCamelCase_ ,**lowerCamelCase_    )    ->      str:
          super().__init__(*lowerCamelCase_ ,**lowerCamelCase_    )
          self.check_model_type(lowerCamelCase_    )




    def UpperCamelCase__		( self ,lowerCamelCase_=None ,lowerCamelCase_=None ,lowerCamelCase_=None ,**lowerCamelCase_    )    ->      List[Any]:
          A  ,			A				  =		{}, {}
          if padding is not None:
                A				  =		padding
          if truncation is not None:
                A				  =		truncation
          if top_k is not None:
                A				  =		top_k
          return preprocess_params, {}, postprocess_params




    def __call__( self ,lowerCamelCase_ ,lowerCamelCase_ = None ,**lowerCamelCase_    )    ->      Dict:
          if isinstance(lowerCamelCase_ ,(Image.Image, str)    ) and isinstance(lowerCamelCase_ ,lowerCamelCase_    ):
                A				  =		{"""image""": image, """question""": question}
          else:
                A				  =		image
          A				  =		super().__call__(lowerCamelCase_ ,**lowerCamelCase_    )
          return results




    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_=False ,lowerCamelCase_=False    )    ->      List[Any]:
          A				  =		load_image(inputs["""image"""]    )
          A				  =		self.tokenizer(
              inputs["""question"""] ,return_tensors=self.framework ,padding=lowerCamelCase_ ,truncation=lowerCamelCase_    )
          A				  =		self.image_processor(images=lowerCamelCase_ ,return_tensors=self.framework    )
          model_inputs.update(lowerCamelCase_    )
          return model_inputs




    def UpperCamelCase__		( self ,lowerCamelCase_    )    ->      Union[str, Any]:
          A				  =		self.model(**lowerCamelCase_    )
          return model_outputs




    def UpperCamelCase__		( self ,lowerCamelCase_ ,lowerCamelCase_=5    )    ->      int:
          if top_k > self.model.config.num_labels:
                A				  =		self.model.config.num_labels

          if self.framework == "pt":
                A				  =		model_outputs.logits.sigmoid()[0]
                A  ,			A				  =		probs.topk(lowerCamelCase_    )
          else:
                raise ValueError(f'Unsupported framework: {self.framework}'    )

          A				  =		scores.tolist()
          A				  =		ids.tolist()
          return [{"score": score, "answer": self.model.config.idalabel[_id]} for score, _id in zip(lowerCamelCase_ ,lowerCamelCase_    )]




