


'''simple docstring'''
import warnings
from pathlib import Path
from typing import List, Tuple, Union

import fire
from torch import nn

from transformers import AutoModelForSeqaSeqLM, AutoTokenizer, PreTrainedModel
from transformers.utils import logging


__snake_case							      =     logging.get_logger(__name__)


def 			a      (			__a ,					__a ,					__a   )  ->	None:



					'''simple docstring'''






					UpperCamelCase__   :Dict												= nn.ModuleList([src_layers[i] for i in layers_to_copy]   )
					assert len(__a   ) == len(__a   ), f'''{len(__a   )} != {len(__a   )}'''
					dest_layers.load_state_dict(layers_to_copy.state_dict()   )


__snake_case							      =     {
    # maps  num layers in teacher -> num_layers in student -> which teacher layers to copy.
    # 12: bart, 16: pegasus, 6: marian/Helsinki-NLP
    12: {
        1: [0],  # This says that if the teacher has 12 layers and the student has 1, copy layer 0 of the teacher
        2: [0, 6],
        3: [0, 6, 11],
        4: [0, 4, 8, 11],
        6: [0, 2, 4, 7, 9, 11],
        9: [0, 1, 2, 4, 5, 7, 9, 10, 11],
        12: list(range(12)),
    },
    16: {  # maps  num layers in student -> which teacher layers to copy
        1: [0],
        2: [0, 15],
        3: [0, 8, 15],
        4: [0, 5, 10, 15],
        6: [0, 3, 6, 9, 12, 15],
        8: [0, 2, 4, 6, 8, 10, 12, 15],
        9: [0, 1, 3, 5, 7, 9, 11, 13, 15],
        12: [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15],
        16: list(range(16)),
    },
    6: {1: [0], 2: [0, 5], 3: [0, 2, 5], 4: [0, 1, 3, 5], 6: list(range(6))},
}
__snake_case							      =     {
    # maps  num layers in student -> which teacher layers to copy.
    6: {1: [5], 2: [3, 5], 3: [1, 4, 5], 4: [1, 2, 4, 5]},
    12: {1: [11], 2: [5, 11], 3: [3, 7, 11], 6: [1, 3, 5, 8, 10, 11]},
    16: {1: [15], 4: [4, 9, 12, 15], 8: [1, 3, 5, 7, 9, 11, 13, 15]},
}


def 			a      (			__a ,					__a   )  ->	Any:



					'''simple docstring'''






					try:
										UpperCamelCase__   :List[str]												= LAYERS_TO_COPY[n_teacher][n_student]
										return val
					except KeyError:
										if n_student != n_teacher:
															warnings.warn(
															    f'''no hardcoded layers to copy for teacher {n_teacher} -> student {n_student}, defaulting to first'''
															    f''' {n_student}'''   )
										return list(range(__a   )   )


def 			a      (			__a ,					__a   )  ->	List[int]:



					'''simple docstring'''






					if n_student > n_teacher:
										raise ValueError(f'''Cannot perform intermediate supervision for student {n_student} > teacher {n_teacher}'''   )
					elif n_teacher == n_student:
										return list(range(__a   )   )
					elif n_student == 1:
										return [n_teacher - 1]
					else:
										return LAYERS_TO_SUPERVISE[n_teacher][n_student]


