


from __future__ import annotations

import unittest

from transformers import FunnelConfig, is_tf_available
from transformers.testing_utils import require_tf

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
	import tensorflow as tf

	from transformers import (
	    TFFunnelBaseModel,
	    TFFunnelForMaskedLM,
	    TFFunnelForMultipleChoice,
	    TFFunnelForPreTraining,
	    TFFunnelForQuestionAnswering,
	    TFFunnelForSequenceClassification,
	    TFFunnelForTokenClassification,
	    TFFunnelModel,
	)




class       lowercase_					:





				def __init__(				self       ,  lowercase_       ,  lowercase_=13       ,  lowercase_=7       ,  lowercase_=True       ,  lowercase_=True       ,  lowercase_=True       ,  lowercase_=True       ,  lowercase_=99       ,  lowercase_=[1, 1, 2]       ,  lowercase_=1       ,  lowercase_=32       ,  lowercase_=4       ,  lowercase_=8       ,  lowercase_=37       ,  lowercase_="gelu_new"       ,  lowercase_=0.1       ,  lowercase_=0.1       ,  lowercase_=0.0       ,  lowercase_=512       ,  lowercase_=3       ,  lowercase_=0.02       ,  lowercase_=3       ,  lowercase_=4       ,  lowercase_=None       ,  lowercase_=False       ,  )  -> int:
											a__      =parent
											a__      =batch_size
											a__      =seq_length
											a__      =is_training
											a__      =use_input_mask
											a__      =use_token_type_ids
											a__      =use_labels
											a__      =vocab_size
											a__      =block_sizes
											a__      =num_decoder_layers
											a__      =d_model
											a__      =n_head
											a__      =d_head
											a__      =d_inner
											a__      =hidden_act
											a__      =hidden_dropout
											a__      =attention_dropout
											a__      =activation_dropout
											a__      =max_position_embeddings
											a__      =type_vocab_size
											a__      =2
											a__      =num_labels
											a__      =num_choices
											a__      =scope
											a__      =initializer_std

											# Used in the tests to check the size of the first attention layer
											a__      =n_head
											# Used in the tests to check the size of the first hidden state
											a__      =self.d_model
											# Used in the tests to check the number of output hidden states/attentions
											a__      =sum(self.block_sizes) + (0 if base else self.num_decoder_layers)
											# FunnelModel adds two hidden layers: input embeddings and the sum of the upsampled encoder hidden state with
											# the last hidden state of the first block (which is the first hidden state of the decoder).
											if not base:
																		a__      =self.num_hidden_layers + 2





				def 						__UpperCamelCase    (				self)  -> Any:
											a__      =ids_tensor([self.batch_size, self.seq_length]       ,  self.vocab_size)

											a__      =None
											if self.use_input_mask:
																		a__      =random_attention_mask([self.batch_size, self.seq_length])

											a__      =None
											if self.use_token_type_ids:
																		a__      =ids_tensor([self.batch_size, self.seq_length]       ,  self.type_vocab_size)

											a__      =None
											a__      =None
											a__      =None
											if self.use_labels:
																		a__      =ids_tensor([self.batch_size]       ,  self.type_sequence_label_size)
																		a__      =ids_tensor([self.batch_size, self.seq_length]       ,  self.num_labels)
																		a__      =ids_tensor([self.batch_size]       ,  self.num_choices)

											a__      =FunnelConfig(
											    vocab_size=self.vocab_size       ,  block_sizes=self.block_sizes       ,  num_decoder_layers=self.num_decoder_layers       ,  d_model=self.d_model       ,  n_head=self.n_head       ,  d_head=self.d_head       ,  d_inner=self.d_inner       ,  hidden_act=self.hidden_act       ,  hidden_dropout=self.hidden_dropout       ,  attention_dropout=self.attention_dropout       ,  activation_dropout=self.activation_dropout       ,  max_position_embeddings=self.max_position_embeddings       ,  type_vocab_size=self.type_vocab_size       ,  initializer_std=self.initializer_std       ,  )

											return (
											    config,
											    input_ids,
											    token_type_ids,
											    input_mask,
											    sequence_labels,
											    token_labels,
											    choice_labels,
											)





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> int:
											a__      =TFFunnelModel(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)

											a__      =[input_ids, input_mask]
											a__      =model(lowercase_)

											a__      =model(lowercase_)
											self.parent.assertEqual(result.last_hidden_state.shape       ,  (self.batch_size, self.seq_length, self.d_model))

											a__      =False
											a__      =TFFunnelModel(config=lowercase_)
											a__      =model(lowercase_)
											self.parent.assertEqual(result.last_hidden_state.shape       ,  (self.batch_size, self.seq_length, self.d_model))

											a__      =False
											a__      =TFFunnelModel(config=lowercase_)
											a__      =model(lowercase_)
											self.parent.assertEqual(result.last_hidden_state.shape       ,  (self.batch_size, self.seq_length, self.d_model))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> List[str]:
											a__      =TFFunnelBaseModel(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)

											a__      =[input_ids, input_mask]
											a__      =model(lowercase_)

											a__      =model(lowercase_)
											self.parent.assertEqual(result.last_hidden_state.shape       ,  (self.batch_size, 2, self.d_model))

											a__      =False
											a__      =TFFunnelBaseModel(config=lowercase_)
											a__      =model(lowercase_)
											self.parent.assertEqual(result.last_hidden_state.shape       ,  (self.batch_size, 3, self.d_model))

											a__      =False
											a__      =TFFunnelBaseModel(config=lowercase_)
											a__      =model(lowercase_)
											self.parent.assertEqual(result.last_hidden_state.shape       ,  (self.batch_size, 2, self.d_model))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> List[str]:
											a__      =TFFunnelForPreTraining(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)
											self.parent.assertEqual(result.logits.shape       ,  (self.batch_size, self.seq_length))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> Optional[int]:
											a__      =TFFunnelForMaskedLM(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)
											self.parent.assertEqual(result.logits.shape       ,  (self.batch_size, self.seq_length, self.vocab_size))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> Union[str, Any]:
											a__      =self.num_labels
											a__      =TFFunnelForSequenceClassification(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)
											self.parent.assertEqual(result.logits.shape       ,  (self.batch_size, self.num_labels))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> List[str]:
											a__      =self.num_choices
											a__      =TFFunnelForMultipleChoice(config=lowercase_)
											a__      =tf.tile(tf.expand_dims(lowercase_       ,  1)       ,  (1, self.num_choices, 1))
											a__      =tf.tile(tf.expand_dims(lowercase_       ,  1)       ,  (1, self.num_choices, 1))
											a__      =tf.tile(tf.expand_dims(lowercase_       ,  1)       ,  (1, self.num_choices, 1))
											a__      ={
											    'input_ids': multiple_choice_inputs_ids,
											    'attention_mask': multiple_choice_input_mask,
											    'token_type_ids': multiple_choice_token_type_ids,
											}
											a__      =model(lowercase_)
											self.parent.assertEqual(result.logits.shape       ,  (self.batch_size, self.num_choices))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> Tuple:
											a__      =self.num_labels
											a__      =TFFunnelForTokenClassification(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)
											self.parent.assertEqual(result.logits.shape       ,  (self.batch_size, self.seq_length, self.num_labels))





				def 						__UpperCamelCase    (				self       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  lowercase_       ,  )  -> List[Any]:
											a__      =TFFunnelForQuestionAnswering(config=lowercase_)
											a__      ={'input_ids': input_ids, 'attention_mask': input_mask, 'token_type_ids': token_type_ids}
											a__      =model(lowercase_)
											self.parent.assertEqual(result.start_logits.shape       ,  (self.batch_size, self.seq_length))
											self.parent.assertEqual(result.end_logits.shape       ,  (self.batch_size, self.seq_length))





				def 						__UpperCamelCase    (				self)  -> str:
											a__      =self.prepare_config_and_inputs()
											(
											    (
											    a__
											)    ,     (
											    a__
											)    ,     (
											    a__
											)    ,     (
											    a__
											)    ,     (
											    a__
											)    ,     (
											    a__
											)    ,     (
											    a__
											)    ,     
											)      =config_and_inputs
											a__      ={'input_ids': input_ids, 'token_type_ids': token_type_ids, 'attention_mask': input_mask}
											return config, inputs_dict







