import logging
import os
from dataclasses import dataclass
from typing import List, Optional, Union

import tqdm
from filelock import FileLock

from transformers import (
    BartTokenizer,
    BartTokenizerFast,
    DataProcessor,
    PreTrainedTokenizer,
    RobertaTokenizer,
    RobertaTokenizerFast,
    XLMRobertaTokenizer,
    is_tf_available,
    is_torch_available,
)


lowerCAmelCase__     						=			logging.getLogger(__name__)
@dataclass(frozen=lowerCamelCase__						)
class     a_			:






 '''simple docstring'''






 UpperCAmelCase_     			= 42
 UpperCAmelCase_     			= 42
 UpperCAmelCase_     			= None
 UpperCAmelCase_     			= None
 UpperCAmelCase_     			= None






@dataclass(frozen=lowerCamelCase__						)
class     a_			:






 '''simple docstring'''






 UpperCAmelCase_     			= 42
 UpperCAmelCase_     			= None
 UpperCAmelCase_     			= None
 UpperCAmelCase_     			= None
 UpperCAmelCase_     			= None


if is_torch_available():
    import torch
    from torch.utils.data import Dataset
    class     a_			(						lowerCamelCase__						):






     '''simple docstring'''






     UpperCAmelCase_     			= 42




     def __init__(      self :  Dict      ,   lowercase__ :  str      ,   lowercase__ :  PreTrainedTokenizer      ,   lowercase__ :  str      ,   lowercase__ :  Optional[int] = None      ,   lowercase__ :  Any=False      ,   lowercase__ :  bool = False      ,   ):







            '''simple docstring'''



            lowerCAmelCase__					     = hans_processors[task]()

            lowerCAmelCase__					     = os.path.join(
                lowercase__      ,   'cached_{}_{}_{}_{}'.format(
                    'dev' if evaluate else 'train'      ,   tokenizer.__class__.__name__      ,   str(lowercase__)      ,   lowercase__      ,   )      ,   )
            lowerCAmelCase__					     = processor.get_labels()
            if tokenizer.__class__ in (
                RobertaTokenizer,
                RobertaTokenizerFast,
                XLMRobertaTokenizer,
                BartTokenizer,
                BartTokenizerFast,
            ):
                   # HACK(label indices are swapped in RoBERTa pretrained model)
                   lowerCAmelCase__					     = label_list[2], label_list[1]
            lowerCAmelCase__					     = label_list

            # Make sure only the first process in distributed training processes the dataset,
            # and the others will use the cache.
            lowerCAmelCase__					     = cached_features_file + ".lock"
            with FileLock(lowercase__):
                   if os.path.exists(lowercase__) and not overwrite_cache:
                          logger.info(F"""Loading features from cached file {cached_features_file}""")
                          lowerCAmelCase__					     = torch.load(lowercase__)
                   else:
                          logger.info(F"""Creating features from dataset file at {data_dir}""")

                          lowerCAmelCase__					     = (
                              processor.get_dev_examples(lowercase__) if evaluate else processor.get_train_examples(lowercase__)
                          )

                          logger.info('Training examples: %s'      ,   len(lowercase__))
                          lowerCAmelCase__					     = hans_convert_examples_to_features(lowercase__      ,   lowercase__      ,   lowercase__      ,   lowercase__)
                          logger.info('Saving features into cached file %s'      ,   lowercase__)
                          torch.save(self.features      ,   lowercase__)




     def __len__(      self :  str):







            '''simple docstring'''



            return len(self.features)




     def __getitem__(      self :  List[str]      ,   lowercase__ :  Optional[Any]):







            '''simple docstring'''



            return self.features[i]




     def 		__snake_case						(      self :  Optional[int]):







            '''simple docstring'''



            return self.label_list


