





'''simple docstring'''







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)
snake_case_     :       List[str]						=  logging.getLogger(__name__)


snake_case_     :       Any						=  "Hello world! cécé herlolip"


snake_case_     :       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        lowerCamelCase_      (  SCREAMING_SNAKE_CASE__      :			Tuple,			SCREAMING_SNAKE_CASE__      :			Dict   ) ->	Dict:
						UpperCAmelCase_			:      List[Any]     						=  BertAbsConfig(
						    temp_dir='''.''',			finetune_bert=SCREAMING_SNAKE_CASE__,			large=SCREAMING_SNAKE_CASE__,			share_emb=SCREAMING_SNAKE_CASE__,			use_bert_emb=SCREAMING_SNAKE_CASE__,			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,			)
						UpperCAmelCase_			:      Optional[int]     						=  torch.load(SCREAMING_SNAKE_CASE__,			lambda SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__   : storage   )
						UpperCAmelCase_			:      List[str]     						=  AbsSummarizer(SCREAMING_SNAKE_CASE__,			torch.device('''cpu'''   ),			SCREAMING_SNAKE_CASE__   )
						original.eval()

						UpperCAmelCase_			:      Tuple     						=  BertAbsSummarizer(SCREAMING_SNAKE_CASE__,			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'''   )
						UpperCAmelCase_			:      str     						=  BertTokenizer.from_pretrained('''bert-base-uncased'''   )

						# prepare the model inputs
						UpperCAmelCase_			:      Dict     						=  tokenizer.encode('''This is sample éàalj\'-.'''   )
						encoder_input_ids.extend([tokenizer.pad_token_id] * (512 - len(SCREAMING_SNAKE_CASE__   ))   )
						UpperCAmelCase_			:      List[str]     						=  torch.tensor(SCREAMING_SNAKE_CASE__   ).unsqueeze(0   )
						UpperCAmelCase_			:      Union[str, Any]     						=  tokenizer.encode('''This is sample 3 éàalj\'-.'''   )
						decoder_input_ids.extend([tokenizer.pad_token_id] * (512 - len(SCREAMING_SNAKE_CASE__   ))   )
						UpperCAmelCase_			:      List[Any]     						=  torch.tensor(SCREAMING_SNAKE_CASE__   ).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
						UpperCAmelCase_			:      Optional[int]     						=  encoder_input_ids
						UpperCAmelCase_			:      int     						=  decoder_input_ids
						UpperCAmelCase_			:      str     						=  None
						UpperCAmelCase_			:      Dict     						=  None
						UpperCAmelCase_			:      Dict     						=  None
						UpperCAmelCase_			:      List[str]     						=  None
						UpperCAmelCase_			:      Dict     						=  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
						UpperCAmelCase_			:      Any     						=  original(SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__   )[0]
						UpperCAmelCase_			:      Tuple     						=  original.generator(SCREAMING_SNAKE_CASE__   )

						UpperCAmelCase_			:      Optional[int]     						=  new_model(
						    SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__   )[0]
						UpperCAmelCase_			:      Any     						=  new_model.generator(SCREAMING_SNAKE_CASE__   )

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

						UpperCAmelCase_			:      List[Any]     						=  torch.allclose(SCREAMING_SNAKE_CASE__,			SCREAMING_SNAKE_CASE__,			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__":
					snake_case_     :       List[Any]						=  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.",
					)
					snake_case_     :       Tuple						=  parser.parse_args()

					convert_bertabs_checkpoints(
					    args.bertabs_checkpoint_path,
					    args.pytorch_dump_folder_path,
					)












'''simple docstring'''







import unittest

from transformers import is_torch_available
from transformers.testing_utils import require_torch


if is_torch_available():
					import torch

					from transformers.generation import DisjunctiveConstraint