@require_tf
class       lowercase_					(lowercase__      ,					lowercase__      ,					unittest.TestCase   ):
				snake_case	    =(
				    (
				        TFFunnelModel,
				        TFFunnelForMaskedLM,
				        TFFunnelForPreTraining,
				        TFFunnelForQuestionAnswering,
				        TFFunnelForTokenClassification,
				    )
				    if is_tf_available()
				    else ()
				)
				snake_case	    =(
				    {
				        'feature-extraction': (TFFunnelBaseModel, TFFunnelModel),
				        'fill-mask': TFFunnelForMaskedLM,
				        'question-answering': TFFunnelForQuestionAnswering,
				        'text-classification': TFFunnelForSequenceClassification,
				        'token-classification': TFFunnelForTokenClassification,
				        'zero-shot': TFFunnelForSequenceClassification,
				    }
				    if is_tf_available()
				    else {}
				)
				snake_case	    =False
				snake_case	    =False





				def 						__UpperCamelCase    (				self)  -> List[str]:
											a__      =TFFunnelModelTester(self)
											a__      =ConfigTester(self       ,  config_class=lowercase_)





				def 						__UpperCamelCase    (				self)  -> Tuple:
											self.config_tester.run_common_tests()





				def 						__UpperCamelCase    (				self)  -> List[str]:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_model(*lowercase_)





				def 						__UpperCamelCase    (				self)  -> Union[str, Any]:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_for_pretraining(*lowercase_)





				def 						__UpperCamelCase    (				self)  -> Optional[int]:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_for_masked_lm(*lowercase_)





				def 						__UpperCamelCase    (				self)  -> Optional[int]:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_for_token_classification(*lowercase_)





				def 						__UpperCamelCase    (				self)  -> int:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_for_question_answering(*lowercase_)







