



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 YolosConfig, YolosForObjectDetection, YolosImageProcessor
from transformers.utils import logging


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


def A						(       __UpperCamelCase					)						->      YolosConfig:
			A__       =    YolosConfig()

			# size of the architecture
			if "yolos_ti" in yolos_name:
						A__       =    192
						A__       =    768
						A__       =    12
						A__       =    3
						A__       =    [800, 1_333]
						A__       =    False
			elif yolos_name == "yolos_s_dWr":
						A__       =    330
						A__       =    14
						A__       =    6
						A__       =    1_320
			elif "yolos_s" in yolos_name:
						A__       =    384
						A__       =    1_536
						A__       =    12
						A__       =    6
			elif "yolos_b" in yolos_name:
						A__       =    [800, 1_344]

			A__       =    91
			A__       =    'huggingface/label-files'
			A__       =    'coco-detection-id2label.json'
			A__       =    json.load(open(hf_hub_download(__UpperCamelCase ,	__UpperCamelCase ,	repo_type='dataset'					) ,	'r'					)					)
			A__       =    {int(__UpperCamelCase					): v for k, v in idalabel.items()}
			A__       =    idalabel
			A__       =    {v: k for k, v in idalabel.items()}

			return config


def A						(       __UpperCamelCase ,	__UpperCamelCase ,	__UpperCamelCase = False					)						->      str:
			for i in range(config.num_hidden_layers					):
						# read in weights + bias of input projection layer (in timm, this is a single matrix + bias)
						A__       =    state_dict.pop(f'''blocks.{i}.attn.qkv.weight'''					)
						A__       =    state_dict.pop(f'''blocks.{i}.attn.qkv.bias'''					)
						# next, add query, keys and values (in that order) to the state dict
						A__       =    in_proj_weight[: config.hidden_size, :]
						A__       =    in_proj_bias[: config.hidden_size]
						A__       =    in_proj_weight[
						    config.hidden_size : config.hidden_size * 2, :
						]
						A__       =    in_proj_bias[
						    config.hidden_size : config.hidden_size * 2
						]
						A__       =    in_proj_weight[-config.hidden_size :, :]
						A__       =    in_proj_bias[-config.hidden_size :]


def A						(       __UpperCamelCase					)						->      str:
			if "backbone" in name:
						A__       =    name.replace('backbone' ,	'vit'					)
			if "cls_token" in name:
						A__       =    name.replace('cls_token' ,	'embeddings.cls_token'					)
			if "det_token" in name:
						A__       =    name.replace('det_token' ,	'embeddings.detection_tokens'					)
			if "mid_pos_embed" in name:
						A__       =    name.replace('mid_pos_embed' ,	'encoder.mid_position_embeddings'					)
			if "pos_embed" in name:
						A__       =    name.replace('pos_embed' ,	'embeddings.position_embeddings'					)
			if "patch_embed.proj" in name:
						A__       =    name.replace('patch_embed.proj' ,	'embeddings.patch_embeddings.projection'					)
			if "blocks" in name:
						A__       =    name.replace('blocks' ,	'encoder.layer'					)
			if "attn.proj" in name:
						A__       =    name.replace('attn.proj' ,	'attention.output.dense'					)
			if "attn" in name:
						A__       =    name.replace('attn' ,	'attention.self'					)
			if "norm1" in name:
						A__       =    name.replace('norm1' ,	'layernorm_before'					)
			if "norm2" in name:
						A__       =    name.replace('norm2' ,	'layernorm_after'					)
			if "mlp.fc1" in name:
						A__       =    name.replace('mlp.fc1' ,	'intermediate.dense'					)
			if "mlp.fc2" in name:
						A__       =    name.replace('mlp.fc2' ,	'output.dense'					)
			if "class_embed" in name:
						A__       =    name.replace('class_embed' ,	'class_labels_classifier'					)
			if "bbox_embed" in name:
						A__       =    name.replace('bbox_embed' ,	'bbox_predictor'					)
			if "vit.norm" in name:
						A__       =    name.replace('vit.norm' ,	'vit.layernorm'					)

			return name


