
import argparse
import json

import requests
import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from torchvision import transforms

from transformers import BitImageProcessor, FocalNetConfig, FocalNetForImageClassification
from transformers.image_utils import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD, PILImageResampling




def 							a		(				snake_case__:   Dict   ):


				'''simple docstring'''
				lowercase_	    =   [2, 2, 6, 2] if '''tiny''' in model_name else [2, 2, 18, 2]
				lowercase_	    =   True if '''large''' in model_name or '''huge''' in model_name else False
				lowercase_	    =   True if '''large''' in model_name or '''huge''' in model_name else False
				lowercase_	    =   True if '''large''' in model_name or '''huge''' in model_name else False

				if "large" in model_name or "xlarge" in model_name or "huge" in model_name:
								if "fl3" in model_name:
												lowercase_	    =   [3, 3, 3, 3]
												lowercase_	    =   [5, 5, 5, 5]
								elif "fl4" in model_name:
												lowercase_	    =   [4, 4, 4, 4]
												lowercase_	    =   [3, 3, 3, 3]

				if "tiny" in model_name or "small" in model_name or "base" in model_name:
								lowercase_	    =   [3, 3, 3, 3]
								if "lrf" in model_name:
												lowercase_	    =   [3, 3, 3, 3]
								else:
												lowercase_	    =   [2, 2, 2, 2]

				if "tiny" in model_name:
								lowercase_	    =   96
				elif "small" in model_name:
								lowercase_	    =   96
				elif "base" in model_name:
								lowercase_	    =   128
				elif "large" in model_name:
								lowercase_	    =   192
				elif "xlarge" in model_name:
								lowercase_	    =   256
				elif "huge" in model_name:
								lowercase_	    =   352

				# set label information
				lowercase_	    =   '''huggingface/label-files'''
				if "large" in model_name or "huge" in model_name:
								lowercase_	    =   '''imagenet-22k-id2label.json'''
				else:
								lowercase_	    =   '''imagenet-1k-id2label.json'''

				lowercase_	    =   json.load(open(hf_hub_download(snake_case__		,  snake_case__		,  repo_type='''dataset'''   )		,  '''r'''   )   )
				lowercase_	    =   {int(snake_case__   ): v for k, v in idalabel.items()}
				lowercase_	    =   {v: k for k, v in idalabel.items()}

				lowercase_	    =   FocalNetConfig(
				    embed_dim=snake_case__		,  depths=snake_case__		,  focal_levels=snake_case__		,  focal_windows=snake_case__		,  use_conv_embed=snake_case__		,  idalabel=snake_case__		,  labelaid=snake_case__		,  use_post_layernorm=snake_case__		,  use_layerscale=snake_case__		,  )

				return config




def 							a		(				snake_case__:   Any   ):


				'''simple docstring'''
				if "patch_embed.proj" in name:
								lowercase_	    =   name.replace('''patch_embed.proj'''		,  '''embeddings.patch_embeddings.projection'''   )
				if "patch_embed.norm" in name:
								lowercase_	    =   name.replace('''patch_embed.norm'''		,  '''embeddings.norm'''   )
				if "layers" in name:
								lowercase_	    =   '''encoder.''' + name
				if "encoder.layers" in name:
								lowercase_	    =   name.replace('''encoder.layers'''		,  '''encoder.stages'''   )
				if "downsample.proj" in name:
								lowercase_	    =   name.replace('''downsample.proj'''		,  '''downsample.projection'''   )
				if "blocks" in name:
								lowercase_	    =   name.replace('''blocks'''		,  '''layers'''   )
				if "modulation.f.weight" in name or "modulation.f.bias" in name:
								lowercase_	    =   name.replace('''modulation.f'''		,  '''modulation.projection_in'''   )
				if "modulation.h.weight" in name or "modulation.h.bias" in name:
								lowercase_	    =   name.replace('''modulation.h'''		,  '''modulation.projection_context'''   )
				if "modulation.proj.weight" in name or "modulation.proj.bias" in name:
								lowercase_	    =   name.replace('''modulation.proj'''		,  '''modulation.projection_out'''   )

				if name == "norm.weight":
								lowercase_	    =   '''layernorm.weight'''
				if name == "norm.bias":
								lowercase_	    =   '''layernorm.bias'''

				if "head" in name:
								lowercase_	    =   name.replace('''head'''		,  '''classifier'''   )
				else:
								lowercase_	    =   '''focalnet.''' + name

				return name




