
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 						_snake_case(  SCREAMING_SNAKE_CASE__				) ->    Dict:
       lowercase							:     int       	=      VideoMAEConfig()

       set_architecture_configs(SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__				)

       if "finetuned" not in model_name:
              lowercase							:     Dict       	=      False

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

       return config







def 						_snake_case(  SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__				) ->    Tuple:
       if "small" in model_name:
              lowercase							:     Optional[Any]       	=      384
              lowercase							:     Dict       	=      1_536
              lowercase							:     Optional[Any]       	=      12
              lowercase							:     Union[str, Any]       	=      16
              lowercase							:     List[str]       	=      12
              lowercase							:     int       	=      3
              lowercase							:     List[Any]       	=      192
              lowercase							:     Optional[Any]       	=      768
       elif "large" in model_name:
              lowercase							:     int       	=      1_024
              lowercase							:     Optional[Any]       	=      4_096
              lowercase							:     Optional[Any]       	=      24
              lowercase							:     List[str]       	=      16
              lowercase							:     Optional[int]       	=      12
              lowercase							:     Union[str, Any]       	=      8
              lowercase							:     str       	=      512
              lowercase							:     Union[str, Any]       	=      2_048
       elif "huge" in model_name:
              lowercase							:     Dict       	=      1_280
              lowercase							:     Union[str, Any]       	=      5_120
              lowercase							:     Optional[Any]       	=      32
              lowercase							:     Optional[Any]       	=      16
              lowercase							:     int       	=      12
              lowercase							:     Dict       	=      8
              lowercase							:     Dict       	=      640
              lowercase							:     Dict       	=      2_560
       elif "base" not in model_name:
              raise ValueError("""Model name should include either \"small\", \"base\", \"large\", or \"huge\""""				)







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

       return name







def 						_snake_case(  SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__				) ->    Optional[Any]:
       for key in orig_state_dict.copy().keys():
              lowercase							:     Union[str, Any]       	=      orig_state_dict.pop(SCREAMING_SNAKE_CASE__				)

              if key.startswith("""encoder."""				):
                     lowercase							:     Union[str, Any]       	=      key.replace("""encoder."""					,	""""""				)

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

       return orig_state_dict







def 						_snake_case(  ) ->    Any:
       lowercase							:     str       	=      hf_hub_download(
           repo_id="""hf-internal-testing/spaghetti-video"""					,	filename="""eating_spaghetti.npy"""					,	repo_type="""dataset"""				)
       lowercase							:     Dict       	=      np.load(SCREAMING_SNAKE_CASE__				)
       return list(SCREAMING_SNAKE_CASE__				)