def A						(       __UpperCamelCase ,	__UpperCamelCase					)						->      dict:
			for key in orig_state_dict.copy().keys():
						A__       =    orig_state_dict.pop(__UpperCamelCase					)

						if "qkv" in key:
									A__       =    key.split('.'					)
									A__       =    int(key_split[2]					)
									A__       =    model.vit.encoder.layer[layer_num].attention.attention.all_head_size
									if "weight" in key:
												A__       =    val[:dim, :]
												A__       =    val[
												    dim : dim * 2, :
												]
												A__       =    val[-dim:, :]
									else:
												A__       =    val[:dim]
												A__       =    val[dim : dim * 2]
												A__       =    val[-dim:]
						else:
									A__       =    val

			return orig_state_dict


def A						(       )						->      torch.Tensor:
			A__       =    'http://images.cocodataset.org/val2017/000000039769.jpg'
			A__       =    Image.open(requests.get(__UpperCamelCase ,	stream=__UpperCamelCase					).raw					)
			return im


@torch.no_grad()
def A						(       __UpperCamelCase ,	__UpperCamelCase ,	__UpperCamelCase ,	__UpperCamelCase = False					)						->      List[str]:
			A__       =    get_yolos_config(__UpperCamelCase					)

			# load original state_dict
			A__       =    torch.load(__UpperCamelCase ,	map_location='cpu'					)['model']

			# load 🤗 model
			A__       =    YolosForObjectDetection(__UpperCamelCase					)
			model.eval()
			A__       =    convert_state_dict(__UpperCamelCase ,	__UpperCamelCase					)
			model.load_state_dict(__UpperCamelCase					)

			# Check outputs on an image, prepared by YolosImageProcessor
			A__       =    800 if yolos_name != 'yolos_ti' else 512
			A__       =    YolosImageProcessor(format='coco_detection' ,	size=__UpperCamelCase					)
			A__       =    image_processor(images=prepare_img() ,	return_tensors='pt'					)
			A__       =    model(**__UpperCamelCase					)
			A__     , A__       =    outputs.logits, outputs.pred_boxes

			A__     , A__       =    None, None
			if yolos_name == "yolos_ti":
						A__       =    torch.tensor(
						    [[-39.5022, -11.9820, -17.6888], [-29.9574, -9.9769, -17.7691], [-42.3281, -20.7200, -30.6294]]					)
						A__       =    torch.tensor(
						    [[0.4021, 0.0836, 0.7979], [0.0184, 0.2609, 0.0364], [0.1781, 0.2004, 0.2095]]					)
			elif yolos_name == "yolos_s_200_pre":
						A__       =    torch.tensor(
						    [[-24.0248, -10.3024, -14.8290], [-42.0392, -16.8200, -27.4334], [-27.2743, -11.8154, -18.7148]]					)
						A__       =    torch.tensor(
						    [[0.2559, 0.5455, 0.4706], [0.2989, 0.7279, 0.1875], [0.7732, 0.4017, 0.4462]]					)
			elif yolos_name == "yolos_s_300_pre":
						A__       =    torch.tensor(
						    [[-36.2220, -14.4385, -23.5457], [-35.6970, -14.7583, -21.3935], [-31.5939, -13.6042, -16.8049]]					)
						A__       =    torch.tensor(
						    [[0.7614, 0.2316, 0.4728], [0.7168, 0.4495, 0.3855], [0.4996, 0.1466, 0.9996]]					)
			elif yolos_name == "yolos_s_dWr":
						A__       =    torch.tensor(
						    [[-42.8668, -24.1049, -41.1690], [-34.7456, -14.1274, -24.9194], [-33.7898, -12.1946, -25.6495]]					)
						A__       =    torch.tensor(
						    [[0.5587, 0.2773, 0.0605], [0.5004, 0.3014, 0.9994], [0.4999, 0.1548, 0.9994]]					)
			elif yolos_name == "yolos_base":
						A__       =    torch.tensor(
						    [[-40.6064, -24.3084, -32.6447], [-55.1990, -30.7719, -35.5877], [-51.4311, -33.3507, -35.6462]]					)
						A__       =    torch.tensor(
						    [[0.5555, 0.2794, 0.0655], [0.9049, 0.2664, 0.1894], [0.9183, 0.1984, 0.1635]]					)
			else:
						raise ValueError(f'''Unknown yolos_name: {yolos_name}'''					)

			assert torch.allclose(logits[0, :3, :3] ,	__UpperCamelCase ,	atol=1E-4					)
			assert torch.allclose(pred_boxes[0, :3, :3] ,	__UpperCamelCase ,	atol=1E-4					)

			Path(__UpperCamelCase					).mkdir(exist_ok=__UpperCamelCase					)
			print(f'''Saving model {yolos_name} to {pytorch_dump_folder_path}'''					)
			model.save_pretrained(__UpperCamelCase					)
			print(f'''Saving image processor to {pytorch_dump_folder_path}'''					)
			image_processor.save_pretrained(__UpperCamelCase					)

			if push_to_hub:
						A__       =    {
						    'yolos_ti': 'yolos-tiny',
						    'yolos_s_200_pre': 'yolos-small',
						    'yolos_s_300_pre': 'yolos-small-300',
						    'yolos_s_dWr': 'yolos-small-dwr',
						    'yolos_base': 'yolos-base',
						}

						print('Pushing to the hub...'					)
						A__       =    model_mapping[yolos_name]
						image_processor.push_to_hub(__UpperCamelCase ,	organization='hustvl'					)
						model.push_to_hub(__UpperCamelCase ,	organization='hustvl'					)


