



import argparse
import logging
from collections import namedtuple

import torch
from model_bertabs import BertAbsSummarizer
from models.model_builder import AbsSummarizer  # The authors' implementation

from transformers import BertTokenizer


logging.basicConfig(level=logging.INFO)
a_      :      Union[str, Any]    =     logging.getLogger(__name__)


a_      :      Dict    =     'Hello world! cécé herlolip'


a_      :      List[str]    =     namedtuple(
    'BertAbsConfig',
    [
        'temp_dir',
        'large',
        'use_bert_emb',
        'finetune_bert',
        'encoder',
        'share_emb',
        'max_pos',
        'enc_layers',
        'enc_hidden_size',
        'enc_heads',
        'enc_ff_size',
        'enc_dropout',
        'dec_layers',
        'dec_hidden_size',
        'dec_heads',
        'dec_ff_size',
        'dec_dropout',
    ],
)






def     __a					(		__UpperCAmelCase							,  __UpperCAmelCase       ):
 a__												= BertAbsConfig(
     temp_dir='''.'''							,  finetune_bert=__UpperCAmelCase							,  large=__UpperCAmelCase							,  share_emb=__UpperCAmelCase							,  use_bert_emb=__UpperCAmelCase							,  encoder='''bert'''							,  max_pos=512							,  enc_layers=6							,  enc_hidden_size=512							,  enc_heads=8							,  enc_ff_size=512							,  enc_dropout=0.2							,  dec_layers=6							,  dec_hidden_size=768							,  dec_heads=8							,  dec_ff_size=2048							,  dec_dropout=0.2							,  )
 a__												= torch.load(__UpperCAmelCase							,  lambda __UpperCAmelCase							,  __UpperCAmelCase       : storage       )
 a__												= AbsSummarizer(__UpperCAmelCase							,  torch.device('''cpu'''       )							,  __UpperCAmelCase       )
 original.eval()

 a__												= BertAbsSummarizer(__UpperCAmelCase							,  torch.device('''cpu'''       )       )
 new_model.eval()

 # -------------------
 # Convert the weights
 # -------------------

 logging.info('''convert the model'''       )
 new_model.bert.load_state_dict(original.bert.state_dict()       )
 new_model.decoder.load_state_dict(original.decoder.state_dict()       )
 new_model.generator.load_state_dict(original.generator.state_dict()       )

 # ----------------------------------
 # Make sure the outpus are identical
 # ----------------------------------

 logging.info('''Make sure that the models\' outputs are identical'''       )
 a__												= BertTokenizer.from_pretrained('''bert-base-uncased'''       )

 # prepare the model inputs
 a__												= tokenizer.encode('''This is sample éàalj\'-.'''       )
 encoder_input_ids.extend([tokenizer.pad_token_id] * (512 - len(__UpperCAmelCase       ))       )
 a__												= torch.tensor(__UpperCAmelCase       ).unsqueeze(0       )
 a__												= tokenizer.encode('''This is sample 3 éàalj\'-.'''       )
 decoder_input_ids.extend([tokenizer.pad_token_id] * (512 - len(__UpperCAmelCase       ))       )
 a__												= torch.tensor(__UpperCAmelCase       ).unsqueeze(0       )

 # failsafe to make sure the weights reset does not affect the
 # loaded weights.
 assert torch.max(torch.abs(original.generator[0].weight - new_model.generator[0].weight       )       ) == 0

 # forward pass
 a__												= encoder_input_ids
 a__												= decoder_input_ids
 a__												= a__												= None
 a__												= None
 a__												= a__												= None
 a__												= a__												= None
 a__												= None

 # The original model does not apply the geneator layer immediatly but rather in
 # the beam search (where it combines softmax + linear layer). Since we already
 # apply the softmax in our generation process we only apply the linear layer here.
 # We make sure that the outputs of the full stack are identical
 a__												= original(__UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase       )[0]
 a__												= original.generator(__UpperCAmelCase       )

 a__												= new_model(
     __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase							,  __UpperCAmelCase       )[0]
 a__												= new_model.generator(__UpperCAmelCase       )

 a__												= torch.max(torch.abs(output_converted_model - output_original_model       )       ).item()
 print('''Maximum absolute difference beween weights: {:.2f}'''.format(__UpperCAmelCase       )       )
 a__												= torch.max(torch.abs(output_converted_generator - output_original_generator       )       ).item()
 print('''Maximum absolute difference beween weights: {:.2f}'''.format(__UpperCAmelCase       )       )

 a__												= torch.allclose(__UpperCAmelCase							,  __UpperCAmelCase							,  atol=1e-3       )
 if are_identical:
  logging.info('''all weights are equal up to 1e-3'''       )
 else:
  raise ValueError('''the weights are different. The new model is likely different from the original one.'''       )

 # The model has been saved with torch.save(model) and this is bound to the exact
 # directory structure. We save the state_dict instead.
 logging.info('''saving the model\'s state dictionary'''       )
 torch.save(
     new_model.state_dict()							,  '''./bertabs-finetuned-cnndm-extractive-abstractive-summarization/pytorch_model.bin'''       )


