

import argparse
import json

import gdown
import numpy as np
import torch
from huggingface_hub import hf_hub_download

from transformers import (
    VideoMAEConfig,
    VideoMAEForPreTraining,
    VideoMAEForVideoClassification,
    VideoMAEImageProcessor,
)

def 		UpperCamelCase      (		lowercase_:				int      )  ->   Optional[int]:
	A__							:					List[str]       =	VideoMAEConfig()

	set_architecture_configs(lowerCAmelCase_					,   lowerCAmelCase_      )

	if "finetuned" not in model_name:
		A__							:					Tuple       =	False

	if "finetuned" in model_name:
		A__							:					Optional[int]       =	"huggingface/label-files"
		if "kinetics" in model_name:
			A__							:					Union[str, Any]       =	400
			A__							:					Dict       =	"kinetics400-id2label.json"
		elif "ssv2" in model_name:
			A__							:					Optional[int]       =	174
			A__							:					Optional[int]       =	"something-something-v2-id2label.json"
		else:
			raise ValueError("""Model name should either contain 'kinetics' or 'ssv2' in case it's fine-tuned."""      )
		A__							:					Dict       =	json.load(open(hf_hub_download(lowerCAmelCase_					,   lowerCAmelCase_					,   repo_type="""dataset"""      )					,   """r"""      )      )
		A__							:					str       =	{int(lowerCAmelCase_      ): v for k, v in idalabel.items()}
		A__							:					Tuple       =	idalabel
		A__							:					Dict       =	{v: k for k, v in idalabel.items()}

	return config

def 		UpperCamelCase      (		lowercase_:				Optional[int]					,   lowercase_:				Optional[int]      )  ->   Any:


	if "small" in model_name:
		A__							:					Dict       =	384
		A__							:					Optional[int]       =	1536
		A__							:					int       =	12
		A__							:					Tuple       =	16
		A__							:					List[str]       =	12
		A__							:					Dict       =	3
		A__							:					Dict       =	192
		A__							:					Any       =	768
	elif "large" in model_name:
		A__							:					Any       =	1024
		A__							:					Tuple       =	4096
		A__							:					Union[str, Any]       =	24
		A__							:					List[str]       =	16
		A__							:					Union[str, Any]       =	12
		A__							:					Any       =	8
		A__							:					Tuple       =	512
		A__							:					str       =	2048
	elif "huge" in model_name:
		A__							:					str       =	1280
		A__							:					int       =	5120
		A__							:					List[Any]       =	32
		A__							:					Dict       =	16
		A__							:					Tuple       =	12
		A__							:					Union[str, Any]       =	8
		A__							:					Dict       =	640
		A__							:					Tuple       =	2560
	elif "base" not in model_name:
		raise ValueError("""Model name should include either \"small\", \"base\", \"large\", or \"huge\""""      )

