






from __future__ import annotations

import unittest

from transformers import is_tf_available
from transformers.testing_utils import require_tf, slow

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
		import numpy
		import tensorflow as tf

		from transformers import (
		    TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST,
		    TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST,
		    TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST,
		    BertConfig,
		    DPRConfig,
		    TFDPRContextEncoder,
		    TFDPRQuestionEncoder,
		    TFDPRReader,
		)





class __lowerCamelCase :





	"""simple docstring"""






	def __init__(							self       ,    UpperCAmelCase       ,    UpperCAmelCase=13       ,    UpperCAmelCase=7       ,    UpperCAmelCase=True       ,    UpperCAmelCase=True       ,    UpperCAmelCase=True       ,    UpperCAmelCase=True       ,    UpperCAmelCase=99       ,    UpperCAmelCase=32       ,    UpperCAmelCase=2       ,    UpperCAmelCase=4       ,    UpperCAmelCase=37       ,    UpperCAmelCase="gelu"       ,    UpperCAmelCase=0.1       ,    UpperCAmelCase=0.1       ,    UpperCAmelCase=512       ,    UpperCAmelCase=16       ,    UpperCAmelCase=2       ,    UpperCAmelCase=0.02       ,    UpperCAmelCase=3       ,    UpperCAmelCase=4       ,    UpperCAmelCase=None       ,    UpperCAmelCase=0       ,    ):
							"""simple docstring"""







							_UpperCAmelCase									=			parent
							_UpperCAmelCase									=			batch_size
							_UpperCAmelCase									=			seq_length
							_UpperCAmelCase									=			is_training
							_UpperCAmelCase									=			use_input_mask
							_UpperCAmelCase									=			use_token_type_ids
							_UpperCAmelCase									=			use_labels
							_UpperCAmelCase									=			vocab_size
							_UpperCAmelCase									=			hidden_size
							_UpperCAmelCase									=			num_hidden_layers
							_UpperCAmelCase									=			num_attention_heads
							_UpperCAmelCase									=			intermediate_size
							_UpperCAmelCase									=			hidden_act
							_UpperCAmelCase									=			hidden_dropout_prob
							_UpperCAmelCase									=			attention_probs_dropout_prob
							_UpperCAmelCase									=			max_position_embeddings
							_UpperCAmelCase									=			type_vocab_size
							_UpperCAmelCase									=			type_sequence_label_size
							_UpperCAmelCase									=			initializer_range
							_UpperCAmelCase									=			num_labels
							_UpperCAmelCase									=			num_choices
							_UpperCAmelCase									=			scope
							_UpperCAmelCase									=			projection_dim

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			ids_tensor([self.batch_size, self.seq_length]       ,    self.vocab_size    )

							_UpperCAmelCase									=			None
							if self.use_input_mask:
													# follow test_modeling_tf_ctrl.py
													_UpperCAmelCase									=			random_attention_mask([self.batch_size, self.seq_length]    )

							_UpperCAmelCase									=			None
							if self.use_token_type_ids:
													_UpperCAmelCase									=			ids_tensor([self.batch_size, self.seq_length]       ,    self.type_vocab_size    )

							_UpperCAmelCase									=			None
							_UpperCAmelCase									=			None
							_UpperCAmelCase									=			None
							if self.use_labels:
													_UpperCAmelCase									=			ids_tensor([self.batch_size]       ,    self.type_sequence_label_size    )
													_UpperCAmelCase									=			ids_tensor([self.batch_size, self.seq_length]       ,    self.num_labels    )
													_UpperCAmelCase									=			ids_tensor([self.batch_size]       ,    self.num_choices    )

							_UpperCAmelCase									=			BertConfig(
							    vocab_size=self.vocab_size       ,    hidden_size=self.hidden_size       ,    num_hidden_layers=self.num_hidden_layers       ,    num_attention_heads=self.num_attention_heads       ,    intermediate_size=self.intermediate_size       ,    hidden_act=self.hidden_act       ,    hidden_dropout_prob=self.hidden_dropout_prob       ,    attention_probs_dropout_prob=self.attention_probs_dropout_prob       ,    max_position_embeddings=self.max_position_embeddings       ,    type_vocab_size=self.type_vocab_size       ,    is_decoder=UpperCAmelCase       ,    initializer_range=self.initializer_range       ,    )
							_UpperCAmelCase									=			DPRConfig(projection_dim=self.projection_dim       ,    **config.to_dict()    )

							return config, input_ids, token_type_ids, input_mask, sequence_labels, token_labels, choice_labels

	def        UpperCamelCase    (							self       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase    ):
							"""simple docstring"""







							_UpperCAmelCase									=			TFDPRContextEncoder(config=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase       ,    attention_mask=UpperCAmelCase       ,    token_type_ids=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase       ,    token_type_ids=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase    )
							self.parent.assertEqual(result.pooler_output.shape       ,    (self.batch_size, self.projection_dim or self.hidden_size)    )

	def        UpperCamelCase    (							self       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase    ):
							"""simple docstring"""







							_UpperCAmelCase									=			TFDPRQuestionEncoder(config=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase       ,    attention_mask=UpperCAmelCase       ,    token_type_ids=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase       ,    token_type_ids=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase    )
							self.parent.assertEqual(result.pooler_output.shape       ,    (self.batch_size, self.projection_dim or self.hidden_size)    )

	def        UpperCamelCase    (							self       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase       ,    UpperCAmelCase    ):
							"""simple docstring"""







							_UpperCAmelCase									=			TFDPRReader(config=UpperCAmelCase    )
							_UpperCAmelCase									=			model(UpperCAmelCase       ,    attention_mask=UpperCAmelCase    )

							self.parent.assertEqual(result.start_logits.shape       ,    (self.batch_size, self.seq_length)    )
							self.parent.assertEqual(result.end_logits.shape       ,    (self.batch_size, self.seq_length)    )
							self.parent.assertEqual(result.relevance_logits.shape       ,    (self.batch_size,)    )

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			self.prepare_config_and_inputs()
							(
							    (
							    _UpperCAmelCase
							)					, (
							    _UpperCAmelCase
							)					, (
							    _UpperCAmelCase
							)					, (
							    _UpperCAmelCase
							)					, (
							    _UpperCAmelCase
							)					, (
							    _UpperCAmelCase
							)					, (
							    _UpperCAmelCase
							)					, 
							)									=			config_and_inputs
							_UpperCAmelCase									=			{'input_ids': input_ids}
							return config, inputs_dict





