



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  lowerCamelCase_	(      lowerCAmelCase__	:	Dict				)       ->							Union[str, Any]:

							'''simple docstring'''






							A      						=    model.config

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

							return encoder_config, decoder_config






def  lowerCamelCase_	(      lowerCAmelCase__	:	List[str]				)       ->							Any:

							'''simple docstring'''






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

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

							return name






def  lowerCamelCase_	(      lowerCAmelCase__	:	Union[str, Any]			,	lowerCAmelCase__	:	Any				)       ->							Optional[Any]:

							'''simple docstring'''






							for key in orig_state_dict.copy().keys():
														A      						=    orig_state_dict.pop(lowerCAmelCase__				)

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

																					if "weight" in key:
																												A      						=    val[:dim, :]
																												A      						=    val[dim : dim * 2, :]
																												A      						=    val[-dim:, :]
																					else:
																												A      						=    val[:dim]
																												A      						=    val[dim : dim * 2]
																												A      						=    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:
																					A      						=    val

							return orig_state_dict






def  lowerCamelCase_	(      lowerCAmelCase__	:	Tuple			,	lowerCAmelCase__	:	Tuple=None			,	lowerCAmelCase__	:	Any=False				)       ->							Any:

							'''simple docstring'''






							A      						=    DonutModel.from_pretrained(lowerCAmelCase__				).eval()

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

							A      						=    original_model.state_dict()
							A      						=    convert_state_dict(lowerCAmelCase__			,	lowerCAmelCase__				)
							model.load_state_dict(lowerCAmelCase__				)

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

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

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

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

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

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

							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__":
				__snake_case     :Any			       =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.',
				)

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




import unittest

from diffusers.pipelines.pipeline_utils import is_safetensors_compatible



class        lowerCAmelCase__					(  unittest.TestCase       ):


				def __UpperCamelCase						(							self      :  List[str]       )		->     Any:
											A      						=    [
											    'safety_checker/pytorch_model.bin',
											    'safety_checker/model.safetensors',
											    'vae/diffusion_pytorch_model.bin',
											    'vae/diffusion_pytorch_model.safetensors',
											    'text_encoder/pytorch_model.bin',
											    'text_encoder/model.safetensors',
											    'unet/diffusion_pytorch_model.bin',
											    'unet/diffusion_pytorch_model.safetensors',
											]
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  str       )		->     List[Any]:
											A      						=    [
											    'unet/diffusion_pytorch_model.bin',
											    'unet/diffusion_pytorch_model.safetensors',
											]
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  Any       )		->     Tuple:
											A      						=    [
											    'safety_checker/pytorch_model.bin',
											    'safety_checker/model.safetensors',
											    'vae/diffusion_pytorch_model.bin',
											    'vae/diffusion_pytorch_model.safetensors',
											    'text_encoder/pytorch_model.bin',
											    'text_encoder/model.safetensors',
											    'unet/diffusion_pytorch_model.bin',
											    # Removed: 'unet/diffusion_pytorch_model.safetensors',
											]
											self.assertFalse(is_safetensors_compatible(__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  Dict       )		->     Any:
											A      						=    [
											    'text_encoder/pytorch_model.bin',
											    'text_encoder/model.safetensors',
											]
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  Optional[int]       )		->     List[str]:
											A      						=    [
											    'safety_checker/pytorch_model.bin',
											    'safety_checker/model.safetensors',
											    'vae/diffusion_pytorch_model.bin',
											    'vae/diffusion_pytorch_model.safetensors',
											    'text_encoder/pytorch_model.bin',
											    # Removed: 'text_encoder/model.safetensors',
											    'unet/diffusion_pytorch_model.bin',
											    'unet/diffusion_pytorch_model.safetensors',
											]
											self.assertFalse(is_safetensors_compatible(__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  List[str]       )		->     List[str]:
											A      						=    [
											    'safety_checker/pytorch_model.fp16.bin',
											    'safety_checker/model.fp16.safetensors',
											    'vae/diffusion_pytorch_model.fp16.bin',
											    'vae/diffusion_pytorch_model.fp16.safetensors',
											    'text_encoder/pytorch_model.fp16.bin',
											    'text_encoder/model.fp16.safetensors',
											    'unet/diffusion_pytorch_model.fp16.bin',
											    'unet/diffusion_pytorch_model.fp16.safetensors',
											]
											A      						=    'fp16'
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  Optional[Any]       )		->     Optional[Any]:
											A      						=    [
											    'unet/diffusion_pytorch_model.fp16.bin',
											    'unet/diffusion_pytorch_model.fp16.safetensors',
											]
											A      						=    'fp16'
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  int       )		->     Optional[int]:
											# pass variant but use the non-variant filenames
											A      						=    [
											    'unet/diffusion_pytorch_model.bin',
											    'unet/diffusion_pytorch_model.safetensors',
											]
											A      						=    'fp16'
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  Any       )		->     List[str]:
											A      						=    [
											    'safety_checker/pytorch_model.fp16.bin',
											    'safety_checker/model.fp16.safetensors',
											    'vae/diffusion_pytorch_model.fp16.bin',
											    'vae/diffusion_pytorch_model.fp16.safetensors',
											    'text_encoder/pytorch_model.fp16.bin',
											    'text_encoder/model.fp16.safetensors',
											    'unet/diffusion_pytorch_model.fp16.bin',
											    # Removed: 'unet/diffusion_pytorch_model.fp16.safetensors',
											]
											A      						=    'fp16'
											self.assertFalse(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  Optional[Any]       )		->     Optional[int]:
											A      						=    [
											    'text_encoder/pytorch_model.fp16.bin',
											    'text_encoder/model.fp16.safetensors',
											]
											A      						=    'fp16'
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  List[str]       )		->     int:
											# pass variant but use the non-variant filenames
											A      						=    [
											    'text_encoder/pytorch_model.bin',
											    'text_encoder/model.safetensors',
											]
											A      						=    'fp16'
											self.assertTrue(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )


				def __UpperCamelCase						(							self      :  List[str]       )		->     Optional[Any]:
											A      						=    [
											    'safety_checker/pytorch_model.fp16.bin',
											    'safety_checker/model.fp16.safetensors',
											    'vae/diffusion_pytorch_model.fp16.bin',
											    'vae/diffusion_pytorch_model.fp16.safetensors',
											    'text_encoder/pytorch_model.fp16.bin',
											    # 'text_encoder/model.fp16.safetensors',
											    'unet/diffusion_pytorch_model.fp16.bin',
											    'unet/diffusion_pytorch_model.fp16.safetensors',
											]
											A      						=    'fp16'
											self.assertFalse(is_safetensors_compatible(__UpperCamelCase						, variant=__UpperCamelCase       )       )