if is_tf_available():
    import tensorflow as tf
    class     a_			:






     '''simple docstring'''






     UpperCAmelCase_     			= 42




     def __init__(      self :  int      ,   lowercase__ :  str      ,   lowercase__ :  PreTrainedTokenizer      ,   lowercase__ :  str      ,   lowercase__ :  Optional[int] = 128      ,   lowercase__ :  Dict=False      ,   lowercase__ :  bool = False      ,   ):







            '''simple docstring'''



            lowerCAmelCase__					     = hans_processors[task]()
            lowerCAmelCase__					     = processor.get_labels()
            if tokenizer.__class__ in (
                RobertaTokenizer,
                RobertaTokenizerFast,
                XLMRobertaTokenizer,
                BartTokenizer,
                BartTokenizerFast,
            ):
                   # HACK(label indices are swapped in RoBERTa pretrained model)
                   lowerCAmelCase__					     = label_list[2], label_list[1]
            lowerCAmelCase__					     = label_list

            lowerCAmelCase__					     = processor.get_dev_examples(lowercase__) if evaluate else processor.get_train_examples(lowercase__)
            lowerCAmelCase__					     = hans_convert_examples_to_features(lowercase__      ,   lowercase__      ,   lowercase__      ,   lowercase__)

            def gen():
                   for ex_index, ex in tqdm.tqdm(enumerate(self.features)      ,   desc='convert examples to features'):
                          if ex_index % 10_000 == 0:
                                 logger.info('Writing example %d of %d' % (ex_index, len(lowercase__)))

                          yield (
                              {
                                  "example_id": 0,
                                  "input_ids": ex.input_ids,
                                  "attention_mask": ex.attention_mask,
                                  "token_type_ids": ex.token_type_ids,
                              },
                              ex.label,
                          )

            lowerCAmelCase__					     = tf.data.Dataset.from_generator(
                lowercase__      ,   (
                    {
                        'example_id': tf.intaa,
                        'input_ids': tf.intaa,
                        'attention_mask': tf.intaa,
                        'token_type_ids': tf.intaa,
                    },
                    tf.intaa,
                )      ,   (
                    {
                        'example_id': tf.TensorShape([]),
                        'input_ids': tf.TensorShape([None, None]),
                        'attention_mask': tf.TensorShape([None, None]),
                        'token_type_ids': tf.TensorShape([None, None]),
                    },
                    tf.TensorShape([]),
                )      ,   )




     def 		__snake_case						(      self :  Optional[Any]):







            '''simple docstring'''



            return self.dataset




     def __len__(      self :  int):







            '''simple docstring'''



            return len(self.features)




     def __getitem__(      self :  Optional[Any]      ,   lowercase__ :  List[Any]):







            '''simple docstring'''



            return self.features[i]




     def 		__snake_case						(      self :  Any):







            '''simple docstring'''



            return self.label_list
class     a_			(						lowerCamelCase__						):






 '''simple docstring'''






 def 		__snake_case						(      self :  Any      ,   lowercase__ :  Dict):







        '''simple docstring'''



        return self._create_examples(self._read_tsv(os.path.join(lowercase__      ,   'heuristics_train_set.txt'))      ,   'train')




 def 		__snake_case						(      self :  Union[str, Any]      ,   lowercase__ :  Union[str, Any]):







        '''simple docstring'''



        return self._create_examples(self._read_tsv(os.path.join(lowercase__      ,   'heuristics_evaluation_set.txt'))      ,   'dev')




 def 		__snake_case						(      self :  Union[str, Any]):







        '''simple docstring'''



        return ["contradiction", "entailment", "neutral"]




 def 		__snake_case						(      self :  Optional[int]      ,   lowercase__ :  Union[str, Any]      ,   lowercase__ :  Union[str, Any]):







        '''simple docstring'''



        lowerCAmelCase__					     = []
        for i, line in enumerate(lowercase__):
               if i == 0:
                      continue
               lowerCAmelCase__					     = "%s-%s" % (set_type, line[0])
               lowerCAmelCase__					     = line[5]
               lowerCAmelCase__					     = line[6]
               lowerCAmelCase__					     = line[7][2:] if line[7].startswith('ex') else line[7]
               lowerCAmelCase__					     = line[0]
               examples.append(InputExample(guid=lowercase__      ,   text_a=lowercase__      ,   text_b=lowercase__      ,   label=lowercase__      ,   pairID=lowercase__))
        return examples






def 				__lowerCamelCase		(						lowerCAmelCase__     ,  lowerCAmelCase__     ,  lowerCAmelCase__     ,  lowerCAmelCase__     ,  ):
       lowerCAmelCase__					     = {label: i for i, label in enumerate(_lowerCAmelCase     )}

       lowerCAmelCase__					     = []
       for ex_index, example in tqdm.tqdm(enumerate(_lowerCAmelCase     )     ,  desc='convert examples to features'     ):
              if ex_index % 1_0_0_0_0 == 0:
                     logger.info('Writing example %d' % (ex_index)     )

              lowerCAmelCase__					     = tokenizer(
                  example.text_a     ,  example.text_b     ,  add_special_tokens=_lowerCAmelCase     ,  max_length=_lowerCAmelCase     ,  padding='max_length'     ,  truncation=_lowerCAmelCase     ,  return_overflowing_tokens=_lowerCAmelCase     ,  )

              lowerCAmelCase__					     = label_map[example.label] if example.label in label_map else 0

              lowerCAmelCase__					     = int(example.pairID     )

              features.append(InputFeatures(**_lowerCAmelCase     ,  label=_lowerCAmelCase     ,  pairID=_lowerCAmelCase     )     )

       for i, example in enumerate(examples[:5]     ):
              logger.info('*** Example ***'     )
              logger.info(F"""guid: {example}"""     )
              logger.info(F"""features: {features[i]}"""     )

       return features


