


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


_lowerCAmelCase:						List[Any]   				=       logging.getLogger(__name__)






def   _lowercase(					__a				:						str    ,     __a				:						Any     ):
							return (preds == labels).mean()




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







@dataclass
class       lowercase_					:
				snake_case	    =field(metadata={'help': 'The name of the task to train on: ' + ', '.join(processors.keys()   )}   )
				snake_case	    =field(metadata={'help': 'Should contain the data files for the task.'}   )
				snake_case	    =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.'
				        )
				    }      ,					)
				snake_case	    =field(
				    default=lowercase__      ,					metadata={'help': 'Overwrite the cached training and evaluation sets'}   )







def   _lowercase(					):
							# See all possible arguments in src/transformers/training_args.py
							# or by passing the --help flag to this script.
							# We now keep distinct sets of args, for a cleaner separation of concerns.

							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   _lowercase(					__a				:						Dict     ):
							# For xla_spawn (TPUs)
							main()


if __name__ == "__main__":
	main()





import absl  # noqa: F401 # Here to have a nice missing dependency error message early on
import nltk  # noqa: F401 # Here to have a nice missing dependency error message early on
import numpy  # noqa: F401 # Here to have a nice missing dependency error message early on
import six  # noqa: F401 # Here to have a nice missing dependency error message early on
from rouge_score import rouge_scorer, scoring

import datasets


_lowerCAmelCase:						Union[str, Any]   				=       '\\n@inproceedings{lin-2004-rouge,\n    title = "{ROUGE}: A Package for Automatic Evaluation of Summaries",\n    author = "Lin, Chin-Yew",\n    booktitle = "Text Summarization Branches Out",\n    month = jul,\n    year = "2004",\n    address = "Barcelona, Spain",\n    publisher = "Association for Computational Linguistics",\n    url = "https://www.aclweb.org/anthology/W04-1013",\n    pages = "74--81",\n}\n'

_lowerCAmelCase:						Dict   				=       '\\nROUGE, or Recall-Oriented Understudy for Gisting Evaluation, is a set of metrics and a software package used for\nevaluating automatic summarization and machine translation software in natural language processing.\nThe metrics compare an automatically produced summary or translation against a reference or a set of references (human-produced) summary or translation.\n\nNote that ROUGE is case insensitive, meaning that upper case letters are treated the same way as lower case letters.\n\nThis metrics is a wrapper around Google Research reimplementation of ROUGE:\nhttps://github.com/google-research/google-research/tree/master/rouge\n'

_lowerCAmelCase:						List[Any]   				=       '\nCalculates average rouge scores for a list of hypotheses and references\nArgs:\n    predictions: list of predictions to score. Each prediction\n        should be a string with tokens separated by spaces.\n    references: list of reference for each prediction. Each\n        reference should be a string with tokens separated by spaces.\n    rouge_types: A list of rouge types to calculate.\n        Valid names:\n        `"rouge{n}"` (e.g. `"rouge1"`, `"rouge2"`) where: {n} is the n-gram based scoring,\n        `"rougeL"`: Longest common subsequence based scoring.\n        `"rougeLSum"`: rougeLsum splits text using `"\n"`.\n        See details in https://github.com/huggingface/datasets/issues/617\n    use_stemmer: Bool indicating whether Porter stemmer should be used to strip word suffixes.\n    use_aggregator: Return aggregates if this is set to True\nReturns:\n    rouge1: rouge_1 (precision, recall, f1),\n    rouge2: rouge_2 (precision, recall, f1),\n    rougeL: rouge_l (precision, recall, f1),\n    rougeLsum: rouge_lsum (precision, recall, f1)\nExamples:\n\n    >>> rouge = datasets.load_metric(\'rouge\')\n    >>> predictions = ["hello there", "general kenobi"]\n    >>> references = ["hello there", "general kenobi"]\n    >>> results = rouge.compute(predictions=predictions, references=references)\n    >>> print(list(results.keys()))\n    [\'rouge1\', \'rouge2\', \'rougeL\', \'rougeLsum\']\n    >>> print(results["rouge1"])\n    AggregateScore(low=Score(precision=1.0, recall=1.0, fmeasure=1.0), mid=Score(precision=1.0, recall=1.0, fmeasure=1.0), high=Score(precision=1.0, recall=1.0, fmeasure=1.0))\n    >>> print(results["rouge1"].mid.fmeasure)\n    1.0\n'




@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION      ,					_KWARGS_DESCRIPTION   )
class       lowercase_					(datasets.Metric   ):





				def 						__UpperCamelCase    (				self)  -> Optional[int]:
											return datasets.MetricInfo(
											    description=_DESCRIPTION       ,  citation=_CITATION       ,  inputs_description=_KWARGS_DESCRIPTION       ,  features=datasets.Features(
											        {
											            'predictions': datasets.Value('string'       ,  id='sequence'),
											            'references': datasets.Value('string'       ,  id='sequence'),
											        })       ,  codebase_urls=['https://github.com/google-research/google-research/tree/master/rouge']       ,  reference_urls=[
											        'https://en.wikipedia.org/wiki/ROUGE_(metric)',
											        'https://github.com/google-research/google-research/tree/master/rouge',
											    ]       ,  )





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_=None       ,  lowercase_=True       ,  lowercase_=False)  -> Any:
											if rouge_types is None:
																		a__      =['rouge1', 'rouge2', 'rougeL', 'rougeLsum']

											a__      =rouge_scorer.RougeScorer(rouge_types=lowercase_       ,  use_stemmer=lowercase_)
											if use_aggregator:
																		a__      =scoring.BootstrapAggregator()
											else:
																		a__      =[]

											for ref, pred in zip(lowercase_       ,  lowercase_):
																		a__      =scorer.score(lowercase_       ,  lowercase_)
																		if use_aggregator:
																									aggregator.add_scores(lowercase_)
																		else:
																									scores.append(lowercase_)

											if use_aggregator:
																		a__      =aggregator.aggregate()
											else:
																		a__      ={}
																		for key in scores[0]:
																									a__      =[score[key] for score in scores]

											return result

