






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 				snake_case__							(							UpperCAmelCase							:  int       ):
    lowerCAmelCase__   :Optional[int]      							=				model.config

    lowerCAmelCase__   :Optional[int]      							=				DonutSwinConfig(
        image_size=original_config.input_size    ,			patch_size=4    ,			depths=original_config.encoder_layer    ,			num_heads=[4, 8, 1_6, 3_2]    ,			window_size=original_config.window_size    ,			embed_dim=1_2_8    ,			)
    lowerCAmelCase__   :List[Any]      							=				MBartConfig(
        is_decoder=UpperCAmelCase    ,			is_encoder_decoder=UpperCAmelCase    ,			add_cross_attention=UpperCAmelCase    ,			decoder_layers=original_config.decoder_layer    ,			max_position_embeddings=original_config.max_position_embeddings    ,			vocab_size=len(
            model.decoder.tokenizer       )    ,			scale_embedding=UpperCAmelCase    ,			add_final_layer_norm=UpperCAmelCase    ,			)

    return encoder_config, decoder_config


def 				snake_case__							(							UpperCAmelCase							:  Dict       ):



    if "encoder.model" in name:
        lowerCAmelCase__   :Dict      							=				name.replace("encoder.model"    ,			"encoder"       )
    if "decoder.model" in name:
        lowerCAmelCase__   :int      							=				name.replace("decoder.model"    ,			"decoder"       )
    if "patch_embed.proj" in name:
        lowerCAmelCase__   :str      							=				name.replace("patch_embed.proj"    ,			"embeddings.patch_embeddings.projection"       )
    if "patch_embed.norm" in name:
        lowerCAmelCase__   :Optional[Any]      							=				name.replace("patch_embed.norm"    ,			"embeddings.norm"       )
    if name.startswith("encoder"       ):
        if "layers" in name:
            lowerCAmelCase__   :List[str]      							=				'''encoder.''' + name
        if "attn.proj" in name:
            lowerCAmelCase__   :List[Any]      							=				name.replace("attn.proj"    ,			"attention.output.dense"       )
        if "attn" in name and "mask" not in name:
            lowerCAmelCase__   :Dict      							=				name.replace("attn"    ,			"attention.self"       )
        if "norm1" in name:
            lowerCAmelCase__   :Any      							=				name.replace("norm1"    ,			"layernorm_before"       )
        if "norm2" in name:
            lowerCAmelCase__   :Union[str, Any]      							=				name.replace("norm2"    ,			"layernorm_after"       )
        if "mlp.fc1" in name:
            lowerCAmelCase__   :Optional[int]      							=				name.replace("mlp.fc1"    ,			"intermediate.dense"       )
        if "mlp.fc2" in name:
            lowerCAmelCase__   :List[str]      							=				name.replace("mlp.fc2"    ,			"output.dense"       )

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

    return name


def 				snake_case__							(							UpperCAmelCase							:  Union[str, Any]    ,			UpperCAmelCase							:  int       ):



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

        if "qkv" in key:
            lowerCAmelCase__   :Optional[Any]      							=				key.split("."       )
            lowerCAmelCase__   :List[Any]      							=				int(key_split[3]       )
            lowerCAmelCase__   :List[Any]      							=				int(key_split[5]       )
            lowerCAmelCase__   :Tuple      							=				model.encoder.encoder.layers[layer_num].blocks[block_num].attention.self.all_head_size

            if "weight" in key:
                lowerCAmelCase__   :List[Any]      							=				val[:dim, :]
                lowerCAmelCase__   :Optional[Any]      							=				val[dim : dim * 2, :]
                lowerCAmelCase__   :Optional[int]      							=				val[-dim:, :]
            else:
                lowerCAmelCase__   :Any      							=				val[:dim]
                lowerCAmelCase__   :Optional[int]      							=				val[dim : dim * 2]
                lowerCAmelCase__   :str      							=				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:
            lowerCAmelCase__   :Optional[Any]      							=				val

    return orig_state_dict


