


import argparse
import json

import requests
import torch
from huggingface_hub import hf_hub_download
from PIL import Image

from transformers import ViTImageProcessor, ViTMSNConfig, ViTMSNModel
from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD


torch.set_grad_enabled(False)



def 			lowerCAmelCase (		lowerCAmelCase_ ,   lowerCAmelCase_=False )-> Optional[Any]:
				lowerCAmelCase_ :      Dict    				=				[]
				for i in range(config.num_hidden_layers ):
								# encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
								rename_keys.append((f"""module.blocks.{i}.norm1.weight""", f"""vit.encoder.layer.{i}.layernorm_before.weight""") )
								rename_keys.append((f"""module.blocks.{i}.norm1.bias""", f"""vit.encoder.layer.{i}.layernorm_before.bias""") )
								rename_keys.append(
								    (f"""module.blocks.{i}.attn.proj.weight""", f"""vit.encoder.layer.{i}.attention.output.dense.weight""") )
								rename_keys.append((f"""module.blocks.{i}.attn.proj.bias""", f"""vit.encoder.layer.{i}.attention.output.dense.bias""") )
								rename_keys.append((f"""module.blocks.{i}.norm2.weight""", f"""vit.encoder.layer.{i}.layernorm_after.weight""") )
								rename_keys.append((f"""module.blocks.{i}.norm2.bias""", f"""vit.encoder.layer.{i}.layernorm_after.bias""") )
								rename_keys.append((f"""module.blocks.{i}.mlp.fc1.weight""", f"""vit.encoder.layer.{i}.intermediate.dense.weight""") )
								rename_keys.append((f"""module.blocks.{i}.mlp.fc1.bias""", f"""vit.encoder.layer.{i}.intermediate.dense.bias""") )
								rename_keys.append((f"""module.blocks.{i}.mlp.fc2.weight""", f"""vit.encoder.layer.{i}.output.dense.weight""") )
								rename_keys.append((f"""module.blocks.{i}.mlp.fc2.bias""", f"""vit.encoder.layer.{i}.output.dense.bias""") )

				# projection layer + position embeddings
				rename_keys.extend(
				    [
				        ('''module.cls_token''', '''vit.embeddings.cls_token'''),
				        ('''module.patch_embed.proj.weight''', '''vit.embeddings.patch_embeddings.projection.weight'''),
				        ('''module.patch_embed.proj.bias''', '''vit.embeddings.patch_embeddings.projection.bias'''),
				        ('''module.pos_embed''', '''vit.embeddings.position_embeddings'''),
				    ] )

				if base_model:
								# layernorm + pooler
								rename_keys.extend(
								    [
								        ('''module.norm.weight''', '''layernorm.weight'''),
								        ('''module.norm.bias''', '''layernorm.bias'''),
								    ] )

								# if just the base model, we should remove "vit" from all keys that start with "vit"
								lowerCAmelCase_ :      List[str]    				=				[(pair[0], pair[1][4:]) if pair[1].startswith('''vit''' ) else pair for pair in rename_keys]
				else:
								# layernorm + classification head
								rename_keys.extend(
								    [
								        ('''norm.weight''', '''vit.layernorm.weight'''),
								        ('''norm.bias''', '''vit.layernorm.bias'''),
								        ('''head.weight''', '''classifier.weight'''),
								        ('''head.bias''', '''classifier.bias'''),
								    ] )

				return rename_keys