@require_tf
class       lowercase_					(lowercase__      ,					unittest.TestCase   ):
				snake_case	    =(
				    (TFFunnelBaseModel, TFFunnelForMultipleChoice, TFFunnelForSequenceClassification) if is_tf_available() else ()
				)
				snake_case	    =False
				snake_case	    =False





				def 						__UpperCamelCase    (				self)  -> Optional[int]:
											a__      =TFFunnelModelTester(self       ,  base=lowercase_)
											a__      =ConfigTester(self       ,  config_class=lowercase_)





				def 						__UpperCamelCase    (				self)  -> Optional[Any]:
											self.config_tester.run_common_tests()





				def 						__UpperCamelCase    (				self)  -> str:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_base_model(*lowercase_)





				def 						__UpperCamelCase    (				self)  -> Any:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_for_sequence_classification(*lowercase_)





				def 						__UpperCamelCase    (				self)  -> List[str]:
											a__      =self.model_tester.prepare_config_and_inputs()
											self.model_tester.create_and_check_for_multiple_choice(*lowercase_)








import argparse

import torch
from datasets import load_dataset
from donut import DonutModel

from transformers import (
    DonutImageProcessor,
    DonutProcessor,
    DonutSwinConfig,
    DonutSwinModel,
    MBartConfig,
    MBartForCausalLM,
    VisionEncoderDecoderModel,
    XLMRobertaTokenizerFast,
)



def  SCREAMING_SNAKE_CASE				(      snake_case							)		->    Optional[int]:
		__lowercase											=     model.config

		__lowercase											=     DonutSwinConfig(
		    image_size=original_config.input_size						,   patch_size=4						,   depths=original_config.encoder_layer						,   num_heads=[4, 8, 16, 32]						,   window_size=original_config.window_size						,   embed_dim=128						,   )
		__lowercase											=     MBartConfig(
		    is_decoder=snake_case						,   is_encoder_decoder=snake_case						,   add_cross_attention=snake_case						,   decoder_layers=original_config.decoder_layer						,   max_position_embeddings=original_config.max_position_embeddings						,   vocab_size=len(
		        model.decoder.tokenizer							)						,   scale_embedding=snake_case						,   add_final_layer_norm=snake_case						,   )

		return encoder_config, decoder_config



