




"""simple docstring"""





import argparse

import torch
from clip import load

from transformers import CLIPConfig, CLIPModel

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						snake_case__    :   str							     =   pt_attn_layer.in_proj_weight.chunk(3 ,     dim=0						)
						snake_case__    :   Union[str, Any]							     =   pt_attn_layer.in_proj_bias.chunk(3 ,     dim=0						)

						snake_case__    :   Tuple							     =   pt_attn_layer.out_proj.weight
						snake_case__    :   Any							     =   pt_attn_layer.out_proj.bias

						snake_case__    :   Tuple							     =   q_proj
						snake_case__    :   List[Any]							     =   q_proj_bias

						snake_case__    :   Optional[int]							     =   k_proj
						snake_case__    :   List[str]							     =   k_proj_bias

						snake_case__    :   Optional[Any]							     =   v_proj
						snake_case__    :   Tuple							     =   v_proj_bias

						snake_case__    :   Optional[Any]							     =   out_proj_weights
						snake_case__    :   List[Any]							     =   out_proj_bias

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						copy_linear(hf_mlp.fca ,     pt_mlp.c_fc						)
						copy_linear(hf_mlp.fca ,     pt_mlp.c_proj						)

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						snake_case__    :   List[Any]							     =   pt_linear.weight
						snake_case__    :   str							     =   pt_linear.bias

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						copy_linear(hf_layer.layer_norma ,     pt_layer.ln_a						)
						copy_linear(hf_layer.layer_norma ,     pt_layer.ln_a						)

						# copy MLP
						copy_mlp(hf_layer.mlp ,     pt_layer.mlp						)

						# copy attn
						copy_attn_layer(hf_layer.self_attn ,     pt_layer.attn						)

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						for hf_layer, pt_layer in zip(_lowerCAmelCase ,     _lowerCAmelCase						):
												copy_layer(_lowerCAmelCase ,     _lowerCAmelCase						)

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						snake_case__    :   List[str]							     =   pt_model.token_embedding.weight
						snake_case__    :   int							     =   pt_model.positional_embedding

						# copy layer norm
						copy_linear(hf_encoder.final_layer_norm ,     pt_model.ln_final						)

						# copy hidden layers
						copy_layers(hf_encoder.encoder.layers ,     pt_model.transformer.resblocks						)

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						snake_case__    :   int							     =   pt_model.text_projection.data.T

						# copy text encoder
						copy_encoder(hf_model.text_model ,     _lowerCAmelCase						)

def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase						):
						'''simple docstring'''


						snake_case__    :   Optional[Any]							     =   pt_model.visual.proj.data.T

						# copy layer norms
						copy_linear(hf_model.vision_model.pre_layrnorm ,     pt_model.visual.ln_pre						)
						copy_linear(hf_model.vision_model.post_layernorm ,     pt_model.visual.ln_post						)

						# copy embeds
						snake_case__    :   Dict							     =   pt_model.visual.conva.weight.data
						snake_case__    :   Optional[Any]							     =   pt_model.visual.class_embedding
						snake_case__    :   Tuple							     =   pt_model.visual.positional_embedding.data

						# copy encoder
						copy_layers(hf_model.vision_model.encoder.layers ,     pt_model.visual.transformer.resblocks						)

@torch.no_grad()
def 						lowerCAmelCase							(	lowerCamelCase ,     lowerCamelCase ,     lowerCamelCase=None						):
						'''simple docstring'''


						if config_path is not None:
												snake_case__    :   str							     =   CLIPConfig.from_pretrained(_lowerCAmelCase						)
						else:
												snake_case__    :   List[str]							     =   CLIPConfig(projection_dim=512 ,     text_config={} ,     vision_config={}						)

						snake_case__    :   str							     =   CLIPModel(_lowerCAmelCase						).eval()

						snake_case__    :   str							     =   load(_lowerCAmelCase ,     device='''cpu''' ,     jit=_lowerCAmelCase						)
						snake_case__    :   Optional[Any]							     =   pt_model.eval()

						copy_text_model_and_projection(_lowerCAmelCase ,     _lowerCAmelCase						)
						copy_vison_model_and_projection(_lowerCAmelCase ,     _lowerCAmelCase						)
						snake_case__    :   List[str]							     =   pt_model.logit_scale

						snake_case__    :   int							     =   torch.arange(0 ,     77						).unsqueeze(0						)
						snake_case__    :   Optional[Any]							     =   torch.randn(1 ,     3 ,     224 ,     224						)

						snake_case__    :   str							     =   hf_model(input_ids=_lowerCAmelCase ,     pixel_values=_lowerCAmelCase ,     return_dict=_lowerCAmelCase						)
						snake_case__    :   List[Any]							     =   hf_outputs.logits_per_image
						snake_case__    :   Optional[int]							     =   hf_outputs.logits_per_text
						snake_case__    :   int							     =   pt_model(_lowerCAmelCase ,     _lowerCAmelCase						)

						assert torch.allclose(_lowerCAmelCase ,     _lowerCAmelCase ,     atol=1e-3						)
						assert torch.allclose(_lowerCAmelCase ,     _lowerCAmelCase ,     atol=1e-3						)

						hf_model.save_pretrained(_lowerCAmelCase						)


