
import faiss  # noqa: F401 # Here to have a nice missing dependency error message early on
import numpy  # noqa: F401 # Here to have a nice missing dependency error message early on
import requests  # noqa: F401 # Here to have a nice missing dependency error message early on
import sklearn  # noqa: F401 # Here to have a nice missing dependency error message early on
import tqdm  # noqa: F401 # Here to have a nice missing dependency error message early on
from mauve import compute_mauve  # From: mauve-text

import datasets


lowercase__       ='\\n@inproceedings{pillutla-etal:mauve:neurips2021,\n  title={MAUVE: Measuring the Gap Between Neural Text and Human Text using Divergence Frontiers},\n  author={Pillutla, Krishna and Swayamdipta, Swabha and Zellers, Rowan and Thickstun, John and Welleck, Sean and Choi, Yejin and Harchaoui, Zaid},\n  booktitle = {NeurIPS},\n  year      = {2021}\n}\n\n'

lowercase__       ='\\nMAUVE is a library built on PyTorch and HuggingFace Transformers to measure the gap between neural text and human text with the eponymous MAUVE measure.\n\nMAUVE summarizes both Type I and Type II errors measured softly using Kullback–Leibler (KL) divergences.\n\nFor details, see the MAUVE paper: https://arxiv.org/abs/2102.01454 (Neurips, 2021).\n\nThis metrics is a wrapper around the official implementation of MAUVE:\nhttps://github.com/krishnap25/mauve\n'

lowercase__       ='\nCalculates MAUVE scores between two lists of generated text and reference text.\nArgs:\n    predictions: list of generated text to score. Each predictions\n        should be a string with tokens separated by spaces.\n    references: list of reference for each prediction. Each\n        reference should be a string with tokens separated by spaces.\nOptional Args:\n    num_buckets: the size of the histogram to quantize P and Q. Options: \'auto\' (default) or an integer\n    pca_max_data: the number data points to use for PCA dimensionality reduction prior to clustering. If -1, use all the data. Default -1\n    kmeans_explained_var: amount of variance of the data to keep in dimensionality reduction by PCA. Default 0.9\n    kmeans_num_redo: number of times to redo k-means clustering (the best objective is kept). Default 5\n    kmeans_max_iter: maximum number of k-means iterations. Default 500\n    featurize_model_name: name of the model from which features are obtained. Default \'gpt2-large\' Use one of [\'gpt2\', \'gpt2-medium\', \'gpt2-large\', \'gpt2-xl\'].\n    device_id: Device for featurization. Supply a GPU id (e.g. 0 or 3) to use GPU. If no GPU with this id is found, use CPU\n    max_text_length: maximum number of tokens to consider. Default 1024\n    divergence_curve_discretization_size: Number of points to consider on the divergence curve. Default 25\n    mauve_scaling_factor: "c" from the paper. Default 5.\n    verbose: If True (default), print running time updates\n    seed: random seed to initialize k-means cluster assignments.\nReturns:\n    mauve: MAUVE score, a number between 0 and 1. Larger values indicate that P and Q are closer,\n    frontier_integral: Frontier Integral, a number between 0 and 1. Smaller values indicate that P and Q are closer,\n    divergence_curve: a numpy.ndarray of shape (m, 2); plot it with matplotlib to view the divergence curve,\n    p_hist: a discrete distribution, which is a quantized version of the text distribution p_text,\n    q_hist: same as above, but with q_text.\nExamples:\n\n    >>> # faiss segfaults in doctest for some reason, so the .compute call is not tested with doctest\n    >>> import datasets\n    >>> mauve = datasets.load_metric(\'mauve\')\n    >>> predictions = ["hello there", "general kenobi"]\n    >>> references = ["hello there", "general kenobi"]\n    >>> out = mauve.compute(predictions=predictions, references=references) # doctest: +SKIP\n    >>> print(out.mauve) # doctest: +SKIP\n    1.0\n'