if __name__ == "__main__":
							SCREAMING_SNAKE_CASE__       =      argparse.ArgumentParser()
							# Required parameters
							parser.add_argument(
							    '''--yolos_name''',
							    default='''yolos_s_200_pre''',
							    type=str,
							    help=(
							        '''Name of the YOLOS model you\'d like to convert. Should be one of \'yolos_ti\', \'yolos_s_200_pre\','''
							        ''' \'yolos_s_300_pre\', \'yolos_s_dWr\', \'yolos_base\'.'''
							    ),
							)
							parser.add_argument(
							    '''--checkpoint_path''', default=None, type=str, help='''Path to the original state dict (.pth file).'''
							)
							parser.add_argument(
							    '''--pytorch_dump_folder_path''', default=None, type=str, help='''Path to the output PyTorch model directory.'''
							)
							parser.add_argument(
							    '''--push_to_hub''', action='''store_true''', help='''Whether or not to push the converted model to the 🤗 hub.'''
							)

							SCREAMING_SNAKE_CASE__       =      parser.parse_args()
							convert_yolos_checkpoint(args.yolos_name, args.checkpoint_path, args.pytorch_dump_folder_path, args.push_to_hub)









import inspect
import unittest

from transformers import ViTHybridConfig
from transformers.testing_utils import require_accelerate, require_torch, require_vision, slow, torch_device
from transformers.utils import cached_property, is_torch_available, is_vision_available

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
							import torch
							from torch import nn

							from transformers import ViTHybridForImageClassification, ViTHybridImageProcessor, ViTHybridModel
							from transformers.models.vit_hybrid.modeling_vit_hybrid import VIT_HYBRID_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
							from PIL import Image


