
"""simple docstring"""
import argparse
import logging
import os
from pathlib import Path
from typing import Any, Dict

import pytorch_lightning as pl
from pytorch_lightning.utilities import rank_zero_info

from transformers import (
    AdamW,
    AutoConfig,
    AutoModel,
    AutoModelForPreTraining,
    AutoModelForQuestionAnswering,
    AutoModelForSeqaSeqLM,
    AutoModelForSequenceClassification,
    AutoModelForTokenClassification,
    AutoModelWithLMHead,
    AutoTokenizer,
    PretrainedConfig,
    PreTrainedTokenizer,
)
from transformers.optimization import (
    Adafactor,
    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.utils.versions import require_version


_a   :      Dict       =				logging.getLogger(__name__)

require_version("""pytorch_lightning>=1.0.4""")

_a   :      Dict       =				{
    """base""": AutoModel,
    """sequence-classification""": AutoModelForSequenceClassification,
    """question-answering""": AutoModelForQuestionAnswering,
    """pretraining""": AutoModelForPreTraining,
    """token-classification""": AutoModelForTokenClassification,
    """language-modeling""": AutoModelWithLMHead,
    """summarization""": AutoModelForSeqaSeqLM,
    """translation""": AutoModelForSeqaSeqLM,
}


# update this and the import above to support new schedulers from transformers.optimization
_a   :      List[str]       =				{
    """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,
    # '': get_constant_schedule,             # not supported for now
    # '': get_constant_schedule_with_warmup, # not supported for now
}
_a   :      Optional[int]       =				sorted(arg_to_scheduler.keys())
_a   :      Tuple       =				"""{""" + """, """.join(arg_to_scheduler_choices) + """}"""






class   _UpperCAmelCase					(       pl.LightningModule):
    def __init__(     self    ,     snake_case_    ,     snake_case_=None    ,     snake_case_="base"    ,     snake_case_=None    ,     snake_case_=None    ,     snake_case_=None    ,     **snake_case_    ,     ):
      super().__init__()
      # TODO: move to self.save_hyperparameters()
      # self.save_hyperparameters()
      # can also expand arguments into trainer signature for easier reading

      self.save_hyperparameters(snake_case_  )
      _snake_case  :    str            = 0
      _snake_case  :    Tuple            = Path(self.hparams.output_dir  )
      _snake_case  :    Optional[int]            = self.hparams.cache_dir if self.hparams.cache_dir else None
      if config is None:
        _snake_case  :    List[str]            = AutoConfig.from_pretrained(
            self.hparams.config_name if self.hparams.config_name else self.hparams.model_name_or_path    ,     **({"num_labels": num_labels} if num_labels is not None else {})    ,     cache_dir=snake_case_    ,     **snake_case_    ,     )
      else:
        _snake_case  :    PretrainedConfig            = config

      _snake_case  :    List[Any]            = ("encoder_layerdrop", "decoder_layerdrop", "dropout", "attention_dropout")
      for p in extra_model_params:
        if getattr(self.hparams    ,     snake_case_    ,     snake_case_  ):
          assert hasattr(self.config    ,     snake_case_  ), F'model config doesn\'t have a `{p}` attribute'
          setattr(self.config    ,     snake_case_    ,     getattr(self.hparams    ,     snake_case_  )  )

      if tokenizer is None:
        _snake_case  :    Tuple            = AutoTokenizer.from_pretrained(
            self.hparams.tokenizer_name if self.hparams.tokenizer_name else self.hparams.model_name_or_path    ,     cache_dir=snake_case_    ,     )
      else:
        _snake_case  :    PreTrainedTokenizer            = tokenizer
      _snake_case  :    List[Any]            = MODEL_MODES[mode]
      if model is None:
        _snake_case  :    int            = self.model_type.from_pretrained(
            self.hparams.model_name_or_path    ,     from_tf=bool(".ckpt" in self.hparams.model_name_or_path  )    ,     config=self.config    ,     cache_dir=snake_case_    ,     )
      else:
        _snake_case  :    Optional[int]            = model
    def        lowerCamelCase__						(     self    ,     *snake_case_    ,     **snake_case_  ):
      _snake_case  :    List[Any]            = self.model_type.from_pretrained(*snake_case_    ,     **snake_case_  )
    def        lowerCamelCase__						(     self  ):
      _snake_case  :    Union[str, Any]            = arg_to_scheduler[self.hparams.lr_scheduler]
      _snake_case  :    Union[str, Any]            = get_schedule_func(
          self.opt    ,     num_warmup_steps=self.hparams.warmup_steps    ,     num_training_steps=self.total_steps()  )
      _snake_case  :    Union[str, Any]            = {"scheduler": scheduler, "interval": "step", "frequency": 1}
      return scheduler
    def        lowerCamelCase__						(     self  ):
      _snake_case  :    List[Any]            = self.model
      _snake_case  :    List[Any]            = ["bias", "LayerNorm.weight"]
      _snake_case  :    Optional[Any]            = [
          {
              "params": [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay  )],
              "weight_decay": self.hparams.weight_decay,
          },
          {
              "params": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay  )],
              "weight_decay": 0.0,
          },
      ]
      if self.hparams.adafactor:
        _snake_case  :    int            = Adafactor(
            snake_case_    ,     lr=self.hparams.learning_rate    ,     scale_parameter=snake_case_    ,     relative_step=snake_case_  )

      else:
        _snake_case  :    Tuple            = AdamW(
            snake_case_    ,     lr=self.hparams.learning_rate    ,     eps=self.hparams.adam_epsilon  )
      _snake_case  :    Any            = optimizer

      _snake_case  :    List[str]            = self.get_lr_scheduler()

      return [optimizer], [scheduler]
    def        lowerCamelCase__						(     self    ,     snake_case_    ,     snake_case_  ):
      return self.validation_step(snake_case_    ,     snake_case_  )
    def        lowerCamelCase__						(     self    ,     snake_case_  ):
      return self.validation_end(snake_case_  )
    def        lowerCamelCase__						(     self  ):
      _snake_case  :    str            = max(1    ,     self.hparams.gpus  )  # TODO: consider num_tpu_cores
      _snake_case  :    List[str]            = self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices
      return (self.dataset_size / effective_batch_size) * self.hparams.max_epochs
    def        lowerCamelCase__						(     self    ,     snake_case_  ):
      if stage == "test":
        _snake_case  :    int            = len(self.test_dataloader().dataset  )
      else:
        _snake_case  :    Tuple            = self.get_dataloader("train"    ,     self.hparams.train_batch_size    ,     shuffle=snake_case_  )
        _snake_case  :    Union[str, Any]            = len(self.train_dataloader().dataset  )
    def        lowerCamelCase__						(     self    ,     snake_case_    ,     snake_case_    ,     snake_case_ = False  ):
      raise NotImplementedError("You must implement this for your task"  )
    def        lowerCamelCase__						(     self  ):
      return self.train_loader
    def        lowerCamelCase__						(     self  ):
      return self.get_dataloader("dev"    ,     self.hparams.eval_batch_size    ,     shuffle=snake_case_  )
    def        lowerCamelCase__						(     self  ):
      return self.get_dataloader("test"    ,     self.hparams.eval_batch_size    ,     shuffle=snake_case_  )
    def        lowerCamelCase__						(     self    ,     snake_case_  ):
      return os.path.join(
          self.hparams.data_dir    ,     "cached_{}_{}_{}".format(
              snake_case_    ,     list(filter(snake_case_    ,     self.hparams.model_name_or_path.split("/"  )  )  ).pop()    ,     str(self.hparams.max_seq_length  )    ,     )    ,     )
    @pl.utilities.rank_zero_only
    def        lowerCamelCase__						(     self    ,     snake_case_  ):
      _snake_case  :    Optional[Any]            = self.output_dir.joinpath("best_tfmr"  )
      _snake_case  :    int            = self.step_count
      self.model.save_pretrained(snake_case_  )
      self.tokenizer.save_pretrained(snake_case_  )


    @staticmethod
    def        lowerCamelCase__						(     snake_case_    ,     snake_case_  ):
      parser.add_argument(
          "--model_name_or_path"    ,     default=snake_case_    ,     type=snake_case_    ,     required=snake_case_    ,     help="Path to pretrained model or model identifier from huggingface.co/models"    ,     )
      parser.add_argument(
          "--config_name"    ,     default=""    ,     type=snake_case_    ,     help="Pretrained config name or path if not the same as model_name"  )
      parser.add_argument(
          "--tokenizer_name"    ,     default=snake_case_    ,     type=snake_case_    ,     help="Pretrained tokenizer name or path if not the same as model_name"    ,     )
      parser.add_argument(
          "--cache_dir"    ,     default=""    ,     type=snake_case_    ,     help="Where do you want to store the pre-trained models downloaded from huggingface.co"    ,     )
      parser.add_argument(
          "--encoder_layerdrop"    ,     type=snake_case_    ,     help="Encoder layer dropout probability (Optional). Goes into model.config"    ,     )
      parser.add_argument(
          "--decoder_layerdrop"    ,     type=snake_case_    ,     help="Decoder layer dropout probability (Optional). Goes into model.config"    ,     )
      parser.add_argument(
          "--dropout"    ,     type=snake_case_    ,     help="Dropout probability (Optional). Goes into model.config"    ,     )
      parser.add_argument(
          "--attention_dropout"    ,     type=snake_case_    ,     help="Attention dropout probability (Optional). Goes into model.config"    ,     )
      parser.add_argument("--learning_rate"    ,     default=5E-5    ,     type=snake_case_    ,     help="The initial learning rate for Adam."  )
      parser.add_argument(
          "--lr_scheduler"    ,     default="linear"    ,     choices=snake_case_    ,     metavar=snake_case_    ,     type=snake_case_    ,     help="Learning rate scheduler"    ,     )
      parser.add_argument("--weight_decay"    ,     default=0.0    ,     type=snake_case_    ,     help="Weight decay if we apply some."  )
      parser.add_argument("--adam_epsilon"    ,     default=1E-8    ,     type=snake_case_    ,     help="Epsilon for Adam optimizer."  )
      parser.add_argument("--warmup_steps"    ,     default=0    ,     type=snake_case_    ,     help="Linear warmup over warmup_steps."  )
      parser.add_argument("--num_workers"    ,     default=4    ,     type=snake_case_    ,     help="kwarg passed to DataLoader"  )
      parser.add_argument("--num_train_epochs"    ,     dest="max_epochs"    ,     default=3    ,     type=snake_case_  )
      parser.add_argument("--train_batch_size"    ,     default=32    ,     type=snake_case_  )
      parser.add_argument("--eval_batch_size"    ,     default=32    ,     type=snake_case_  )
      parser.add_argument("--adafactor"    ,     action="store_true"  )






class   _UpperCAmelCase					(       pl.Callback):
    def        lowerCamelCase__						(     self    ,     snake_case_    ,     snake_case_  ):
      if (
          trainer.is_global_zero and trainer.global_rank == 0
      ):  # we initialize the retriever only on master worker with RAY. In new pytorch-lightning accelorators are removed.
        pl_module.model.rag.retriever.init_retrieval()  # better to use hook functions.






class   _UpperCAmelCase					(       pl.Callback):
    def        lowerCamelCase__						(     self    ,     snake_case_    ,     snake_case_  ):
      _snake_case  :    Optional[int]            = trainer.lr_schedulers[0]["scheduler"]
      _snake_case  :    int            = {F'lr_group_{i}': lr for i, lr in enumerate(lr_scheduler.get_lr()  )}
      pl_module.logger.log_metrics(snake_case_  )
    def        lowerCamelCase__						(     self    ,     snake_case_    ,     snake_case_  ):
      rank_zero_info("***** Validation results *****"  )
      _snake_case  :    Union[str, Any]            = trainer.callback_metrics
      # Log results
      for key in sorted(snake_case_  ):
        if key not in ["log", "progress_bar"]:
          rank_zero_info("{} = {}\n".format(snake_case_    ,     str(metrics[key]  )  )  )


    def        lowerCamelCase__						(     self    ,     snake_case_    ,     snake_case_  ):
      rank_zero_info("***** Test results *****"  )
      _snake_case  :    List[Any]            = trainer.callback_metrics
      # Log and save results to file
      _snake_case  :    Optional[int]            = os.path.join(pl_module.hparams.output_dir    ,     "test_results.txt"  )
      with open(snake_case_    ,     "w"  ) as writer:
        for key in sorted(snake_case_  ):
          if key not in ["log", "progress_bar"]:
            rank_zero_info("{} = {}\n".format(snake_case_    ,     str(metrics[key]  )  )  )
            writer.write("{} = {}\n".format(snake_case_    ,     str(metrics[key]  )  )  )


def 					a__ ( a :					Optional[Any]							,  a :					Tuple		):

  """simple docstring"""







  parser.add_argument(
      "--output_dir"							,  default=a							,  type=a							,  required=a							,  help="The output directory where the model predictions and checkpoints will be written."							,  )
  parser.add_argument(
      "--fp16"							,  action="store_true"							,  help="Whether to use 16-bit (mixed) precision (through NVIDIA apex) instead of 32-bit"							,  )

  parser.add_argument(
      "--fp16_opt_level"							,  type=a							,  default="O2"							,  help=(
          "For fp16: Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']."
          "See details at https://nvidia.github.io/apex/amp.html"
      )							,  )
  parser.add_argument("--n_tpu_cores"							,  dest="tpu_cores"							,  type=a		)
  parser.add_argument("--max_grad_norm"							,  dest="gradient_clip_val"							,  default=1.0							,  type=a							,  help="Max gradient norm"		)
  parser.add_argument("--do_train"							,  action="store_true"							,  help="Whether to run training."		)
  parser.add_argument("--do_predict"							,  action="store_true"							,  help="Whether to run predictions on the test set."		)
  parser.add_argument(
      "--gradient_accumulation_steps"							,  dest="accumulate_grad_batches"							,  type=a							,  default=1							,  help="Number of updates steps to accumulate before performing a backward/update pass."							,  )
  parser.add_argument("--seed"							,  type=a							,  default=42							,  help="random seed for initialization"		)
  parser.add_argument(
      "--data_dir"							,  default=a							,  type=a							,  required=a							,  help="The input data dir. Should contain the training files for the CoNLL-2003 NER task."							,  )



def 					a__ ( a :					BaseTransformer							,  a :					argparse.Namespace							,  a :					str=None							,  a :					Tuple=True							,  a :					Optional[Any]=None							,  a :					Dict=[]							,  a :					str=None							,  a :					int=None							,  **a :					Optional[int]							,  ):

  """simple docstring"""







  pl.seed_everything(args.seed		)

  # init model
  _snake_case  :    str            = Path(model.hparams.output_dir		)
  odir.mkdir(exist_ok=a		)

  # add custom checkpoints
  if checkpoint_callback is None:
    _snake_case  :    str            = pl.callbacks.ModelCheckpoint(
        filepath=args.output_dir							,  prefix="checkpoint"							,  monitor="val_loss"							,  mode="min"							,  save_top_k=1		)
  if early_stopping_callback:
    extra_callbacks.append(a		)
  if logging_callback is None:
    _snake_case  :    Optional[int]            = LoggingCallback()

  _snake_case  :    List[Any]            = {}

  # TODO: remove with PyTorch 1.6 since pl uses native amp
  if args.fpaa:
    _snake_case  :    Union[str, Any]            = 16
    # train_params["amp_level"] = args.fp16_opt_level

  if args.gpus > 1:
    _snake_case  :    Dict            = "auto"  # "ddp"
    _snake_case  :    str            = "ddp"

  _snake_case  :    Optional[int]            = args.accumulate_grad_batches
  _snake_case  :    Tuple            = None  # extra_train_kwargs.get("profiler", None) #get unwanted logs
  _snake_case  :    Union[str, Any]            = "auto"

  _snake_case  :    Dict            = pl.Trainer.from_argparse_args(
      a							,  weights_summary=a							,  callbacks=[logging_callback] + extra_callbacks + [checkpoint_callback] + [InitCallback()]							,  logger=a							,  **a							,  )

  if args.do_train:
    trainer.fit(a		)

  return trainer


import json
import os
import tempfile
import unittest

from transformers.modelcard import ModelCard






class     __UpperCAmelCase(    unittest.TestCase				):






 """simple docstring"""




 def  UpperCAmelCase   (    self      ):

        """simple docstring"""

        A_							:       Optional[int]	      =				{
            '''model_details''': {
                '''Organization''': '''testing''',
                '''Model date''': '''today''',
                '''Model version''': '''v2.1, Developed by Test Corp in 2019.''',
                '''Architecture''': '''Convolutional Neural Network.''',
            },
            '''metrics''': '''BLEU and ROUGE-1''',
            '''evaluation_data''': {
                '''Datasets''': {'''BLEU''': '''My-great-dataset-v1''', '''ROUGE-1''': '''My-short-dataset-v2.1'''},
                '''Preprocessing''': '''See details on https://arxiv.org/pdf/1810.03993.pdf''',
            },
            '''training_data''': {
                '''Dataset''': '''English Wikipedia dump dated 2018-12-01''',
                '''Preprocessing''': (
                    '''Using SentencePiece vocabulary of size 52k tokens. See details on'''
                    ''' https://arxiv.org/pdf/1810.03993.pdf'''
                ),
            },
            '''quantitative_analyses''': {'''BLEU''': 55.1, '''ROUGE-1''': 76},
        }
 def  UpperCAmelCase   (    self      ):

        """simple docstring"""

        A_							:       Tuple	      =				ModelCard.from_dict(self.inputs_dict      )
        self.assertTrue(hasattr(__magic_name__ ,       '''model_details'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''intended_use'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''factors'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''metrics'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''evaluation_data'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''training_data'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''quantitative_analyses'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''ethical_considerations'''      )      )
        self.assertTrue(hasattr(__magic_name__ ,       '''caveats_and_recommendations'''      )      )
 def  UpperCAmelCase   (    self      ):

        """simple docstring"""

        A_							:       Optional[Any]	      =				ModelCard.from_dict(self.inputs_dict      )
        A_							:       List[Any]	      =				json.loads(modelcard.to_json_string()      )
        for key, value in self.inputs_dict.items():
               self.assertEqual(obj[key] ,       __magic_name__      )
 def  UpperCAmelCase   (    self      ):

        """simple docstring"""

        A_							:       Dict	      =				ModelCard.from_dict(self.inputs_dict      )

        with tempfile.TemporaryDirectory() as tmpdirname:
               A_							:       str	      =				os.path.join(__magic_name__ ,       '''modelcard.json'''      )
               model_card_first.to_json_file(__magic_name__      )
               A_							:       str	      =				ModelCard.from_json_file(__magic_name__      )

        self.assertEqual(model_card_second.to_dict() ,       model_card_first.to_dict()      )
 def  UpperCAmelCase   (    self      ):

        """simple docstring"""

        A_							:       List[str]	      =				ModelCard.from_dict(self.inputs_dict      )

        with tempfile.TemporaryDirectory() as tmpdirname:
               model_card_first.save_pretrained(__magic_name__      )
               A_							:       Optional[int]	      =				ModelCard.from_pretrained(__magic_name__      )

        self.assertEqual(model_card_second.to_dict() ,       model_card_first.to_dict()      )


