

from typing import TYPE_CHECKING

# rely on isort to merge the imports
from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_sentencepiece_available, is_torch_available


_lowerCamelCase							:  List[Any]     =				{
    '''configuration_ernie_m''': ['''ERNIE_M_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''ErnieMConfig'''],
}

try:
     if not is_sentencepiece_available():
          raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
     pass
else:
     _lowerCamelCase							:  Any     =				['''ErnieMTokenizer''']

try:
     if not is_torch_available():
          raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
     pass
else:
     _lowerCamelCase							:  Dict     =				[
         '''ERNIE_M_PRETRAINED_MODEL_ARCHIVE_LIST''',
         '''ErnieMForMultipleChoice''',
         '''ErnieMForQuestionAnswering''',
         '''ErnieMForSequenceClassification''',
         '''ErnieMForTokenClassification''',
         '''ErnieMModel''',
         '''ErnieMPreTrainedModel''',
         '''ErnieMForInformationExtraction''',
     ]


if TYPE_CHECKING:
     from .configuration_ernie_m import ERNIE_M_PRETRAINED_CONFIG_ARCHIVE_MAP, ErnieMConfig

     try:
          if not is_sentencepiece_available():
               raise OptionalDependencyNotAvailable()
     except OptionalDependencyNotAvailable:
          pass
     else:
          from .tokenization_ernie_m import ErnieMTokenizer

     try:
          if not is_torch_available():
               raise OptionalDependencyNotAvailable()
     except OptionalDependencyNotAvailable:
          pass
     else:
          from .modeling_ernie_m import (
              ERNIE_M_PRETRAINED_MODEL_ARCHIVE_LIST,
              ErnieMForInformationExtraction,
              ErnieMForMultipleChoice,
              ErnieMForQuestionAnswering,
              ErnieMForSequenceClassification,
              ErnieMForTokenClassification,
              ErnieMModel,
              ErnieMPreTrainedModel,
          )


else:
     import sys

     _lowerCamelCase							:  int     =				_LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__)












import argparse
import json
from pathlib import Path

import requests
import torch
from huggingface_hub import cached_download, hf_hub_download, hf_hub_url
from PIL import Image

from transformers import DetaConfig, DetaForObjectDetection, DetaImageProcessor
from transformers.utils import logging


logging.set_verbosity_info()
UpperCAmelCase__    :      List[Any]       					=logging.get_logger(__name__)





def   _lowercase       (    )    ->	List[Any]:
				lowerCamelCase									=DetaConfig(
				    num_queries=9_00      ,   encoder_ffn_dim=20_48      ,   decoder_ffn_dim=20_48      ,   num_feature_levels=5      ,   assign_first_stage=_UpperCAmelCase      ,   with_box_refine=_UpperCAmelCase      ,   two_stage=_UpperCAmelCase      ,   )

				# set labels
				lowerCamelCase									=91
				lowerCamelCase									="""huggingface/label-files"""
				lowerCamelCase									="""coco-detection-id2label.json"""
				lowerCamelCase									=json.load(open(cached_download(hf_hub_url(_UpperCAmelCase      ,   _UpperCAmelCase      ,   repo_type="""dataset"""					)					)      ,   """r"""					)					)
				lowerCamelCase									={int(_UpperCAmelCase					): v for k, v in idalabel.items()}
				lowerCamelCase									=idalabel
				lowerCamelCase									={v: k for k, v in idalabel.items()}

				return config





