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


__lowercase										= logging.getLogger(__name__)



def lowerCamelCase  (       SCREAMING_SNAKE_CASE  ,      SCREAMING_SNAKE_CASE     ):
    '''simple docstring'''







    return (preds == labels).mean()


@dataclass
class      lowerCamelCase_					:






    '''simple docstring'''






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


@dataclass
class      lowerCamelCase_					:






    '''simple docstring'''






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



def lowerCamelCase  (       ):
    '''simple docstring'''







    __UpperCamelCase					:Tuple        =		HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments)     )
    __UpperCamelCase  ,	__UpperCamelCase  ,	__UpperCamelCase					:Dict        =		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'''  ,      SCREAMING_SNAKE_CASE     )

    # Set seed
    set_seed(training_args.seed     )

    try:
        __UpperCamelCase					:List[Any]        =		processors[data_args.task_name]()
        __UpperCamelCase					:Optional[Any]        =		processor.get_labels()
        __UpperCamelCase					:List[str]        =		len(SCREAMING_SNAKE_CASE     )
    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.

    __UpperCamelCase					:Tuple        =		AutoConfig.from_pretrained(
        model_args.config_name if model_args.config_name else model_args.model_name_or_path  ,      num_labels=SCREAMING_SNAKE_CASE  ,      finetuning_task=data_args.task_name  ,      cache_dir=model_args.cache_dir  ,      )
    __UpperCamelCase					:Optional[int]        =		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  ,      )
    __UpperCamelCase					:Dict        =		AutoModelForMultipleChoice.from_pretrained(
        model_args.model_name_or_path  ,      from_tf=bool('''.ckpt''' in model_args.model_name_or_path     )  ,      config=SCREAMING_SNAKE_CASE  ,      cache_dir=model_args.cache_dir  ,      )

    # Get datasets
    __UpperCamelCase					:Dict        =		(
        MultipleChoiceDataset(
            data_dir=data_args.data_dir  ,      tokenizer=SCREAMING_SNAKE_CASE  ,      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
    )
    __UpperCamelCase					:Any        =		(
        MultipleChoiceDataset(
            data_dir=data_args.data_dir  ,      tokenizer=SCREAMING_SNAKE_CASE  ,      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(SCREAMING_SNAKE_CASE     ) -> Dict:
        __UpperCamelCase					:List[Any]        =		np.argmax(p.predictions  ,      axis=1     )
        return {"acc": simple_accuracy(SCREAMING_SNAKE_CASE  ,      p.label_ids     )}

    # Data collator
    __UpperCamelCase					:Optional[int]        =		DataCollatorWithPadding(SCREAMING_SNAKE_CASE  ,      pad_to_multiple_of=8     ) if training_args.fpaa else None

    # Initialize our Trainer
    __UpperCamelCase					:List[str]        =		Trainer(
        model=SCREAMING_SNAKE_CASE  ,      args=SCREAMING_SNAKE_CASE  ,      train_dataset=SCREAMING_SNAKE_CASE  ,      eval_dataset=SCREAMING_SNAKE_CASE  ,      compute_metrics=SCREAMING_SNAKE_CASE  ,      data_collator=SCREAMING_SNAKE_CASE  ,      )

    # 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
    __UpperCamelCase					:Any        =		{}
    if training_args.do_eval:
        logger.info('''*** Evaluate ***'''     )

        __UpperCamelCase					:Optional[Any]        =		trainer.evaluate()

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

                results.update(SCREAMING_SNAKE_CASE     )

    return results



def lowerCamelCase  (       SCREAMING_SNAKE_CASE     ):
    '''simple docstring'''







    main()


if __name__ == "__main__":
    main()






import unittest

from transformers import BertGenerationTokenizer
from transformers.testing_utils import get_tests_dir, require_sentencepiece, require_torch, slow
from transformers.utils import cached_property

from ...test_tokenization_common import TokenizerTesterMixin


__lowercase										= '''▁'''

__lowercase										= get_tests_dir('''fixtures/test_sentencepiece.model''')


@require_sentencepiece
class      lowerCamelCase_					(       UpperCAmelCase_						,     unittest.TestCase			):






    '''simple docstring'''






    a__     :						int      =				BertGenerationTokenizer
    a__     :						Dict      =				False
    a__     :						str      =				True







    def       UpperCamelCase__       (     self)	->     List[str]:
        super().setUp()

        __UpperCamelCase					:Optional[Any]        =		BertGenerationTokenizer(__lowercase			,			keep_accents=__lowercase)
        tokenizer.save_pretrained(self.tmpdirname)







    def       UpperCamelCase__       (     self)	->     int:
        __UpperCamelCase					:Dict        =		'''<s>'''
        __UpperCamelCase					:Dict        =		1

        self.assertEqual(self.get_tokenizer()._convert_token_to_id(__lowercase)			,			__lowercase)
        self.assertEqual(self.get_tokenizer()._convert_id_to_token(__lowercase)			,			__lowercase)







    def       UpperCamelCase__       (     self)	->     Optional[int]:
        __UpperCamelCase					:Optional[Any]        =		list(self.get_tokenizer().get_vocab().keys())

        self.assertEqual(vocab_keys[0]			,			'''<unk>''')
        self.assertEqual(vocab_keys[1]			,			'''<s>''')
        self.assertEqual(vocab_keys[-1]			,			'''<pad>''')
        self.assertEqual(len(__lowercase)			,			1_002)







    def       UpperCamelCase__       (     self)	->     Dict:
        self.assertEqual(self.get_tokenizer().vocab_size			,			1_000)







    def       UpperCamelCase__       (     self)	->     Optional[Any]:
        __UpperCamelCase					:str        =		BertGenerationTokenizer(__lowercase			,			keep_accents=__lowercase)

        __UpperCamelCase					:Optional[Any]        =		tokenizer.tokenize('''This is a test''')
        self.assertListEqual(__lowercase			,			['''▁This''', '''▁is''', '''▁a''', '''▁t''', '''est'''])

        self.assertListEqual(
            tokenizer.convert_tokens_to_ids(__lowercase)			,			[285, 46, 10, 170, 382]			,			)

        __UpperCamelCase					:List[Any]        =		tokenizer.tokenize('''I was born in 92000, and this is falsé.''')
        self.assertListEqual(
            __lowercase			,			[
                SPIECE_UNDERLINE + '''I''',
                SPIECE_UNDERLINE + '''was''',
                SPIECE_UNDERLINE + '''b''',
                '''or''',
                '''n''',
                SPIECE_UNDERLINE + '''in''',
                SPIECE_UNDERLINE + '''''',
                '''9''',
                '''2''',
                '''0''',
                '''0''',
                '''0''',
                ''',''',
                SPIECE_UNDERLINE + '''and''',
                SPIECE_UNDERLINE + '''this''',
                SPIECE_UNDERLINE + '''is''',
                SPIECE_UNDERLINE + '''f''',
                '''al''',
                '''s''',
                '''é''',
                '''.''',
            ]			,			)
        __UpperCamelCase					:Any        =		tokenizer.convert_tokens_to_ids(__lowercase)
        self.assertListEqual(
            __lowercase			,			[8, 21, 84, 55, 24, 19, 7, 0, 602, 347, 347, 347, 3, 12, 66, 46, 72, 80, 6, 0, 4]			,			)

        __UpperCamelCase					:Tuple        =		tokenizer.convert_ids_to_tokens(__lowercase)
        self.assertListEqual(
            __lowercase			,			[
                SPIECE_UNDERLINE + '''I''',
                SPIECE_UNDERLINE + '''was''',
                SPIECE_UNDERLINE + '''b''',
                '''or''',
                '''n''',
                SPIECE_UNDERLINE + '''in''',
                SPIECE_UNDERLINE + '''''',
                '''<unk>''',
                '''2''',
                '''0''',
                '''0''',
                '''0''',
                ''',''',
                SPIECE_UNDERLINE + '''and''',
                SPIECE_UNDERLINE + '''this''',
                SPIECE_UNDERLINE + '''is''',
                SPIECE_UNDERLINE + '''f''',
                '''al''',
                '''s''',
                '''<unk>''',
                '''.''',
            ]			,			)







    @cached_property
    def       UpperCamelCase__       (     self)	->     int:
        return BertGenerationTokenizer.from_pretrained('''google/bert_for_seq_generation_L-24_bbc_encoder''')







    @slow
    def       UpperCamelCase__       (     self)	->     List[str]:
        __UpperCamelCase					:Optional[Any]        =		'''Hello World!'''
        __UpperCamelCase					:Optional[int]        =		[18_536, 2_260, 101]

        self.assertListEqual(__lowercase			,			self.big_tokenizer.encode(__lowercase))







    @slow
    def       UpperCamelCase__       (     self)	->     List[str]:
        __UpperCamelCase					:Optional[Any]        =		(
            '''This is a very long text with a lot of weird characters, such as: . , ~ ? ( ) " [ ] ! : - . Also we will'''
            ''' add words that should not exsist and be tokenized to <unk>, such as saoneuhaoesuth'''
        )
        __UpperCamelCase					:Union[str, Any]        =		[
            871,
            419,
            358,
            946,
            991,
            2_521,
            452,
            358,
            1_357,
            387,
            7_751,
            3_536,
            112,
            985,
            456,
            126,
            865,
            938,
            5_400,
            5_734,
            458,
            1_368,
            467,
            786,
            2_462,
            5_246,
            1_159,
            633,
            865,
            4_519,
            457,
            582,
            852,
            2_557,
            427,
            916,
            508,
            405,
            34_324,
            497,
            391,
            408,
            11_342,
            1_244,
            385,
            100,
            938,
            985,
            456,
            574,
            362,
            12_597,
            3_200,
            3_129,
            1_172,
        ]

        self.assertListEqual(__lowercase			,			self.big_tokenizer.encode(__lowercase))







    @require_torch
    @slow
    def       UpperCamelCase__       (     self)	->     Optional[int]:
        import torch

        from transformers import BertGenerationConfig, BertGenerationEncoder

        # Build sequence
        __UpperCamelCase					:Optional[Any]        =		list(self.big_tokenizer.get_vocab().keys())[:10]
        __UpperCamelCase					:Optional[int]        =		''' '''.join(__lowercase)
        __UpperCamelCase					:Optional[int]        =		self.big_tokenizer.encode_plus(__lowercase			,			return_tensors='''pt'''			,			return_token_type_ids=__lowercase)
        __UpperCamelCase					:List[str]        =		self.big_tokenizer.batch_encode_plus(
            [sequence + ''' ''' + sequence]			,			return_tensors='''pt'''			,			return_token_type_ids=__lowercase)

        __UpperCamelCase					:List[Any]        =		BertGenerationConfig()
        __UpperCamelCase					:Optional[Any]        =		BertGenerationEncoder(__lowercase)

        assert model.get_input_embeddings().weight.shape[0] >= self.big_tokenizer.vocab_size

        with torch.no_grad():
            model(**__lowercase)
            model(**__lowercase)







    @slow
    def       UpperCamelCase__       (     self)	->     Dict:
        # fmt: off
        __UpperCamelCase					:List[str]        =		{'''input_ids''': [[39_286, 458, 36_335, 2_001, 456, 13_073, 13_266, 455, 113, 7_746, 1_741, 11_157, 391, 13_073, 13_266, 455, 113, 3_967, 35_412, 113, 4_936, 109, 3_870, 2_377, 113, 30_084, 45_720, 458, 134, 17_496, 112, 503, 11_672, 113, 118, 112, 5_665, 13_347, 38_687, 112, 1_496, 31_389, 112, 3_268, 47_264, 134, 962, 112, 16_377, 8_035, 23_130, 430, 12_169, 15_518, 28_592, 458, 146, 41_697, 109, 391, 12_169, 15_518, 16_689, 458, 146, 41_358, 109, 452, 726, 4_034, 111, 763, 35_412, 5_082, 388, 1_903, 111, 9_051, 391, 2_870, 48_918, 1_900, 1_123, 550, 998, 112, 9_586, 15_985, 455, 391, 410, 22_955, 37_636, 114], [448, 17_496, 419, 3_663, 385, 763, 113, 27_533, 2_870, 3_283, 13_043, 1_639, 24_713, 523, 656, 24_013, 18_550, 2_521, 517, 27_014, 21_244, 420, 1_212, 1_465, 391, 927, 4_833, 388, 578, 11_786, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [484, 2_169, 7_687, 21_932, 18_146, 726, 363, 17_032, 3_391, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], '''attention_mask''': [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]}  # noqa: E501
        # fmt: on

        self.tokenizer_integration_test_util(
            expected_encoding=__lowercase			,			model_name='''google/bert_for_seq_generation_L-24_bbc_encoder'''			,			revision='''c817d1fd1be2ffa69431227a1fe320544943d4db'''			,			)