def  SCREAMING_SNAKE_CASE				(      snake_case							)		->    Tuple:
		if "encoder.model" in name:
				__lowercase											=     name.replace('encoder.model'						,   'encoder'							)
		if "decoder.model" in name:
				__lowercase											=     name.replace('decoder.model'						,   'decoder'							)
		if "patch_embed.proj" in name:
				__lowercase											=     name.replace('patch_embed.proj'						,   'embeddings.patch_embeddings.projection'							)
		if "patch_embed.norm" in name:
				__lowercase											=     name.replace('patch_embed.norm'						,   'embeddings.norm'							)
		if name.startswith('encoder'							):
				if "layers" in name:
						__lowercase											=     'encoder.' + name
				if "attn.proj" in name:
						__lowercase											=     name.replace('attn.proj'						,   'attention.output.dense'							)
				if "attn" in name and "mask" not in name:
						__lowercase											=     name.replace('attn'						,   'attention.self'							)
				if "norm1" in name:
						__lowercase											=     name.replace('norm1'						,   'layernorm_before'							)
				if "norm2" in name:
						__lowercase											=     name.replace('norm2'						,   'layernorm_after'							)
				if "mlp.fc1" in name:
						__lowercase											=     name.replace('mlp.fc1'						,   'intermediate.dense'							)
				if "mlp.fc2" in name:
						__lowercase											=     name.replace('mlp.fc2'						,   'output.dense'							)

				if name == "encoder.norm.weight":
						__lowercase											=     'encoder.layernorm.weight'
				if name == "encoder.norm.bias":
						__lowercase											=     'encoder.layernorm.bias'

		return name



def  SCREAMING_SNAKE_CASE				(      snake_case						,   snake_case							)		->    List[Any]:
		for key in orig_state_dict.copy().keys():
				__lowercase											=     orig_state_dict.pop(snake_case							)

				if "qkv" in key:
						__lowercase											=     key.split('.'							)
						__lowercase											=     int(key_split[3]							)
						__lowercase											=     int(key_split[5]							)
						__lowercase											=     model.encoder.encoder.layers[layer_num].blocks[block_num].attention.self.all_head_size

						if "weight" in key:
								__lowercase											=     val[:dim, :]
								__lowercase											=     val[dim : dim * 2, :]
								__lowercase											=     val[-dim:, :]
						else:
								__lowercase											=     val[:dim]
								__lowercase											=     val[dim : dim * 2]
								__lowercase											=     val[-dim:]
				elif "attn_mask" in key or key in ["encoder.model.norm.weight", "encoder.model.norm.bias"]:
						# HuggingFace implementation doesn't use attn_mask buffer
						# and model doesn't use final LayerNorms for the encoder
						pass
				else:
						__lowercase											=     val

		return orig_state_dict