def 		UpperCamelCase      (		lowercase_:				Optional[int]      )  ->   Optional[int]:


	if "encoder." in name:
		A__							:					List[str]       =	name.replace("""encoder."""					,   """"""      )
	if "cls_token" in name:
		A__							:					List[str]       =	name.replace("""cls_token"""					,   """videomae.embeddings.cls_token"""      )
	if "decoder_pos_embed" in name:
		A__							:					Optional[Any]       =	name.replace("""decoder_pos_embed"""					,   """decoder.decoder_pos_embed"""      )
	if "pos_embed" in name and "decoder" not in name:
		A__							:					List[Any]       =	name.replace("""pos_embed"""					,   """videomae.embeddings.position_embeddings"""      )
	if "patch_embed.proj" in name:
		A__							:					List[Any]       =	name.replace("""patch_embed.proj"""					,   """videomae.embeddings.patch_embeddings.projection"""      )
	if "patch_embed.norm" in name:
		A__							:					Optional[int]       =	name.replace("""patch_embed.norm"""					,   """videomae.embeddings.norm"""      )
	if "decoder.blocks" in name:
		A__							:					Optional[int]       =	name.replace("""decoder.blocks"""					,   """decoder.decoder_layers"""      )
	if "blocks" in name:
		A__							:					Dict       =	name.replace("""blocks"""					,   """videomae.encoder.layer"""      )
	if "attn.proj" in name:
		A__							:					Union[str, Any]       =	name.replace("""attn.proj"""					,   """attention.output.dense"""      )
	if "attn" in name and "bias" not in name:
		A__							:					Any       =	name.replace("""attn"""					,   """attention.self"""      )
	if "attn" in name:
		A__							:					Any       =	name.replace("""attn"""					,   """attention.attention"""      )
	if "norm1" in name:
		A__							:					Tuple       =	name.replace("""norm1"""					,   """layernorm_before"""      )
	if "norm2" in name:
		A__							:					str       =	name.replace("""norm2"""					,   """layernorm_after"""      )
	if "mlp.fc1" in name:
		A__							:					Tuple       =	name.replace("""mlp.fc1"""					,   """intermediate.dense"""      )
	if "mlp.fc2" in name:
		A__							:					Optional[int]       =	name.replace("""mlp.fc2"""					,   """output.dense"""      )
	if "decoder_embed" in name:
		A__							:					Any       =	name.replace("""decoder_embed"""					,   """decoder.decoder_embed"""      )
	if "decoder_norm" in name:
		A__							:					Tuple       =	name.replace("""decoder_norm"""					,   """decoder.decoder_norm"""      )
	if "decoder_pred" in name:
		A__							:					List[str]       =	name.replace("""decoder_pred"""					,   """decoder.decoder_pred"""      )
	if "norm.weight" in name and "decoder" not in name and "fc" not in name:
		A__							:					List[Any]       =	name.replace("""norm.weight"""					,   """videomae.layernorm.weight"""      )
	if "norm.bias" in name and "decoder" not in name and "fc" not in name:
		A__							:					Optional[Any]       =	name.replace("""norm.bias"""					,   """videomae.layernorm.bias"""      )
	if "head" in name and "decoder" not in name:
		A__							:					List[Any]       =	name.replace("""head"""					,   """classifier"""      )

	return name

def 		UpperCamelCase      (		lowercase_:				Tuple					,   lowercase_:				Optional[Any]      )  ->   Any:


	for key in orig_state_dict.copy().keys():
		A__							:					int       =	orig_state_dict.pop(lowerCAmelCase_      )

		if key.startswith("""encoder."""      ):
			A__							:					Any       =	key.replace("""encoder."""					,   """"""      )

		if "qkv" in key:
			A__							:					List[str]       =	key.split("""."""      )
			if key.startswith("""decoder.blocks"""      ):
				A__							:					Tuple       =	config.decoder_hidden_size
				A__							:					int       =	int(key_split[2]      )
				A__							:					List[str]       =	"decoder.decoder_layers."
				if "weight" in key:
					A__							:					str       =	val[:dim, :]
					A__							:					List[Any]       =	val[dim : dim * 2, :]
					A__							:					Union[str, Any]       =	val[-dim:, :]
			else:
				A__							:					Union[str, Any]       =	config.hidden_size
				A__							:					Any       =	int(key_split[1]      )
				A__							:					List[Any]       =	"videomae.encoder.layer."
				if "weight" in key:
					A__							:					Optional[int]       =	val[:dim, :]
					A__							:					Dict       =	val[dim : dim * 2, :]
					A__							:					List[Any]       =	val[-dim:, :]
		else:
			A__							:					Dict       =	val

	return orig_state_dict

def 		UpperCamelCase      (		)  ->   Optional[int]:
	A__							:					Optional[int]       =	hf_hub_download(
	    repo_id="""hf-internal-testing/spaghetti-video"""					,   filename="""eating_spaghetti.npy"""					,   repo_type="""dataset"""      )
	A__							:					Union[str, Any]       =	np.load(lowerCAmelCase_      )
	return list(lowerCAmelCase_      )