def 			lowerCAmelCase (		lowerCAmelCase_ ,   lowerCAmelCase_ ,   lowerCAmelCase_=False )-> List[str]:
				for i in range(config.num_hidden_layers ):
								if base_model:
												lowerCAmelCase_ :      Optional[Any]    				=				''''''
								else:
												lowerCAmelCase_ :      Optional[Any]    				=				'''vit.'''
								# read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
								lowerCAmelCase_ :      List[Any]    				=				state_dict.pop(f"""module.blocks.{i}.attn.qkv.weight""" )
								lowerCAmelCase_ :      Optional[Any]    				=				state_dict.pop(f"""module.blocks.{i}.attn.qkv.bias""" )
								# next, add query, keys and values (in that order) to the state dict
								lowerCAmelCase_ :      Optional[int]    				=				in_proj_weight[
								    : config.hidden_size, :
								]
								lowerCAmelCase_ :      List[str]    				=				in_proj_bias[: config.hidden_size]
								lowerCAmelCase_ :      Union[str, Any]    				=				in_proj_weight[
								    config.hidden_size : config.hidden_size * 2, :
								]
								lowerCAmelCase_ :      Tuple    				=				in_proj_bias[
								    config.hidden_size : config.hidden_size * 2
								]
								lowerCAmelCase_ :      List[Any]    				=				in_proj_weight[
								    -config.hidden_size :, :
								]
								lowerCAmelCase_ :      Optional[int]    				=				in_proj_bias[-config.hidden_size :]



def 			lowerCAmelCase (		lowerCAmelCase_ )-> Optional[int]:
				lowerCAmelCase_ :      Union[str, Any]    				=				['''head.weight''', '''head.bias''']
				for k in ignore_keys:
								state_dict.pop(lowerCAmelCase_ ,   lowerCAmelCase_ )



def 			lowerCAmelCase (		lowerCAmelCase_ )-> int:
				# projection head is used in the self-supervised pre-training in MSN,
				# for downstream task it's not needed.
				lowerCAmelCase_ :      Optional[int]    				=				[
				    '''module.fc.fc1.weight''',
				    '''module.fc.fc1.bias''',
				    '''module.fc.bn1.weight''',
				    '''module.fc.bn1.bias''',
				    '''module.fc.bn1.running_mean''',
				    '''module.fc.bn1.running_var''',
				    '''module.fc.bn1.num_batches_tracked''',
				    '''module.fc.fc2.weight''',
				    '''module.fc.fc2.bias''',
				    '''module.fc.bn2.weight''',
				    '''module.fc.bn2.bias''',
				    '''module.fc.bn2.running_mean''',
				    '''module.fc.bn2.running_var''',
				    '''module.fc.bn2.num_batches_tracked''',
				    '''module.fc.fc3.weight''',
				    '''module.fc.fc3.bias''',
				]
				for k in ignore_keys:
								state_dict.pop(lowerCAmelCase_ ,   lowerCAmelCase_ )



def 			lowerCAmelCase (		lowerCAmelCase_ ,   lowerCAmelCase_ ,   lowerCAmelCase_ )-> Tuple:
				lowerCAmelCase_ :      Union[str, Any]    				=				dct.pop(lowerCAmelCase_ )
				lowerCAmelCase_ :      Union[str, Any]    				=				val



