


import unittest

import numpy as np

from transformers import DistilBertConfig, is_flax_available
from transformers.testing_utils import require_flax, slow

from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor, random_attention_mask


if is_flax_available():
	import jax.numpy as jnp

	from transformers.models.distilbert.modeling_flax_distilbert import (
	    FlaxDistilBertForMaskedLM,
	    FlaxDistilBertForMultipleChoice,
	    FlaxDistilBertForQuestionAnswering,
	    FlaxDistilBertForSequenceClassification,
	    FlaxDistilBertForTokenClassification,
	    FlaxDistilBertModel,
	)



class 				A       (			unittest.TestCase				):
					'''simple docstring'''






					def __init__(self       :		List[str] ,   _UpperCAmelCase       :		Dict ,   _UpperCAmelCase       :		List[Any]=13 ,   _UpperCAmelCase       :		List[str]=7 ,   _UpperCAmelCase       :		Union[str, Any]=True ,   _UpperCAmelCase       :		str=True ,   _UpperCAmelCase       :		Any=True ,   _UpperCAmelCase       :		Dict=True ,   _UpperCAmelCase       :		List[Any]=99 ,   _UpperCAmelCase       :		Tuple=32 ,   _UpperCAmelCase       :		Dict=5 ,   _UpperCAmelCase       :		Optional[int]=4 ,   _UpperCAmelCase       :		str=37 ,   _UpperCAmelCase       :		str="gelu" ,   _UpperCAmelCase       :		int=0.1 ,   _UpperCAmelCase       :		int=0.1 ,   _UpperCAmelCase       :		Dict=512 ,   _UpperCAmelCase       :		List[str]=16 ,   _UpperCAmelCase       :		Any=2 ,   _UpperCAmelCase       :		Optional[int]=0.02 ,   _UpperCAmelCase       :		Optional[Any]=4 ,   )		->  Any:




							"""simple docstring"""


							lowercase__	     =						parent
							lowercase__	     =						batch_size
							lowercase__	     =						seq_length
							lowercase__	     =						is_training
							lowercase__	     =						use_attention_mask
							lowercase__	     =						use_token_type_ids
							lowercase__	     =						use_labels
							lowercase__	     =						vocab_size
							lowercase__	     =						hidden_size
							lowercase__	     =						num_hidden_layers
							lowercase__	     =						num_attention_heads
							lowercase__	     =						intermediate_size
							lowercase__	     =						hidden_act
							lowercase__	     =						hidden_dropout_prob
							lowercase__	     =						attention_probs_dropout_prob
							lowercase__	     =						max_position_embeddings
							lowercase__	     =						type_vocab_size
							lowercase__	     =						type_sequence_label_size
							lowercase__	     =						initializer_range
							lowercase__	     =						num_choices

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




							"""simple docstring"""


							lowercase__	     =						ids_tensor([self.batch_size, self.seq_length] ,   self.vocab_size						)

							lowercase__	     =						None
							if self.use_attention_mask:
									lowercase__	     =						random_attention_mask([self.batch_size, self.seq_length]						)

							lowercase__	     =						DistilBertConfig(
							    vocab_size=self.vocab_size ,   dim=self.hidden_size ,   n_layers=self.num_hidden_layers ,   n_heads=self.num_attention_heads ,   hidden_dim=self.intermediate_size ,   hidden_act=self.hidden_act ,   dropout=self.hidden_dropout_prob ,   attention_dropout=self.attention_probs_dropout_prob ,   max_position_embeddings=self.max_position_embeddings ,   initializer_range=self.initializer_range ,   tie_weights_=_UpperCAmelCase ,   )

							return config, input_ids, attention_mask


					def     lowerCamelCase__	(self       :		Any						)		->  List[Any]:




							"""simple docstring"""


							lowercase__	     =						self.prepare_config_and_inputs()
							lowercase__     ,      lowercase__     ,      lowercase__	     =						config_and_inputs
							lowercase__	     =						{"""input_ids""": input_ids, """attention_mask""": attention_mask}
							return config, inputs_dict