def  SCREAMING_SNAKE_CASE				(      snake_case						,   snake_case=None						,   snake_case=False							)		->    Any:
		# load original model
		__lowercase											=     DonutModel.from_pretrained(snake_case							).eval()

		# load HuggingFace model
		__lowercase						,      __lowercase											=     get_configs(snake_case							)
		__lowercase											=     DonutSwinModel(snake_case							)
		__lowercase											=     MBartForCausalLM(snake_case							)
		__lowercase											=     VisionEncoderDecoderModel(encoder=snake_case						,   decoder=snake_case							)
		model.eval()

		__lowercase											=     original_model.state_dict()
		__lowercase											=     convert_state_dict(snake_case						,   snake_case							)
		model.load_state_dict(snake_case							)

		# verify results on scanned document
		__lowercase											=     load_dataset('hf-internal-testing/example-documents'							)
		__lowercase											=     dataset['test'][0]['image'].convert('RGB'							)

		__lowercase											=     XLMRobertaTokenizerFast.from_pretrained(snake_case						,   from_slow=snake_case							)
		__lowercase											=     DonutImageProcessor(
		    do_align_long_axis=original_model.config.align_long_axis						,   size=original_model.config.input_size[::-1]							)
		__lowercase											=     DonutProcessor(snake_case						,   snake_case							)
		__lowercase											=     processor(snake_case						,   return_tensors='pt'							).pixel_values

		if model_name == "naver-clova-ix/donut-base-finetuned-docvqa":
				__lowercase											=     '<s_docvqa><s_question>{user_input}</s_question><s_answer>'
				__lowercase											=     'When is the coffee break?'
				__lowercase											=     task_prompt.replace('{user_input}'						,   snake_case							)
		elif model_name == "naver-clova-ix/donut-base-finetuned-rvlcdip":
				__lowercase											=     '<s_rvlcdip>'
		elif model_name in [
		    "naver-clova-ix/donut-base-finetuned-cord-v1",
		    "naver-clova-ix/donut-base-finetuned-cord-v1-2560",
		]:
				__lowercase											=     '<s_cord>'
		elif model_name == "naver-clova-ix/donut-base-finetuned-cord-v2":
				__lowercase											=     's_cord-v2>'
		elif model_name == "naver-clova-ix/donut-base-finetuned-zhtrainticket":
				__lowercase											=     '<s_zhtrainticket>'
		elif model_name in ["naver-clova-ix/donut-proto", "naver-clova-ix/donut-base"]:
				# use a random prompt
				__lowercase											=     'hello world'
		else:
				raise ValueError('Model name not supported'							)
		__lowercase											=     original_model.decoder.tokenizer(snake_case						,   add_special_tokens=snake_case						,   return_tensors='pt'							)[
		    'input_ids'
		]

		__lowercase											=     original_model.encoder.model.patch_embed(snake_case							)
		__lowercase						,      __lowercase											=     model.encoder.embeddings(snake_case							)
		assert torch.allclose(snake_case						,   snake_case						,   atol=1E-3							)

		# verify encoder hidden states
		__lowercase											=     original_model.encoder(snake_case							)
		__lowercase											=     model.encoder(snake_case							).last_hidden_state
		assert torch.allclose(snake_case						,   snake_case						,   atol=1E-2							)

		# verify decoder hidden states
		__lowercase											=     original_model(snake_case						,   snake_case						,   snake_case							).logits
		__lowercase											=     model(snake_case						,   decoder_input_ids=snake_case							).logits
		assert torch.allclose(snake_case						,   snake_case						,   atol=1E-3							)
		print('Looks ok!'							)

		if pytorch_dump_folder_path is not None:
				print(F"Saving model and processor to {pytorch_dump_folder_path}"							)
				model.save_pretrained(snake_case							)
				processor.save_pretrained(snake_case							)

		if push_to_hub:
				model.push_to_hub('nielsr/' + model_name.split('/'							)[-1]						,   commit_message='Update model'							)
				processor.push_to_hub('nielsr/' + model_name.split('/'							)[-1]						,   commit_message='Update model'							)


if __name__ == "__main__":
		SCREAMING_SNAKE_CASE_   :      Dict			=   argparse.ArgumentParser()
		# Required parameters
		parser.add_argument(
		    '''--model_name''',
		    default='''naver-clova-ix/donut-base-finetuned-docvqa''',
		    required=False,
		    type=str,
		    help='''Name of the original model you\'d like to convert.''',
		)
		parser.add_argument(
		    '''--pytorch_dump_folder_path''',
		    default=None,
		    required=False,
		    type=str,
		    help='''Path to the output PyTorch model directory.''',
		)
		parser.add_argument(
		    '''--push_to_hub''',
		    action='''store_true''',
		    help='''Whether or not to push the converted model and processor to the 🤗 hub.''',
		)

		SCREAMING_SNAKE_CASE_   :      Tuple			=   parser.parse_args()
		convert_donut_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)