def 			lowerCAmelCase (		lowerCAmelCase_ ,   lowerCAmelCase_ )-> Optional[int]:
				lowerCAmelCase_ :      Any    				=				ViTMSNConfig()
				lowerCAmelCase_ :      Optional[int]    				=				1_000

				lowerCAmelCase_ :      Optional[int]    				=				'''datasets/huggingface/label-files'''
				lowerCAmelCase_ :      Optional[Any]    				=				'''imagenet-1k-id2label.json'''
				lowerCAmelCase_ :      List[Any]    				=				json.load(open(hf_hub_download(lowerCAmelCase_ ,   lowerCAmelCase_ ) ,   '''r''' ) )
				lowerCAmelCase_ :      Optional[int]    				=				{int(lowerCAmelCase_ ): v for k, v in idalabel.items()}
				lowerCAmelCase_ :      Optional[int]    				=				idalabel
				lowerCAmelCase_ :      Dict    				=				{v: k for k, v in idalabel.items()}

				if "s16" in checkpoint_url:
								lowerCAmelCase_ :      str    				=				384
								lowerCAmelCase_ :      Optional[Any]    				=				1_536
								lowerCAmelCase_ :      Dict    				=				6
				elif "l16" in checkpoint_url:
								lowerCAmelCase_ :      Dict    				=				1_024
								lowerCAmelCase_ :      List[Any]    				=				4_096
								lowerCAmelCase_ :      Optional[Any]    				=				24
								lowerCAmelCase_ :      Optional[int]    				=				16
								lowerCAmelCase_ :      List[str]    				=				0.1
				elif "b4" in checkpoint_url:
								lowerCAmelCase_ :      Dict    				=				4
				elif "l7" in checkpoint_url:
								lowerCAmelCase_ :      Tuple    				=				7
								lowerCAmelCase_ :      Any    				=				1_024
								lowerCAmelCase_ :      Optional[int]    				=				4_096
								lowerCAmelCase_ :      Optional[Any]    				=				24
								lowerCAmelCase_ :      Optional[Any]    				=				16
								lowerCAmelCase_ :      Optional[int]    				=				0.1

				lowerCAmelCase_ :      List[str]    				=				ViTMSNModel(lowerCAmelCase_ )

				lowerCAmelCase_ :      List[str]    				=				torch.hub.load_state_dict_from_url(lowerCAmelCase_ ,   map_location='''cpu''' )['''target_encoder''']

				lowerCAmelCase_ :      List[str]    				=				ViTImageProcessor(size=config.image_size )

				remove_projection_head(lowerCAmelCase_ )
				lowerCAmelCase_ :      Dict    				=				create_rename_keys(lowerCAmelCase_ ,   base_model=lowerCAmelCase_ )

				for src, dest in rename_keys:
								rename_key(lowerCAmelCase_ ,   lowerCAmelCase_ ,   lowerCAmelCase_ )
				read_in_q_k_v(lowerCAmelCase_ ,   lowerCAmelCase_ ,   base_model=lowerCAmelCase_ )

				model.load_state_dict(lowerCAmelCase_ )
				model.eval()

				lowerCAmelCase_ :      Dict    				=				'''http://images.cocodataset.org/val2017/000000039769.jpg'''

				lowerCAmelCase_ :      str    				=				Image.open(requests.get(lowerCAmelCase_ ,   stream=lowerCAmelCase_ ).raw )
				lowerCAmelCase_ :      Optional[Any]    				=				ViTImageProcessor(
				    size=config.image_size ,   image_mean=lowerCAmelCase_ ,   image_std=lowerCAmelCase_ )
				lowerCAmelCase_ :      str    				=				image_processor(images=lowerCAmelCase_ ,   return_tensors='''pt''' )

				# forward pass
				torch.manual_seed(2 )
				lowerCAmelCase_ :      Optional[Any]    				=				model(**lowerCAmelCase_ )
				lowerCAmelCase_ :      List[Any]    				=				outputs.last_hidden_state

				# The following Colab Notebook was used to generate these outputs:
				# https://colab.research.google.com/gist/sayakpaul/3672419a04f5997827503fd84079bdd1/scratchpad.ipynb
				if "s16" in checkpoint_url:
								lowerCAmelCase_ :      Optional[int]    				=				torch.tensor([[-1.0915, -1.4876, -1.1809]] )
				elif "b16" in checkpoint_url:
								lowerCAmelCase_ :      List[str]    				=				torch.tensor([[14.2889, -18.9045, 11.7281]] )
				elif "l16" in checkpoint_url:
								lowerCAmelCase_ :      str    				=				torch.tensor([[41.5028, -22.8681, 45.6475]] )
				elif "b4" in checkpoint_url:
								lowerCAmelCase_ :      str    				=				torch.tensor([[-4.3868, 5.2932, -0.4137]] )
				else:
								lowerCAmelCase_ :      Union[str, Any]    				=				torch.tensor([[-0.1792, -0.6465, 2.4263]] )

				# verify logits
				assert torch.allclose(last_hidden_state[:, 0, :3] ,   lowerCAmelCase_ ,   atol=1e-4 )

				print(f"""Saving model to {pytorch_dump_folder_path}""" )
				model.save_pretrained(lowerCAmelCase_ )

				print(f"""Saving image processor to {pytorch_dump_folder_path}""" )
				image_processor.save_pretrained(lowerCAmelCase_ )