@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION    ,_KWARGS_DESCRIPTION    )
class 		UpperCamelCase__  (       datasets.Metric    ):
   def       lowerCAmelCase			(self :					Any   ):
    return datasets.MetricInfo(
        description=_DESCRIPTION					,				citation=_CITATION					,				homepage='''https://github.com/krishnap25/mauve'''					,				inputs_description=_KWARGS_DESCRIPTION					,				features=datasets.Features(
            {
                '''predictions''': datasets.Value('''string'''					,				id='''sequence'''   ),
                '''references''': datasets.Value('''string'''					,				id='''sequence'''   ),
            }   )					,				codebase_urls=['''https://github.com/krishnap25/mauve''']					,				reference_urls=[
            '''https://arxiv.org/abs/2102.01454''',
            '''https://github.com/krishnap25/mauve''',
        ]					,				)







   def       lowerCAmelCase			(self :					int					,				snake_case_ :					str					,				snake_case_ :					List[str]					,				snake_case_ :					List[Any]=None					,				snake_case_ :					str=None					,				snake_case_ :					Dict=None					,				snake_case_ :					Optional[Any]=None					,				snake_case_ :					Optional[Any]="auto"					,				snake_case_ :					List[str]=-1					,				snake_case_ :					Dict=0.9					,				snake_case_ :					Tuple=5					,				snake_case_ :					int=5_0_0					,				snake_case_ :					Optional[int]="gpt2-large"					,				snake_case_ :					str=-1					,				snake_case_ :					Dict=1_0_2_4					,				snake_case_ :					str=2_5					,				snake_case_ :					Any=5					,				snake_case_ :					Optional[int]=True					,				snake_case_ :					int=2_5					,				):
    __a :  int						=  compute_mauve(
        p_text=snake_case_					,				q_text=snake_case_					,				p_features=snake_case_					,				q_features=snake_case_					,				p_tokens=snake_case_					,				q_tokens=snake_case_					,				num_buckets=snake_case_					,				pca_max_data=snake_case_					,				kmeans_explained_var=snake_case_					,				kmeans_num_redo=snake_case_					,				kmeans_max_iter=snake_case_					,				featurize_model_name=snake_case_					,				device_id=snake_case_					,				max_text_length=snake_case_					,				divergence_curve_discretization_size=snake_case_					,				mauve_scaling_factor=snake_case_					,				verbose=snake_case_					,				seed=snake_case_					,				)
    return out


import argparse

import requests
import torch
from PIL import Image

from transformers import CLIPProcessor, GroupViTConfig, GroupViTModel