def   _lowercase       (    _UpperCAmelCase					)    ->	List[str]:
				lowerCamelCase									=[]

				# stem
				# fmt: off
				rename_keys.append(("""backbone.0.body.conv1.weight""", """model.backbone.model.embedder.embedder.convolution.weight""")					)
				rename_keys.append(("""backbone.0.body.bn1.weight""", """model.backbone.model.embedder.embedder.normalization.weight""")					)
				rename_keys.append(("""backbone.0.body.bn1.bias""", """model.backbone.model.embedder.embedder.normalization.bias""")					)
				rename_keys.append(("""backbone.0.body.bn1.running_mean""", """model.backbone.model.embedder.embedder.normalization.running_mean""")					)
				rename_keys.append(("""backbone.0.body.bn1.running_var""", """model.backbone.model.embedder.embedder.normalization.running_var""")					)
				# stages
				for stage_idx in range(len(config.backbone_config.depths					)					):
								for layer_idx in range(config.backbone_config.depths[stage_idx]					):
												# shortcut
												if layer_idx == 0:
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.0.weight""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.convolution.weight""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.weight""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.weight""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.bias""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.bias""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_mean""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_mean""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.downsample.1.running_var""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.shortcut.normalization.running_var""",
																    )					)
												# 3 convs
												for i in range(3					):
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.conv{i+1}.weight""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.convolution.weight""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.weight""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.weight""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.bias""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.bias""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_mean""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_mean""",
																    )					)
																rename_keys.append(
																    (
																        F"""backbone.0.body.layer{stage_idx + 1}.{layer_idx}.bn{i+1}.running_var""",
																        F"""model.backbone.model.encoder.stages.{stage_idx}.layers.{layer_idx}.layer.{i}.normalization.running_var""",
																    )					)
    # transformer encoder
				for i in range(config.encoder_layers					):
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.sampling_offsets.weight""", F"""model.encoder.layers.{i}.self_attn.sampling_offsets.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.sampling_offsets.bias""", F"""model.encoder.layers.{i}.self_attn.sampling_offsets.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.attention_weights.weight""", F"""model.encoder.layers.{i}.self_attn.attention_weights.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.attention_weights.bias""", F"""model.encoder.layers.{i}.self_attn.attention_weights.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.value_proj.weight""", F"""model.encoder.layers.{i}.self_attn.value_proj.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.value_proj.bias""", F"""model.encoder.layers.{i}.self_attn.value_proj.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.output_proj.weight""", F"""model.encoder.layers.{i}.self_attn.output_proj.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.self_attn.output_proj.bias""", F"""model.encoder.layers.{i}.self_attn.output_proj.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.norm1.weight""", F"""model.encoder.layers.{i}.self_attn_layer_norm.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.norm1.bias""", F"""model.encoder.layers.{i}.self_attn_layer_norm.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.linear1.weight""", F"""model.encoder.layers.{i}.fc1.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.linear1.bias""", F"""model.encoder.layers.{i}.fc1.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.linear2.weight""", F"""model.encoder.layers.{i}.fc2.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.linear2.bias""", F"""model.encoder.layers.{i}.fc2.bias""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.norm2.weight""", F"""model.encoder.layers.{i}.final_layer_norm.weight""")					)
								rename_keys.append((F"""transformer.encoder.layers.{i}.norm2.bias""", F"""model.encoder.layers.{i}.final_layer_norm.bias""")					)

				# transformer decoder
				for i in range(config.decoder_layers					):
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.sampling_offsets.weight""", F"""model.decoder.layers.{i}.encoder_attn.sampling_offsets.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.sampling_offsets.bias""", F"""model.decoder.layers.{i}.encoder_attn.sampling_offsets.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.attention_weights.weight""", F"""model.decoder.layers.{i}.encoder_attn.attention_weights.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.attention_weights.bias""", F"""model.decoder.layers.{i}.encoder_attn.attention_weights.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.value_proj.weight""", F"""model.decoder.layers.{i}.encoder_attn.value_proj.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.value_proj.bias""", F"""model.decoder.layers.{i}.encoder_attn.value_proj.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.output_proj.weight""", F"""model.decoder.layers.{i}.encoder_attn.output_proj.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.cross_attn.output_proj.bias""", F"""model.decoder.layers.{i}.encoder_attn.output_proj.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.norm1.weight""", F"""model.decoder.layers.{i}.encoder_attn_layer_norm.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.norm1.bias""", F"""model.decoder.layers.{i}.encoder_attn_layer_norm.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.self_attn.out_proj.weight""", F"""model.decoder.layers.{i}.self_attn.out_proj.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.self_attn.out_proj.bias""", F"""model.decoder.layers.{i}.self_attn.out_proj.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.norm2.weight""", F"""model.decoder.layers.{i}.self_attn_layer_norm.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.norm2.bias""", F"""model.decoder.layers.{i}.self_attn_layer_norm.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.linear1.weight""", F"""model.decoder.layers.{i}.fc1.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.linear1.bias""", F"""model.decoder.layers.{i}.fc1.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.linear2.weight""", F"""model.decoder.layers.{i}.fc2.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.linear2.bias""", F"""model.decoder.layers.{i}.fc2.bias""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.norm3.weight""", F"""model.decoder.layers.{i}.final_layer_norm.weight""")					)
								rename_keys.append((F"""transformer.decoder.layers.{i}.norm3.bias""", F"""model.decoder.layers.{i}.final_layer_norm.bias""")					)

				# fmt: on

				return rename_keys