def 			a      (			__a ,					__a = "student" ,					__a = None ,					__a = None ,					__a=False ,					__a=None ,					__a=None ,					**__a ,					)  ->	Tuple[PreTrainedModel, List[int], List[int]]:



					'''simple docstring'''






					UpperCamelCase__   :Optional[int]												= '''encoder_layers and decoder_layers cannot be both None-- you would just have an identical teacher.'''
					assert (e is not None) or (d is not None), _msg
					if isinstance(__a ,					__a   ):
										AutoTokenizer.from_pretrained(__a   ).save_pretrained(__a   )  # purely for convenience
										UpperCamelCase__   :Union[str, Any]												= AutoModelForSeqaSeqLM.from_pretrained(__a   ).eval()
					else:
										assert isinstance(__a ,					__a   ), f'''teacher must be a model or string got type {type(__a   )}'''
					UpperCamelCase__   :Optional[int]												= teacher.config.to_diff_dict()

					try:
										UpperCamelCase__					,				UpperCamelCase__   :Union[str, Any]												= teacher.config.encoder_layers, teacher.config.decoder_layers
										if e is None:
															UpperCamelCase__   :Dict												= teacher_e
										if d is None:
															UpperCamelCase__   :Tuple												= teacher_d
										init_kwargs.update({'''encoder_layers''': e, '''decoder_layers''': d}   )
					except AttributeError:  # T5
										if hasattr(teacher.config ,					'''num_encoder_layers'''   ):
															UpperCamelCase__					,				UpperCamelCase__   :Dict												= teacher.config.num_encoder_layers, teacher.config.num_decoder_layers
										else:
															UpperCamelCase__					,				UpperCamelCase__   :int												= teacher.config.num_layers, teacher.config.num_decoder_layers
										if e is None:
															UpperCamelCase__   :List[str]												= teacher_e
										if d is None:
															UpperCamelCase__   :Dict												= teacher_d
										if hasattr(teacher.config ,					'''num_encoder_layers'''   ):
															init_kwargs.update({'''num_encoder_layers''': e, '''num_decoder_layers''': d}   )
										else:
															init_kwargs.update({'''num_layers''': e, '''num_decoder_layers''': d}   )

    # Kwargs to instantiate student: teacher kwargs with updated layer numbers + **extra_config_kwargs
					init_kwargs.update(__a   )

					# Copy weights
					UpperCamelCase__   :Union[str, Any]												= teacher.config_class(**__a   )
					UpperCamelCase__   :str												= AutoModelForSeqaSeqLM.from_config(__a   )
					# Start by copying the full teacher state dict this will copy the first N teacher layers to the student.
					UpperCamelCase__   :Tuple												= student.load_state_dict(teacher.state_dict() ,					strict=__a   )
					assert info.missing_keys == [], info.missing_keys  # every student key should have a teacher keys.

					if copy_first_teacher_layers:  # Our copying is done. We just log and save
										UpperCamelCase__					,				UpperCamelCase__   :Any												= list(range(__a   )   ), list(range(__a   )   )
										logger.info(
										    f'''Copied encoder layers {e_layers_to_copy} and decoder layers {d_layers_to_copy}. Saving them to'''
										    f''' {save_path}'''   )
										student.save_pretrained(__a   )
										return student, e_layers_to_copy, d_layers_to_copy

					# Decide which layers of the teacher to copy. Not exactly alternating -- we try to keep first and last layer.
					if e_layers_to_copy is None:
										UpperCamelCase__   :List[int]												= pick_layers_to_copy(__a ,					__a   )
					if d_layers_to_copy is None:
										UpperCamelCase__   :List[int]												= pick_layers_to_copy(__a ,					__a   )

					try:
										if hasattr(
										    __a ,					'''prophetnet'''   ):  # For ProphetNet, student.model.encoder.layers is called student.prophetnet.encoder.layers
															copy_layers(teacher.prophetnet.encoder.layers ,					student.prophetnet.encoder.layers ,					__a   )
															copy_layers(teacher.prophetnet.decoder.layers ,					student.prophetnet.decoder.layers ,					__a   )
										else:
															copy_layers(teacher.model.encoder.layers ,					student.model.encoder.layers ,					__a   )
															copy_layers(teacher.model.decoder.layers ,					student.model.decoder.layers ,					__a   )
					except AttributeError:  # For t5, student.model.encoder.layers is called student.encoder.block
										copy_layers(teacher.encoder.block ,					student.encoder.block ,					__a   )
										copy_layers(teacher.decoder.block ,					student.decoder.block ,					__a   )
					logger.info(
					    f'''Copied encoder layers {e_layers_to_copy} and decoder layers {d_layers_to_copy}. Saving them to {save_path}'''   )
					UpperCamelCase__   :Union[str, Any]												= {
					    '''teacher_type''': teacher.config.model_type,
					    '''copied_encoder_layers''': e_layers_to_copy,
					    '''copied_decoder_layers''': d_layers_to_copy,
					}
					student.save_pretrained(__a   )
					# Save information about copying for easier reproducibility

					return student, e_layers_to_copy, d_layers_to_copy


