



"""simple docstring"""





import unittest

import numpy as np

from transformers.testing_utils import require_torch, require_vision
from transformers.utils import is_torch_available, is_vision_available

from ...test_image_processing_common import ImageProcessingSavingTestMixin, prepare_image_inputs


if is_torch_available():
					import torch

if is_vision_available():
					from PIL import Image

					from transformers import LevitImageProcessor



class  _lowerCAmelCase     (					unittest.TestCase		):





		"""simple docstring"""






		def __init__(       self				,     _lowercase				,     _lowercase=7				,     _lowercase=3				,     _lowercase=1_8				,     _lowercase=3_0				,     _lowercase=4_0_0				,     _lowercase=True				,     _lowercase=None				,     _lowercase=True				,     _lowercase=None				,     _lowercase=True				,     _lowercase=[0.5, 0.5, 0.5]				,     _lowercase=[0.5, 0.5, 0.5]				,     )			->    Tuple:







								'''simple docstring'''

								snake_case_ :			Any            =      size if size is not None else {"""shortest_edge""": 1_8}
								snake_case_ :			str            =      crop_size if crop_size is not None else {"""height""": 1_8, """width""": 1_8}
								snake_case_ :			List[str]            =      parent
								snake_case_ :			Optional[Any]            =      batch_size
								snake_case_ :			List[Any]            =      num_channels
								snake_case_ :			Any            =      image_size
								snake_case_ :			int            =      min_resolution
								snake_case_ :			Tuple            =      max_resolution
								snake_case_ :			Tuple            =      do_resize
								snake_case_ :			int            =      size
								snake_case_ :			Union[str, Any]            =      do_center_crop
								snake_case_ :			Union[str, Any]            =      crop_size
								snake_case_ :			Optional[int]            =      do_normalize
								snake_case_ :			List[str]            =      image_mean
								snake_case_ :			Optional[Any]            =      image_std





		def  UpperCAmelCase__				(       self )			->    str:







								'''simple docstring'''

								return {
								    "image_mean": self.image_mean,
								    "image_std": self.image_std,
								    "do_normalize": self.do_normalize,
								    "do_resize": self.do_resize,
								    "do_center_crop": self.do_center_crop,
								    "size": self.size,
								    "crop_size": self.crop_size,
								}