def 		UpperCamelCase      (		lowercase_:				int					,   lowercase_:				Tuple					,   lowercase_:				Dict					,   lowercase_:				Dict      )  ->   List[str]:
	A__							:					Any       =	get_videomae_config(lowerCAmelCase_      )

	if "finetuned" in model_name:
		A__							:					Optional[Any]       =	VideoMAEForVideoClassification(lowerCAmelCase_      )
	else:
		A__							:					Union[str, Any]       =	VideoMAEForPreTraining(lowerCAmelCase_      )

	# download original checkpoint, hosted on Google Drive
	A__							:					Tuple       =	"pytorch_model.bin"
	gdown.cached_download(lowerCAmelCase_					,   lowerCAmelCase_					,   quiet=lowerCAmelCase_      )
	A__							:					Optional[Any]       =	torch.load(lowerCAmelCase_					,   map_location="""cpu"""      )
	if "model" in files:
		A__							:					Dict       =	files["model"]
	else:
		A__							:					Optional[Any]       =	files["module"]
	A__							:					Optional[int]       =	convert_state_dict(lowerCAmelCase_					,   lowerCAmelCase_      )

	model.load_state_dict(lowerCAmelCase_      )
	model.eval()

	# verify model on basic input
	A__							:					List[Any]       =	VideoMAEImageProcessor(image_mean=[0.5, 0.5, 0.5]					,   image_std=[0.5, 0.5, 0.5]      )
	A__							:					Any       =	prepare_video()
	A__							:					Optional[Any]       =	image_processor(lowerCAmelCase_					,   return_tensors="""pt"""      )

	if "finetuned" not in model_name:
		A__							:					Union[str, Any]       =	hf_hub_download(repo_id="""hf-internal-testing/bool-masked-pos"""					,   filename="""bool_masked_pos.pt"""      )
		A__							:					Union[str, Any]       =	torch.load(lowerCAmelCase_      )

	A__							:					str       =	model(**lowerCAmelCase_      )
	A__							:					List[str]       =	outputs.logits

	A__							:					List[Any]       =	[
	    "videomae-small-finetuned-kinetics",
	    "videomae-small-finetuned-ssv2",
	    # Kinetics-400 checkpoints (short = pretrained only for 800 epochs instead of 1600)
	    "videomae-base-short",
	    "videomae-base-short-finetuned-kinetics",
	    "videomae-base",
	    "videomae-base-finetuned-kinetics",
	    "videomae-large",
	    "videomae-large-finetuned-kinetics",
	    "videomae-huge-finetuned-kinetics",
	    # Something-Something-v2 checkpoints (short = pretrained only for 800 epochs instead of 2400)
	    "videomae-base-short-ssv2",
	    "videomae-base-short-finetuned-ssv2",
	    "videomae-base-ssv2",
	    "videomae-base-finetuned-ssv2",
	]

	# NOTE: logits were tested with image_mean and image_std equal to [0.5, 0.5, 0.5] and [0.5, 0.5, 0.5]
	if model_name == "videomae-small-finetuned-kinetics":
		A__							:					str       =	torch.Size([1, 400]      )
		A__							:					List[Any]       =	torch.tensor([-0.9291, -0.4061, -0.9307]      )
	elif model_name == "videomae-small-finetuned-ssv2":
		A__							:					str       =	torch.Size([1, 174]      )
		A__							:					Optional[int]       =	torch.tensor([0.2671, -0.4689, -0.8235]      )
	elif model_name == "videomae-base":
		A__							:					List[Any]       =	torch.Size([1, 1408, 1536]      )
		A__							:					Optional[int]       =	torch.tensor([[0.7739, 0.7968, 0.7089], [0.6701, 0.7487, 0.6209], [0.4287, 0.5158, 0.4773]]      )
	elif model_name == "videomae-base-short":
		A__							:					Union[str, Any]       =	torch.Size([1, 1408, 1536]      )
		A__							:					Any       =	torch.tensor([[0.7994, 0.9612, 0.8508], [0.7401, 0.8958, 0.8302], [0.5862, 0.7468, 0.7325]]      )
		# we verified the loss both for normalized and unnormalized targets for this one
		A__							:					Any       =	torch.tensor([0.5142]      ) if config.norm_pix_loss else torch.tensor([0.6469]      )
	elif model_name == "videomae-large":
		A__							:					Dict       =	torch.Size([1, 1408, 1536]      )
		A__							:					str       =	torch.tensor([[0.7149, 0.7997, 0.6966], [0.6768, 0.7869, 0.6948], [0.5139, 0.6221, 0.5605]]      )
	elif model_name == "videomae-large-finetuned-kinetics":
		A__							:					int       =	torch.Size([1, 400]      )
		A__							:					Optional[Any]       =	torch.tensor([0.0771, 0.0011, -0.3625]      )
	elif model_name == "videomae-huge-finetuned-kinetics":
		A__							:					Union[str, Any]       =	torch.Size([1, 400]      )
		A__							:					Optional[Any]       =	torch.tensor([0.2433, 0.1632, -0.4894]      )
	elif model_name == "videomae-base-short-finetuned-kinetics":
		A__							:					Tuple       =	torch.Size([1, 400]      )
		A__							:					Tuple       =	torch.tensor([0.6588, 0.0990, -0.2493]      )
	elif model_name == "videomae-base-finetuned-kinetics":
		A__							:					Optional[Any]       =	torch.Size([1, 400]      )
		A__							:					Optional[Any]       =	torch.tensor([0.3669, -0.0688, -0.2421]      )
	elif model_name == "videomae-base-short-ssv2":
		A__							:					List[str]       =	torch.Size([1, 1408, 1536]      )
		A__							:					Optional[Any]       =	torch.tensor([[0.4712, 0.5296, 0.5786], [0.2278, 0.2729, 0.4026], [0.0352, 0.0730, 0.2506]]      )
	elif model_name == "videomae-base-short-finetuned-ssv2":
		A__							:					Dict       =	torch.Size([1, 174]      )
		A__							:					Tuple       =	torch.tensor([-0.0537, -0.1539, -0.3266]      )
	elif model_name == "videomae-base-ssv2":
		A__							:					Union[str, Any]       =	torch.Size([1, 1408, 1536]      )
		A__							:					Any       =	torch.tensor([[0.8131, 0.8727, 0.8546], [0.7366, 0.9377, 0.8870], [0.5935, 0.8874, 0.8564]]      )
	elif model_name == "videomae-base-finetuned-ssv2":
		A__							:					Optional[int]       =	torch.Size([1, 174]      )
		A__							:					List[Any]       =	torch.tensor([0.1961, -0.8337, -0.6389]      )
	else:
		raise ValueError(f"""Model name not supported. Should be one of {model_names}"""      )

	# verify logits
	assert logits.shape == expected_shape
	if "finetuned" in model_name:
		assert torch.allclose(logits[0, :3]					,   lowerCAmelCase_					,   atol=1E-4      )
	else:
		print("""Logits:"""					,   logits[0, :3, :3]      )
		assert torch.allclose(logits[0, :3, :3]					,   lowerCAmelCase_					,   atol=1E-4      )
	print("""Logits ok!"""      )

	# verify loss, if applicable
	if model_name == "videomae-base-short":
		A__							:					Dict       =	outputs.loss
		assert torch.allclose(lowerCAmelCase_					,   lowerCAmelCase_					,   atol=1E-4      )
		print("""Loss ok!"""      )

	if pytorch_dump_folder_path is not None:
		print(f"""Saving model and image processor to {pytorch_dump_folder_path}"""      )
		image_processor.save_pretrained(lowerCAmelCase_      )
		model.save_pretrained(lowerCAmelCase_      )

	if push_to_hub:
		print("""Pushing to the hub..."""      )
		model.push_to_hub(lowerCAmelCase_					,   organization="""nielsr"""      )