lowerCAmelCase__     						=			{
    '''hans''': 3,
}



lowerCAmelCase__     						=			{
    '''hans''': HansProcessor,
}


import logging
import os

import quant_trainer
import torch
from torch.utils.data import DataLoader

from transformers import Trainer, is_torch_tpu_available
from transformers.trainer_utils import PredictionOutput


lowerCAmelCase__     						=			logging.getLogger(__name__)

if is_torch_tpu_available(check_device=False):
    import torch_xla.core.xla_model as xm
    import torch_xla.debug.metrics as met
class     a_			(						SCREAMING_SNAKE_CASE						):






 '''simple docstring'''






 def __init__(      self :  int      ,   *lowercase__ :  Dict      ,   lowercase__ :  List[Any]=None      ,   lowercase__ :  Optional[Any]=None      ,   lowercase__ :  Dict=None      ,   **lowercase__ :  Optional[int]):







        '''simple docstring'''



        super().__init__(*lowercase__      ,   **lowercase__)
        lowerCAmelCase__					     = eval_examples
        lowerCAmelCase__					     = post_process_function
        lowerCAmelCase__					     = quant_trainer_args
        lowerCAmelCase__					     = 128  # default number of calibration samples




 def 		__snake_case						(      self :  Tuple      ,   lowercase__ :  Any=None):







        '''simple docstring'''



        if calib_dataset is None and self.calib_dataset is None:
               raise ValueError('Trainer: calibration requires an calib_dataset.')
        lowerCAmelCase__					     = calib_dataset if calib_dataset is not None else self.calib_dataset

        lowerCAmelCase__					     = self._remove_unused_columns(lowercase__      ,   description='Calibration')

        return DataLoader(
            lowercase__      ,   batch_size=self.args.eval_batch_size      ,   collate_fn=self.data_collator      ,   drop_last=self.args.dataloader_drop_last      ,   num_workers=self.args.dataloader_num_workers      ,   pin_memory=self.args.dataloader_pin_memory      ,   shuffle=lowercase__      ,   )




 def 		__snake_case						(      self :  List[Any]      ,   lowercase__ :  Union[str, Any]=None):







        '''simple docstring'''



        lowerCAmelCase__					     = self.train_dataset if calib_dataset is None else calib_dataset
        lowerCAmelCase__					     = self.get_calib_dataloader(lowercase__)

        lowerCAmelCase__					     = self.model
        quant_trainer.configure_model(lowercase__      ,   self.quant_trainer_args      ,   calib=lowercase__)
        model.eval()
        quant_trainer.enable_calibration(lowercase__)

        logger.info('***** Running calibration *****')
        logger.info(F"""  Num examples = {self.calib_num}""")
        logger.info(F"""  Batch size = {calib_dataloader.batch_size}""")

        for step, inputs in enumerate(lowercase__):
               # Prediction step
               lowerCAmelCase__     , lowerCAmelCase__     , lowerCAmelCase__					     = self.prediction_step(lowercase__      ,   lowercase__      ,   prediction_loss_only=lowercase__)
               if (step + 1) * calib_dataloader.batch_size >= self.calib_num:
                      break

        quant_trainer.finish_calibration(lowercase__      ,   self.quant_trainer_args)
        lowerCAmelCase__					     = model




 def 		__snake_case						(      self :  Optional[Any]      ,   lowercase__ :  List[Any]=None      ,   lowercase__ :  Optional[Any]=None      ,   lowercase__ :  List[Any]=None      ,   lowercase__ :  str = "eval"):







        '''simple docstring'''



        lowerCAmelCase__					     = self.eval_dataset if eval_dataset is None else eval_dataset
        lowerCAmelCase__					     = self.get_eval_dataloader(lowercase__)
        lowerCAmelCase__					     = self.eval_examples if eval_examples is None else eval_examples

        # Temporarily disable metric computation, we will do it in the loop here.
        lowerCAmelCase__					     = self.compute_metrics
        lowerCAmelCase__					     = None
        lowerCAmelCase__					     = self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
        try:
               lowerCAmelCase__					     = eval_loop(
                   lowercase__      ,   description='Evaluation'      ,   prediction_loss_only=True if compute_metrics is None else None      ,   ignore_keys=lowercase__      ,   )
        finally:
               lowerCAmelCase__					     = compute_metrics

        if self.post_process_function is not None and self.compute_metrics is not None:
               lowerCAmelCase__					     = self.post_process_function(lowercase__      ,   lowercase__      ,   output.predictions)
               lowerCAmelCase__					     = self.compute_metrics(lowercase__)

               # Prefix all keys with metric_key_prefix + '_'
               for key in list(metrics.keys()):
                      if not key.startswith(F"""{metric_key_prefix}_"""):
                             lowerCAmelCase__					     = metrics.pop(lowercase__)

               self.log(lowercase__)
        else:
               lowerCAmelCase__					     = {}

        if self.args.tpu_metrics_debug or self.args.debug:
               # tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.)
               xm.master_print(met.metrics_report())

        lowerCAmelCase__					     = self.callback_handler.on_evaluate(self.args      ,   self.state      ,   self.control      ,   lowercase__)
        return metrics




 def 		__snake_case						(      self :  Optional[int]      ,   lowercase__ :  str      ,   lowercase__ :  Any      ,   lowercase__ :  List[str]=None      ,   lowercase__ :  str = "test"):







        '''simple docstring'''



        lowerCAmelCase__					     = self.get_test_dataloader(lowercase__)

        # Temporarily disable metric computation, we will do it in the loop here.
        lowerCAmelCase__					     = self.compute_metrics
        lowerCAmelCase__					     = None
        lowerCAmelCase__					     = self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
        try:
               lowerCAmelCase__					     = eval_loop(
                   lowercase__      ,   description='Prediction'      ,   prediction_loss_only=True if compute_metrics is None else None      ,   ignore_keys=lowercase__      ,   )
        finally:
               lowerCAmelCase__					     = compute_metrics

        if self.post_process_function is None or self.compute_metrics is None:
               return output

        lowerCAmelCase__					     = self.post_process_function(lowercase__      ,   lowercase__      ,   output.predictions      ,   'predict')
        lowerCAmelCase__					     = self.compute_metrics(lowercase__)

        # Prefix all keys with metric_key_prefix + '_'
        for key in list(metrics.keys()):
               if not key.startswith(F"""{metric_key_prefix}_"""):
                      lowerCAmelCase__					     = metrics.pop(lowercase__)

        return PredictionOutput(predictions=predictions.predictions      ,   label_ids=predictions.label_ids      ,   metrics=lowercase__)




 def 		__snake_case						(      self :  List[str]      ,   lowercase__ :  List[str]="./"):







        '''simple docstring'''



        lowerCAmelCase__					     = self.eval_dataset
        lowerCAmelCase__					     = self.get_eval_dataloader(lowercase__)

        lowerCAmelCase__					     = next(iter(lowercase__))

        # saving device - to make it consistent
        lowerCAmelCase__					     = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

        # convert to tuple
        lowerCAmelCase__					     = tuple(v.to(lowercase__) for k, v in batch.items())

        logger.info('Converting model to be onnx compatible')
        from pytorch_quantization.nn import TensorQuantizer

        lowerCAmelCase__					     = True

        lowerCAmelCase__					     = self.model.to(lowercase__)

        model.eval()
        model.float()

        lowerCAmelCase__					     = model.module if hasattr(lowercase__      ,   'module') else model
        quant_trainer.configure_model(lowercase__      ,   self.quant_trainer_args)

        lowerCAmelCase__					     = os.path.join(lowercase__      ,   'model.onnx')
        logger.info(F"""exporting model to {output_model_file}""")

        lowerCAmelCase__					     = {0: 'batch_size', 1: 'seq_len'}

        torch.onnx.export(
            lowercase__      ,   lowercase__      ,   lowercase__      ,   export_params=lowercase__      ,   opset_version=13      ,   do_constant_folding=lowercase__      ,   input_names=['input_ids', 'attention_mask', 'token_type_ids']      ,   output_names=['output_start_logits', 'output_end_logits']      ,   dynamic_axes={
                'input_ids': axes,
                'attention_mask': axes,
                'token_type_ids': axes,
                'output_start_logits': axes,
                'output_end_logits': axes,
            }      ,   verbose=lowercase__      ,   )
        logger.info('onnx export finished')