if __name__ == "__main__":
	_lowercase		 =      argparse.ArgumentParser()
	parser.add_argument("""--pytorch_dump_folder_path""", default=None, type=str, help="""Path to the output PyTorch model.""")
	parser.add_argument("""--checkpoint_path""", default=None, type=str, help="""Path to fairseq checkpoint""")
	parser.add_argument("""--config_path""", default=None, type=str, help="""Path to hf config.json of model to convert""")
	_lowercase		 =      parser.parse_args()

	convert_clip_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path)








"""simple docstring"""





class  __lowercase    :


				'''simple docstring'''


				class  __lowercase    :


								'''simple docstring'''


								_lowerCAmelCase		     ="_prev", "_data", "_next"

								def __init__(				self				:       List[Any] ,SCREAMING_SNAKE_CASE_				:       int ,SCREAMING_SNAKE_CASE_				:       Union[str, Any] ,SCREAMING_SNAKE_CASE_				:       Any ):
														snake_case__    :   Any							     =   link_p
														snake_case__    :   List[str]							     =   element
														snake_case__    :   str							     =   link_n





								def  _lowerCamelCase   (				self				:       Optional[Any] ):
														return (
														    F''' Prev -> {self._prev is not None}, Next -> {self._next is not None}'''
														)







				def __init__(				self				:       Any ):
										snake_case__    :   int							     =   self._Node(SCREAMING_SNAKE_CASE_ ,SCREAMING_SNAKE_CASE_ ,SCREAMING_SNAKE_CASE_ )
										snake_case__    :   Optional[int]							     =   self._Node(SCREAMING_SNAKE_CASE_ ,SCREAMING_SNAKE_CASE_ ,SCREAMING_SNAKE_CASE_ )
										snake_case__    :   Union[str, Any]							     =   self._trailer
										snake_case__    :   Union[str, Any]							     =   self._header
										snake_case__    :   Any							     =   0

				def __len__(				self				:       str ):
										return self._size

				def  _lowerCamelCase   (				self				:       Union[str, Any] ):
										return self.__len__() == 0

				def  _lowerCamelCase   (				self				:       Any ,SCREAMING_SNAKE_CASE_				:       List[Any] ,SCREAMING_SNAKE_CASE_				:       List[str] ,SCREAMING_SNAKE_CASE_				:       Dict ):
										# Create new_node by setting it's prev.link -> header
										# setting it's next.link -> trailer
										snake_case__    :   Dict							     =   self._Node(SCREAMING_SNAKE_CASE_ ,SCREAMING_SNAKE_CASE_ ,SCREAMING_SNAKE_CASE_ )
										snake_case__    :   Any							     =   new_node
										snake_case__    :   str							     =   new_node
										self._size += 1
										return self





				def  _lowerCamelCase   (				self				:       Union[str, Any] ,SCREAMING_SNAKE_CASE_				:       Dict ):
										snake_case__    :   Union[str, Any]							     =   node._prev
										snake_case__    :   Union[str, Any]							     =   node._next

										snake_case__    :   List[Any]							     =   successor
										snake_case__    :   Dict							     =   predecessor
										self._size -= 1
										snake_case__    :   Dict							     =   node._data
										snake_case__    :   List[str]							     =   None
										del node
										return temp







class  __lowercase    (     _DoublyLinkedBase		):


				'''simple docstring'''


				def  _lowerCamelCase   (				self				:       Optional[int] ):
										if self.is_empty():
																raise Exception('''List is empty''' )
										return self._header._next._data

				def  _lowerCamelCase   (				self				:       Union[str, Any] ):
										if self.is_empty():
																raise Exception('''List is empty''' )
										return self._trailer._prev._data

				def  _lowerCamelCase   (				self				:       Any ,SCREAMING_SNAKE_CASE_				:       Dict ):
										return self._insert(self._header ,SCREAMING_SNAKE_CASE_ ,self._header._next )

				def  _lowerCamelCase   (				self				:       Dict ,SCREAMING_SNAKE_CASE_				:       Union[str, Any] ):
										return self._insert(self._trailer._prev ,SCREAMING_SNAKE_CASE_ ,self._trailer )

				def  _lowerCamelCase   (				self				:       Optional[int] ):
										if self.is_empty():
																raise IndexError('''remove_first from empty list''' )
										return self._delete(self._header._next )





				def  _lowerCamelCase   (				self				:       Optional[Any] ):
										if self.is_empty():
																raise IndexError('''remove_first from empty list''' )
										return self._delete(self._trailer._prev )