def 				snake_case__							(							UpperCAmelCase							:  Optional[int]    ,			UpperCAmelCase							:  List[Any]=None    ,			UpperCAmelCase							:  Any=False       ):
    lowerCAmelCase__   :Tuple      							=				DonutModel.from_pretrained(UpperCAmelCase       ).eval()

    # load HuggingFace model
    lowerCAmelCase__   :Optional[int]      							=				get_configs(UpperCAmelCase       )
    lowerCAmelCase__   :List[str]      							=				DonutSwinModel(UpperCAmelCase       )
    lowerCAmelCase__   :str      							=				MBartForCausalLM(UpperCAmelCase       )
    lowerCAmelCase__   :Union[str, Any]      							=				VisionEncoderDecoderModel(encoder=UpperCAmelCase    ,			decoder=UpperCAmelCase       )
    model.eval()

    lowerCAmelCase__   :Union[str, Any]      							=				original_model.state_dict()
    lowerCAmelCase__   :Optional[int]      							=				convert_state_dict(UpperCAmelCase    ,			UpperCAmelCase       )
    model.load_state_dict(UpperCAmelCase       )

    # verify results on scanned document
    lowerCAmelCase__   :Union[str, Any]      							=				load_dataset("hf-internal-testing/example-documents"       )
    lowerCAmelCase__   :Tuple      							=				dataset['''test'''][0]['''image'''].convert("RGB"       )

    lowerCAmelCase__   :str      							=				XLMRobertaTokenizerFast.from_pretrained(UpperCAmelCase    ,			from_slow=UpperCAmelCase       )
    lowerCAmelCase__   :Tuple      							=				DonutImageProcessor(
        do_align_long_axis=original_model.config.align_long_axis    ,			size=original_model.config.input_size[::-1]       )
    lowerCAmelCase__   :List[Any]      							=				DonutProcessor(UpperCAmelCase    ,			UpperCAmelCase       )
    lowerCAmelCase__   :List[str]      							=				processor(UpperCAmelCase    ,			return_tensors="pt"       ).pixel_values

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

    lowerCAmelCase__   :Optional[int]      							=				original_model.encoder.model.patch_embed(UpperCAmelCase       )
    lowerCAmelCase__   :Any      							=				model.encoder.embeddings(UpperCAmelCase       )
    assert torch.allclose(UpperCAmelCase    ,			UpperCAmelCase    ,			atol=1E-3       )

    # verify encoder hidden states
    lowerCAmelCase__   :List[Any]      							=				original_model.encoder(UpperCAmelCase       )
    lowerCAmelCase__   :Tuple      							=				model.encoder(UpperCAmelCase       ).last_hidden_state
    assert torch.allclose(UpperCAmelCase    ,			UpperCAmelCase    ,			atol=1E-2       )

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

    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    :   List[str]        =			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    :   str        =			parser.parse_args()
 convert_donut_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)








from math import isqrt, loga


def 				snake_case__							(							UpperCAmelCase							:  int       ):
    lowerCAmelCase__   :Optional[int]      							=				[True] * max_number
    for i in range(2    ,			isqrt(max_number - 1       ) + 1       ):
        if is_prime[i]:
            for j in range(i**2    ,			UpperCAmelCase    ,			UpperCAmelCase       ):
                lowerCAmelCase__   :int      							=				False

    return [i for i in range(2    ,			UpperCAmelCase       ) if is_prime[i]]


def 				snake_case__							(							UpperCAmelCase							:  int = 8_0_0_8_0_0    ,			UpperCAmelCase							:  int = 8_0_0_8_0_0       ):
    lowerCAmelCase__   :str      							=				degree * loga(UpperCAmelCase       )
    lowerCAmelCase__   :Any      							=				int(UpperCAmelCase       )
    lowerCAmelCase__   :List[Any]      							=				calculate_prime_numbers(UpperCAmelCase       )

    lowerCAmelCase__   :List[str]      							=				0
    lowerCAmelCase__   :List[str]      							=				0
    lowerCAmelCase__   :Optional[Any]      							=				len(UpperCAmelCase       ) - 1
    while left < right:
        while (
            prime_numbers[right] * loga(prime_numbers[left]       )
            + prime_numbers[left] * loga(prime_numbers[right]       )
            > upper_bound
        ):
            right -= 1
        hybrid_integers_count += right - left
        left += 1

    return hybrid_integers_count


if __name__ == "__main__":
 print(f"""{solution() = }""")