def 							a		(				snake_case__:   str		,  snake_case__:   str		,  snake_case__:   Any=False   ):


				'''simple docstring'''
				# fmt: off
				lowercase_	    =   {
				    '''focalnet-tiny''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_tiny_srf.pth''',
				    '''focalnet-tiny-lrf''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_tiny_lrf.pth''',
				    '''focalnet-small''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_small_srf.pth''',
				    '''focalnet-small-lrf''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_small_lrf.pth''',
				    '''focalnet-base''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_base_srf.pth''',
				    '''focalnet-base-lrf''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_base_lrf.pth''',
				    '''focalnet-large-lrf-fl3''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_large_lrf_384.pth''',
				    '''focalnet-large-lrf-fl4''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_large_lrf_384_fl4.pth''',
				    '''focalnet-xlarge-lrf-fl3''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_xlarge_lrf_384.pth''',
				    '''focalnet-xlarge-lrf-fl4''': '''https://projects4jw.blob.core.windows.net/focalnet/release/classification/focalnet_xlarge_lrf_384_fl4.pth''',
				}
				# fmt: on

				lowercase_	    =   model_name_to_url[model_name]
				print('''Checkpoint URL: '''		,  snake_case__   )
				lowercase_	    =   torch.hub.load_state_dict_from_url(snake_case__		,  map_location='''cpu'''   )['''model''']

				# rename keys
				for key in state_dict.copy().keys():
								lowercase_	    =   state_dict.pop(snake_case__   )
								lowercase_	    =   val

				lowercase_	    =   get_focalnet_config(snake_case__   )
				lowercase_	    =   FocalNetForImageClassification(snake_case__   )
				model.eval()

				# load state dict
				model.load_state_dict(snake_case__   )

				# verify conversion
				lowercase_	    =   '''http://images.cocodataset.org/val2017/000000039769.jpg'''

				lowercase_	    =   BitImageProcessor(
				    do_resize=snake_case__		,  size={'''shortest_edge''': 256}		,  resample=PILImageResampling.BILINEAR		,  do_center_crop=snake_case__		,  crop_size=224		,  do_normalize=snake_case__		,  image_mean=snake_case__		,  image_std=snake_case__		,  )
				lowercase_	    =   Image.open(requests.get(snake_case__		,  stream=snake_case__   ).raw   )
				lowercase_	    =   processor(images=snake_case__		,  return_tensors='''pt'''   )

				lowercase_	    =   transforms.Compose(
				    [
				        transforms.Resize(256   ),
				        transforms.CenterCrop(224   ),
				        transforms.ToTensor(),
				        transforms.Normalize(mean=[0.4_8_5, 0.4_5_6, 0.4_0_6]		,  std=[0.2_2_9, 0.2_2_4, 0.2_2_5]   ),
				    ]   )

				lowercase_	    =   image_transforms(snake_case__   ).unsqueeze(0   )

				# verify pixel_values
				assert torch.allclose(inputs.pixel_values		,  snake_case__		,  atol=1e-4   )

				lowercase_	    =   model(**snake_case__   )

				lowercase_	    =   outputs.logits.argmax(-1   ).item()
				print('''Predicted class:'''		,  model.config.idalabel[predicted_class_idx]   )

				print('''First values of logits:'''		,  outputs.logits[0, :3]   )

				if model_name == "focalnet-tiny":
								lowercase_	    =   torch.tensor([0.2_1_6_6, -0.4_3_6_8, 0.2_1_9_1]   )
				elif model_name == "focalnet-tiny-lrf":
								lowercase_	    =   torch.tensor([1.1_6_6_9, 0.0_1_2_5, -0.1_6_9_5]   )
				elif model_name == "focalnet-small":
								lowercase_	    =   torch.tensor([0.4_9_1_7, -0.0_4_3_0, 0.1_3_4_1]   )
				elif model_name == "focalnet-small-lrf":
								lowercase_	    =   torch.tensor([-0.2_5_8_8, -0.5_3_4_2, -0.2_3_3_1]   )
				elif model_name == "focalnet-base":
								lowercase_	    =   torch.tensor([-0.1_6_5_5, -0.4_0_9_0, -0.1_7_3_0]   )
				elif model_name == "focalnet-base-lrf":
								lowercase_	    =   torch.tensor([0.5_3_0_6, -0.0_4_8_3, -0.3_9_2_8]   )
				assert torch.allclose(outputs.logits[0, :3]		,  snake_case__		,  atol=1e-4   )
				print('''Looks ok!'''   )

				if pytorch_dump_folder_path is not None:
								print(F'''Saving model and processor of {model_name} to {pytorch_dump_folder_path}'''   )
								model.save_pretrained(snake_case__   )
								processor.save_pretrained(snake_case__   )

				if push_to_hub:
								print(F'''Pushing model and processor of {model_name} to the hub...'''   )
								model.push_to_hub(F'''{model_name}'''   )
								processor.push_to_hub(F'''{model_name}'''   )