@require_torch
@require_vision
class  _lowerCAmelCase     (					SCREAMING_SNAKE_CASE__	,					unittest.TestCase		):





		"""simple docstring"""






		_lowerCamelCase      	=							LevitImageProcessor if is_vision_available() else None





		def  UpperCAmelCase__				(       self )			->    Dict:







								'''simple docstring'''

								snake_case_ :			Dict            =      LevitImageProcessingTester(self )





		@property
		def  UpperCAmelCase__				(       self )			->    Optional[int]:







								'''simple docstring'''

								return self.image_processor_tester.prepare_image_processor_dict()





		def  UpperCAmelCase__				(       self )			->    int:







								'''simple docstring'''

								snake_case_ :			Optional[Any]            =      self.image_processing_class(**self.image_processor_dict )
								self.assertTrue(hasattr(_lowercase				,     """image_mean""" ) )
								self.assertTrue(hasattr(_lowercase				,     """image_std""" ) )
								self.assertTrue(hasattr(_lowercase				,     """do_normalize""" ) )
								self.assertTrue(hasattr(_lowercase				,     """do_resize""" ) )
								self.assertTrue(hasattr(_lowercase				,     """do_center_crop""" ) )
								self.assertTrue(hasattr(_lowercase				,     """size""" ) )





		def  UpperCAmelCase__				(       self )			->    str:







								'''simple docstring'''

								snake_case_ :			List[Any]            =      self.image_processing_class.from_dict(self.image_processor_dict )
								self.assertEqual(image_processor.size				,     {"""shortest_edge""": 1_8} )
								self.assertEqual(image_processor.crop_size				,     {"""height""": 1_8, """width""": 1_8} )

								snake_case_ :			int            =      self.image_processing_class.from_dict(self.image_processor_dict				,     size=4_2				,     crop_size=8_4 )
								self.assertEqual(image_processor.size				,     {"""shortest_edge""": 4_2} )
								self.assertEqual(image_processor.crop_size				,     {"""height""": 8_4, """width""": 8_4} )





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







								'''simple docstring'''

								pass





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







								'''simple docstring'''

								snake_case_ :			Union[str, Any]            =      self.image_processing_class(**self.image_processor_dict )
								# create random PIL images
								snake_case_ :			List[str]            =      prepare_image_inputs(self.image_processor_tester				,     equal_resolution=_lowercase )
								for image in image_inputs:
														self.assertIsInstance(_lowercase				,     Image.Image )

								# Test not batched input
								snake_case_ :			Any            =      image_processing(image_inputs[0]				,     return_tensors="""pt""" ).pixel_values
								self.assertEqual(
								    encoded_images.shape				,     (
								        1,
								        self.image_processor_tester.num_channels,
								        self.image_processor_tester.crop_size["""height"""],
								        self.image_processor_tester.crop_size["""width"""],
								    )				,     )

								# Test batched
								snake_case_ :			str            =      image_processing(_lowercase				,     return_tensors="""pt""" ).pixel_values
								self.assertEqual(
								    encoded_images.shape				,     (
								        self.image_processor_tester.batch_size,
								        self.image_processor_tester.num_channels,
								        self.image_processor_tester.crop_size["""height"""],
								        self.image_processor_tester.crop_size["""width"""],
								    )				,     )





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







								'''simple docstring'''

								snake_case_ :			Any            =      self.image_processing_class(**self.image_processor_dict )
								# create random numpy tensors
								snake_case_ :			str            =      prepare_image_inputs(self.image_processor_tester				,     equal_resolution=_lowercase				,     numpify=_lowercase )
								for image in image_inputs:
														self.assertIsInstance(_lowercase				,     np.ndarray )

								# Test not batched input
								snake_case_ :			List[Any]            =      image_processing(image_inputs[0]				,     return_tensors="""pt""" ).pixel_values
								self.assertEqual(
								    encoded_images.shape				,     (
								        1,
								        self.image_processor_tester.num_channels,
								        self.image_processor_tester.crop_size["""height"""],
								        self.image_processor_tester.crop_size["""width"""],
								    )				,     )

								# Test batched
								snake_case_ :			Dict            =      image_processing(_lowercase				,     return_tensors="""pt""" ).pixel_values
								self.assertEqual(
								    encoded_images.shape				,     (
								        self.image_processor_tester.batch_size,
								        self.image_processor_tester.num_channels,
								        self.image_processor_tester.crop_size["""height"""],
								        self.image_processor_tester.crop_size["""width"""],
								    )				,     )





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







								'''simple docstring'''

								snake_case_ :			int            =      self.image_processing_class(**self.image_processor_dict )
								# create random PyTorch tensors
								snake_case_ :			Any            =      prepare_image_inputs(self.image_processor_tester				,     equal_resolution=_lowercase				,     torchify=_lowercase )
								for image in image_inputs:
														self.assertIsInstance(_lowercase				,     torch.Tensor )

								# Test not batched input
								snake_case_ :			List[str]            =      image_processing(image_inputs[0]				,     return_tensors="""pt""" ).pixel_values
								self.assertEqual(
								    encoded_images.shape				,     (
								        1,
								        self.image_processor_tester.num_channels,
								        self.image_processor_tester.crop_size["""height"""],
								        self.image_processor_tester.crop_size["""width"""],
								    )				,     )

								# Test batched
								snake_case_ :			int            =      image_processing(_lowercase				,     return_tensors="""pt""" ).pixel_values
								self.assertEqual(
								    encoded_images.shape				,     (
								        self.image_processor_tester.batch_size,
								        self.image_processor_tester.num_channels,
								        self.image_processor_tester.crop_size["""height"""],
								        self.image_processor_tester.crop_size["""width"""],
								    )				,     )





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)