def   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase      ,   _UpperCAmelCase					)    ->	Union[str, Any]:
				lowerCamelCase									=dct.pop(_UpperCAmelCase					)
				lowerCamelCase									=val





def   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase					)    ->	Dict:
				# transformer decoder self-attention layers
				lowerCamelCase									=config.d_model
				for i in range(config.decoder_layers					):
								# read in weights + bias of input projection layer of self-attention
								lowerCamelCase									=state_dict.pop(F"""transformer.decoder.layers.{i}.self_attn.in_proj_weight"""					)
								lowerCamelCase									=state_dict.pop(F"""transformer.decoder.layers.{i}.self_attn.in_proj_bias"""					)
								# next, add query, keys and values (in that order) to the state dict
								lowerCamelCase									=in_proj_weight[:hidden_size, :]
								lowerCamelCase									=in_proj_bias[:hidden_size]
								lowerCamelCase									=in_proj_weight[
								    hidden_size : hidden_size * 2, :
								]
								lowerCamelCase									=in_proj_bias[hidden_size : hidden_size * 2]
								lowerCamelCase									=in_proj_weight[-hidden_size:, :]
								lowerCamelCase									=in_proj_bias[-hidden_size:]





def   _lowercase       (    )    ->	List[str]:
				lowerCamelCase									="""http://images.cocodataset.org/val2017/000000039769.jpg"""
				lowerCamelCase									=Image.open(requests.get(_UpperCAmelCase      ,   stream=_UpperCAmelCase					).raw					)

				return im