if __name__ == "__main__":
		fire.Fire(create_student_by_copying_alternating_layers)



'''simple docstring'''
import argparse
from collections import OrderedDict
from pathlib import Path

import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from torchvision.transforms import functional as F

from transformers import DetrImageProcessor, TableTransformerConfig, TableTransformerForObjectDetection
from transformers.utils import logging


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

# here we list all keys to be renamed (original name on the left, our name on the right)
__snake_case							      =     []
for i in range(6):
		# encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
		rename_keys.append(
		    (F"""transformer.encoder.layers.{i}.self_attn.out_proj.weight""", F"""encoder.layers.{i}.self_attn.out_proj.weight""")
		)
		rename_keys.append(
		    (F"""transformer.encoder.layers.{i}.self_attn.out_proj.bias""", F"""encoder.layers.{i}.self_attn.out_proj.bias""")
		)
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear1.weight""", F"""encoder.layers.{i}.fc1.weight"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear1.bias""", F"""encoder.layers.{i}.fc1.bias"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear2.weight""", F"""encoder.layers.{i}.fc2.weight"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear2.bias""", F"""encoder.layers.{i}.fc2.bias"""))
		rename_keys.append(
		    (F"""transformer.encoder.layers.{i}.norm1.weight""", F"""encoder.layers.{i}.self_attn_layer_norm.weight""")
		)
		rename_keys.append((F"""transformer.encoder.layers.{i}.norm1.bias""", F"""encoder.layers.{i}.self_attn_layer_norm.bias"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.norm2.weight""", F"""encoder.layers.{i}.final_layer_norm.weight"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.norm2.bias""", F"""encoder.layers.{i}.final_layer_norm.bias"""))
		# decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.self_attn.out_proj.weight""", F"""decoder.layers.{i}.self_attn.out_proj.weight""")
		)
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.self_attn.out_proj.bias""", F"""decoder.layers.{i}.self_attn.out_proj.bias""")
		)
		rename_keys.append(
		    (
		        F"""transformer.decoder.layers.{i}.multihead_attn.out_proj.weight""",
		        F"""decoder.layers.{i}.encoder_attn.out_proj.weight""",
		    )
		)
		rename_keys.append(
		    (
		        F"""transformer.decoder.layers.{i}.multihead_attn.out_proj.bias""",
		        F"""decoder.layers.{i}.encoder_attn.out_proj.bias""",
		    )
		)
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear1.weight""", F"""decoder.layers.{i}.fc1.weight"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear1.bias""", F"""decoder.layers.{i}.fc1.bias"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear2.weight""", F"""decoder.layers.{i}.fc2.weight"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear2.bias""", F"""decoder.layers.{i}.fc2.bias"""))
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.norm1.weight""", F"""decoder.layers.{i}.self_attn_layer_norm.weight""")
		)
		rename_keys.append((F"""transformer.decoder.layers.{i}.norm1.bias""", F"""decoder.layers.{i}.self_attn_layer_norm.bias"""))
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.norm2.weight""", F"""decoder.layers.{i}.encoder_attn_layer_norm.weight""")
		)
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.norm2.bias""", F"""decoder.layers.{i}.encoder_attn_layer_norm.bias""")
		)
		rename_keys.append((F"""transformer.decoder.layers.{i}.norm3.weight""", F"""decoder.layers.{i}.final_layer_norm.weight"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.norm3.bias""", F"""decoder.layers.{i}.final_layer_norm.bias"""))

