





import argparse
import json
from pathlib import Path

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

from transformers import (
    BertTokenizer,
    ViltConfig,
    ViltForImageAndTextRetrieval,
    ViltForImagesAndTextClassification,
    ViltForMaskedLM,
    ViltForQuestionAnswering,
    ViltImageProcessor,
    ViltProcessor,
)
from transformers.utils import logging


logging.set_verbosity_info()
_UpperCamelCase							=			logging.get_logger(__name__)







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

  # embeddings
  rename_keys.extend(
      [
          # text embeddings
          ("text_embeddings.word_embeddings.weight", "vilt.embeddings.text_embeddings.word_embeddings.weight"),
          (
              "text_embeddings.position_embeddings.weight",
              "vilt.embeddings.text_embeddings.position_embeddings.weight",
          ),
          ("text_embeddings.position_ids", "vilt.embeddings.text_embeddings.position_ids"),
          (
              "text_embeddings.token_type_embeddings.weight",
              "vilt.embeddings.text_embeddings.token_type_embeddings.weight",
          ),
          ("text_embeddings.LayerNorm.weight", "vilt.embeddings.text_embeddings.LayerNorm.weight"),
          ("text_embeddings.LayerNorm.bias", "vilt.embeddings.text_embeddings.LayerNorm.bias"),
          # patch embeddings
          ("transformer.cls_token", "vilt.embeddings.cls_token"),
          ("transformer.patch_embed.proj.weight", "vilt.embeddings.patch_embeddings.projection.weight"),
          ("transformer.patch_embed.proj.bias", "vilt.embeddings.patch_embeddings.projection.bias"),
          ("transformer.pos_embed", "vilt.embeddings.position_embeddings"),
          # token type embeddings
          ("token_type_embeddings.weight", "vilt.embeddings.token_type_embeddings.weight"),
      ]					)

  # final layernorm + pooler
  rename_keys.extend(
      [
          ("transformer.norm.weight", "vilt.layernorm.weight"),
          ("transformer.norm.bias", "vilt.layernorm.bias"),
          ("pooler.dense.weight", "vilt.pooler.dense.weight"),
          ("pooler.dense.bias", "vilt.pooler.dense.bias"),
      ]					)

  # classifier head(s)
  if vqa_model:
    # classification head
    rename_keys.extend(
        [
            ("vqa_classifier.0.weight", "classifier.0.weight"),
            ("vqa_classifier.0.bias", "classifier.0.bias"),
            ("vqa_classifier.1.weight", "classifier.1.weight"),
            ("vqa_classifier.1.bias", "classifier.1.bias"),
            ("vqa_classifier.3.weight", "classifier.3.weight"),
            ("vqa_classifier.3.bias", "classifier.3.bias"),
        ]					)
  elif nlvr_model:
    # classification head
    rename_keys.extend(
        [
            ("nlvr2_classifier.0.weight", "classifier.0.weight"),
            ("nlvr2_classifier.0.bias", "classifier.0.bias"),
            ("nlvr2_classifier.1.weight", "classifier.1.weight"),
            ("nlvr2_classifier.1.bias", "classifier.1.bias"),
            ("nlvr2_classifier.3.weight", "classifier.3.weight"),
            ("nlvr2_classifier.3.bias", "classifier.3.bias"),
        ]					)
  else:
    pass

  return rename_keys







def    lowerCAmelCase__(						lowercase							:     List[str] ,  lowercase							:     List[str]					)			->     Any:

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







def    lowerCAmelCase__(						lowercase							:     Dict					)			->     str:
  __snake_case :					Tuple          =							["head.weight", "head.bias"]
  for k in ignore_keys:
    state_dict.pop(lowercase ,  lowercase					)







def    lowerCAmelCase__(						lowercase							:     Any ,  lowercase							:     int ,  lowercase							:     List[str]					)			->     List[Any]:
  __snake_case :					List[str]          =							dct.pop(lowercase					)
  __snake_case :					Optional[int]          =							val