class      __lowerCAmelCase     :
					"""simple docstring"""






					def __init__(     self					:       List[Any]				,					_snake_case					:       Any				,					_snake_case					:       Optional[int]=13				,					_snake_case					:       Optional[Any]=64				,					_snake_case					:       List[str]=2				,					_snake_case					:       Any=3				,					_snake_case					:       Union[str, Any]=True				,					_snake_case					:       Dict=True				,					_snake_case					:       int=32				,					_snake_case					:       int=5				,					_snake_case					:       Union[str, Any]=4				,					_snake_case					:       int=37				,					_snake_case					:       Tuple="gelu"				,					_snake_case					:       Optional[int]=0.1				,					_snake_case					:       Dict=0.1				,					_snake_case					:       List[str]=10				,					_snake_case					:       Union[str, Any]=0.02				,					_snake_case					:       Dict=[1, 16, 4, 4]				,					_snake_case					:       Dict=None				,					):






								"""simple docstring"""


								A__       =    parent
								A__       =    batch_size
								A__       =    image_size
								A__       =    patch_size
								A__       =    num_channels
								A__       =    is_training
								A__       =    use_labels
								A__       =    hidden_size
								A__       =    num_hidden_layers
								A__       =    num_attention_heads
								A__       =    intermediate_size
								A__       =    hidden_act
								A__       =    hidden_dropout_prob
								A__       =    attention_probs_dropout_prob
								A__       =    type_sequence_label_size
								A__       =    initializer_range
								A__       =    scope
								A__       =    backbone_featmap_shape

								# in ViT hybrid, the seq length equals the number of patches + 1 (we add 1 for the [CLS] token)
								# the number of patches is based on the feature map of the backbone, which by default uses an output stride
								# of 32, which means that the feature map has a spatial resolution of 1/32 of the input image size
								A__       =    (self.image_size // 32) ** 2
								A__       =    num_patches + 1



					def     _a							(     self					:       Any					):






								"""simple docstring"""


								A__       =    floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]					)

								A__       =    None
								if self.use_labels:
											A__       =    ids_tensor([self.batch_size]				,					self.type_sequence_label_size					)

								A__       =    self.get_config()

								return config, pixel_values, labels



					def     _a							(     self					:       Tuple					):






								"""simple docstring"""


								A__       =    {
								    'global_padding': 'same',
								    'layer_type': 'bottleneck',
								    'depths': [3, 4, 9],
								    'out_features': ['stage1', 'stage2', 'stage3'],
								    'embedding_dynamic_padding': True,
								    'hidden_sizes': [4, 8, 16, 32],
								    'num_groups': 2,
								}

								return ViTHybridConfig(
								    image_size=self.image_size				,					patch_size=self.patch_size				,					num_channels=self.num_channels				,					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				,					is_decoder=_snake_case				,					initializer_range=self.initializer_range				,					backbone_featmap_shape=self.backbone_featmap_shape				,					backbone_config=_snake_case				,					)



					def     _a							(     self					:       int				,					_snake_case					:       Optional[int]				,					_snake_case					:       Union[str, Any]				,					_snake_case					:       Optional[int]					):






								"""simple docstring"""


								A__       =    ViTHybridModel(config=_snake_case					)
								model.to(_snake_case					)
								model.eval()
								A__       =    model(_snake_case					)
								self.parent.assertEqual(result.last_hidden_state.shape				,					(self.batch_size, self.seq_length, self.hidden_size)					)



					def     _a							(     self					:       List[str]				,					_snake_case					:       str				,					_snake_case					:       Union[str, Any]				,					_snake_case					:       Any					):






								"""simple docstring"""


								A__       =    self.type_sequence_label_size
								A__       =    ViTHybridForImageClassification(_snake_case					)
								model.to(_snake_case					)
								model.eval()
								A__       =    model(_snake_case				,					labels=_snake_case					)
								self.parent.assertEqual(result.logits.shape				,					(self.batch_size, self.type_sequence_label_size)					)



					def     _a							(     self					:       Dict					):






								"""simple docstring"""


								A__       =    self.prepare_config_and_inputs()
								A__     , A__     , A__       =    config_and_inputs
								A__       =    {'pixel_values': pixel_values}
								return config, inputs_dict







