
'''simple docstring'''



import numpy as np
import torch
from torch.utils.data import Dataset

from utils import logger

class    _a				(_lowerCamelCase):





       """simple docstring"""




       def __init__(							self       ,							A__       ,							A__      )    ->			Any:
          _SCREAMING_SNAKE_CASE      =				params

          _SCREAMING_SNAKE_CASE      =				np.array(A__      )
          _SCREAMING_SNAKE_CASE      =				np.array([len(A__      ) for t in data]      )

          self.check()
          self.remove_long_sequences()
          self.remove_empty_sequences()
          self.remove_unknown_sequences()
          self.check()
          self.print_statistics()






       def __getitem__(							self       ,							A__      )    ->			Dict:
          return (self.token_ids[index], self.lengths[index])






       def __len__(							self      )    ->			Tuple:
          return len(self.lengths      )






       def        UpperCamelCase				(							self      )    ->			Dict:
          assert len(self.token_ids      ) == len(self.lengths      )
          assert all(self.lengths[i] == len(self.token_ids[i]      ) for i in range(len(self.lengths      )      )      )






       def        UpperCamelCase				(							self      )    ->			List[str]:
          _SCREAMING_SNAKE_CASE      =				self.params.max_model_input_size
          _SCREAMING_SNAKE_CASE      =				self.lengths > max_len
          logger.info(F"Splitting {sum(A__      )} too long sequences."      )

          def divide_chunks(A__       ,							A__      ):
             return [l[i : i + n] for i in range(0       ,							len(A__      )       ,							A__      )]

          _SCREAMING_SNAKE_CASE      =				[]
          _SCREAMING_SNAKE_CASE      =				[]
          if self.params.mlm:
             _SCREAMING_SNAKE_CASE ,							_SCREAMING_SNAKE_CASE      =				self.params.special_tok_ids["""cls_token"""], self.params.special_tok_ids["""sep_token"""]
          else:
             _SCREAMING_SNAKE_CASE ,							_SCREAMING_SNAKE_CASE      =				self.params.special_tok_ids["""bos_token"""], self.params.special_tok_ids["""eos_token"""]

          for seq_, len_ in zip(self.token_ids       ,							self.lengths      ):
             assert (seq_[0] == cls_id) and (seq_[-1] == sep_id), seq_
             if len_ <= max_len:
                new_tok_ids.append(seq_      )
                new_lengths.append(len_      )
             else:
                _SCREAMING_SNAKE_CASE      =				[]
                for sub_s in divide_chunks(seq_       ,							max_len - 2      ):
                   if sub_s[0] != cls_id:
                      _SCREAMING_SNAKE_CASE      =				np.insert(A__       ,							0       ,							A__      )
                   if sub_s[-1] != sep_id:
                      _SCREAMING_SNAKE_CASE      =				np.insert(A__       ,							len(A__      )       ,							A__      )
                   assert len(A__      ) <= max_len
                   assert (sub_s[0] == cls_id) and (sub_s[-1] == sep_id), sub_s
                   sub_seqs.append(A__      )

                new_tok_ids.extend(A__      )
                new_lengths.extend([len(A__      ) for l in sub_seqs]      )

          _SCREAMING_SNAKE_CASE      =				np.array(A__      )
          _SCREAMING_SNAKE_CASE      =				np.array(A__      )






       def        UpperCamelCase				(							self      )    ->			List[str]:
          _SCREAMING_SNAKE_CASE      =				len(self      )
          _SCREAMING_SNAKE_CASE      =				self.lengths > 11
          _SCREAMING_SNAKE_CASE      =				self.token_ids[indices]
          _SCREAMING_SNAKE_CASE      =				self.lengths[indices]
          _SCREAMING_SNAKE_CASE      =				len(self      )
          logger.info(F"Remove {init_size - new_size} too short (<=11 tokens) sequences."      )






       def        UpperCamelCase				(							self      )    ->			int:
          if "unk_token" not in self.params.special_tok_ids:
             return
          else:
             _SCREAMING_SNAKE_CASE      =				self.params.special_tok_ids["""unk_token"""]
          _SCREAMING_SNAKE_CASE      =				len(self      )
          _SCREAMING_SNAKE_CASE      =				np.array([np.count_nonzero(a == unk_token_id      ) for a in self.token_ids]      )
          _SCREAMING_SNAKE_CASE      =				(unk_occs / self.lengths) < 0.5
          _SCREAMING_SNAKE_CASE      =				self.token_ids[indices]
          _SCREAMING_SNAKE_CASE      =				self.lengths[indices]
          _SCREAMING_SNAKE_CASE      =				len(self      )
          logger.info(F"Remove {init_size - new_size} sequences with a high level of unknown tokens (50%)."      )






       def        UpperCamelCase				(							self      )    ->			Optional[Any]:
          if not self.params.is_master:
             return
          logger.info(F"{len(self      )} sequences"      )
          # data_len = sum(self.lengths)
          # nb_unique_tokens = len(Counter(list(chain(*self.token_ids))))
          # logger.info(f'{data_len} tokens ({nb_unique_tokens} unique)')

          # unk_idx = self.params.special_tok_ids['unk_token']
          # nb_unknown = sum([(t==unk_idx).sum() for t in self.token_ids])
          # logger.info(f'{nb_unknown} unknown tokens (covering {100*nb_unknown/data_len:.2f}% of the data)')






       def        UpperCamelCase				(							self       ,							A__      )    ->			Any:
          _SCREAMING_SNAKE_CASE      =				[t[0] for t in batch]
          _SCREAMING_SNAKE_CASE      =				[t[1] for t in batch]
          assert len(A__      ) == len(A__      )

          # Max for paddings
          _SCREAMING_SNAKE_CASE      =				max(A__      )

          # Pad token ids
          if self.params.mlm:
             _SCREAMING_SNAKE_CASE      =				self.params.special_tok_ids["""pad_token"""]
          else:
             _SCREAMING_SNAKE_CASE      =				self.params.special_tok_ids["""unk_token"""]
          _SCREAMING_SNAKE_CASE      =				[list(t.astype(A__      )      ) + [pad_idx] * (max_seq_len_ - len(A__      )) for t in token_ids]
          assert len(tk_      ) == len(A__      )
          assert all(len(A__      ) == max_seq_len_ for t in tk_      )

          _SCREAMING_SNAKE_CASE      =				torch.tensor(tk_      )  # (bs, max_seq_len_)
          _SCREAMING_SNAKE_CASE      =				torch.tensor(A__      )  # (bs)
          return tk_t, lg_t