@torch.no_grad()
def    lowerCAmelCase__(						lowercase							:     int ,  lowercase							:     List[str]					)			->     List[Any]:
  __snake_case :					Dict          =							ViltConfig(image_size=384 ,  patch_size=32 ,  tie_word_embeddings=lowercase					)
  __snake_case :					str          =							False
  __snake_case :					Optional[int]          =							False
  __snake_case :					str          =							False
  __snake_case :					Tuple          =							False
  if "vqa" in checkpoint_url:
    __snake_case :					Optional[Any]          =							True
    __snake_case :					int          =							3129
    __snake_case :					List[str]          =							"huggingface/label-files"
    __snake_case :					str          =							"vqa2-id2label.json"
    __snake_case :					Optional[Any]          =							json.load(open(hf_hub_download(lowercase ,  lowercase ,  repo_type="dataset"					) ,  "r"					)					)
    __snake_case :					Tuple          =							{int(lowercase					): v for k, v in idalabel.items()}
    __snake_case :					Any          =							idalabel
    __snake_case :					Optional[int]          =							{v: k for k, v in idalabel.items()}
    __snake_case :					str          =							ViltForQuestionAnswering(lowercase					)
  elif "nlvr" in checkpoint_url:
    __snake_case :					Optional[int]          =							True
    __snake_case :					Any          =							2
    __snake_case :					Tuple          =							{0: "False", 1: "True"}
    __snake_case :					str          =							{v: k for k, v in config.idalabel.items()}
    __snake_case :					List[Any]          =							3
    __snake_case :					Optional[Any]          =							ViltForImagesAndTextClassification(lowercase					)
  elif "irtr" in checkpoint_url:
    __snake_case :					Tuple          =							True
    __snake_case :					List[str]          =							ViltForImageAndTextRetrieval(lowercase					)
  elif "mlm_itm" in checkpoint_url:
    __snake_case :					int          =							True
    __snake_case :					Optional[int]          =							ViltForMaskedLM(lowercase					)
  else:
    raise ValueError("Unknown model type"					)

  # load state_dict of original model, remove and rename some keys
  __snake_case :					int          =							torch.hub.load_state_dict_from_url(lowercase ,  map_location="cpu"					)["state_dict"]
  __snake_case :					Tuple          =							create_rename_keys(lowercase ,  lowercase ,  lowercase ,  lowercase					)
  for src, dest in rename_keys:
    rename_key(lowercase ,  lowercase ,  lowercase					)
  read_in_q_k_v(lowercase ,  lowercase					)
  if mlm_model or irtr_model:
    __snake_case :					int          =							["itm_score.fc.weight", "itm_score.fc.bias"]
    for k in ignore_keys:
      state_dict.pop(lowercase ,  lowercase					)

    # load state dict into HuggingFace model
  model.eval()
  if mlm_model:
    __snake_case     , __snake_case :					str          =							model.load_state_dict(lowercase ,  strict=lowercase					)
    assert missing_keys == ["mlm_score.decoder.bias"]
  else:
    model.load_state_dict(lowercase					)

  # Define processor
  __snake_case :					Optional[Any]          =							ViltImageProcessor(size=384					)
  __snake_case :					Union[str, Any]          =							BertTokenizer.from_pretrained("bert-base-uncased"					)
  __snake_case :					Optional[int]          =							ViltProcessor(lowercase ,  lowercase					)

  # Forward pass on example inputs (image + text)
  if nlvr_model:
    __snake_case :					Union[str, Any]          =							Image.open(requests.get("https://lil.nlp.cornell.edu/nlvr/exs/ex0_0.jpg" ,  stream=lowercase					).raw					)
    __snake_case :					Optional[int]          =							Image.open(requests.get("https://lil.nlp.cornell.edu/nlvr/exs/ex0_0.jpg" ,  stream=lowercase					).raw					)
    __snake_case :					Optional[Any]          =							(
        "The left image contains twice the number of dogs as the right image, and at least two dogs in total are"
        " standing."
    )
    __snake_case :					Optional[int]          =							processor(lowercase ,  lowercase ,  return_tensors="pt"					)
    __snake_case :					List[Any]          =							processor(lowercase ,  lowercase ,  return_tensors="pt"					)
    __snake_case :					Any          =							model(
        input_ids=encoding_a.input_ids ,  pixel_values=encoding_a.pixel_values ,  pixel_values_a=encoding_a.pixel_values ,  )
  else:
    __snake_case :					Any          =							Image.open(requests.get("http://images.cocodataset.org/val2017/000000039769.jpg" ,  stream=lowercase					).raw					)
    if mlm_model:
      __snake_case :					List[Any]          =							"a bunch of [MASK] laying on a [MASK]."
    else:
      __snake_case :					List[str]          =							"How many cats are there?"
    __snake_case :					Any          =							processor(lowercase ,  lowercase ,  return_tensors="pt"					)
    __snake_case :					Optional[int]          =							model(**lowercase					)

  # Verify outputs
  if mlm_model:
    __snake_case :					Optional[Any]          =							torch.Size([1, 11, 3_0522]					)
    __snake_case :					Optional[int]          =							torch.tensor([-12.5061, -12.5123, -12.5174]					)
    assert outputs.logits.shape == expected_shape
    assert torch.allclose(outputs.logits[0, 0, :3] ,  lowercase ,  atol=1E-4					)

    # verify masked token prediction equals "cats"
    __snake_case :					List[Any]          =							outputs.logits[0, 4, :].argmax(-1					).item()
    assert tokenizer.decode([predicted_id]					) == "cats"
  elif vqa_model:
    __snake_case :					List[str]          =							torch.Size([1, 3129]					)
    __snake_case :					Optional[Any]          =							torch.tensor([-15.9495, -18.1472, -10.3041]					)
    assert torch.allclose(outputs.logits[0, :3] ,  lowercase ,  atol=1E-4					)
    assert outputs.logits.shape == expected_shape
    assert torch.allclose(outputs.logits[0, 0, :3] ,  lowercase ,  atol=1E-4					)

    # verify vqa prediction equals "2"
    __snake_case :					Union[str, Any]          =							outputs.logits.argmax(-1					).item()
    assert model.config.idalabel[predicted_idx] == "2"
  elif nlvr_model:
    __snake_case :					Any          =							torch.Size([1, 2]					)
    __snake_case :					Dict          =							torch.tensor([-2.8_7_2_1, 2.1_2_9_1]					)
    assert torch.allclose(outputs.logits[0, :3] ,  lowercase ,  atol=1E-4					)
    assert outputs.logits.shape == expected_shape

  Path(lowercase					).mkdir(exist_ok=lowercase					)
  print(f"""Saving model and processor to {pytorch_dump_folder_path}"""					)
  model.save_pretrained(lowercase					)
  processor.save_pretrained(lowercase					)