@require_torch
class      __lowerCAmelCase     (		UpperCAmelCase_							,     UpperCAmelCase_							,     unittest.TestCase      ):
					"""simple docstring"""






					A__				:		Union[str, Any]			       =    (ViTHybridModel, ViTHybridForImageClassification) if is_torch_available() else ()
					A__				:		str			       =    (
					    {"feature-extraction": ViTHybridModel, "image-classification": ViTHybridForImageClassification}
					    if is_torch_available()
					    else {}
					)
					A__				:		Union[str, Any]			       =    False
					A__				:		Any			       =    False
					A__				:		Union[str, Any]			       =    False



					def     _a							(     self					:       Dict					):






								"""simple docstring"""


								A__       =    ViTHybridModelTester(self					)
								A__       =    ConfigTester(self				,					config_class=_snake_case				,					has_text_modality=_snake_case				,					hidden_size=37					)



					def     _a							(     self					:       int					):






								"""simple docstring"""


								self.config_tester.run_common_tests()



					@unittest.skip(reason='ViT does not use inputs_embeds'					)
					def     _a							(     self					:       int					):






								"""simple docstring"""


								pass



					def     _a							(     self					:       int					):






								"""simple docstring"""


								A__     , A__       =    self.model_tester.prepare_config_and_inputs_for_common()

								for model_class in self.all_model_classes:
											A__       =    model_class(_snake_case					)
											self.assertIsInstance(model.get_input_embeddings()				,					(nn.Module)					)
											A__       =    model.get_output_embeddings()
											self.assertTrue(x is None or isinstance(_snake_case				,					nn.Linear					)					)



					def     _a							(     self					:       List[str]					):






								"""simple docstring"""


								A__     , A__       =    self.model_tester.prepare_config_and_inputs_for_common()

								for model_class in self.all_model_classes:
											A__       =    model_class(_snake_case					)
											A__       =    inspect.signature(model.forward					)
											# signature.parameters is an OrderedDict => so arg_names order is deterministic
											A__       =    [*signature.parameters.keys()]

											A__       =    ['pixel_values']
											self.assertListEqual(arg_names[:1]				,					_snake_case					)



					def     _a							(     self					:       Any					):






								"""simple docstring"""


								A__       =    self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_model(*_snake_case					)



					def     _a							(     self					:       str					):






								"""simple docstring"""


								A__       =    self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_for_image_classification(*_snake_case					)



					def     _a							(     self					:       Any					):






								"""simple docstring"""


								A__     , A__       =    self.model_tester.prepare_config_and_inputs_for_common()

								A__       =    _config_zero_init(_snake_case					)
								for model_class in self.all_model_classes:
											A__       =    model_class(config=_snake_case					)
											# Skip the check for the backbone
											for name, module in model.named_modules():
														if module.__class__.__name__ == "ViTHybridPatchEmbeddings":
																	A__       =    [F'''{name}.{key}''' for key in module.state_dict().keys()]
																	break

											for name, param in model.named_parameters():
														if param.requires_grad:
																	if name in backbone_params:
																				continue
																	self.assertIn(
																	    ((param.data.mean() * 1E9).round() / 1E9).item()				,					[0.0, 1.0]				,					msg=F'''Parameter {name} of model {model_class} seems not properly initialized'''				,					)



					@slow
					def     _a							(     self					:       int					):






								"""simple docstring"""


								for model_name in VIT_HYBRID_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
											A__       =    ViTHybridModel.from_pretrained(_snake_case					)
											self.assertIsNotNone(_snake_case					)







def A						(       )						->      Union[str, Any]:
			A__       =    Image.open('./tests/fixtures/tests_samples/COCO/000000039769.png'					)
			return image






@require_torch
@require_vision
class      __lowerCAmelCase     (		unittest.TestCase      ):
					"""simple docstring"""






					@cached_property
					def     _a							(     self					:       Tuple					):






								"""simple docstring"""


								return (
								    ViTHybridImageProcessor.from_pretrained(VIT_HYBRID_PRETRAINED_MODEL_ARCHIVE_LIST[0]					)
								    if is_vision_available()
								    else None
								)



					@slow
					def     _a							(     self					:       Optional[Any]					):






								"""simple docstring"""


								A__       =    ViTHybridForImageClassification.from_pretrained(VIT_HYBRID_PRETRAINED_MODEL_ARCHIVE_LIST[0]					).to(
								    _snake_case					)

								A__       =    self.default_image_processor
								A__       =    prepare_img()
								A__       =    image_processor(images=_snake_case				,					return_tensors='pt'					).to(_snake_case					)

								# forward pass
								with torch.no_grad():
											A__       =    model(**_snake_case					)

								# verify the logits
								A__       =    torch.Size((1, 10_00)					)
								self.assertEqual(outputs.logits.shape				,					_snake_case					)

								A__       =    torch.tensor([-1.9090, -0.4993, -0.2389]					).to(_snake_case					)

								self.assertTrue(torch.allclose(outputs.logits[0, :3]				,					_snake_case				,					atol=1E-4					)					)



					@slow
					@require_accelerate
					def     _a							(     self					:       List[Any]					):






								"""simple docstring"""


								A__       =    ViTHybridImageProcessor.from_pretrained('google/vit-hybrid-base-bit-384'					)
								A__       =    ViTHybridForImageClassification.from_pretrained('google/vit-hybrid-base-bit-384'				,					device_map='auto'					)

								A__       =    prepare_img()

								A__       =    image_processor(images=_snake_case				,					return_tensors='pt'					)
								A__       =    model(**_snake_case					)
								A__       =    outputs.logits
								# model predicts one of the 1000 ImageNet classes
								A__       =    logits.argmax(-1					).item()

								self.assertTrue(model.config.idalabel[predicted_class_idx]				,					'tabby, tabby cat'					)