@require_flax
class 				A       (			UpperCAmelCase__					,    unittest.TestCase				):
					'''simple docstring'''






					A__     =					(
					    (
					        FlaxDistilBertModel,
					        FlaxDistilBertForMaskedLM,
					        FlaxDistilBertForMultipleChoice,
					        FlaxDistilBertForQuestionAnswering,
					        FlaxDistilBertForSequenceClassification,
					        FlaxDistilBertForTokenClassification,
					        FlaxDistilBertForQuestionAnswering,
					    )
					    if is_flax_available()
					    else ()
					)

					def     lowerCamelCase__	(self       :		List[Any]						)		->  Tuple:




							"""simple docstring"""


							lowercase__	     =						FlaxDistilBertModelTester(self						)


					@slow
					def     lowerCamelCase__	(self       :		List[str]						)		->  List[Any]:




							"""simple docstring"""


							for model_class_name in self.all_model_classes:
									lowercase__	     =						model_class_name.from_pretrained("""distilbert-base-uncased"""						)
									lowercase__	     =						model(np.ones((1, 1)						)						)
									self.assertIsNotNone(_UpperCAmelCase						)






@require_flax
class 				A       (			unittest.TestCase				):
					'''simple docstring'''






					@slow
					def     lowerCamelCase__	(self       :		Optional[int]						)		->  Optional[Any]:




							"""simple docstring"""


							lowercase__	     =						FlaxDistilBertModel.from_pretrained("""distilbert-base-uncased"""						)
							lowercase__	     =						np.array([[0, 345, 232, 328, 740, 140, 1695, 69, 6078, 1588, 2]]						)
							lowercase__	     =						np.array([[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]						)
							lowercase__	     =						model(_UpperCAmelCase ,   attention_mask=_UpperCAmelCase						)[0]
							lowercase__	     =						(1, 11, 768)
							self.assertEqual(output.shape ,   _UpperCAmelCase						)
							lowercase__	     =						np.array([[[-0.1_639, 0.3_299, 0.1_648], [-0.1_746, 0.3_289, 0.1_710], [-0.1_884, 0.3_357, 0.1_810]]]						)

							self.assertTrue(jnp.allclose(output[:, 1:4, 1:4] ,   _UpperCAmelCase ,   atol=1E-4						)						)





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 					UpperCamelCase   (      __magic_name__	:				Any	)  ->    int:
		"""simple docstring"""




		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=__magic_name__       ,       is_encoder_decoder=__magic_name__       ,       add_cross_attention=__magic_name__       ,       decoder_layers=original_config.decoder_layer       ,       max_position_embeddings=original_config.max_position_embeddings       ,       vocab_size=len(
		        model.decoder.tokenizer	)       ,       scale_embedding=__magic_name__       ,       add_final_layer_norm=__magic_name__       ,       )

		return encoder_config, decoder_config






def 					UpperCamelCase   (      __magic_name__	:				Optional[Any]	)  ->    Optional[Any]:
		"""simple docstring"""




		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 					UpperCamelCase   (      __magic_name__	:				Any       ,       __magic_name__	:				str	)  ->    Optional[int]:
		"""simple docstring"""




		for key in orig_state_dict.copy().keys():
				lowercase__	     =						orig_state_dict.pop(__magic_name__	)

				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 					UpperCamelCase   (      __magic_name__	:				Union[str, Any]       ,       __magic_name__	:				List[Any]=None       ,       __magic_name__	:				Dict=False	)  ->    int:
		"""simple docstring"""




		lowercase__	     =						DonutModel.from_pretrained(__magic_name__	).eval()

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

		lowercase__	     =						original_model.state_dict()
		lowercase__	     =						convert_state_dict(__magic_name__       ,       __magic_name__	)
		model.load_state_dict(__magic_name__	)

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

		lowercase__	     =						XLMRobertaTokenizerFast.from_pretrained(__magic_name__       ,       from_slow=__magic_name__	)
		lowercase__	     =						DonutImageProcessor(
		    do_align_long_axis=original_model.config.align_long_axis       ,       size=original_model.config.input_size[::-1]	)
		lowercase__	     =						DonutProcessor(__magic_name__       ,       __magic_name__	)
		lowercase__	     =						processor(__magic_name__       ,       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}"""       ,       __magic_name__	)
		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(__magic_name__       ,       add_special_tokens=__magic_name__       ,       return_tensors="""pt"""	)[
		    """input_ids"""
		]

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

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

		# verify decoder hidden states
		lowercase__	     =						original_model(__magic_name__       ,       __magic_name__       ,       __magic_name__	).logits
		lowercase__	     =						model(__magic_name__       ,       decoder_input_ids=__magic_name__	).logits
		assert torch.allclose(__magic_name__       ,       __magic_name__       ,       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(__magic_name__	)
				processor.save_pretrained(__magic_name__	)

		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__":
	A			:						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.',
	)

	A			:						Optional[int]        =  parser.parse_args()
	convert_donut_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)