def    __UpperCamelCase     (				lowerCAmelCase__							:				Any  ):
 # vision encoder
 if "img_encoder.pos_embed" in name:
  __a :  Any						=  name.replace('''img_encoder.pos_embed'''  ,   '''vision_model.embeddings.position_embeddings'''  )
 if "img_encoder.patch_embed.proj" in name:
  __a :  str						=  name.replace('''img_encoder.patch_embed.proj'''  ,   '''vision_model.embeddings.patch_embeddings.projection'''  )
 if "img_encoder.patch_embed.norm" in name:
  __a :  int						=  name.replace('''img_encoder.patch_embed.norm'''  ,   '''vision_model.embeddings.layernorm'''  )
 if "img_encoder.layers" in name:
  __a :  Union[str, Any]						=  name.replace('''img_encoder.layers'''  ,   '''vision_model.encoder.stages'''  )
 if "blocks" in name and "res" not in name:
  __a :  List[Any]						=  name.replace('''blocks'''  ,   '''layers'''  )
 if "attn" in name and "pre_assign" not in name:
  __a :  Tuple						=  name.replace('''attn'''  ,   '''self_attn'''  )
 if "proj" in name and "self_attn" in name and "text" not in name:
  __a :  List[Any]						=  name.replace('''proj'''  ,   '''out_proj'''  )
 if "pre_assign_attn.attn.proj" in name:
  __a :  Any						=  name.replace('''pre_assign_attn.attn.proj'''  ,   '''pre_assign_attn.attn.out_proj'''  )
 if "norm1" in name:
  __a :  Union[str, Any]						=  name.replace('''norm1'''  ,   '''layer_norm1'''  )
 if "norm2" in name and "pre_assign" not in name:
  __a :  Optional[int]						=  name.replace('''norm2'''  ,   '''layer_norm2'''  )
 if "img_encoder.norm" in name:
  __a :  Union[str, Any]						=  name.replace('''img_encoder.norm'''  ,   '''vision_model.layernorm'''  )
 # text encoder
 if "text_encoder.token_embedding" in name:
  __a :  List[Any]						=  name.replace('''text_encoder.token_embedding'''  ,   '''text_model.embeddings.token_embedding'''  )
 if "text_encoder.positional_embedding" in name:
  __a :  Any						=  name.replace('''text_encoder.positional_embedding'''  ,   '''text_model.embeddings.position_embedding.weight'''  )
 if "text_encoder.transformer.resblocks." in name:
  __a :  Any						=  name.replace('''text_encoder.transformer.resblocks.'''  ,   '''text_model.encoder.layers.'''  )
 if "ln_1" in name:
  __a :  str						=  name.replace('''ln_1'''  ,   '''layer_norm1'''  )
 if "ln_2" in name:
  __a :  Union[str, Any]						=  name.replace('''ln_2'''  ,   '''layer_norm2'''  )
 if "c_fc" in name:
  __a :  Union[str, Any]						=  name.replace('''c_fc'''  ,   '''fc1'''  )
 if "c_proj" in name:
  __a :  Union[str, Any]						=  name.replace('''c_proj'''  ,   '''fc2'''  )
 if "text_encoder" in name:
  __a :  Optional[int]						=  name.replace('''text_encoder'''  ,   '''text_model'''  )
 if "ln_final" in name:
  __a :  str						=  name.replace('''ln_final'''  ,   '''final_layer_norm'''  )
 # projection layers
 if "img_projector.linear_hidden." in name:
  __a :  List[str]						=  name.replace('''img_projector.linear_hidden.'''  ,   '''visual_projection.'''  )
 if "img_projector.linear_out." in name:
  __a :  str						=  name.replace('''img_projector.linear_out.'''  ,   '''visual_projection.3.'''  )
 if "text_projector.linear_hidden" in name:
  __a :  int						=  name.replace('''text_projector.linear_hidden'''  ,   '''text_projection'''  )
 if "text_projector.linear_out" in name:
  __a :  List[str]						=  name.replace('''text_projector.linear_out'''  ,   '''text_projection.3'''  )

 return name




def    __UpperCamelCase     (				lowerCAmelCase__							:				Union[str, Any]  ,   lowerCAmelCase__							:				Tuple  ):
 for key in orig_state_dict.copy().keys():
  __a :  List[Any]						=  orig_state_dict.pop(lowerCAmelCase__  )

  if "qkv" in key:
   # weights and biases of the key, value and query projections of vision encoder's attention layers require special treatment:
   # we need to split them up into separate matrices/vectors
   __a :  Tuple						=  key.split('''.'''  )
   __a				,       __a :  List[Any]						=  int(key_split[2]  ), int(key_split[4]  )
   __a :  List[Any]						=  config.vision_config.hidden_size
   if "weight" in key:
    __a :  int						=  val[:dim, :]
    __a :  List[str]						=  val[dim : dim * 2, :]
    __a :  List[Any]						=  val[-dim:, :]
   else:
    __a :  List[str]						=  val[:dim]
    __a :  int						=  val[dim : dim * 2]
    __a :  Any						=  val[-dim:]
  elif "in_proj" in key:
   # weights and biases of the key, value and query projections of text encoder's attention layers require special treatment:
   # we need to split them up into separate matrices/vectors
   __a :  int						=  key.split('''.'''  )
   __a :  str						=  int(key_split[3]  )
   __a :  List[Any]						=  config.text_config.hidden_size
   if "weight" in key:
    __a :  List[str]						=  val[:dim, :]
    __a :  Any						=  val[
        dim : dim * 2, :
    ]
    __a :  Dict						=  val[-dim:, :]
   else:
    __a :  List[str]						=  val[:dim]
    __a :  Any						=  val[dim : dim * 2]
    __a :  Any						=  val[-dim:]
  else:
   __a :  Union[str, Any]						=  rename_key(lowerCAmelCase__  )
   # squeeze if necessary
   if (
       "text_projection.0" in new_name
       or "text_projection.3" in new_name
       or "visual_projection.0" in new_name
       or "visual_projection.3" in new_name
   ):
    __a :  List[Any]						=  val.squeeze_()
   else:
    __a :  Dict						=  val

 return orig_state_dict




