






"""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()
_UpperCamelCase					      =  logging.get_logger(__name__)

def _a			(		_snake_case				,	_snake_case=False							):







      """simple docstring"""






      UpperCAmelCase          =	[]
      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          =	[(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 _a			(		_snake_case				,	_snake_case				,	_snake_case=False							):







      """simple docstring"""






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

def _a			(		_snake_case							):







      """simple docstring"""






      UpperCAmelCase          =	["""head.weight""", """head.bias"""]
      for k in ignore_keys:
            state_dict.pop(_snake_case				,	_snake_case							)

def _a			(		_snake_case				,	_snake_case				,	_snake_case							):







      """simple docstring"""






      UpperCAmelCase          =	dct.pop(_snake_case							)
      UpperCAmelCase          =	val

def _a			(		):







      """simple docstring"""






      UpperCAmelCase          =	"""http://images.cocodataset.org/val2017/000000039769.jpg"""
      UpperCAmelCase          =	Image.open(requests.get(_snake_case				,	stream=_snake_case							).raw							)
      return im

@torch.no_grad()
def _a			(		_snake_case				,	_snake_case				,	_snake_case=True							):







      """simple docstring"""






      UpperCAmelCase          =	ViTConfig()
      # patch_size
      if model_name[-1] == "8":
            UpperCAmelCase          =	8
      # set labels if required
      if not base_model:
            UpperCAmelCase          =	1000
            UpperCAmelCase          =	"""huggingface/label-files"""
            UpperCAmelCase          =	"""imagenet-1k-id2label.json"""
            UpperCAmelCase          =	json.load(open(hf_hub_download(_snake_case				,	_snake_case				,	repo_type="""dataset"""							)				,	"""r"""							)							)
            UpperCAmelCase          =	{int(_snake_case							): v for k, v in idalabel.items()}
            UpperCAmelCase          =	idalabel
            UpperCAmelCase          =	{v: k for k, v in idalabel.items()}
      # size of the architecture
      if model_name in ["dino_vits8", "dino_vits16"]:
            UpperCAmelCase          =	384
            UpperCAmelCase          =	1536
            UpperCAmelCase          =	12
            UpperCAmelCase          =	6

      # load original model from torch hub
      UpperCAmelCase          =	torch.hub.load("""facebookresearch/dino:main"""				,	_snake_case							)
      original_model.eval()

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

      # load HuggingFace model
      if base_model:
            UpperCAmelCase          =	ViTModel(_snake_case				,	add_pooling_layer=_snake_case							).eval()
      else:
            UpperCAmelCase          =	ViTForImageClassification(_snake_case							).eval()
      model.load_state_dict(_snake_case							)

      # Check outputs on an image, prepared by ViTImageProcessor
      UpperCAmelCase          =	ViTImageProcessor()
      UpperCAmelCase          =	image_processor(images=prepare_img()				,	return_tensors="""pt"""							)
      UpperCAmelCase          =	encoding["""pixel_values"""]
      UpperCAmelCase          =	model(_snake_case							)

      if base_model:
            UpperCAmelCase          =	original_model(_snake_case							)
            assert torch.allclose(_snake_case				,	outputs.last_hidden_state[:, 0, :]				,	atol=1E-1							)
      else:
            UpperCAmelCase          =	original_model(_snake_case							)
            assert logits.shape == outputs.logits.shape
            assert torch.allclose(_snake_case				,	outputs.logits				,	atol=1E-3							)

      Path(_snake_case							).mkdir(exist_ok=_snake_case							)
      print(F'''Saving model {model_name} to {pytorch_dump_folder_path}'''							)
      model.save_pretrained(_snake_case							)
      print(F'''Saving image processor to {pytorch_dump_folder_path}'''							)
      image_processor.save_pretrained(_snake_case							)


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











"""simple docstring"""







from typing import Dict, List, Optional, Union

import numpy as np

from transformers.utils import is_vision_available
from transformers.utils.generic import TensorType

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import (
    center_crop,
    get_resize_output_image_size,
    normalize,
    rescale,
    resize,
    to_channel_dimension_format,
)
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    is_valid_image,
    to_numpy_array,
    valid_images,
)
from ...utils import logging


if is_vision_available():
  import PIL

_UpperCamelCase					      =  logging.get_logger(__name__)

def _a			(		_snake_case							):







      """simple docstring"""






      if isinstance(_snake_case				,	(list, tuple)							) and isinstance(videos[0]				,	(list, tuple)							) and is_valid_image(videos[0][0]							):
            return videos

      elif isinstance(_snake_case				,	(list, tuple)							) and is_valid_image(videos[0]							):
            return [videos]

      elif is_valid_image(_snake_case							):
            return [[videos]]

      raise ValueError(F'''Could not make batched video from {videos}'''							)