@torch.no_grad()
def   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase      ,   _UpperCAmelCase					)    ->	Optional[int]:
				lowerCamelCase									=get_deta_config()

				# load original state dict
				if model_name == "deta-resnet-50":
								lowerCamelCase									="""adet_checkpoint0011.pth"""
				elif model_name == "deta-resnet-50-24-epochs":
								lowerCamelCase									="""adet_2x_checkpoint0023.pth"""
				else:
								raise ValueError(F"""Model name {model_name} not supported"""					)
				lowerCamelCase									=hf_hub_download(repo_id="""nielsr/deta-checkpoints"""      ,   filename=_UpperCAmelCase					)
				lowerCamelCase									=torch.load(_UpperCAmelCase      ,   map_location="""cpu"""					)["""model"""]

				# rename keys
				lowerCamelCase									=create_rename_keys(_UpperCAmelCase					)
				for src, dest in rename_keys:
								rename_key(_UpperCAmelCase      ,   _UpperCAmelCase      ,   _UpperCAmelCase					)
				read_in_decoder_q_k_v(_UpperCAmelCase      ,   _UpperCAmelCase					)

				# fix some prefixes
				for key in state_dict.copy().keys():
								if "transformer.decoder.class_embed" in key or "transformer.decoder.bbox_embed" in key:
												lowerCamelCase									=state_dict.pop(_UpperCAmelCase					)
												lowerCamelCase									=val
								if "input_proj" in key:
												lowerCamelCase									=state_dict.pop(_UpperCAmelCase					)
												lowerCamelCase									=val
								if "level_embed" in key or "pos_trans" in key or "pix_trans" in key or "enc_output" in key:
												lowerCamelCase									=state_dict.pop(_UpperCAmelCase					)
												lowerCamelCase									=val

    # finally, create HuggingFace model and load state dict
				lowerCamelCase									=DetaForObjectDetection(_UpperCAmelCase					)
				model.load_state_dict(_UpperCAmelCase					)
				model.eval()

				lowerCamelCase									="""cuda""" if torch.cuda.is_available() else """cpu"""
				model.to(_UpperCAmelCase					)

				# load image processor
				lowerCamelCase									=DetaImageProcessor(format="""coco_detection"""					)

				# verify our conversion on image
				lowerCamelCase									=prepare_img()
				lowerCamelCase									=processor(images=_UpperCAmelCase      ,   return_tensors="""pt"""					)
				lowerCamelCase									=encoding["""pixel_values"""]
				lowerCamelCase									=model(pixel_values.to(_UpperCAmelCase					)					)

				# verify logits
				if model_name == "deta-resnet-50":
								lowerCamelCase									=torch.tensor(
								    [[-7.3_9_7_8, -2.5_4_0_6, -4.1_6_6_8], [-8.2_6_8_4, -3.9_9_3_3, -3.8_0_9_6], [-7.0_5_1_5, -3.7_9_7_3, -5.8_5_1_6]]					)
								lowerCamelCase									=torch.tensor([[0.5_0_4_3, 0.4_9_7_3, 0.9_9_9_8], [0.2_5_4_2, 0.5_4_8_9, 0.4_7_4_8], [0.5_4_9_0, 0.2_7_6_5, 0.0_5_7_0]]					)
				elif model_name == "deta-resnet-50-24-epochs":
								lowerCamelCase									=torch.tensor(
								    [[-7.1_6_8_8, -2.4_8_5_7, -4.8_6_6_9], [-7.8_6_3_0, -3.8_1_5_4, -4.2_6_7_4], [-7.2_7_3_0, -4.1_8_6_5, -5.5_3_2_3]]					)
								lowerCamelCase									=torch.tensor([[0.5_0_2_1, 0.4_9_7_1, 0.9_9_9_4], [0.2_5_4_6, 0.5_4_8_6, 0.4_7_3_1], [0.1_6_8_6, 0.1_9_8_6, 0.2_1_4_2]]					)

				assert torch.allclose(outputs.logits[0, :3, :3]      ,   expected_logits.to(_UpperCAmelCase					)      ,   atol=1e-4					)
				assert torch.allclose(outputs.pred_boxes[0, :3, :3]      ,   expected_boxes.to(_UpperCAmelCase					)      ,   atol=1e-4					)
				print("""Everything ok!"""					)

				if pytorch_dump_folder_path:
								# Save model and processor
								logger.info(F"""Saving PyTorch model and processor to {pytorch_dump_folder_path}..."""					)
								Path(_UpperCAmelCase					).mkdir(exist_ok=_UpperCAmelCase					)
								model.save_pretrained(_UpperCAmelCase					)
								processor.save_pretrained(_UpperCAmelCase					)

				# Push to hub
				if push_to_hub:
								print("""Pushing model and processor to hub..."""					)
								model.push_to_hub(F"""jozhang97/{model_name}"""					)
								processor.push_to_hub(F"""jozhang97/{model_name}"""					)


if __name__ == "__main__":
							UpperCAmelCase__    :      Any       					=argparse.ArgumentParser()

							parser.add_argument(
							    '''--model_name''',
							    type=str,
							    default='''deta-resnet-50''',
							    choices=['''deta-resnet-50''', '''deta-resnet-50-24-epochs'''],
							    help='''Name of the model you\'d like to convert.''',
							)
							parser.add_argument(
							    '''--pytorch_dump_folder_path''',
							    default=None,
							    type=str,
							    help='''Path to the folder to output PyTorch model.''',
							)
							parser.add_argument(
							    '''--push_to_hub''', action='''store_true''', help='''Whether or not to push the converted model to the 🤗 hub.'''
							)
							UpperCAmelCase__    :      Dict       					=parser.parse_args()
							convert_deta_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)





