




"""simple docstring"""





import os
from typing import List, Union

import tensorflow as tf
from tensorflow_text import BertTokenizer as BertTokenizerLayer
from tensorflow_text import FastBertTokenizer, ShrinkLongestTrimmer, case_fold_utfa, combine_segments, pad_model_inputs

from .tokenization_bert import BertTokenizer

class    __lowercase							(      tf.keras.layers.Layer						):


				'''simple docstring'''


				def __init__( self :  List[Any]   ,SCREAMING_SNAKE_CASE_ :  List   ,SCREAMING_SNAKE_CASE_ :  bool   ,SCREAMING_SNAKE_CASE_ :  int = None   ,SCREAMING_SNAKE_CASE_ :  int = None   ,SCREAMING_SNAKE_CASE_ :  int = None   ,SCREAMING_SNAKE_CASE_ :  str = "longest"   ,SCREAMING_SNAKE_CASE_ :  bool = True   ,SCREAMING_SNAKE_CASE_ :  int = 5_1_2   ,SCREAMING_SNAKE_CASE_ :  int = None   ,SCREAMING_SNAKE_CASE_ :  bool = True   ,SCREAMING_SNAKE_CASE_ :  bool = True   ,SCREAMING_SNAKE_CASE_ :  bool = True   ,**SCREAMING_SNAKE_CASE_ :  Optional[int]   ,):
										super().__init__()
										if use_fast_bert_tokenizer:
																snake_case__							:       Any				      =       FastBertTokenizer(
																    _A   ,token_out_type=tf.intaa   ,lower_case_nfd_strip_accents=_A   ,**_A   )
										else:
																snake_case__							:       List[Any]				      =       tf.lookup.StaticVocabularyTable(
																    tf.lookup.KeyValueTensorInitializer(
																        keys=_A   ,key_dtype=tf.string   ,values=tf.range(tf.size(_A   ,out_type=tf.intaa   )   ,dtype=tf.intaa   )   ,value_dtype=tf.intaa   ,)   ,num_oov_buckets=1   ,)
																snake_case__							:       List[Any]				      =       BertTokenizerLayer(
																    _A   ,token_out_type=tf.intaa   ,lower_case=_A   ,**_A   )

										snake_case__							:       Any				      =       vocab_list
										snake_case__							:       List[str]				      =       do_lower_case
										snake_case__							:       Dict				      =       cls_token_id or vocab_list.index('''[CLS]'''   )
										snake_case__							:       Tuple				      =       sep_token_id or vocab_list.index('''[SEP]'''   )
										snake_case__							:       List[str]				      =       pad_token_id or vocab_list.index('''[PAD]'''   )
										snake_case__							:       Dict				      =       ShrinkLongestTrimmer(max_length - 3   ,axis=1   )  # Allow room for special tokens
										snake_case__							:       Optional[int]				      =       max_length
										snake_case__							:       str				      =       padding
										snake_case__							:       Any				      =       truncation
										snake_case__							:       Optional[Any]				      =       pad_to_multiple_of
										snake_case__							:       int				      =       return_token_type_ids
										snake_case__							:       List[Any]				      =       return_attention_mask

				@classmethod
				def    _lowerCamelCase       ( cls :  Optional[Any]   ,SCREAMING_SNAKE_CASE_ :  "PreTrainedTokenizerBase"   ,**SCREAMING_SNAKE_CASE_ :  Tuple   ):  # noqa: F821
										snake_case__							:       str				      =       kwargs.pop('''do_lower_case'''   ,_A   )
										snake_case__							:       str				      =       tokenizer.do_lower_case if do_lower_case is None else do_lower_case
										snake_case__							:       Union[str, Any]				      =       kwargs.pop('''cls_token_id'''   ,_A   )
										snake_case__							:       str				      =       tokenizer.cls_token_id if cls_token_id is None else cls_token_id
										snake_case__							:       int				      =       kwargs.pop('''sep_token_id'''   ,_A   )
										snake_case__							:       int				      =       tokenizer.sep_token_id if sep_token_id is None else sep_token_id
										snake_case__							:       Dict				      =       kwargs.pop('''pad_token_id'''   ,_A   )
										snake_case__							:       int				      =       tokenizer.pad_token_id if pad_token_id is None else pad_token_id

										snake_case__							:       List[str]				      =       tokenizer.get_vocab()
										snake_case__							:       List[Any]				      =       sorted([(wordpiece, idx) for wordpiece, idx in vocab.items()]   ,key=lambda SCREAMING_SNAKE_CASE_   : x[1]   )
										snake_case__							:       Any				      =       [entry[0] for entry in vocab]
										return cls(
										    vocab_list=_A   ,do_lower_case=_A   ,cls_token_id=_A   ,sep_token_id=_A   ,pad_token_id=_A   ,**_A   ,)

				@classmethod
				def    _lowerCamelCase       ( cls :  int   ,SCREAMING_SNAKE_CASE_ :  Union[str, os.PathLike]   ,*SCREAMING_SNAKE_CASE_ :  List[str]   ,**SCREAMING_SNAKE_CASE_ :  Optional[Any]   ):
										try:
																snake_case__							:       Union[str, Any]				      =       BertTokenizer.from_pretrained(_A   ,*_A   ,**_A   )
										except:  # noqa: E722
																from .tokenization_bert_fast import BertTokenizerFast

																snake_case__							:       Dict				      =       BertTokenizerFast.from_pretrained(_A   ,*_A   ,**_A   )
										return cls.from_tokenizer(_A   ,**_A   )

				def    _lowerCamelCase       ( self :  List[Any]   ,SCREAMING_SNAKE_CASE_ :  str   ):
										if self.do_lower_case:
																snake_case__							:       Dict				      =       case_fold_utfa(_A   )
										snake_case__							:       Any				      =       self.tf_tokenizer.tokenize(_A   )
										return tokens.merge_dims(1   ,-1   )

				def    _lowerCamelCase       ( self :  Any   ,SCREAMING_SNAKE_CASE_ :  Optional[Any]   ,SCREAMING_SNAKE_CASE_ :  Optional[Any]=None   ,SCREAMING_SNAKE_CASE_ :  str=None   ,SCREAMING_SNAKE_CASE_ :  Tuple=None   ,SCREAMING_SNAKE_CASE_ :  int=None   ,SCREAMING_SNAKE_CASE_ :  Tuple=None   ,SCREAMING_SNAKE_CASE_ :  str=None   ,SCREAMING_SNAKE_CASE_ :  Optional[int]=None   ,):
										if padding is None:
																snake_case__							:       Optional[int]				      =       self.padding
										if padding not in ("longest", "max_length"):
																raise ValueError('''Padding must be either \'longest\' or \'max_length\'!'''   )
										if max_length is not None and text_pair is not None:
																# Because we have to instantiate a Trimmer to do it properly
																raise ValueError('''max_length cannot be overridden at call time when truncating paired texts!'''   )
										if max_length is None:
																snake_case__							:       Optional[Any]				      =       self.max_length
										if truncation is None:
																snake_case__							:       Tuple				      =       self.truncation
										if pad_to_multiple_of is None:
																snake_case__							:       Tuple				      =       self.pad_to_multiple_of
										if return_token_type_ids is None:
																snake_case__							:       Tuple				      =       self.return_token_type_ids
										if return_attention_mask is None:
																snake_case__							:       Dict				      =       self.return_attention_mask
										if not isinstance(_A   ,tf.Tensor   ):
																snake_case__							:       Union[str, Any]				      =       tf.convert_to_tensor(_A   )
										if text_pair is not None and not isinstance(_A   ,tf.Tensor   ):
																snake_case__							:       List[str]				      =       tf.convert_to_tensor(_A   )
										if text_pair is not None:
																if text.shape.rank > 1:
																						raise ValueError('''text argument should not be multidimensional when a text pair is supplied!'''   )
																if text_pair.shape.rank > 1:
																						raise ValueError('''text_pair should not be multidimensional!'''   )
										if text.shape.rank == 2:
																snake_case__      ,						snake_case__							:       Union[str, Any]				      =       text[:, 0], text[:, 1]
										snake_case__							:       str				      =       self.unpaired_tokenize(_A   )
										if text_pair is None:  # Unpaired text
																if truncation:
																						snake_case__							:       str				      =       text[:, : max_length - 2]  # Allow room for special tokens
																snake_case__      ,						snake_case__							:       Tuple				      =       combine_segments(
																    (text,)   ,start_of_sequence_id=self.cls_token_id   ,end_of_segment_id=self.sep_token_id   )
										else:  # Paired text
																snake_case__							:       Union[str, Any]				      =       self.unpaired_tokenize(_A   )
																if truncation:
																						snake_case__      ,						snake_case__							:       List[Any]				      =       self.paired_trimmer.trim([text, text_pair]   )
																snake_case__      ,						snake_case__							:       int				      =       combine_segments(
																    (text, text_pair)   ,start_of_sequence_id=self.cls_token_id   ,end_of_segment_id=self.sep_token_id   )
										if padding == "longest":
																snake_case__							:       Dict				      =       input_ids.bounding_shape(axis=1   )
																if pad_to_multiple_of is not None:
																						# No ceiling division in tensorflow, so we negate floordiv instead
																						snake_case__							:       Optional[Any]				      =       pad_to_multiple_of * (-tf.math.floordiv(-pad_length   ,_A   ))
										else:
																snake_case__							:       Union[str, Any]				      =       max_length

										snake_case__      ,						snake_case__							:       Optional[Any]				      =       pad_model_inputs(_A   ,max_seq_length=_A   ,pad_value=self.pad_token_id   )
										snake_case__							:       List[str]				      =       {'''input_ids''': input_ids}
										if return_attention_mask:
																snake_case__							:       Optional[Any]				      =       attention_mask
										if return_token_type_ids:
																snake_case__      ,						snake_case__							:       Tuple				      =       pad_model_inputs(
																    _A   ,max_seq_length=_A   ,pad_value=self.pad_token_id   )
																snake_case__							:       Any				      =       token_type_ids
										return output





				def    _lowerCamelCase       ( self :  int   ):
										return {
										    "vocab_list": self.vocab_list,
										    "do_lower_case": self.do_lower_case,
										    "cls_token_id": self.cls_token_id,
										    "sep_token_id": self.sep_token_id,
										    "pad_token_id": self.pad_token_id,
										}




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