'''simple docstring'''



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


UpperCamelCase__      :		Tuple       							=  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				(_lowerCamelCase):





       """simple docstring"""




       def __init__(							self       ,							*A__       ,							A__=None       ,							A__=None       ,							A__=None       ,							**A__      )    ->			Optional[int]:
          super().__init__(*A__       ,							**A__      )
          _SCREAMING_SNAKE_CASE      =				eval_examples
          _SCREAMING_SNAKE_CASE      =				post_process_function
          _SCREAMING_SNAKE_CASE      =				quant_trainer_args
          _SCREAMING_SNAKE_CASE      =				1_28  # default number of calibration samples






       def        UpperCamelCase				(							self       ,							A__=None      )    ->			Union[str, Any]:
          if calib_dataset is None and self.calib_dataset is None:
             raise ValueError("""Trainer: calibration requires an calib_dataset."""      )
          _SCREAMING_SNAKE_CASE      =				calib_dataset if calib_dataset is not None else self.calib_dataset

          _SCREAMING_SNAKE_CASE      =				self._remove_unused_columns(A__       ,							description="""Calibration"""      )

          return DataLoader(
              A__       ,							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=A__       ,							)






       def        UpperCamelCase				(							self       ,							A__=None      )    ->			str:
          _SCREAMING_SNAKE_CASE      =				self.train_dataset if calib_dataset is None else calib_dataset
          _SCREAMING_SNAKE_CASE      =				self.get_calib_dataloader(A__      )

          _SCREAMING_SNAKE_CASE      =				self.model
          quant_trainer.configure_model(A__       ,							self.quant_trainer_args       ,							calib=A__      )
          model.eval()
          quant_trainer.enable_calibration(A__      )

          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(A__      ):
             # Prediction step
             _SCREAMING_SNAKE_CASE ,							_SCREAMING_SNAKE_CASE ,							_SCREAMING_SNAKE_CASE      =				self.prediction_step(A__       ,							A__       ,							prediction_loss_only=A__      )
             if (step + 1) * calib_dataloader.batch_size >= self.calib_num:
                break

          quant_trainer.finish_calibration(A__       ,							self.quant_trainer_args      )
          _SCREAMING_SNAKE_CASE      =				model






       def        UpperCamelCase				(							self       ,							A__=None       ,							A__=None       ,							A__=None       ,							A__ = "eval"      )    ->			List[Any]:
          _SCREAMING_SNAKE_CASE      =				self.eval_dataset if eval_dataset is None else eval_dataset
          _SCREAMING_SNAKE_CASE      =				self.get_eval_dataloader(A__      )
          _SCREAMING_SNAKE_CASE      =				self.eval_examples if eval_examples is None else eval_examples

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

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

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

             self.log(A__      )
          else:
             _SCREAMING_SNAKE_CASE      =				{}

          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()      )

          _SCREAMING_SNAKE_CASE      =				self.callback_handler.on_evaluate(self.args       ,							self.state       ,							self.control       ,							A__      )
          return metrics






       def        UpperCamelCase				(							self       ,							A__       ,							A__       ,							A__=None       ,							A__ = "test"      )    ->			List[str]:
          _SCREAMING_SNAKE_CASE      =				self.get_test_dataloader(A__      )

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

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

          _SCREAMING_SNAKE_CASE      =				self.post_process_function(A__       ,							A__       ,							output.predictions       ,							"""predict"""      )
          _SCREAMING_SNAKE_CASE      =				self.compute_metrics(A__      )

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

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






       def        UpperCamelCase				(							self       ,							A__="./"      )    ->			Tuple:
          _SCREAMING_SNAKE_CASE      =				self.eval_dataset
          _SCREAMING_SNAKE_CASE      =				self.get_eval_dataloader(A__      )

          _SCREAMING_SNAKE_CASE      =				next(iter(A__      )      )

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

          # convert to tuple
          _SCREAMING_SNAKE_CASE      =				tuple(v.to(A__      ) for k, v in batch.items()      )

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

          _SCREAMING_SNAKE_CASE      =				True

          _SCREAMING_SNAKE_CASE      =				self.model.to(A__      )

          model.eval()
          model.float()

          _SCREAMING_SNAKE_CASE      =				model.module if hasattr(A__       ,							"""module"""      ) else model
          quant_trainer.configure_model(A__       ,							self.quant_trainer_args      )

          _SCREAMING_SNAKE_CASE      =				os.path.join(A__       ,							"""model.onnx"""      )
          logger.info(F"exporting model to {output_model_file}"      )

          _SCREAMING_SNAKE_CASE      =				{0: """batch_size""", 1: """seq_len"""}

          torch.onnx.export(
              A__       ,							A__       ,							A__       ,							export_params=A__       ,							opset_version=13       ,							do_constant_folding=A__       ,							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=A__       ,							)
          logger.info("""onnx export finished"""      )