class  lowerCamelCase__ (	snake_case			):
    SCREAMING_SNAKE_CASE		=      ['''pixel_values''']






    def __init__(			self     ,A = True     ,A = None     ,A = PILImageResampling.BILINEAR     ,A = True     ,A = None     ,A = True     ,A = 1 / 255     ,A = True     ,A = True     ,A = None     ,A = None     ,**A     ,):
          super().__init__(**A )
          UpperCAmelCase          =	size if size is not None else {"""shortest_edge""": 256}
          UpperCAmelCase          =	get_size_dict(A     ,default_to_square=A )
          UpperCAmelCase          =	crop_size if crop_size is not None else {"""height""": 224, """width""": 224}
          UpperCAmelCase          =	get_size_dict(A     ,param_name="""crop_size""" )

          UpperCAmelCase          =	do_resize
          UpperCAmelCase          =	size
          UpperCAmelCase          =	do_center_crop
          UpperCAmelCase          =	crop_size
          UpperCAmelCase          =	resample
          UpperCAmelCase          =	do_rescale
          UpperCAmelCase          =	rescale_factor
          UpperCAmelCase          =	offset
          UpperCAmelCase          =	do_normalize
          UpperCAmelCase          =	image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
          UpperCAmelCase          =	image_std if image_std is not None else IMAGENET_STANDARD_STD






    def     _UpperCamelCase							(			self     ,A     ,A     ,A = PILImageResampling.BILINEAR     ,A = None     ,**A     ,):
          UpperCAmelCase          =	get_size_dict(A     ,default_to_square=A )
          if "shortest_edge" in size:
                UpperCAmelCase          =	get_resize_output_image_size(A     ,size["""shortest_edge"""]     ,default_to_square=A )
          elif "height" in size and "width" in size:
                UpperCAmelCase          =	(size["""height"""], size["""width"""])
          else:
                raise ValueError(F'''Size must have \'height\' and \'width\' or \'shortest_edge\' as keys. Got {size.keys()}''' )
          return resize(A     ,size=A     ,resample=A     ,data_format=A     ,**A )






    def     _UpperCamelCase							(			self     ,A     ,A     ,A = None     ,**A     ,):
          UpperCAmelCase          =	get_size_dict(A )
          if "height" not in size or "width" not in size:
                raise ValueError(F'''Size must have \'height\' and \'width\' as keys. Got {size.keys()}''' )
          return center_crop(A     ,size=(size["""height"""], size["""width"""])     ,data_format=A     ,**A )






    def     _UpperCamelCase							(			self     ,A     ,A     ,A = True     ,A = None     ,**A     ,):
          UpperCAmelCase          =	image.astype(np.floataa )
          if offset:
                UpperCAmelCase          =	image - (scale / 2)
          return rescale(A     ,scale=A     ,data_format=A     ,**A )






    def     _UpperCamelCase							(			self     ,A     ,A     ,A     ,A = None     ,**A     ,):
          return normalize(A     ,mean=A     ,std=A     ,data_format=A     ,**A )






    def     _UpperCamelCase							(			self     ,A     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = ChannelDimension.FIRST     ,):
          if do_resize and size is None or resample is None:
                raise ValueError("""Size and resample must be specified if do_resize is True.""" )

          if do_center_crop and crop_size is None:
                raise ValueError("""Crop size must be specified if do_center_crop is True.""" )

          if do_rescale and rescale_factor is None:
                raise ValueError("""Rescale factor must be specified if do_rescale is True.""" )

          if do_normalize and (image_mean is None or image_std is None):
                raise ValueError("""Image mean and std must be specified if do_normalize is True.""" )

          if offset and not do_rescale:
                raise ValueError("""For offset, do_rescale must also be set to True.""" )

          # All transformations expect numpy arrays.
          UpperCAmelCase          =	to_numpy_array(A )

          if do_resize:
                UpperCAmelCase          =	self.resize(image=A     ,size=A     ,resample=A )

          if do_center_crop:
                UpperCAmelCase          =	self.center_crop(A     ,size=A )

          if do_rescale:
                UpperCAmelCase          =	self.rescale(image=A     ,scale=A     ,offset=A )

          if do_normalize:
                UpperCAmelCase          =	self.normalize(image=A     ,mean=A     ,std=A )

          UpperCAmelCase          =	to_channel_dimension_format(A     ,A )
          return image






    def     _UpperCamelCase							(			self     ,A     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = None     ,A = ChannelDimension.FIRST     ,**A     ,):
          UpperCAmelCase          =	do_resize if do_resize is not None else self.do_resize
          UpperCAmelCase          =	resample if resample is not None else self.resample
          UpperCAmelCase          =	do_center_crop if do_center_crop is not None else self.do_center_crop
          UpperCAmelCase          =	do_rescale if do_rescale is not None else self.do_rescale
          UpperCAmelCase          =	rescale_factor if rescale_factor is not None else self.rescale_factor
          UpperCAmelCase          =	offset if offset is not None else self.offset
          UpperCAmelCase          =	do_normalize if do_normalize is not None else self.do_normalize
          UpperCAmelCase          =	image_mean if image_mean is not None else self.image_mean
          UpperCAmelCase          =	image_std if image_std is not None else self.image_std

          UpperCAmelCase          =	size if size is not None else self.size
          UpperCAmelCase          =	get_size_dict(A     ,default_to_square=A )
          UpperCAmelCase          =	crop_size if crop_size is not None else self.crop_size
          UpperCAmelCase          =	get_size_dict(A     ,param_name="""crop_size""" )

          if not valid_images(A ):
                raise ValueError(
                    """Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, """
                    """torch.Tensor, tf.Tensor or jax.ndarray.""" )

          UpperCAmelCase          =	make_batched(A )

          UpperCAmelCase          =	[
              [
                  self._preprocess_image(
                      image=A     ,do_resize=A     ,size=A     ,resample=A     ,do_center_crop=A     ,crop_size=A     ,do_rescale=A     ,rescale_factor=A     ,offset=A     ,do_normalize=A     ,image_mean=A     ,image_std=A     ,data_format=A     ,)
                  for img in video
              ]
              for video in videos
          ]

          UpperCAmelCase          =	{"""pixel_values""": videos}
          return BatchFeature(data=A     ,tensor_type=A )