import transformers
from transformers import (
    AutoConfig,
    AutoModelForQuestionAnswering,
    AutoTokenizer,
    DataCollatorWithPadding,
    HfArgumentParser,
    SquadDataset,
    Trainer,
    TrainingArguments,
)
from transformers import SquadDataTrainingArguments as DataTrainingArguments
from transformers.trainer_utils import is_main_process


_A       =					logging.getLogger(__name__)







@dataclass
class 	lowerCamelCase						:
     UpperCAmelCase__							:				str 	=						field(
         metadata={"help": "Path to pretrained model or model identifier from huggingface.co/models"}    )
     UpperCAmelCase__							:				Optional[str] 	=						field(
         default=A_				,					metadata={"help": "Pretrained config name or path if not the same as model_name"}    )
     UpperCAmelCase__							:				Optional[str] 	=						field(
         default=A_				,					metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"}    )
     UpperCAmelCase__							:				bool 	=						field(default=A_				,					metadata={"help": "Set this flag to use fast tokenization."}    )
     # If you want to tweak more attributes on your tokenizer, you should do it in a distinct script,
     # or just modify its tokenizer_config.json.
     UpperCAmelCase__							:				Optional[str] 	=						field(
         default=A_				,					metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"}				,					)



def 		lowercase_     (  )				->				int:
    """simple docstring"""

    snake_case						=   HfArgumentParser((ModelArguments, DataTrainingArguments, TrainingArguments)						)

    if len(sys.argv						) == 2 and sys.argv[1].endswith(".json"						):
        # If we pass only one argument to the script and it's the path to a json file,
        # let's parse it to get our arguments.
        snake_case	,				snake_case	,				snake_case						=   parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]						)						)
    else:
        snake_case	,				snake_case	,				snake_case						=   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__						)

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

    snake_case						=   AutoConfig.from_pretrained(
        model_args.config_name if model_args.config_name else model_args.model_name_or_path					,						cache_dir=model_args.cache_dir					,						)
    snake_case						=   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					,						use_fast=A__					,						)
    snake_case						=   AutoModelForQuestionAnswering.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
    snake_case						=   hasattr(model.config					,						"lang2id"						)
    snake_case						=   (
        SquadDataset(
            A__					,						tokenizer=A__					,						is_language_sensitive=A__					,						cache_dir=model_args.cache_dir						)
        if training_args.do_train
        else None
    )
    snake_case						=   (
        SquadDataset(
            A__					,						tokenizer=A__					,						mode="dev"					,						is_language_sensitive=A__					,						cache_dir=model_args.cache_dir					,						)
        if training_args.do_eval
        else None
    )

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

    # Initialize our Trainer
    snake_case						=   Trainer(
        model=A__					,						args=A__					,						train_dataset=A__					,						eval_dataset=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						)



def 		lowercase_     (  A__						)				->				Optional[Any]:
    """simple docstring"""

    main()


if __name__ == "__main__":
   main()