if __name__ == "__main__":
						__a         =   argparse.ArgumentParser()
						# Required parameters
						parser.add_argument(
						    '--model_name',
						    default='focalnet-tiny',
						    type=str,
						    help='Name of the FocalNet model 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(
						    '--push_to_hub',
						    action='store_true',
						    help='Whether to push the model and processor to the hub.',
						)

						__a         =   parser.parse_args()
						convert_focalnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)





'''simple docstring'''


import copy
import inspect
import unittest

from transformers import AutoBackbone
from transformers.configuration_utils import PretrainedConfig
from transformers.testing_utils import require_timm, require_torch, torch_device
from transformers.utils.import_utils import is_torch_available

from ...test_backbone_common import BackboneTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor


if is_torch_available():
					import torch

					from transformers import TimmBackbone, TimmBackboneConfig

from ...test_pipeline_mixin import PipelineTesterMixin






class     A :





							def __init__(   self					:				List[str]  ,		__a					:				List[Any]  ,		__a					:				Dict=None  ,		__a					:				str=None  ,		__a					:				List[Any]=None  ,		__a					:				Union[str, Any]="resnet50"  ,		__a					:				List[Any]=3  ,		__a					:				List[Any]=3_2  ,		__a					:				List[Any]=3  ,		__a					:				Optional[int]=True  ,		__a					:				str=True  ,		)				->						Any:
								__UpperCAmelCase      					=      parent
								__UpperCAmelCase      					=      out_indices if out_indices is not None else [4]
								__UpperCAmelCase      					=      stage_names
								__UpperCAmelCase      					=      out_features
								__UpperCAmelCase      					=      backbone
								__UpperCAmelCase      					=      batch_size
								__UpperCAmelCase      					=      image_size
								__UpperCAmelCase      					=      num_channels
								__UpperCAmelCase      					=      use_pretrained_backbone
								__UpperCAmelCase      					=      is_training





							def    snake_case__    (   self					:				Optional[Any]						)				->						Optional[int]:
								__UpperCAmelCase      					=      floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]						)
								__UpperCAmelCase      					=      self.get_config()

								return config, pixel_values





							def    snake_case__    (   self					:				Union[str, Any]						)				->						str:
								return TimmBackboneConfig(
								    image_size=self.image_size  ,		num_channels=self.num_channels  ,		out_features=self.out_features  ,		out_indices=self.out_indices  ,		stage_names=self.stage_names  ,		use_pretrained_backbone=self.use_pretrained_backbone  ,		backbone=self.backbone  ,		)





							def    snake_case__    (   self					:				int  ,		__a					:				Union[str, Any]  ,		__a					:				List[Any]						)				->						Tuple:
								__UpperCAmelCase      					=      TimmBackbone(config=__a						)
								model.to(__a						)
								model.eval()
								with torch.no_grad():
									__UpperCAmelCase      					=      model(__a						)
								self.parent.assertEqual(
								    result.feature_map[-1].shape  ,		(self.batch_size, model.channels[-1], 1_4, 1_4)  ,		)






							def    snake_case__    (   self					:				Dict						)				->						Tuple:
								__UpperCAmelCase      					=      self.prepare_config_and_inputs()
								__UpperCAmelCase					,      __UpperCAmelCase      					=      config_and_inputs
								__UpperCAmelCase      					=      {'''pixel_values''': pixel_values}
								return config, inputs_dict