# convolutional projection + query embeddings + layernorm of encoder + layernorm of decoder + class and bounding box heads
rename_keys.extend(
    [
        ('''input_proj.weight''', '''input_projection.weight'''),
        ('''input_proj.bias''', '''input_projection.bias'''),
        ('''query_embed.weight''', '''query_position_embeddings.weight'''),
        ('''transformer.encoder.norm.weight''', '''encoder.layernorm.weight'''),
        ('''transformer.encoder.norm.bias''', '''encoder.layernorm.bias'''),
        ('''transformer.decoder.norm.weight''', '''decoder.layernorm.weight'''),
        ('''transformer.decoder.norm.bias''', '''decoder.layernorm.bias'''),
        ('''class_embed.weight''', '''class_labels_classifier.weight'''),
        ('''class_embed.bias''', '''class_labels_classifier.bias'''),
        ('''bbox_embed.layers.0.weight''', '''bbox_predictor.layers.0.weight'''),
        ('''bbox_embed.layers.0.bias''', '''bbox_predictor.layers.0.bias'''),
        ('''bbox_embed.layers.1.weight''', '''bbox_predictor.layers.1.weight'''),
        ('''bbox_embed.layers.1.bias''', '''bbox_predictor.layers.1.bias'''),
        ('''bbox_embed.layers.2.weight''', '''bbox_predictor.layers.2.weight'''),
        ('''bbox_embed.layers.2.bias''', '''bbox_predictor.layers.2.bias'''),
    ]
)


def 			a      (			__a ,					__a ,					__a   )  ->	List[str]:



					'''simple docstring'''






					UpperCamelCase__   :List[Any]												= state_dict.pop(__a   )
					UpperCamelCase__   :int												= val


def 			a      (			__a   )  ->	Any:



					'''simple docstring'''






					UpperCamelCase__   :Tuple												= OrderedDict()
					for key, value in state_dict.items():
										if "backbone.0.body" in key:
															UpperCamelCase__   :Dict												= key.replace('''backbone.0.body''' ,					'''backbone.conv_encoder.model'''   )
															UpperCamelCase__   :List[str]												= value
										else:
															UpperCamelCase__   :Dict												= value

					return new_state_dict


def 			a      (			__a   )  ->	Optional[Any]:



					'''simple docstring'''






					UpperCamelCase__   :Optional[Any]												= ''''''

					# first: transformer encoder
					for i in range(6   ):
										# read in weights + bias of input projection layer (in PyTorch's MultiHeadAttention, this is a single matrix + bias)
										UpperCamelCase__   :Optional[Any]												= state_dict.pop(f'''{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_weight'''   )
										UpperCamelCase__   :str												= state_dict.pop(f'''{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_bias'''   )
										# next, add query, keys and values (in that order) to the state dict
										UpperCamelCase__   :Any												= in_proj_weight[:256, :]
										UpperCamelCase__   :Tuple												= in_proj_bias[:256]
										UpperCamelCase__   :Optional[int]												= in_proj_weight[256:512, :]
										UpperCamelCase__   :Optional[Any]												= in_proj_bias[256:512]
										UpperCamelCase__   :Tuple												= in_proj_weight[-256:, :]
										UpperCamelCase__   :Dict												= in_proj_bias[-256:]
					# next: transformer decoder (which is a bit more complex because it also includes cross-attention)
					for i in range(6   ):
										# read in weights + bias of input projection layer of self-attention
										UpperCamelCase__   :List[str]												= state_dict.pop(f'''{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_weight'''   )
										UpperCamelCase__   :Optional[Any]												= state_dict.pop(f'''{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_bias'''   )
										# next, add query, keys and values (in that order) to the state dict
										UpperCamelCase__   :Any												= in_proj_weight[:256, :]
										UpperCamelCase__   :Optional[int]												= in_proj_bias[:256]
										UpperCamelCase__   :Tuple												= in_proj_weight[256:512, :]
										UpperCamelCase__   :Dict												= in_proj_bias[256:512]
										UpperCamelCase__   :Any												= in_proj_weight[-256:, :]
										UpperCamelCase__   :Dict												= in_proj_bias[-256:]
										# read in weights + bias of input projection layer of cross-attention
										UpperCamelCase__   :List[str]												= state_dict.pop(
										    f'''{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_weight'''   )
										UpperCamelCase__   :Any												= state_dict.pop(f'''{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_bias'''   )
										# next, add query, keys and values (in that order) of cross-attention to the state dict
										UpperCamelCase__   :Optional[Any]												= in_proj_weight_cross_attn[:256, :]
										UpperCamelCase__   :Any												= in_proj_bias_cross_attn[:256]
										UpperCamelCase__   :Any												= in_proj_weight_cross_attn[256:512, :]
										UpperCamelCase__   :Dict												= in_proj_bias_cross_attn[256:512]
										UpperCamelCase__   :str												= in_proj_weight_cross_attn[-256:, :]
										UpperCamelCase__   :Tuple												= in_proj_bias_cross_attn[-256:]