if __name__ == "__main__":
     a_      :      Optional[int]    =     argparse.ArgumentParser()
     parser.add_argument(
         '--bertabs_checkpoint_path',
         default=None,
         type=str,
         required=True,
         help='Path the official PyTorch dump.',
     )
     parser.add_argument(
         '--pytorch_dump_folder_path',
         default=None,
         type=str,
         required=True,
         help='Path to the output PyTorch model.',
     )
     a_      :      List[Any]    =     parser.parse_args()

     convert_bertabs_checkpoints(
         args.bertabs_checkpoint_path,
         args.pytorch_dump_folder_path,
     )










import math
import time
from typing import Dict, List, Optional

from torch.utils.data import Dataset

from transformers import SeqaSeqTrainer, is_torch_tpu_available
from transformers.trainer_utils import PredictionOutput, speed_metrics


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

 """simple docstring"""



 def __init__(	self		,				*SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE=None		,				SCREAMING_SNAKE_CASE=None		,				**SCREAMING_SNAKE_CASE      ) ->			Tuple:
  super().__init__(*SCREAMING_SNAKE_CASE		,				**SCREAMING_SNAKE_CASE      )
  a__												= eval_examples
  a__												= post_process_function

 def 						_UpperCAmelCase       (	self		,				SCREAMING_SNAKE_CASE = None		,				SCREAMING_SNAKE_CASE=None		,				SCREAMING_SNAKE_CASE = None		,				SCREAMING_SNAKE_CASE = "eval"		,				**SCREAMING_SNAKE_CASE		,				) ->			Dict[str, float]:
  a__												= gen_kwargs.copy()
  a__												= (
      gen_kwargs['''max_length'''] if gen_kwargs.get('''max_length'''      ) is not None else self.args.generation_max_length
  )
  a__												= (
      gen_kwargs['''num_beams'''] if gen_kwargs.get('''num_beams'''      ) is not None else self.args.generation_num_beams
  )
  a__												= gen_kwargs

  a__												= self.eval_dataset if eval_dataset is None else eval_dataset
  a__												= self.get_eval_dataloader(SCREAMING_SNAKE_CASE      )
  a__												= self.eval_examples if eval_examples is None else eval_examples

  # Temporarily disable metric computation, we will do it in the loop here.
  a__												= self.compute_metrics
  a__												= None
  a__												= time.time()
  a__												= self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
  try:
   a__												= eval_loop(
       SCREAMING_SNAKE_CASE		,				description='''Evaluation'''		,				prediction_loss_only=True if compute_metrics is None else None		,				ignore_keys=SCREAMING_SNAKE_CASE		,				metric_key_prefix=SCREAMING_SNAKE_CASE		,				)
  finally:
   a__												= compute_metrics
  a__												= self.args.eval_batch_size * self.args.world_size
  if f"{metric_key_prefix}_jit_compilation_time" in output.metrics:
   start_time += output.metrics[f"{metric_key_prefix}_jit_compilation_time"]
  output.metrics.update(
      speed_metrics(
          SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE		,				num_samples=output.num_samples		,				num_steps=math.ceil(output.num_samples / total_batch_size      )		,				)      )

  if self.post_process_function is not None and self.compute_metrics is not None and self.args.should_save:
   # Only the main node write the results by default
   a__												= self.post_process_function(SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE      )
   a__												= self.compute_metrics(SCREAMING_SNAKE_CASE      )

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

   metrics.update(output.metrics      )
  else:
   a__												= output.metrics

  if self.args.should_log:
   # Only the main node log the results by default
   self.log(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()      )

  a__												= self.callback_handler.on_evaluate(self.args		,				self.state		,				self.control		,				SCREAMING_SNAKE_CASE      )
  return metrics



 def 						_UpperCAmelCase       (	self		,				SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE=None		,				SCREAMING_SNAKE_CASE = "test"		,				**SCREAMING_SNAKE_CASE      ) ->			List[str]:
  a__												= gen_kwargs.copy()

  a__												= self.get_test_dataloader(SCREAMING_SNAKE_CASE      )

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

  a__												= self.args.eval_batch_size * self.args.world_size
  if f"{metric_key_prefix}_jit_compilation_time" in output.metrics:
   start_time += output.metrics[f"{metric_key_prefix}_jit_compilation_time"]
  output.metrics.update(
      speed_metrics(
          SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE		,				num_samples=output.num_samples		,				num_steps=math.ceil(output.num_samples / total_batch_size      )		,				)      )
  if self.post_process_function is None or self.compute_metrics is None:
   return output

  a__												= self.post_process_function(SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE		,				SCREAMING_SNAKE_CASE		,				'''predict'''      )
  a__												= self.compute_metrics(SCREAMING_SNAKE_CASE      )

  # Prefix all keys with metric_key_prefix + '_'
  for key in list(metrics.keys()      ):
   if not key.startswith(f"{metric_key_prefix}_"      ):
    a__												= metrics.pop(SCREAMING_SNAKE_CASE      )
  metrics.update(output.metrics      )
  return PredictionOutput(predictions=predictions.predictions		,				label_ids=predictions.label_ids		,				metrics=SCREAMING_SNAKE_CASE      )





