


'''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()
lowercase							=logging.get_logger(__name__)





def lowerCamelCase__      (						__lowerCamelCase	:							Union[str, Any]	,   __lowerCamelCase	:							str=False							):







   '''simple docstring'''




   _UpperCAmelCase       :       str							   =[]
   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"
      _UpperCAmelCase       :       str							   =[(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__      (						__lowerCamelCase	:							int	,   __lowerCamelCase	:							Optional[int]	,   __lowerCamelCase	:							Optional[int]=False							):







   '''simple docstring'''




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





def lowerCamelCase__      (						__lowerCamelCase	:							List[str]							):







   '''simple docstring'''




   _UpperCAmelCase       :       Optional[int]							   =['head.weight', 'head.bias']
   for k in ignore_keys:
      state_dict.pop(__lowerCamelCase	,   __lowerCamelCase							)





def lowerCamelCase__      (						__lowerCamelCase	:							Optional[int]	,   __lowerCamelCase	:							List[Any]	,   __lowerCamelCase	:							Dict							):







   '''simple docstring'''




   _UpperCAmelCase       :       List[Any]							   =dct.pop(__lowerCamelCase							)
   _UpperCAmelCase       :       Dict							   =val





def lowerCamelCase__      (						):







   '''simple docstring'''




   _UpperCAmelCase       :       List[Any]							   ='http://images.cocodataset.org/val2017/000000039769.jpg'
   _UpperCAmelCase       :       Optional[int]							   =Image.open(requests.get(__lowerCamelCase	,   stream=__lowerCamelCase							).raw							)
   return im





@torch.no_grad()
def lowerCamelCase__      (						__lowerCamelCase	:							List[Any]	,   __lowerCamelCase	:							Optional[int]	,   __lowerCamelCase	:							List[str]=True							):







   '''simple docstring'''




   _UpperCAmelCase       :       Optional[int]							   =ViTConfig()
   # patch_size
   if model_name[-1] == "8":
      _UpperCAmelCase       :       Dict							   =8
   # set labels if required
   if not base_model:
      _UpperCAmelCase       :       Optional[Any]							   =1_0_0_0
      _UpperCAmelCase       :       Union[str, Any]							   ='huggingface/label-files'
      _UpperCAmelCase       :       Dict							   ='imagenet-1k-id2label.json'
      _UpperCAmelCase       :       Dict							   =json.load(open(hf_hub_download(__lowerCamelCase	,   __lowerCamelCase	,   repo_type='dataset'							)	,   'r'							)							)
      _UpperCAmelCase       :       Tuple							   ={int(__lowerCamelCase							): v for k, v in idalabel.items()}
      _UpperCAmelCase       :       Tuple							   =idalabel
      _UpperCAmelCase       :       List[Any]							   ={v: k for k, v in idalabel.items()}
   # size of the architecture
   if model_name in ["dino_vits8", "dino_vits16"]:
      _UpperCAmelCase       :       Union[str, Any]							   =3_8_4
      _UpperCAmelCase       :       Optional[int]							   =1_5_3_6
      _UpperCAmelCase       :       List[Any]							   =1_2
      _UpperCAmelCase       :       str							   =6

   # load original model from torch hub
   _UpperCAmelCase       :       List[Any]							   =torch.hub.load('facebookresearch/dino:main'	,   __lowerCamelCase							)
   original_model.eval()

   # load state_dict of original model, remove and rename some keys
   _UpperCAmelCase       :       int							   =original_model.state_dict()
   if base_model:
      remove_classification_head_(__lowerCamelCase							)
   _UpperCAmelCase       :       Dict							   =create_rename_keys(__lowerCamelCase	,   base_model=__lowerCamelCase							)
   for src, dest in rename_keys:
      rename_key(__lowerCamelCase	,   __lowerCamelCase	,   __lowerCamelCase							)
   read_in_q_k_v(__lowerCamelCase	,   __lowerCamelCase	,   __lowerCamelCase							)

   # load HuggingFace model
   if base_model:
      _UpperCAmelCase       :       Dict							   =ViTModel(__lowerCamelCase	,   add_pooling_layer=__lowerCamelCase							).eval()
   else:
      _UpperCAmelCase       :       int							   =ViTForImageClassification(__lowerCamelCase							).eval()
   model.load_state_dict(__lowerCamelCase							)

   # Check outputs on an image, prepared by ViTImageProcessor
   _UpperCAmelCase       :       int							   =ViTImageProcessor()
   _UpperCAmelCase       :       Dict							   =image_processor(images=prepare_img()	,   return_tensors='pt'							)
   _UpperCAmelCase       :       Dict							   =encoding['pixel_values']
   _UpperCAmelCase       :       Tuple							   =model(__lowerCamelCase							)

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

   Path(__lowerCamelCase							).mkdir(exist_ok=__lowerCamelCase							)
   print(f"Saving model {model_name} to {pytorch_dump_folder_path}"							)
   model.save_pretrained(__lowerCamelCase							)
   print(f"Saving image processor to {pytorch_dump_folder_path}"							)
   image_processor.save_pretrained(__lowerCamelCase							)


if __name__ == "__main__":
 lowercase							=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)
 lowercase							=parser.parse_args()
 convert_vit_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.base_model)





'''simple docstring'''






from __future__ import annotations

from random import choice





def lowerCamelCase__      (						__lowerCamelCase	:							Optional[int]							):







   '''simple docstring'''




   return choice(__lowerCamelCase							)





def lowerCamelCase__      (						__lowerCamelCase	:							list[int]	,   __lowerCamelCase	:							int							):







   '''simple docstring'''




   _UpperCAmelCase       :       int							   =random_pivot(__lowerCamelCase							)

   # partition based on pivot
   # linear time
   _UpperCAmelCase       :       str							   =[e for e in lst if e < pivot]
   _UpperCAmelCase       :       Dict							   =[e for e in lst if e > pivot]

   # if we get lucky, pivot might be the element we want.
   # we can easily see this:
   # small (elements smaller than k)
   # + pivot (kth element)
   # + big (elements larger than k)
   if len(__lowerCamelCase							) == k - 1:
      return pivot
   # pivot is in elements bigger than k
   elif len(__lowerCamelCase							) < k - 1:
      return kth_number(__lowerCamelCase	,   k - len(__lowerCamelCase							) - 1							)
   # pivot is in elements smaller than k
   else:
      return kth_number(__lowerCamelCase	,   __lowerCamelCase							)


if __name__ == "__main__":
 import doctest

 doctest.testmod()