@require_torch
class 					__a      (unittest.TestCase     ):

							def     UpperCAmelCase__	(							self							:     Optional[Any]   )					->       List[Any]:







													"""simple docstring"""
													# For consistency across different places the DisjunctiveConstraint is called,
													# dc.token_ids is a list of integers. It is also initialized only by integers.

													UpperCAmelCase_			:      List[str]     						=  [[1, 2, 4], [1, 2, 3, 4]]
													UpperCAmelCase_			:      List[str]     						=  DisjunctiveConstraint(__magic_name__   )
													self.assertTrue(isinstance(dc.token_ids       ,     __magic_name__   )   )

													with self.assertRaises(__magic_name__   ):
																			DisjunctiveConstraint(torch.LongTensor([[1, 2, 4], [1, 2, 3]]   )   )

													with self.assertRaises(__magic_name__   ):
																			DisjunctiveConstraint([torch.LongTensor([1, 2, 4]   ), torch.LongTensor([1, 2, 3, 4, 5]   )]   )

							def     UpperCAmelCase__	(							self							:     List[str]   )					->       Dict:







													"""simple docstring"""
													# We can't have constraints that are complete subsets of another. This leads to a preverse
													# interpretation of "constraint fulfillment": does generating [1,2,3] fulfill the constraint?
													# It would mean that it generated [1,2] which fulfills it, but it's in the middle of potentially
													# fulfilling [1,2,3,4]. If we believe that [1,2,3] does fulfill the constraint, then the algorithm
													# will necessarily never reach [1,2,3,4], giving users a false sense of control (better to just not allow it).
													UpperCAmelCase_			:      Tuple     						=  [[1, 2], [1, 2, 3, 4]]

													with self.assertRaises(__magic_name__   ):
																			DisjunctiveConstraint(__magic_name__   )  # fails here

							def     UpperCAmelCase__	(							self							:     Optional[int]   )					->       Union[str, Any]:







													"""simple docstring"""
													UpperCAmelCase_			:      Optional[int]     						=  [[1, 2, 3], [1, 2, 4]]

													UpperCAmelCase_			:      List[str]     						=  DisjunctiveConstraint(__magic_name__   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      List[Any]     						=  dc.update(1   )
													UpperCAmelCase_			:      Dict     						=  stepped is True and completed is False and reset is False
													self.assertTrue(__magic_name__   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.current_seq == [1]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      str     						=  dc.update(2   )
													UpperCAmelCase_			:      Optional[Any]     						=  stepped is True and completed is False and reset is False
													self.assertTrue(__magic_name__   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.current_seq == [1, 2]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      List[Any]     						=  dc.update(3   )
													UpperCAmelCase_			:      Dict     						=  stepped is True and completed is True and reset is False
													self.assertTrue(__magic_name__   )
													self.assertTrue(dc.completed   )  # Completed!
													self.assertTrue(dc.current_seq == [1, 2, 3]   )



							def     UpperCAmelCase__	(							self							:     int   )					->       Dict:







													"""simple docstring"""
													UpperCAmelCase_			:      Any     						=  [[1, 2, 3], [1, 2, 4, 5], [1, 2, 5]]

													UpperCAmelCase_			:      Tuple     						=  DisjunctiveConstraint(__magic_name__   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      List[Any]     						=  dc.update(1   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.current_seq == [1]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      Optional[int]     						=  dc.update(2   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.current_seq == [1, 2]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      int     						=  dc.update(4   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.current_seq == [1, 2, 4]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      int     						=  dc.update(5   )
													self.assertTrue(dc.completed   )  # Completed!
													self.assertTrue(dc.current_seq == [1, 2, 4, 5]   )

													dc.reset()

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      List[Any]     						=  dc.update(1   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.remaining() == 3   )
													self.assertTrue(dc.current_seq == [1]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      Optional[Any]     						=  dc.update(2   )
													self.assertTrue(not dc.completed   )
													self.assertTrue(dc.remaining() == 2   )
													self.assertTrue(dc.current_seq == [1, 2]   )

													UpperCAmelCase_						,       UpperCAmelCase_						,       UpperCAmelCase_			:      Optional[int]     						=  dc.update(5   )
													self.assertTrue(dc.completed   )  # Completed!
													self.assertTrue(dc.remaining() == 0   )
													self.assertTrue(dc.current_seq == [1, 2, 5]   )





