


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_   (	_a     ,       _a=False	):




		"""simple docstring"""






		lowerCAmelCase__       :      int   					= []
		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__       :      Dict   					= [(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_   (	_a     ,       _a     ,       _a=False	):




		"""simple docstring"""






		for i in range(config.num_hidden_layers	):
				if base_model:
						lowerCAmelCase__       :      List[str]   					= ''''''
				else:
						lowerCAmelCase__       :      Union[str, Any]   					= '''vit.'''
				# read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
				lowerCAmelCase__       :      int   					= state_dict.pop(f'module.blocks.{i}.attn.qkv.weight'	)
				lowerCAmelCase__       :      Optional[int]   					= 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[Any]   					= in_proj_weight[
				    : config.hidden_size, :
				]
				lowerCAmelCase__       :      List[Any]   					= in_proj_bias[: config.hidden_size]
				lowerCAmelCase__       :      Optional[Any]   					= in_proj_weight[
				    config.hidden_size : config.hidden_size * 2, :
				]
				lowerCAmelCase__       :      int   					= in_proj_bias[
				    config.hidden_size : config.hidden_size * 2
				]
				lowerCAmelCase__       :      Optional[int]   					= in_proj_weight[
				    -config.hidden_size :, :
				]
				lowerCAmelCase__       :      Optional[Any]   					= in_proj_bias[-config.hidden_size :]






def 					lowerCamelCase_   (	_a	):




		"""simple docstring"""






		lowerCAmelCase__       :      str   					= ['''head.weight''', '''head.bias''']
		for k in ignore_keys:
				state_dict.pop(_a     ,       _a	)






def 					lowerCamelCase_   (	_a	):




		"""simple docstring"""






		lowerCAmelCase__       :      Optional[Any]   					= [
		    '''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(_a     ,       _a	)






def 					lowerCamelCase_   (	_a     ,       _a     ,       _a	):




		"""simple docstring"""






		lowerCAmelCase__       :      str   					= dct.pop(_a	)
		lowerCAmelCase__       :      Optional[Any]   					= val






def 					lowerCamelCase_   (	_a     ,       _a	):




		"""simple docstring"""






		lowerCAmelCase__       :      List[Any]   					= ViTMSNConfig()
		lowerCAmelCase__       :      Optional[Any]   					= 1_000

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

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

		lowerCAmelCase__       :      str   					= ViTMSNModel(_a	)

		lowerCAmelCase__       :      Any   					= torch.hub.load_state_dict_from_url(_a     ,       map_location='''cpu'''	)['''target_encoder''']

		lowerCAmelCase__       :      Optional[Any]   					= ViTImageProcessor(size=config.image_size	)

		remove_projection_head(_a	)
		lowerCAmelCase__       :      int   					= create_rename_keys(_a     ,       base_model=_a	)

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

		model.load_state_dict(_a	)
		model.eval()

		lowerCAmelCase__       :      Any   					= '''http://images.cocodataset.org/val2017/000000039769.jpg'''

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

		# forward pass
		torch.manual_seed(2	)
		lowerCAmelCase__       :      Any   					= model(**_a	)
		lowerCAmelCase__       :      str   					= 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__       :      int   					= torch.tensor([[-1.09_15, -1.48_76, -1.18_09]]	)
		elif "b16" in checkpoint_url:
				lowerCAmelCase__       :      List[Any]   					= torch.tensor([[14.28_89, -18.90_45, 11.72_81]]	)
		elif "l16" in checkpoint_url:
				lowerCAmelCase__       :      List[Any]   					= torch.tensor([[41.50_28, -22.86_81, 45.64_75]]	)
		elif "b4" in checkpoint_url:
				lowerCAmelCase__       :      Union[str, Any]   					= torch.tensor([[-4.38_68, 5.29_32, -0.41_37]]	)
		else:
				lowerCAmelCase__       :      Union[str, Any]   					= torch.tensor([[-0.17_92, -0.64_65, 2.42_63]]	)

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

		print(f'Saving model to {pytorch_dump_folder_path}'	)
		model.save_pretrained(_a	)

		print(f'Saving image processor to {pytorch_dump_folder_path}'	)
		image_processor.save_pretrained(_a	)


if __name__ == "__main__":
		lowerCamelCase						=		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.'''
		)

		lowerCamelCase						=		parser.parse_args()
		convert_vit_msn_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)








import timeit

import numpy as np

import datasets
from datasets.arrow_writer import ArrowWriter
from datasets.features.features import _ArrayXD






def 					lowerCamelCase_   (	_a	):




		"""simple docstring"""






		def wrapper(*_a     ,       **_a	):
				lowerCAmelCase__       :      List[str]   					= timeit.default_timer()
				lowerCAmelCase__       :      List[Any]   					= func(*_a     ,       **_a	)
				lowerCAmelCase__       :      Any   					= timeit.default_timer() - starttime
				return delta

		lowerCAmelCase__       :      Any   					= func.__name__

		return wrapper






def 					lowerCamelCase_   (	_a     ,       _a=100     ,       _a=None	):




		"""simple docstring"""






		lowerCAmelCase__       :      str   					= []
		lowerCAmelCase__       :      str   					= seq_shapes or {}
		for i in range(_a	):
				lowerCAmelCase__       :      List[str]   					= {}
				for col_id, (k, v) in enumerate(features.items()	):
						if isinstance(_a     ,       _ArrayXD	):
								lowerCAmelCase__       :      List[str]   					= np.random.rand(*v.shape	).astype(v.dtype	)
						elif isinstance(_a     ,       datasets.Value	):
								if v.dtype == "string":
										lowerCAmelCase__       :      Dict   					= '''The small grey turtle was surprisingly fast when challenged.'''
								else:
										lowerCAmelCase__       :      Any   					= np.random.randint(10     ,       size=1	).astype(v.dtype	).item()
						elif isinstance(_a     ,       datasets.Sequence	):
								while isinstance(_a     ,       datasets.Sequence	):
										lowerCAmelCase__       :      Optional[int]   					= v.feature
								lowerCAmelCase__       :      str   					= seq_shapes[k]
								lowerCAmelCase__       :      Any   					= np.random.rand(*_a	).astype(v.dtype	)
						lowerCAmelCase__       :      int   					= data

				dummy_data.append((i, example)	)

		return dummy_data






def 					lowerCamelCase_   (	_a     ,       _a     ,       _a=100     ,       _a=None	):




		"""simple docstring"""






		lowerCAmelCase__       :      Optional[Any]   					= generate_examples(_a     ,       num_examples=_a     ,       seq_shapes=_a	)

		with ArrowWriter(features=_a     ,       path=_a	) as writer:
				for key, record in dummy_data:
						lowerCAmelCase__       :      Optional[int]   					= features.encode_example(_a	)
						writer.write(_a	)

				lowerCAmelCase__					,     lowerCAmelCase__       :      List[str]   					= writer.finalize()

		if not num_final_examples == num_examples:
				raise ValueError(
				    f'Error writing the dataset, wrote {num_final_examples} examples but should have written {num_examples}.'	)

		lowerCAmelCase__       :      List[Any]   					= datasets.Dataset.from_file(filename=_a     ,       info=datasets.DatasetInfo(features=_a	)	)

		return dataset