@require_tf
class __lowerCamelCase (      snake_case__     ,       snake_case__     ,       unittest.TestCase):





	"""simple docstring"""






	UpperCamelCase__								=      (
	    (
	        TFDPRContextEncoder,
	        TFDPRQuestionEncoder,
	        TFDPRReader,
	    )
	    if is_tf_available()
	    else ()
	)
	UpperCamelCase__								=      {"feature-extraction": TFDPRQuestionEncoder} if is_tf_available() else {}

	UpperCamelCase__								=      False
	UpperCamelCase__								=      False
	UpperCamelCase__								=      False
	UpperCamelCase__								=      False
	UpperCamelCase__								=      False

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			TFDPRModelTester(self    )
							_UpperCAmelCase									=			ConfigTester(self       ,    config_class=UpperCAmelCase       ,    hidden_size=37    )

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							self.config_tester.run_common_tests()

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_dpr_context_encoder(*UpperCAmelCase    )

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_dpr_question_encoder(*UpperCAmelCase    )

	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_dpr_reader(*UpperCAmelCase    )

	@slow
	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							for model_name in TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
													_UpperCAmelCase									=			TFDPRContextEncoder.from_pretrained(UpperCAmelCase    )
													self.assertIsNotNone(UpperCAmelCase    )

							for model_name in TF_DPR_CONTEXT_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
													_UpperCAmelCase									=			TFDPRContextEncoder.from_pretrained(UpperCAmelCase    )
													self.assertIsNotNone(UpperCAmelCase    )

							for model_name in TF_DPR_QUESTION_ENCODER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
													_UpperCAmelCase									=			TFDPRQuestionEncoder.from_pretrained(UpperCAmelCase    )
													self.assertIsNotNone(UpperCAmelCase    )

							for model_name in TF_DPR_READER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
													_UpperCAmelCase									=			TFDPRReader.from_pretrained(UpperCAmelCase    )
													self.assertIsNotNone(UpperCAmelCase    )