if __name__ == "__main__":
						_UpperCAmelCase			:  str     =argparse.ArgumentParser()
						# Required parameters
						parser.add_argument(
						    """--checkpoint_url""",
						    default="""https://dl.fbaipublicfiles.com/msn/vits16_800ep.pth.tar""",
						    type=str,
						    help="""URL of the checkpoint you'd like to convert.""",
						)
						parser.add_argument(
						    """--pytorch_dump_folder_path""", default=None, type=str, help="""Path to the output PyTorch model directory."""
						)

						_UpperCAmelCase			:  List[Any]     =parser.parse_args()
						convert_vit_msn_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)



_UpperCAmelCase			:  int     =frozenset(
    [
        """prompt""",
        """height""",
        """width""",
        """guidance_scale""",
        """negative_prompt""",
        """prompt_embeds""",
        """negative_prompt_embeds""",
        """cross_attention_kwargs""",
    ]
)

_UpperCAmelCase			:  List[Any]     =frozenset(["""prompt""", """negative_prompt"""])

_UpperCAmelCase			:  Dict     =frozenset([])

_UpperCAmelCase			:  int     =frozenset(["""image"""])

_UpperCAmelCase			:  Tuple     =frozenset(
    [
        """image""",
        """height""",
        """width""",
        """guidance_scale""",
    ]
)

_UpperCAmelCase			:  int     =frozenset(["""image"""])

_UpperCAmelCase			:  str     =frozenset(
    [
        """prompt""",
        """image""",
        """height""",
        """width""",
        """guidance_scale""",
        """negative_prompt""",
        """prompt_embeds""",
        """negative_prompt_embeds""",
    ]
)

_UpperCAmelCase			:  int     =frozenset(["""prompt""", """image""", """negative_prompt"""])

_UpperCAmelCase			:  Optional[int]     =frozenset(
    [
        # Text guided image variation with an image mask
        """prompt""",
        """image""",
        """mask_image""",
        """height""",
        """width""",
        """guidance_scale""",
        """negative_prompt""",
        """prompt_embeds""",
        """negative_prompt_embeds""",
    ]
)

_UpperCAmelCase			:  Optional[int]     =frozenset(["""prompt""", """image""", """mask_image""", """negative_prompt"""])

_UpperCAmelCase			:  Optional[Any]     =frozenset(
    [
        # image variation with an image mask
        """image""",
        """mask_image""",
        """height""",
        """width""",
        """guidance_scale""",
    ]
)

_UpperCAmelCase			:  Optional[Any]     =frozenset(["""image""", """mask_image"""])

_UpperCAmelCase			:  Union[str, Any]     =frozenset(
    [
        """example_image""",
        """image""",
        """mask_image""",
        """height""",
        """width""",
        """guidance_scale""",
    ]
)

_UpperCAmelCase			:  Tuple     =frozenset(["""example_image""", """image""", """mask_image"""])

_UpperCAmelCase			:  Any     =frozenset(["""class_labels"""])

_UpperCAmelCase			:  List[Any]     =frozenset(["""class_labels"""])

_UpperCAmelCase			:  int     =frozenset(["""batch_size"""])

_UpperCAmelCase			:  str     =frozenset([])

_UpperCAmelCase			:  str     =frozenset(["""batch_size"""])

_UpperCAmelCase			:  Optional[Any]     =frozenset([])

_UpperCAmelCase			:  Tuple     =frozenset(
    [
        """prompt""",
        """audio_length_in_s""",
        """guidance_scale""",
        """negative_prompt""",
        """prompt_embeds""",
        """negative_prompt_embeds""",
        """cross_attention_kwargs""",
    ]
)

_UpperCAmelCase			:  Tuple     =frozenset(["""prompt""", """negative_prompt"""])
_UpperCAmelCase			:  List[str]     =frozenset(["""input_tokens"""])

_UpperCAmelCase			:  Optional[Any]     =frozenset(["""input_tokens"""])