




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()
snake_case_					:					Dict       						=			logging.get_logger(__name__)


def   A		()  -> int:







     """simple docstring"""


     UpperCAmelCase_		=				DetaConfig(
         num_queries=900  ,							encoder_ffn_dim=2048  ,							decoder_ffn_dim=2048  ,							num_feature_levels=5  ,							assign_first_stage=__A  ,							with_box_refine=__A  ,							two_stage=__A  ,							)

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

     return config


def   A		(__A  :       int			)  -> Union[str, Any]:







     """simple docstring"""


     UpperCAmelCase_		=				[]

     # 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   A		(__A  :       Tuple  ,							__A  :       List[str]  ,							__A  :       Union[str, Any]			)  -> Any:







     """simple docstring"""


     UpperCAmelCase_		=				dct.pop(__A			)
     UpperCAmelCase_		=				val


def   A		(__A  :       Any  ,							__A  :       List[str]			)  -> Optional[int]:







     """simple docstring"""


     UpperCAmelCase_		=				config.d_model
     for i in range(config.decoder_layers			):
          # read in weights + bias of input projection layer of self-attention
          UpperCAmelCase_		=				state_dict.pop(F"""transformer.decoder.layers.{i}.self_attn.in_proj_weight"""			)
          UpperCAmelCase_		=				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
          UpperCAmelCase_		=				in_proj_weight[:hidden_size, :]
          UpperCAmelCase_		=				in_proj_bias[:hidden_size]
          UpperCAmelCase_		=				in_proj_weight[
              hidden_size : hidden_size * 2, :
          ]
          UpperCAmelCase_		=				in_proj_bias[hidden_size : hidden_size * 2]
          UpperCAmelCase_		=				in_proj_weight[-hidden_size:, :]
          UpperCAmelCase_		=				in_proj_bias[-hidden_size:]


def   A		()  -> Any:







     """simple docstring"""


     UpperCAmelCase_		=				'''http://images.cocodataset.org/val2017/000000039769.jpg'''
     UpperCAmelCase_		=				Image.open(requests.get(__A  ,							stream=__A			).raw			)

     return im


@torch.no_grad()
def   A		(__A  :       Tuple  ,							__A  :       Dict  ,							__A  :       Dict			)  -> List[str]:







     """simple docstring"""


     UpperCAmelCase_		=				get_deta_config()

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

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

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

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

     UpperCAmelCase_		=				'''cuda''' if torch.cuda.is_available() else '''cpu'''
     model.to(__A			)

     # load image processor
     UpperCAmelCase_		=				DetaImageProcessor(format='''coco_detection'''			)

     # verify our conversion on image
     UpperCAmelCase_		=				prepare_img()
     UpperCAmelCase_		=				processor(images=__A  ,							return_tensors='''pt'''			)
     UpperCAmelCase_		=				encoding['''pixel_values''']
     UpperCAmelCase_		=				model(pixel_values.to(__A			)			)

     # verify logits
     if model_name == "deta-resnet-50":
          UpperCAmelCase_		=				torch.tensor(
              [[-7.3_978, -2.5_406, -4.1_668], [-8.2_684, -3.9_933, -3.8_096], [-7.0_515, -3.7_973, -5.8_516]]			)
          UpperCAmelCase_		=				torch.tensor([[0.5_043, 0.4_973, 0.9_998], [0.2_542, 0.5_489, 0.4_748], [0.5_490, 0.2_765, 0.0_570]]			)
     elif model_name == "deta-resnet-50-24-epochs":
          UpperCAmelCase_		=				torch.tensor(
              [[-7.1_688, -2.4_857, -4.8_669], [-7.8_630, -3.8_154, -4.2_674], [-7.2_730, -4.1_865, -5.5_323]]			)
          UpperCAmelCase_		=				torch.tensor([[0.5_021, 0.4_971, 0.9_994], [0.2_546, 0.5_486, 0.4_731], [0.1_686, 0.1_986, 0.2_142]]			)

     assert torch.allclose(outputs.logits[0, :3, :3]  ,							expected_logits.to(__A			)  ,							atol=1E-4			)
     assert torch.allclose(outputs.pred_boxes[0, :3, :3]  ,							expected_boxes.to(__A			)  ,							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(__A			).mkdir(exist_ok=__A			)
          model.save_pretrained(__A			)
          processor.save_pretrained(__A			)

     # 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__":
    snake_case_					:					Tuple       						=			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."
    )
    snake_case_					:					int       						=			parser.parse_args()
    convert_deta_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)












def   A		(__A  :       int			)  -> int:







     """simple docstring"""


     if not isinstance(__A  ,							__A			):
          UpperCAmelCase_		=				F"""Input value of [number={number}] must be an integer"""
          raise TypeError(__A			)
     if number < 1:
          raise ValueError('''Input must be a positive integer'''			)
     return number * (2 * number - 1)


if __name__ == "__main__":
    import doctest

    doctest.testmod()