@require_tf
class __lowerCamelCase (      unittest.TestCase):





	"""simple docstring"""






	@slow
	def        UpperCamelCase    (							self    ):
							"""simple docstring"""







							_UpperCAmelCase									=			TFDPRQuestionEncoder.from_pretrained('facebook/dpr-question_encoder-single-nq-base'    )

							_UpperCAmelCase									=			tf.constant(
							    [[101, 7592, 1010, 2003, 2026, 3899, 1_0140, 1029, 102]]    )  # [CLS] hello, is my dog cute? [SEP]
							_UpperCAmelCase									=			model(UpperCAmelCase    )[0]  # embedding shape = (1, 768)
							# compare the actual values for a slice.
							_UpperCAmelCase									=			tf.constant(
							    [
							        [
							            0.03_23_62_53,
							            0.12_75_33_35,
							            0.16_81_85_09,
							            0.00_27_97_86,
							            0.3_89_69_33,
							            0.24_26_49_45,
							            0.2_17_89_71,
							            -0.02_33_52_27,
							            -0.08_48_19_59,
							            -0.14_32_41_17,
							        ]
							    ]    )
							self.assertTrue(numpy.allclose(output[:, :10].numpy()       ,    expected_slice.numpy()       ,    atol=1e-4    )    )








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


def __A    (      __lowerCAmelCase ,		__lowerCAmelCase=False	)->  Union[str, Any]:





						"""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    (      __lowerCAmelCase ,		__lowerCAmelCase ,		__lowerCAmelCase=False	)->  List[str]:





						"""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    (      __lowerCAmelCase	)->  Optional[Any]:





						"""simple docstring"""



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


def __A    (      __lowerCAmelCase ,		__lowerCAmelCase ,		__lowerCAmelCase	)->  int:





						"""simple docstring"""



						_UpperCAmelCase									=			dct.pop(__lowerCAmelCase	)
						_UpperCAmelCase									=			val


def __A    (      )->  str:





						"""simple docstring"""



						_UpperCAmelCase									=			'http://images.cocodataset.org/val2017/000000039769.jpg'
						_UpperCAmelCase									=			Image.open(requests.get(__lowerCAmelCase ,		stream=__lowerCAmelCase	).raw	)
						return im


@torch.no_grad()
def __A    (      __lowerCAmelCase ,		__lowerCAmelCase ,		__lowerCAmelCase=True	)->  List[str]:





						"""simple docstring"""



						_UpperCAmelCase									=			ViTConfig()
						# patch_size
						if model_name[-1] == "8":
												_UpperCAmelCase									=			8
						# set labels if required
						if not base_model:
												_UpperCAmelCase									=			1_000
												_UpperCAmelCase									=			'huggingface/label-files'
												_UpperCAmelCase									=			'imagenet-1k-id2label.json'
												_UpperCAmelCase									=			json.load(open(hf_hub_download(__lowerCAmelCase ,		__lowerCAmelCase ,		repo_type='dataset'	) ,		'r'	)	)
												_UpperCAmelCase									=			{int(__lowerCAmelCase	): 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									=			1_536
												_UpperCAmelCase									=			12
												_UpperCAmelCase									=			6

						# load original model from torch hub
						_UpperCAmelCase									=			torch.hub.load('facebookresearch/dino:main' ,		__lowerCAmelCase	)
						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_(__lowerCAmelCase	)
						_UpperCAmelCase									=			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									=			ViTModel(__lowerCAmelCase ,		add_pooling_layer=__lowerCAmelCase	).eval()
						else:
												_UpperCAmelCase									=			ViTForImageClassification(__lowerCAmelCase	).eval()
						model.load_state_dict(__lowerCAmelCase	)

						# 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(__lowerCAmelCase	)

						if base_model:
												_UpperCAmelCase									=			original_model(__lowerCAmelCase	)
												assert torch.allclose(__lowerCAmelCase ,		outputs.last_hidden_state[:, 0, :] ,		atol=1E-1	)
						else:
												_UpperCAmelCase									=			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__":
		_a      	=  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)
		_a      	=  parser.parse_args()
		convert_vit_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.base_model)
