





"""simple docstring"""
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 ViTConfig, ViTForImageClassification, ViTImageProcessor, ViTModel
from transformers.utils import logging


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



def 					__lowerCamelCase       (							a_					:		Any			,       a_					:		Any=False							)      ->				Tuple:
      __SCREAMING_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'''blocks.{i}.norm1.weight''', f'''vit.encoder.layer.{i}.layernorm_before.weight''')							)
            rename_keys.append((f'''blocks.{i}.norm1.bias''', f'''vit.encoder.layer.{i}.layernorm_before.bias''')							)
            rename_keys.append((f'''blocks.{i}.attn.proj.weight''', f'''vit.encoder.layer.{i}.attention.output.dense.weight''')							)
            rename_keys.append((f'''blocks.{i}.attn.proj.bias''', f'''vit.encoder.layer.{i}.attention.output.dense.bias''')							)
            rename_keys.append((f'''blocks.{i}.norm2.weight''', f'''vit.encoder.layer.{i}.layernorm_after.weight''')							)
            rename_keys.append((f'''blocks.{i}.norm2.bias''', f'''vit.encoder.layer.{i}.layernorm_after.bias''')							)
            rename_keys.append((f'''blocks.{i}.mlp.fc1.weight''', f'''vit.encoder.layer.{i}.intermediate.dense.weight''')							)
            rename_keys.append((f'''blocks.{i}.mlp.fc1.bias''', f'''vit.encoder.layer.{i}.intermediate.dense.bias''')							)
            rename_keys.append((f'''blocks.{i}.mlp.fc2.weight''', f'''vit.encoder.layer.{i}.output.dense.weight''')							)
            rename_keys.append((f'''blocks.{i}.mlp.fc2.bias''', f'''vit.encoder.layer.{i}.output.dense.bias''')							)

      # projection layer + position embeddings
      rename_keys.extend(
          [
              ('''cls_token''', '''vit.embeddings.cls_token'''),
              ('''patch_embed.proj.weight''', '''vit.embeddings.patch_embeddings.projection.weight'''),
              ('''patch_embed.proj.bias''', '''vit.embeddings.patch_embeddings.projection.bias'''),
              ('''pos_embed''', '''vit.embeddings.position_embeddings'''),
          ]							)

      if base_model:
            # layernorm + pooler
            rename_keys.extend(
                [
                    ('''norm.weight''', '''layernorm.weight'''),
                    ('''norm.bias''', '''layernorm.bias'''),
                ]							)

            # if just the base model, we should remove "vit" from all keys that start with "vit"
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  [(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_					:		int			,       a_					:		List[Any]			,       a_					:		List[Any]=False							)      ->				int:
      for i in range(config.num_hidden_layers							):
            if base_model:
                  __SCREAMING_SNAKE_CASE       :Any		    =  ""
            else:
                  __SCREAMING_SNAKE_CASE       :int		    =  "vit."
            # read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
            __SCREAMING_SNAKE_CASE       :int		    =  state_dict.pop(f'''blocks.{i}.attn.qkv.weight'''							)
            __SCREAMING_SNAKE_CASE       :Tuple		    =  state_dict.pop(f'''blocks.{i}.attn.qkv.bias'''							)
            # next, add query, keys and values (in that order) to the state dict
            __SCREAMING_SNAKE_CASE       :int		    =  in_proj_weight[
                : config.hidden_size, :
            ]
            __SCREAMING_SNAKE_CASE       :str		    =  in_proj_bias[: config.hidden_size]
            __SCREAMING_SNAKE_CASE       :Dict		    =  in_proj_weight[
                config.hidden_size : config.hidden_size * 2, :
            ]
            __SCREAMING_SNAKE_CASE       :List[str]		    =  in_proj_bias[
                config.hidden_size : config.hidden_size * 2
            ]
            __SCREAMING_SNAKE_CASE       :Tuple		    =  in_proj_weight[
                -config.hidden_size :, :
            ]
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  in_proj_bias[-config.hidden_size :]



def 					__lowerCamelCase       (							a_					:		Optional[Any]							)      ->				Union[str, Any]:
      __SCREAMING_SNAKE_CASE       :List[Any]		    =  ["head.weight", "head.bias"]
      for k in ignore_keys:
            state_dict.pop(a_			,       a_							)



def 					__lowerCamelCase       (							a_					:		Tuple			,       a_					:		Union[str, Any]			,       a_					:		Any							)      ->				Tuple:
      __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  dct.pop(a_							)
      __SCREAMING_SNAKE_CASE       :List[Any]		    =  val



def 					__lowerCamelCase       (							)      ->				Optional[int]:
      __SCREAMING_SNAKE_CASE       :List[Any]		    =  "http://images.cocodataset.org/val2017/000000039769.jpg"
      __SCREAMING_SNAKE_CASE       :Optional[int]		    =  Image.open(requests.get(a_			,       stream=a_							).raw							)
      return im



@torch.no_grad()
def 					__lowerCamelCase       (							a_					:		Optional[int]			,       a_					:		Optional[Any]			,       a_					:		Union[str, Any]=True							)      ->				Tuple:
      __SCREAMING_SNAKE_CASE       :Optional[int]		    =  ViTConfig()
      # patch_size
      if model_name[-1] == "8":
            __SCREAMING_SNAKE_CASE       :List[str]		    =  8
      # set labels if required
      if not base_model:
            __SCREAMING_SNAKE_CASE       :str		    =  10_00
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  "huggingface/label-files"
            __SCREAMING_SNAKE_CASE       :Dict		    =  "imagenet-1k-id2label.json"
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  json.load(open(hf_hub_download(a_			,       a_			,       repo_type='''dataset'''							)			,       '''r'''							)							)
            __SCREAMING_SNAKE_CASE       :Any		    =  {int(a_							): v for k, v in idalabel.items()}
            __SCREAMING_SNAKE_CASE       :List[Any]		    =  idalabel
            __SCREAMING_SNAKE_CASE       :Dict		    =  {v: k for k, v in idalabel.items()}
      # size of the architecture
      if model_name in ["dino_vits8", "dino_vits16"]:
            __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  3_84
            __SCREAMING_SNAKE_CASE       :List[str]		    =  15_36
            __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  12
            __SCREAMING_SNAKE_CASE       :Optional[int]		    =  6

      # load original model from torch hub
      __SCREAMING_SNAKE_CASE       :Tuple		    =  torch.hub.load('''facebookresearch/dino:main'''			,       a_							)
      original_model.eval()

      # load state_dict of original model, remove and rename some keys
      __SCREAMING_SNAKE_CASE       :int		    =  original_model.state_dict()
      if base_model:
            remove_classification_head_(a_							)
      __SCREAMING_SNAKE_CASE       :List[Any]		    =  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_			,       a_							)

      # load HuggingFace model
      if base_model:
            __SCREAMING_SNAKE_CASE       :Optional[int]		    =  ViTModel(a_			,       add_pooling_layer=a_							).eval()
      else:
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  ViTForImageClassification(a_							).eval()
      model.load_state_dict(a_							)

      # Check outputs on an image, prepared by ViTImageProcessor
      __SCREAMING_SNAKE_CASE       :List[Any]		    =  ViTImageProcessor()
      __SCREAMING_SNAKE_CASE       :int		    =  image_processor(images=prepare_img()			,       return_tensors='''pt'''							)
      __SCREAMING_SNAKE_CASE       :Tuple		    =  encoding["pixel_values"]
      __SCREAMING_SNAKE_CASE       :Tuple		    =  model(a_							)

      if base_model:
            __SCREAMING_SNAKE_CASE       :Any		    =  original_model(a_							)
            assert torch.allclose(a_			,       outputs.last_hidden_state[:, 0, :]			,       atol=1e-1							)
      else:
            __SCREAMING_SNAKE_CASE       :Any		    =  original_model(a_							)
            assert logits.shape == outputs.logits.shape
            assert torch.allclose(a_			,       outputs.logits			,       atol=1e-3							)

      Path(a_							).mkdir(exist_ok=a_							)
      print(f'''Saving model {model_name} 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(
      "--model_name",
      default="dino_vitb16",
      type=str,
      help="Name of the model trained with DINO you\'d like to convert.",
  )
  parser.add_argument(
      "--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model directory."
  )
  parser.add_argument(
      "--base_model",
      action="store_true",
      help="Whether to only convert the base model (no projection head weights).",
  )

  parser.set_defaults(base_model=True)
  lowerCamelCase_       =		parser.parse_args()
  convert_vit_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.base_model)






"""simple docstring"""
def 					__lowerCamelCase       (							a_					:		int = 10			,       a_					:		int = 22							)      ->				int:
      __SCREAMING_SNAKE_CASE       :Optional[int]		    =  range(1			,       a_							)
      __SCREAMING_SNAKE_CASE       :List[Any]		    =  range(1			,       a_							)
      return sum(
          1 for power in powers for base in bases if len(str(base**power							)							) == power							)


if __name__ == "__main__":
  print(f'{solution(1_0, 2_2) = }')