if __name__ == "__main__":
	A_ :				List[str]						 =    argparse.ArgumentParser()
	# Required parameters
	parser.add_argument(
	    '--checkpoint_url',
	    default='https://drive.google.com/u/1/uc?id=1tEhLyskjb755TJ65ptsrafUG2llSwQE1&amp;export=download&amp;confirm=t&amp;uuid=aa3276eb-fb7e-482a-adec-dc7171df14c4',
	    type=str,
	    help=(
	        'URL of the original PyTorch checkpoint (on Google Drive) you\'d like to convert. Should be a direct'
	        ' download link.'
	    ),
	)
	parser.add_argument(
	    '--pytorch_dump_folder_path',
	    default='/Users/nielsrogge/Documents/VideoMAE/Test',
	    type=str,
	    help='Path to the output PyTorch model directory.',
	)
	parser.add_argument('--model_name', default='videomae-base', type=str, help='Name of the model.')
	parser.add_argument(
	    '--push_to_hub', action='store_true', help='Whether or not to push the converted model to the 🤗 hub.'
	)

	A_ :				Optional[int]						 =    parser.parse_args()
	convert_videomae_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.model_name, args.push_to_hub)






def 		UpperCamelCase      (lowercase_:				int      )  ->   int:
	if not isinstance(lowercase_					,   lowercase_      ):
		raise TypeError("""Input value must be an 'int' type"""      )

	A__							:					int       =	0
	while number:
		position += 1
		number >>= 1

	return position


if __name__ == "__main__":
	import doctest

	doctest.testmod()