if __name__ == "__main__":
     _UpperCamelCase							=			argparse.ArgumentParser()
     # Required parameters
     parser.add_argument(
         '''--checkpoint_url''',
         default='''https://github.com/dandelin/ViLT/releases/download/200k/vilt_200k_mlm_itm.ckpt''',
         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							=			parser.parse_args()
     convert_vilt_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path)








'''simple docstring'''

import math_equivalence  # From: git+https://github.com/hendrycks/math.git

import datasets


lowercase__		:     str			=							'\\n@article{hendrycksmath2021,\n  title={Measuring Mathematical Problem Solving With the MATH Dataset},\n  author={Dan Hendrycks\n    and Collin Burns\n    and Saurav Kadavath\n    and Akul Arora\n    and Steven Basart\n    and Eric Tang\n    and Dawn Song\n    and Jacob Steinhardt},\n  journal={arXiv preprint arXiv:2103.03874},\n  year={2021}\n}\n'


lowercase__		:     str			=							'\\nThis metric is used to assess performance on the Mathematics Aptitude Test of Heuristics (MATH) dataset.\nIt first canonicalizes the inputs (e.g., converting "1/2" to "\\frac{1}{2}") and then computes accuracy.\n'


lowercase__		:     Dict			=							R'\nCalculates accuracy after canonicalizing inputs.\n\nArgs:\n    predictions: list of predictions to score. Each prediction\n        is a string that contains natural language and LaTex.\n    references: list of reference for each prediction. Each\n        reference is a string that contains natural language\n        and LaTex.\nReturns:\n    accuracy: accuracy after canonicalizing inputs\n        (e.g., converting "1/2" to "\\frac{1}{2}")\n\nExamples:\n    >>> metric = datasets.load_metric("competition_math")\n    >>> results = metric.compute(references=["\\frac{1}{2}"], predictions=["1/2"])\n    >>> print(results)\n    {\'accuracy\': 1.0}\n'
@datasets.utils.file_utils.add_end_docstrings(_DESCRIPTION		,		_KWARGS_DESCRIPTION					)
class 							__lowerCAmelCase	(       datasets.Metric					):






       """simple docstring"""





       def snake_case__		(				self  :						Dict	)       ->	Any:

            '''simple docstring'''




            return datasets.MetricInfo(
                description=_DESCRIPTION			,					citation=_CITATION			,					inputs_description=_KWARGS_DESCRIPTION			,					features=datasets.Features(
                    {
                        '''predictions''': datasets.Value('''string'''	),
                        '''references''': datasets.Value('''string'''	),
                    }	)			,					homepage='''https://github.com/hendrycks/math'''			,					codebase_urls=['''https://github.com/hendrycks/math''']			,					)







       def snake_case__		(				self  :						List[Any]			,					lowerCAmelCase__  :						Dict			,					lowerCAmelCase__  :						int	)       ->	List[str]:

            '''simple docstring'''




            _UpperCamelCase							       =			0.0
            for i, j in zip(lowerCAmelCase__			,					lowerCAmelCase__	):
                 n_correct += 1.0 if math_equivalence.is_equiv(lowerCAmelCase__			,					lowerCAmelCase__	) else 0.0
            _UpperCamelCase							       =			n_correct / len(lowerCAmelCase__	)
            return {
                "accuracy": accuracy,
            }



