



import argparse
import os

import align
import numpy as np
import requests
import tensorflow as tf
import torch
from PIL import Image
from tokenizer import Tokenizer

from transformers import (
    AlignConfig,
    AlignModel,
    AlignProcessor,
    BertConfig,
    BertTokenizer,
    EfficientNetConfig,
    EfficientNetImageProcessor,
)
from transformers.utils import logging


logging.set_verbosity_info()
UpperCAmelCase_			      =  logging.get_logger(__name__)
def   UpperCAmelCase							(		A__     )							->					List[str]:
	_snake_case					:							Any					     =   tf.image.resize(A__				,  (3_46, 3_46)     )
	_snake_case					:							Optional[Any]					     =   tf.image.crop_to_bounding_box(A__				,  (3_46 - 2_89) // 2				,  (3_46 - 2_89) // 2				,  2_89				,  2_89     )
	return image
def   UpperCAmelCase							(		)							->					List[Any]:
	_snake_case					:							List[str]					     =   EfficientNetConfig.from_pretrained("""google/efficientnet-b7"""     )
	_snake_case					:							List[str]					     =   2_89
	_snake_case					:							Union[str, Any]					     =   6_40
	_snake_case					:							Optional[int]					     =   {'''0''': '''LABEL_0''', '''1''': '''LABEL_1'''}
	_snake_case					:							List[Any]					     =   {'''LABEL_0''': 0, '''LABEL_1''': 1}
	_snake_case					:							Tuple					     =   []

	_snake_case					:							Optional[Any]					     =   BertConfig()
	_snake_case					:							Any					     =   AlignConfig.from_text_vision_configs(
	    text_config=A__				,  vision_config=A__				,  projection_dim=6_40     )
	return config
def   UpperCAmelCase							(		)							->					Any:
	_snake_case					:							Optional[Any]					     =   '''http://images.cocodataset.org/val2017/000000039769.jpg'''
	_snake_case					:							List[str]					     =   Image.open(requests.get(A__				,  stream=A__     ).raw     )
	return im
def   UpperCAmelCase							(		)							->					Optional[Any]:
	_snake_case					:							str					     =   EfficientNetImageProcessor(
	    do_center_crop=A__				,  rescale_factor=1 / 127.5				,  rescale_offset=A__				,  do_normalize=A__				,  include_top=A__				,  resample=Image.BILINEAR				,  )
	_snake_case					:							Optional[Any]					     =   BertTokenizer.from_pretrained("""bert-base-uncased"""     )
	_snake_case					:							str					     =   64
	_snake_case					:							Optional[Any]					     =   AlignProcessor(image_processor=A__				,  tokenizer=A__     )
	return processor
def   UpperCAmelCase							(		A__     )							->					List[Any]:
	_snake_case					:							str					     =   [v.split("""_"""     )[0].split("""block"""     )[1] for v in original_param_names if v.startswith("""block"""     )]
	_snake_case					:							List[str]					     =   list(set(A__     )     )
	_snake_case					:							Any					     =   sorted(A__     )
	_snake_case					:							Tuple					     =   len(A__     )
	_snake_case					:							Any					     =   {b: str(A__     ) for b, i in zip(A__				,  range(A__     )     )}

	_snake_case					:							List[str]					     =   []
	rename_keys.append(("""stem_conv/kernel:0""", """embeddings.convolution.weight""")     )
	rename_keys.append(("""stem_bn/gamma:0""", """embeddings.batchnorm.weight""")     )
	rename_keys.append(("""stem_bn/beta:0""", """embeddings.batchnorm.bias""")     )
	rename_keys.append(("""stem_bn/moving_mean:0""", """embeddings.batchnorm.running_mean""")     )
	rename_keys.append(("""stem_bn/moving_variance:0""", """embeddings.batchnorm.running_var""")     )

	for b in block_names:
		_snake_case					:							Tuple					     =   block_name_mapping[b]
		rename_keys.append((f'''block{b}_expand_conv/kernel:0''', f'''encoder.blocks.{hf_b}.expansion.expand_conv.weight''')     )
		rename_keys.append((f'''block{b}_expand_bn/gamma:0''', f'''encoder.blocks.{hf_b}.expansion.expand_bn.weight''')     )
		rename_keys.append((f'''block{b}_expand_bn/beta:0''', f'''encoder.blocks.{hf_b}.expansion.expand_bn.bias''')     )
		rename_keys.append(
		    (f'''block{b}_expand_bn/moving_mean:0''', f'''encoder.blocks.{hf_b}.expansion.expand_bn.running_mean''')     )
		rename_keys.append(
		    (f'''block{b}_expand_bn/moving_variance:0''', f'''encoder.blocks.{hf_b}.expansion.expand_bn.running_var''')     )
		rename_keys.append(
		    (f'''block{b}_dwconv/depthwise_kernel:0''', f'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_conv.weight''')     )
		rename_keys.append((f'''block{b}_bn/gamma:0''', f'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.weight''')     )
		rename_keys.append((f'''block{b}_bn/beta:0''', f'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.bias''')     )
		rename_keys.append(
		    (f'''block{b}_bn/moving_mean:0''', f'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_mean''')     )
		rename_keys.append(
		    (f'''block{b}_bn/moving_variance:0''', f'''encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_var''')     )

		rename_keys.append((f'''block{b}_se_reduce/kernel:0''', f'''encoder.blocks.{hf_b}.squeeze_excite.reduce.weight''')     )
		rename_keys.append((f'''block{b}_se_reduce/bias:0''', f'''encoder.blocks.{hf_b}.squeeze_excite.reduce.bias''')     )
		rename_keys.append((f'''block{b}_se_expand/kernel:0''', f'''encoder.blocks.{hf_b}.squeeze_excite.expand.weight''')     )
		rename_keys.append((f'''block{b}_se_expand/bias:0''', f'''encoder.blocks.{hf_b}.squeeze_excite.expand.bias''')     )
		rename_keys.append(
		    (f'''block{b}_project_conv/kernel:0''', f'''encoder.blocks.{hf_b}.projection.project_conv.weight''')     )
		rename_keys.append((f'''block{b}_project_bn/gamma:0''', f'''encoder.blocks.{hf_b}.projection.project_bn.weight''')     )
		rename_keys.append((f'''block{b}_project_bn/beta:0''', f'''encoder.blocks.{hf_b}.projection.project_bn.bias''')     )
		rename_keys.append(
		    (f'''block{b}_project_bn/moving_mean:0''', f'''encoder.blocks.{hf_b}.projection.project_bn.running_mean''')     )
		rename_keys.append(
		    (f'''block{b}_project_bn/moving_variance:0''', f'''encoder.blocks.{hf_b}.projection.project_bn.running_var''')     )

	_snake_case					:							Tuple					     =   {}
	for item in rename_keys:
		if item[0] in original_param_names:
			_snake_case					:							str					     =   '''vision_model.''' + item[1]

    # BERT text encoder
	_snake_case					:							Union[str, Any]					     =   []
	_snake_case					:							Tuple					     =   '''tf_bert_model/bert'''
	_snake_case					:							Optional[Any]					     =   '''text_model'''
	for i in range(12     ):
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/self/query/kernel:0''',
		        f'''{new}.encoder.layer.{i}.attention.self.query.weight''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/self/query/bias:0''',
		        f'''{new}.encoder.layer.{i}.attention.self.query.bias''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/self/key/kernel:0''',
		        f'''{new}.encoder.layer.{i}.attention.self.key.weight''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/self/key/bias:0''',
		        f'''{new}.encoder.layer.{i}.attention.self.key.bias''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/self/value/kernel:0''',
		        f'''{new}.encoder.layer.{i}.attention.self.value.weight''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/self/value/bias:0''',
		        f'''{new}.encoder.layer.{i}.attention.self.value.bias''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/output/dense/kernel:0''',
		        f'''{new}.encoder.layer.{i}.attention.output.dense.weight''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/output/dense/bias:0''',
		        f'''{new}.encoder.layer.{i}.attention.output.dense.bias''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/output/LayerNorm/gamma:0''',
		        f'''{new}.encoder.layer.{i}.attention.output.LayerNorm.weight''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/attention/output/LayerNorm/beta:0''',
		        f'''{new}.encoder.layer.{i}.attention.output.LayerNorm.bias''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/intermediate/dense/kernel:0''',
		        f'''{new}.encoder.layer.{i}.intermediate.dense.weight''',
		    )     )
		rename_keys.append(
		    (
		        f'''{old}/encoder/layer_._{i}/intermediate/dense/bias:0''',
		        f'''{new}.encoder.layer.{i}.intermediate.dense.bias''',
		    )     )
		rename_keys.append(
		    (f'''{old}/encoder/layer_._{i}/output/dense/kernel:0''', f'''{new}.encoder.layer.{i}.output.dense.weight''')     )
		rename_keys.append(
		    (f'''{old}/encoder/layer_._{i}/output/dense/bias:0''', f'''{new}.encoder.layer.{i}.output.dense.bias''')     )
		rename_keys.append(
		    (f'''{old}/encoder/layer_._{i}/output/LayerNorm/gamma:0''', f'''{new}.encoder.layer.{i}.output.LayerNorm.weight''')     )
		rename_keys.append(
		    (f'''{old}/encoder/layer_._{i}/output/LayerNorm/beta:0''', f'''{new}.encoder.layer.{i}.output.LayerNorm.bias''')     )

	rename_keys.append((f'''{old}/embeddings/word_embeddings/weight:0''', f'''{new}.embeddings.word_embeddings.weight''')     )
	rename_keys.append(
	    (f'''{old}/embeddings/position_embeddings/embeddings:0''', f'''{new}.embeddings.position_embeddings.weight''')     )
	rename_keys.append(
	    (f'''{old}/embeddings/token_type_embeddings/embeddings:0''', f'''{new}.embeddings.token_type_embeddings.weight''')     )
	rename_keys.append((f'''{old}/embeddings/LayerNorm/gamma:0''', f'''{new}.embeddings.LayerNorm.weight''')     )
	rename_keys.append((f'''{old}/embeddings/LayerNorm/beta:0''', f'''{new}.embeddings.LayerNorm.bias''')     )

	rename_keys.append((f'''{old}/pooler/dense/kernel:0''', f'''{new}.pooler.dense.weight''')     )
	rename_keys.append((f'''{old}/pooler/dense/bias:0''', f'''{new}.pooler.dense.bias''')     )
	rename_keys.append(("""dense/kernel:0""", """text_projection.weight""")     )
	rename_keys.append(("""dense/bias:0""", """text_projection.bias""")     )
	rename_keys.append(("""dense/bias:0""", """text_projection.bias""")     )
	rename_keys.append(("""temperature:0""", """temperature""")     )

	for item in rename_keys:
		if item[0] in original_param_names:
			_snake_case					:							str					     =   item[1]
	return key_mapping
def   UpperCAmelCase							(		A__				,  A__				,  A__     )							->					Dict:
	list(hf_params.keys()     )

	for key, value in tf_params.items():
		if key not in key_mapping:
			continue

		_snake_case					:							Optional[int]					     =   key_mapping[key]
		if "_conv" in key and "kernel" in key:
			_snake_case					:							List[str]					     =   torch.from_numpy(A__     ).permute(3				,  2				,  0				,  1     )
		elif "embeddings" in key:
			_snake_case					:							Optional[Any]					     =   torch.from_numpy(A__     )
		elif "depthwise_kernel" in key:
			_snake_case					:							List[str]					     =   torch.from_numpy(A__     ).permute(2				,  3				,  0				,  1     )
		elif "kernel" in key:
			_snake_case					:							Any					     =   torch.from_numpy(np.transpose(A__     )     )
		elif "temperature" in key:
			_snake_case					:							int					     =   value
		elif "bn/gamma" or "bn/beta" in key:
			_snake_case					:							Optional[Any]					     =   torch.from_numpy(np.transpose(A__     )     ).squeeze()
		else:
			_snake_case					:							Union[str, Any]					     =   torch.from_numpy(A__     )

		# Replace HF parameters with original TF model parameters
		hf_params[hf_key].copy_(A__     )
@torch.no_grad()
def   UpperCAmelCase							(		A__				,  A__				,  A__				,  A__     )							->					str:
	_snake_case					:							int					     =   64
	_snake_case					:							Optional[int]					     =   Tokenizer(A__     )
	_snake_case					:							List[str]					     =   align.Align("""efficientnet-b7"""				,  """bert-base"""				,  6_40				,  A__				,  tok.get_vocab_size()     )
	original_model.compile()
	original_model.load_weights(A__     )

	_snake_case					:							int					     =   original_model.trainable_variables
	_snake_case					:							Dict					     =   original_model.non_trainable_variables
	_snake_case					:							List[Any]					     =   {param.name: param.numpy() for param in tf_params}
	for param in tf_non_train_params:
		_snake_case					:							Union[str, Any]					     =   param.numpy()
	_snake_case					:							Any					     =   list(tf_params.keys()     )

	# Load HuggingFace model
	_snake_case					:							Union[str, Any]					     =   get_align_config()
	_snake_case					:							Any					     =   AlignModel(A__     ).eval()
	_snake_case					:							List[str]					     =   hf_model.state_dict()

	# Create src-to-dst parameter name mapping dictionary
	print("""Converting parameters..."""     )
	_snake_case					:							Tuple					     =   rename_keys(A__     )
	replace_params(A__				,  A__				,  A__     )

	# Initialize processor
	_snake_case					:							str					     =   get_processor()
	_snake_case					:							Optional[int]					     =   processor(
	    images=prepare_img()				,  text="""A picture of a cat"""				,  padding="""max_length"""				,  max_length=64				,  return_tensors="""pt"""     )

	# HF model inference
	hf_model.eval()
	with torch.no_grad():
		_snake_case					:							Optional[int]					     =   hf_model(**A__     )

	_snake_case					:							Tuple					     =   outputs.image_embeds.detach().numpy()
	_snake_case					:							Dict					     =   outputs.text_embeds.detach().numpy()

	# Original model inference
	_snake_case					:							str					     =   False
	_snake_case					:							Any					     =   EfficientNetImageProcessor(
	    do_center_crop=A__				,  do_rescale=A__				,  do_normalize=A__				,  include_top=A__				,  resample=Image.BILINEAR				,  )
	_snake_case					:							List[Any]					     =   tf_image_processor(images=prepare_img()				,  return_tensors="""tf"""				,  data_format="""channels_last"""     )['''pixel_values''']
	_snake_case					:							Union[str, Any]					     =   tok(tf.constant(["""A picture of a cat"""]     )     )

	_snake_case					:							int					     =   original_model.image_encoder(A__				,  training=A__     )
	_snake_case					:							List[str]					     =   original_model.text_encoder(A__				,  training=A__     )

	_snake_case					:							Optional[int]					     =   tf.nn.la_normalize(A__				,  axis=-1     )
	_snake_case					:							Union[str, Any]					     =   tf.nn.la_normalize(A__				,  axis=-1     )

	# Check whether original and HF model outputs match  -> np.allclose
	if not np.allclose(A__				,  A__				,  atol=1E-3     ):
		raise ValueError("""The predicted image features are not the same."""     )
	if not np.allclose(A__				,  A__				,  atol=1E-3     ):
		raise ValueError("""The predicted text features are not the same."""     )
	print("""Model outputs match!"""     )

	if save_model:
		# Create folder to save model
		if not os.path.isdir(A__     ):
			os.mkdir(A__     )
		# Save converted model and image processor
		hf_model.save_pretrained(A__     )
		processor.save_pretrained(A__     )

	if push_to_hub:
		# Push model and image processor to hub
		print("""Pushing converted ALIGN to the hub..."""     )
		processor.push_to_hub("""align-base"""     )
		hf_model.push_to_hub("""align-base"""     )


if __name__ == "__main__":
						UpperCAmelCase_			      =  argparse.ArgumentParser()
						# Required parameters
						parser.add_argument(
						    '''--checkpoint_path''',
						    default='''./weights/model-weights''',
						    type=str,
						    help='''Path to the pretrained TF ALIGN checkpoint.''',
						)
						parser.add_argument(
						    '''--pytorch_dump_folder_path''',
						    default='''hf_model''',
						    type=str,
						    help='''Path to the output PyTorch model directory.''',
						)
						parser.add_argument('''--save_model''', action='''store_true''', help='''Save model to local''')
						parser.add_argument('''--push_to_hub''', action='''store_true''', help='''Push model and image processor to the hub''')

						UpperCAmelCase_			      =  parser.parse_args()
						convert_align_checkpoint(args.checkpoint_path, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)








"""simple docstring"""





def 							_lowerCAmelCase   (    UpperCAmelCase  :				int   ,				UpperCAmelCase  :				int   ,				UpperCAmelCase  :				int					):


					'''simple docstring'''






					if power < 0:
										return -1
					base %= mod
					UpperCamelCase__		:     Any								=1

					while power > 0:
										if power & 1:
															UpperCamelCase__		:     Optional[Any]								=(result * base) % mod
										UpperCamelCase__		:     Union[str, Any]								=power >> 1
										UpperCamelCase__		:     Union[str, Any]								=(base * base) % mod

					return result



def 							_lowerCAmelCase   (    ):


					'''simple docstring'''






					print(modular_exponential(3   ,				200   ,				13					)					)


if __name__ == "__main__":
				import doctest

				doctest.testmod()

				main()