def    __UpperCamelCase     (				):
 __a :  Optional[int]						=  '''http://images.cocodataset.org/val2017/000000039769.jpg'''
 __a :  str						=  Image.open(requests.get(lowerCAmelCase__  ,   stream=lowerCAmelCase__  ).raw  )
 return im




@torch.no_grad()
def    __UpperCamelCase     (				lowerCAmelCase__							:				List[Any]  ,   lowerCAmelCase__							:				Optional[int]  ,   lowerCAmelCase__							:				Optional[Any]="groupvit-gcc-yfcc"  ,   lowerCAmelCase__							:				int=False  ):
 __a :  Union[str, Any]						=  GroupViTConfig()
 __a :  int						=  GroupViTModel(lowerCAmelCase__  ).eval()

 __a :  Any						=  torch.load(lowerCAmelCase__  ,   map_location='''cpu'''  )['''model''']
 __a :  Optional[Any]						=  convert_state_dict(lowerCAmelCase__  ,   lowerCAmelCase__  )
 __a				,       __a :  Dict						=  model.load_state_dict(lowerCAmelCase__  ,   strict=lowerCAmelCase__  )
 assert missing_keys == ["text_model.embeddings.position_ids"]
 assert (unexpected_keys == ["multi_label_logit_scale"]) or (len(lowerCAmelCase__  ) == 0)

 # verify result
 __a :  Any						=  CLIPProcessor.from_pretrained('''openai/clip-vit-base-patch32'''  )
 __a :  Optional[Any]						=  prepare_img()
 __a :  Optional[int]						=  processor(text=['''a photo of a cat''', '''a photo of a dog''']  ,   images=lowerCAmelCase__  ,   padding=lowerCAmelCase__  ,   return_tensors='''pt'''  )

 with torch.no_grad():
  __a :  Tuple						=  model(**lowerCAmelCase__  )

 if model_name == "groupvit-gcc-yfcc":
  __a :  List[str]						=  torch.tensor([[13.35_23, 6.36_29]]  )
 elif model_name == "groupvit-gcc-redcaps":
  __a :  List[str]						=  torch.tensor([[16.18_73, 8.62_30]]  )
 else:
  raise ValueError(f"Model name {model_name} not supported."  )
 assert torch.allclose(outputs.logits_per_image  ,   lowerCAmelCase__  ,   atol=1e-3  )

 processor.save_pretrained(lowerCAmelCase__  )
 model.save_pretrained(lowerCAmelCase__  )
 print('''Successfully saved processor and model to'''  ,   lowerCAmelCase__  )

 if push_to_hub:
  print('''Pushing to the hub...'''  )
  processor.push_to_hub(lowerCAmelCase__  ,   organization='''nielsr'''  )
  model.push_to_hub(lowerCAmelCase__  ,   organization='''nielsr'''  )


if __name__ == "__main__":
      lowercase__       =argparse.ArgumentParser()
      parser.add_argument(
          '--pytorch_dump_folder_path', default=None, type=str, help='Path to dump the processor and PyTorch model.'
      )
      parser.add_argument('--checkpoint_path', default=None, type=str, help='Path to GroupViT checkpoint')
      parser.add_argument(
          '--model_name',
          default='groupvit-gccy-fcc',
          type=str,
          help='Name of the model. Expecting either \'groupvit-gcc-yfcc\' or \'groupvit-gcc-redcaps\'',
      )
      parser.add_argument(
          '--push_to_hub',
          action='store_true',
          help='Whether or not to push the converted model and processor to the 🤗 hub using the provided `model_name`.',
      )
      lowercase__       =parser.parse_args()

      convert_groupvit_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.model_name, args.push_to_hub)