def 						_snake_case(  SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__				) ->    Any:
       lowercase							:     Optional[Any]       	=      get_videomae_config(SCREAMING_SNAKE_CASE__				)

       if "finetuned" in model_name:
              lowercase							:     Tuple       	=      VideoMAEForVideoClassification(SCREAMING_SNAKE_CASE__				)
       else:
              lowercase							:     Union[str, Any]       	=      VideoMAEForPreTraining(SCREAMING_SNAKE_CASE__				)

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

       model.load_state_dict(SCREAMING_SNAKE_CASE__				)
       model.eval()

       # verify model on basic input
       lowercase							:     Union[str, Any]       	=      VideoMAEImageProcessor(image_mean=[0.5, 0.5, 0.5]					,	image_std=[0.5, 0.5, 0.5]				)
       lowercase							:     Union[str, Any]       	=      prepare_video()
       lowercase							:     Any       	=      image_processor(SCREAMING_SNAKE_CASE__					,	return_tensors="""pt"""				)

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

       lowercase							:     Optional[int]       	=      model(**SCREAMING_SNAKE_CASE__				)
       lowercase							:     str       	=      outputs.logits

       lowercase							:     int       	=      [
           """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":
              lowercase							:     Tuple       	=      torch.Size([1, 400]				)
              lowercase							:     Any       	=      torch.tensor([-0.9291, -0.4061, -0.9307]				)
       elif model_name == "videomae-small-finetuned-ssv2":
              lowercase							:     int       	=      torch.Size([1, 174]				)
              lowercase							:     List[Any]       	=      torch.tensor([0.2671, -0.4689, -0.8235]				)
       elif model_name == "videomae-base":
              lowercase							:     List[str]       	=      torch.Size([1, 1_408, 1_536]				)
              lowercase							:     Tuple       	=      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":
              lowercase							:     Tuple       	=      torch.Size([1, 1_408, 1_536]				)
              lowercase							:     str       	=      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
              lowercase							:     List[str]       	=      torch.tensor([0.5142]				) if config.norm_pix_loss else torch.tensor([0.6469]				)
       elif model_name == "videomae-large":
              lowercase							:     Tuple       	=      torch.Size([1, 1_408, 1_536]				)
              lowercase							:     int       	=      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":
              lowercase							:     Optional[int]       	=      torch.Size([1, 400]				)
              lowercase							:     Union[str, Any]       	=      torch.tensor([0.0771, 0.0011, -0.3625]				)
       elif model_name == "videomae-huge-finetuned-kinetics":
              lowercase							:     str       	=      torch.Size([1, 400]				)
              lowercase							:     str       	=      torch.tensor([0.2433, 0.1632, -0.4894]				)
       elif model_name == "videomae-base-short-finetuned-kinetics":
              lowercase							:     Dict       	=      torch.Size([1, 400]				)
              lowercase							:     Dict       	=      torch.tensor([0.6588, 0.0990, -0.2493]				)
       elif model_name == "videomae-base-finetuned-kinetics":
              lowercase							:     Tuple       	=      torch.Size([1, 400]				)
              lowercase							:     str       	=      torch.tensor([0.3669, -0.0688, -0.2421]				)
       elif model_name == "videomae-base-short-ssv2":
              lowercase							:     Union[str, Any]       	=      torch.Size([1, 1_408, 1_536]				)
              lowercase							:     Dict       	=      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":
              lowercase							:     Optional[Any]       	=      torch.Size([1, 174]				)
              lowercase							:     Optional[Any]       	=      torch.tensor([-0.0537, -0.1539, -0.3266]				)
       elif model_name == "videomae-base-ssv2":
              lowercase							:     Union[str, Any]       	=      torch.Size([1, 1_408, 1_536]				)
              lowercase							:     int       	=      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":
              lowercase							:     Optional[Any]       	=      torch.Size([1, 174]				)
              lowercase							:     Union[str, 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]					,	SCREAMING_SNAKE_CASE__					,	atol=1e-4				)
       else:
              print("""Logits:"""					,	logits[0, :3, :3]				)
              assert torch.allclose(logits[0, :3, :3]					,	SCREAMING_SNAKE_CASE__					,	atol=1e-4				)
       print("""Logits ok!"""				)

       # verify loss, if applicable
       if model_name == "videomae-base-short":
              lowercase							:     Union[str, Any]       	=      outputs.loss
              assert torch.allclose(SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	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(SCREAMING_SNAKE_CASE__				)
              model.save_pretrained(SCREAMING_SNAKE_CASE__				)

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


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

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


def 						_snake_case(  SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__				) ->    List[str]:
       if index == r:
              for j in range(SCREAMING_SNAKE_CASE__				):
                     print(data[j]					,	end=""" """				)
              print(""" """				)
              return
       #  When no more elements are there to put in data[]
       if i >= n:
              return
       # current is included, put next at next location
       lowercase							:     Tuple       	=      arr[i]
       combination_util(SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	index + 1					,	SCREAMING_SNAKE_CASE__					,	i + 1				)
       # current is excluded, replace it with
       # next (Note that i+1 is passed, but
       # index is not changed)
       combination_util(SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	i + 1				)
       # The main function that prints all combinations
       # of size r in arr[] of size n. This function
       # mainly uses combinationUtil()







def 						_snake_case(  SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__				) ->    List[str]:
       # A temporary array to store all combination one by one
       lowercase							:     Optional[int]       	=      [0] * r
       # Print all combination using temporary array 'data[]'
       combination_util(SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	SCREAMING_SNAKE_CASE__					,	0					,	SCREAMING_SNAKE_CASE__					,	0				)


if __name__ == "__main__":
  # Driver code to check the function above
  lowercase  :					int						    =							[10, 20, 30, 40, 50]
  print_combination(arr, len(arr), 3)
  # This code is contributed by Ambuj sahu