@require_torch
@require_timm
class     A ( UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						unittest.TestCase ):
							a_										=   (TimmBackbone,) if is_torch_available() else ()
							a_										=   {'''feature-extraction''': TimmBackbone} if is_torch_available() else {}
							a_										=   False
							a_										=   False
							a_										=   False
							a_										=   False





							def    snake_case__    (   self					:				Optional[int]						)				->						List[str]:
								__UpperCAmelCase      					=      TimmBackboneModelTester(self						)
								__UpperCAmelCase      					=      ConfigTester(self  ,		config_class=__a  ,		has_text_modality=__a						)





							def    snake_case__    (   self					:				List[str]						)				->						int:
								self.config_tester.create_and_test_config_to_json_string()
								self.config_tester.create_and_test_config_to_json_file()
								self.config_tester.create_and_test_config_from_and_save_pretrained()
								self.config_tester.create_and_test_config_with_num_labels()
								self.config_tester.check_config_can_be_init_without_params()
								self.config_tester.check_config_arguments_init()





							def    snake_case__    (   self					:				List[str]						)				->						str:
								__UpperCAmelCase      					=      '''resnet18'''
								__UpperCAmelCase      					=      '''microsoft/resnet-18'''

								__UpperCAmelCase      					=      AutoBackbone.from_pretrained(__a  ,		use_timm_backbone=__a						)
								__UpperCAmelCase      					=      AutoBackbone.from_pretrained(__a						)

								self.assertEqual(len(timm_model.out_features						)  ,		len(transformers_model.out_features						)						)
								self.assertEqual(len(timm_model.stage_names						)  ,		len(transformers_model.stage_names						)						)
								self.assertEqual(timm_model.channels  ,		transformers_model.channels						)
								# Out indices are set to the last layer by default. For timm models, we don't know
								# the number of layers in advance, so we set it to (-1,), whereas for transformers
								# models, we set it to [len(stage_names) - 1] (kept for backward compatibility).
								self.assertEqual(timm_model.out_indices  ,		(-1,)						)
								self.assertEqual(transformers_model.out_indices  ,		[len(timm_model.stage_names						) - 1]						)

								__UpperCAmelCase      					=      AutoBackbone.from_pretrained(__a  ,		use_timm_backbone=__a  ,		out_indices=[1, 2, 3]						)
								__UpperCAmelCase      					=      AutoBackbone.from_pretrained(__a  ,		out_indices=[1, 2, 3]						)

								self.assertEqual(timm_model.out_indices  ,		transformers_model.out_indices						)
								self.assertEqual(len(timm_model.out_features						)  ,		len(transformers_model.out_features						)						)
								self.assertEqual(timm_model.channels  ,		transformers_model.channels						)





							@unittest.skip('''TimmBackbone doesn\'t support feed forward chunking'''						)
							def    snake_case__    (   self					:				str						)				->						Optional[Any]:
								pass





							@unittest.skip('''TimmBackbone doesn\'t have num_hidden_layers attribute'''						)
							def    snake_case__    (   self					:				str						)				->						List[Any]:
								pass





							@unittest.skip('''TimmBackbone initialization is managed on the timm side'''						)
							def    snake_case__    (   self					:				str						)				->						int:
								pass





							@unittest.skip('''TimmBackbone models doesn\'t have inputs_embeds'''						)
							def    snake_case__    (   self					:				Optional[Any]						)				->						Union[str, Any]:
								pass





							@unittest.skip('''TimmBackbone models doesn\'t have inputs_embeds'''						)
							def    snake_case__    (   self					:				Optional[int]						)				->						Dict:
								pass





							@unittest.skip('''TimmBackbone model cannot be created without specifying a backbone checkpoint'''						)
							def    snake_case__    (   self					:				str						)				->						Dict:
								pass





							@unittest.skip('''Only checkpoints on timm can be loaded into TimmBackbone'''						)
							def    snake_case__    (   self					:				Optional[Any]						)				->						Union[str, Any]:
								pass





							@unittest.skip('''model weights aren\'t tied in TimmBackbone.'''						)
							def    snake_case__    (   self					:				Union[str, Any]						)				->						Dict:
								pass





							@unittest.skip('''model weights aren\'t tied in TimmBackbone.'''						)
							def    snake_case__    (   self					:				List[str]						)				->						Union[str, Any]:
								pass





							@unittest.skip('''Only checkpoints on timm can be loaded into TimmBackbone'''						)
							def    snake_case__    (   self					:				str						)				->						List[Any]:
								pass





							@unittest.skip('''Only checkpoints on timm can be loaded into TimmBackbone'''						)
							def    snake_case__    (   self					:				Tuple						)				->						int:
								pass





							@unittest.skip('''TimmBackbone doesn\'t have hidden size info in its configuration.'''						)
							def    snake_case__    (   self					:				Union[str, Any]						)				->						Union[str, Any]:
								pass





							@unittest.skip('''TimmBackbone doesn\'t support output_attentions.'''						)
							def    snake_case__    (   self					:				List[str]						)				->						Dict:
								pass





							@unittest.skip('''Safetensors is not supported by timm.'''						)
							def    snake_case__    (   self					:				int						)				->						int:
								pass





							@unittest.skip('''Will be fixed soon by reducing the size of the model used for common tests.'''						)
							def    snake_case__    (   self					:				int						)				->						int:
								pass





							def    snake_case__    (   self					:				Optional[Any]						)				->						Optional[int]:
								__UpperCAmelCase					,      __UpperCAmelCase      					=      self.model_tester.prepare_config_and_inputs_for_common()

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

									__UpperCAmelCase      					=      ['''pixel_values''']
									self.assertListEqual(arg_names[:1]  ,		__a						)





							def    snake_case__    (   self					:				Any						)				->						int:
								__UpperCAmelCase					,      __UpperCAmelCase      					=      self.model_tester.prepare_config_and_inputs_for_common()
								__UpperCAmelCase      					=      True
								__UpperCAmelCase      					=      self.has_attentions

								# no need to test all models as different heads yield the same functionality
								__UpperCAmelCase      					=      self.all_model_classes[0]
								__UpperCAmelCase      					=      model_class(__a						)
								model.to(__a						)

								__UpperCAmelCase      					=      self._prepare_for_class(__a  ,		__a						)
								__UpperCAmelCase      					=      model(**__a						)
								__UpperCAmelCase      					=      outputs[0][-1]

								# Encoder-/Decoder-only models
								__UpperCAmelCase      					=      outputs.hidden_states[0]
								hidden_states.retain_grad()

								if self.has_attentions:
									__UpperCAmelCase      					=      outputs.attentions[0]
									attentions.retain_grad()

								output.flatten()[0].backward(retain_graph=__a						)

								self.assertIsNotNone(hidden_states.grad						)

								if self.has_attentions:
									self.assertIsNotNone(attentions.grad						)






							def    snake_case__    (   self					:				Any						)				->						Union[str, Any]:
								__UpperCAmelCase					,      __UpperCAmelCase      					=      self.model_tester.prepare_config_and_inputs_for_common()

								for model_class in self.all_model_classes:
									__UpperCAmelCase      					=      model_class(__a						)
									model.to(__a						)
									model.eval()
									__UpperCAmelCase      					=      model(**__a						)

									self.assertEqual(len(result.feature_maps						)  ,		len(config.out_indices						)						)
									self.assertEqual(len(model.channels						)  ,		len(config.out_indices						)						)

									# Check output of last stage is taken if out_features=None, out_indices=None
									__UpperCAmelCase      					=      copy.deepcopy(__a						)
									__UpperCAmelCase      					=      None
									__UpperCAmelCase      					=      model_class(__a						)
									model.to(__a						)
									model.eval()
									__UpperCAmelCase      					=      model(**__a						)

									self.assertEqual(len(result.feature_maps						)  ,		1						)
									self.assertEqual(len(model.channels						)  ,		1						)

									# Check backbone can be initialized with fresh weights
									__UpperCAmelCase      					=      copy.deepcopy(__a						)
									__UpperCAmelCase      					=      False
									__UpperCAmelCase      					=      model_class(__a						)
									model.to(__a						)
									model.eval()
									__UpperCAmelCase      					=      model(**__a						)