def 			a      (			__a ,					__a   )  ->	Optional[int]:



					'''simple docstring'''






					UpperCamelCase__					,				UpperCamelCase__   :str												= image.size
					UpperCamelCase__   :Optional[Any]												= max(__a ,					__a   )
					UpperCamelCase__   :List[Any]												= 800 if '''detection''' in checkpoint_url else 1000
					UpperCamelCase__   :Dict												= target_max_size / current_max_size
					UpperCamelCase__   :Any												= image.resize((int(round(scale * width   )   ), int(round(scale * height   )   ))   )

					return resized_image


def 			a      (			__a   )  ->	int:



					'''simple docstring'''






					UpperCamelCase__   :Any												= F.to_tensor(__a   )
					UpperCamelCase__   :int												= F.normalize(__a ,					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]   )
					return image


@torch.no_grad()
def 			a      (			__a ,					__a ,					__a   )  ->	Dict:



					'''simple docstring'''






					logger.info('''Converting model...'''   )

					# load original state dict
					UpperCamelCase__   :Optional[Any]												= torch.hub.load_state_dict_from_url(__a ,					map_location='''cpu'''   )
					# rename keys
					for src, dest in rename_keys:
										rename_key(__a ,					__a ,					__a   )
					UpperCamelCase__   :Any												= rename_backbone_keys(__a   )
					# query, key and value matrices need special treatment
					read_in_q_k_v(__a   )
					# important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them
					UpperCamelCase__   :Dict												= '''model.'''
					for key in state_dict.copy().keys():
										if not key.startswith('''class_labels_classifier'''   ) and not key.startswith('''bbox_predictor'''   ):
															UpperCamelCase__   :Optional[Any]												= state_dict.pop(__a   )
															UpperCamelCase__   :int												= val
    # create HuggingFace model and load state dict
					UpperCamelCase__   :str												= TableTransformerConfig(
					    backbone='''resnet18''' ,					mask_loss_coefficient=1 ,					dice_loss_coefficient=1 ,					ce_loss_coefficient=1 ,					bbox_loss_coefficient=5 ,					giou_loss_coefficient=2 ,					eos_coefficient=0.4 ,					class_cost=1 ,					bbox_cost=5 ,					giou_cost=2 ,					)

					if "detection" in checkpoint_url:
										UpperCamelCase__   :List[str]												= 15
										UpperCamelCase__   :int												= 2
										UpperCamelCase__   :Tuple												= {0: '''table''', 1: '''table rotated'''}
										UpperCamelCase__   :int												= idalabel
										UpperCamelCase__   :Dict												= {v: k for k, v in idalabel.items()}
					else:
										UpperCamelCase__   :int												= 125
										UpperCamelCase__   :List[str]												= 6
										UpperCamelCase__   :Optional[Any]												= {
										    0: '''table''',
										    1: '''table column''',
										    2: '''table row''',
										    3: '''table column header''',
										    4: '''table projected row header''',
										    5: '''table spanning cell''',
										}
										UpperCamelCase__   :Dict												= idalabel
										UpperCamelCase__   :Optional[Any]												= {v: k for k, v in idalabel.items()}

					UpperCamelCase__   :List[Any]												= DetrImageProcessor(
					    format='''coco_detection''' ,					max_size=800 if '''detection''' in checkpoint_url else 1000   )
					UpperCamelCase__   :int												= TableTransformerForObjectDetection(__a   )
					model.load_state_dict(__a   )
					model.eval()

					# verify our conversion
					UpperCamelCase__   :Dict												= '''example_pdf.png''' if '''detection''' in checkpoint_url else '''example_table.png'''
					UpperCamelCase__   :Optional[Any]												= hf_hub_download(repo_id='''nielsr/example-pdf''' ,					repo_type='''dataset''' ,					filename=__a   )
					UpperCamelCase__   :Tuple												= Image.open(__a   ).convert('''RGB'''   )
					UpperCamelCase__   :int												= normalize(resize(__a ,					__a   )   ).unsqueeze(0   )

					UpperCamelCase__   :Optional[int]												= model(__a   )

					if "detection" in checkpoint_url:
										UpperCamelCase__   :Dict												= (1, 15, 3)
										UpperCamelCase__   :List[Any]												= torch.tensor(
										    [[-6.7_8_9_7, -1_6.9_9_8_5, 6.7_9_3_7], [-8.0_1_8_6, -2_2.2_1_9_2, 6.9_6_7_7], [-7.3_1_1_7, -2_1.0_7_0_8, 7.4_0_5_5]]   )
										UpperCamelCase__   :Tuple												= torch.tensor([[0.4_8_6_7, 0.1_7_6_7, 0.6_7_3_2], [0.6_7_1_8, 0.4_4_7_9, 0.3_8_3_0], [0.4_7_1_6, 0.1_7_6_0, 0.6_3_6_4]]   )

					else:
										UpperCamelCase__   :Optional[Any]												= (1, 125, 7)
										UpperCamelCase__   :Dict												= torch.tensor(
										    [[-1_8.1_4_3_0, -8.3_2_1_4, 4.8_2_7_4], [-1_8.4_6_8_5, -7.1_3_6_1, -4.2_6_6_7], [-2_6.3_6_9_3, -9.3_4_2_9, -4.9_9_6_2]]   )
										UpperCamelCase__   :List[Any]												= torch.tensor([[0.4_9_8_3, 0.5_5_9_5, 0.9_4_4_0], [0.4_9_1_6, 0.6_3_1_5, 0.5_9_5_4], [0.6_1_0_8, 0.8_6_3_7, 0.1_1_3_5]]   )

					assert outputs.logits.shape == expected_shape
					assert torch.allclose(outputs.logits[0, :3, :3] ,					__a ,					atol=1e-4   )
					assert torch.allclose(outputs.pred_boxes[0, :3, :3] ,					__a ,					atol=1e-4   )
					print('''Looks ok!'''   )

					if pytorch_dump_folder_path is not None:
										# Save model and image processor
										logger.info(f'''Saving PyTorch model and image processor to {pytorch_dump_folder_path}...'''   )
										Path(__a   ).mkdir(exist_ok=__a   )
										model.save_pretrained(__a   )
										image_processor.save_pretrained(__a   )

					if push_to_hub:
										# Push model to HF hub
										logger.info('''Pushing model to the hub...'''   )
										UpperCamelCase__   :Union[str, Any]												= (
										    '''microsoft/table-transformer-detection'''
										    if '''detection''' in checkpoint_url
										    else '''microsoft/table-transformer-structure-recognition'''
										)
										model.push_to_hub(__a   )
										image_processor.push_to_hub(__a   )


if __name__ == "__main__":
		__snake_case							      =     argparse.ArgumentParser()

		parser.add_argument(
		    '''--checkpoint_url''',
		    default='''https://pubtables1m.blob.core.windows.net/model/pubtables1m_detection_detr_r18.pth''',
		    type=str,
		    choices=[
		        '''https://pubtables1m.blob.core.windows.net/model/pubtables1m_detection_detr_r18.pth''',
		        '''https://pubtables1m.blob.core.windows.net/model/pubtables1m_structure_detr_r18.pth''',
		    ],
		    help='''URL of the Table Transformer checkpoint 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							      =     parser.parse_args()
		convert_table_transformer_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub)