
import argparse

import requests
import torch

# pip3 install salesforce-lavis
# I'm actually installing a slightly modified version: pip3 install git+https://github.com/nielsrogge/LAVIS.git@fix_lavis
from lavis.models import load_model_and_preprocess
from PIL import Image

from transformers import (
    AutoTokenizer,
    BlipaConfig,
    BlipaForConditionalGeneration,
    BlipaProcessor,
    BlipaVisionConfig,
    BlipImageProcessor,
    OPTConfig,
    TaConfig,
)
from transformers.utils.constants import OPENAI_CLIP_MEAN, OPENAI_CLIP_STD






def 							_lowercase							(     )		->		List[str]:
					'''simple docstring'''


					SCREAMING_SNAKE_CASE__													= 'https://storage.googleapis.com/sfr-vision-language-research/LAVIS/assets/merlion.png'
					SCREAMING_SNAKE_CASE__													= Image.open(requests.get(UpperCamelCase_	,	stream=UpperCamelCase_		).raw		).convert('RGB'		)

					return image






def 							_lowercase							(     UpperCamelCase_		)		->		Tuple:
					'''simple docstring'''


					SCREAMING_SNAKE_CASE__													= []
					# fmt: off

					# vision encoder
					rename_keys.append(('visual_encoder.cls_token', 'vision_model.embeddings.class_embedding')		)
					rename_keys.append(('visual_encoder.pos_embed', 'vision_model.embeddings.position_embedding')		)
					rename_keys.append(('visual_encoder.patch_embed.proj.weight', 'vision_model.embeddings.patch_embedding.weight')		)
					rename_keys.append(('visual_encoder.patch_embed.proj.bias', 'vision_model.embeddings.patch_embedding.bias')		)
					rename_keys.append(('ln_vision.weight', 'vision_model.post_layernorm.weight')		)
					rename_keys.append(('ln_vision.bias', 'vision_model.post_layernorm.bias')		)

					for i in range(config.vision_config.num_hidden_layers		):
										rename_keys.append((F'visual_encoder.blocks.{i}.norm1.weight', F'vision_model.encoder.layers.{i}.layer_norm1.weight')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.norm1.bias', F'vision_model.encoder.layers.{i}.layer_norm1.bias')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.norm2.weight', F'vision_model.encoder.layers.{i}.layer_norm2.weight')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.norm2.bias', F'vision_model.encoder.layers.{i}.layer_norm2.bias')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.attn.qkv.weight', F'vision_model.encoder.layers.{i}.self_attn.qkv.weight')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.attn.proj.weight', F'vision_model.encoder.layers.{i}.self_attn.projection.weight',)		)
										rename_keys.append((F'visual_encoder.blocks.{i}.attn.proj.bias', F'vision_model.encoder.layers.{i}.self_attn.projection.bias')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.mlp.fc1.weight', F'vision_model.encoder.layers.{i}.mlp.fc1.weight')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.mlp.fc1.bias', F'vision_model.encoder.layers.{i}.mlp.fc1.bias')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.mlp.fc2.weight', F'vision_model.encoder.layers.{i}.mlp.fc2.weight')		)
										rename_keys.append((F'visual_encoder.blocks.{i}.mlp.fc2.bias', F'vision_model.encoder.layers.{i}.mlp.fc2.bias')		)

					# QFormer
					rename_keys.append(('Qformer.bert.embeddings.LayerNorm.weight', 'qformer.layernorm.weight')		)
					rename_keys.append(('Qformer.bert.embeddings.LayerNorm.bias', 'qformer.layernorm.bias')		)

					# fmt: on
					return rename_keys






def 							_lowercase							(     UpperCamelCase_	,	UpperCamelCase_	,	UpperCamelCase_		)		->		Union[str, Any]:
					'''simple docstring'''


					SCREAMING_SNAKE_CASE__													= dct.pop(UpperCamelCase_		)
					SCREAMING_SNAKE_CASE__													= val






def 							_lowercase							(     UpperCamelCase_	,	UpperCamelCase_		)		->		int:
					'''simple docstring'''


					for i in range(config.vision_config.num_hidden_layers		):
										# read in original q and v biases
										SCREAMING_SNAKE_CASE__													= state_dict.pop(F'visual_encoder.blocks.{i}.attn.q_bias'		)
										SCREAMING_SNAKE_CASE__													= state_dict.pop(F'visual_encoder.blocks.{i}.attn.v_bias'		)

										# next, set bias in the state dict
										SCREAMING_SNAKE_CASE__													= torch.cat((q_bias, torch.zeros_like(UpperCamelCase_	,	requires_grad=UpperCamelCase_		), v_bias)		)
										SCREAMING_SNAKE_CASE__													= qkv_bias






def 							_lowercase							(     UpperCamelCase_	,	UpperCamelCase_		)		->		Tuple:
					'''simple docstring'''


					SCREAMING_SNAKE_CASE__													= 364 if 'coco' in model_name else 224
					SCREAMING_SNAKE_CASE__													= BlipaVisionConfig(image_size=UpperCamelCase_		).to_dict()

					# make sure the models have proper bos_token_id and eos_token_id set (important for generation)
					# seems like flan-T5 models don't have bos_token_id properly set?
					if "opt-2.7b" in model_name:
										SCREAMING_SNAKE_CASE__													= OPTConfig.from_pretrained('facebook/opt-2.7b'	,	eos_token_id=UpperCamelCase_		).to_dict()
					elif "opt-6.7b" in model_name:
										SCREAMING_SNAKE_CASE__													= OPTConfig.from_pretrained('facebook/opt-6.7b'	,	eos_token_id=UpperCamelCase_		).to_dict()
					elif "t5-xl" in model_name:
										SCREAMING_SNAKE_CASE__													= TaConfig.from_pretrained('google/flan-t5-xl'	,	dense_act_fn='gelu'	,	bos_token_id=1		).to_dict()
					elif "t5-xxl" in model_name:
										SCREAMING_SNAKE_CASE__													= TaConfig.from_pretrained('google/flan-t5-xxl'	,	dense_act_fn='gelu'	,	bos_token_id=1		).to_dict()

					SCREAMING_SNAKE_CASE__													= BlipaConfig(vision_config=UpperCamelCase_	,	text_config=UpperCamelCase_		)

					return config, image_size






@torch.no_grad()
def 							_lowercase							(     UpperCamelCase_	,	UpperCamelCase_=None	,	UpperCamelCase_=False		)		->		Union[str, Any]:
					'''simple docstring'''


					SCREAMING_SNAKE_CASE__													= (
					    AutoTokenizer.from_pretrained('facebook/opt-2.7b'		)
					    if 'opt' in model_name
					    else AutoTokenizer.from_pretrained('google/flan-t5-xl'		)
					)
					SCREAMING_SNAKE_CASE__													= tokenizer('\n'	,	add_special_tokens=UpperCamelCase_		).input_ids[0]
					SCREAMING_SNAKE_CASE__						, SCREAMING_SNAKE_CASE__													= get_blipa_config(UpperCamelCase_	,	eos_token_id=UpperCamelCase_		)

					SCREAMING_SNAKE_CASE__													= BlipaForConditionalGeneration(UpperCamelCase_		).eval()

					SCREAMING_SNAKE_CASE__													= {
					    'blip2-opt-2.7b': ('blip2_opt', 'pretrain_opt2.7b'),
					    'blip2-opt-6.7b': ('blip2_opt', 'pretrain_opt6.7b'),
					    'blip2-opt-2.7b-coco': ('blip2_opt', 'caption_coco_opt2.7b'),
					    'blip2-opt-6.7b-coco': ('blip2_opt', 'caption_coco_opt6.7b'),
					    'blip2-flan-t5-xl': ('blip2_t5', 'pretrain_flant5xl'),
					    'blip2-flan-t5-xl-coco': ('blip2_t5', 'caption_coco_flant5xl'),
					    'blip2-flan-t5-xxl': ('blip2_t5', 'pretrain_flant5xxl'),
					}

					SCREAMING_SNAKE_CASE__						, SCREAMING_SNAKE_CASE__													= model_name_to_original[model_name]

					# load original model
					print('Loading original model...'		)
					SCREAMING_SNAKE_CASE__													= 'cuda' if torch.cuda.is_available() else 'cpu'
					SCREAMING_SNAKE_CASE__						, SCREAMING_SNAKE_CASE__						, SCREAMING_SNAKE_CASE__													= load_model_and_preprocess(
					    name=UpperCamelCase_	,	model_type=UpperCamelCase_	,	is_eval=UpperCamelCase_	,	device=UpperCamelCase_		)
					original_model.eval()
					print('Done!'		)

					# update state dict keys
					SCREAMING_SNAKE_CASE__													= original_model.state_dict()
					SCREAMING_SNAKE_CASE__													= create_rename_keys(UpperCamelCase_		)
					for src, dest in rename_keys:
										rename_key(UpperCamelCase_	,	UpperCamelCase_	,	UpperCamelCase_		)

					# some keys can be renamed efficiently
					for key, val in state_dict.copy().items():
										SCREAMING_SNAKE_CASE__													= state_dict.pop(UpperCamelCase_		)
										if key.startswith('Qformer.bert'		):
															SCREAMING_SNAKE_CASE__													= key.replace('Qformer.bert'	,	'qformer'		)
										if "attention.self" in key:
															SCREAMING_SNAKE_CASE__													= key.replace('self'	,	'attention'		)
										if "opt_proj" in key:
															SCREAMING_SNAKE_CASE__													= key.replace('opt_proj'	,	'language_projection'		)
										if "t5_proj" in key:
															SCREAMING_SNAKE_CASE__													= key.replace('t5_proj'	,	'language_projection'		)
										if key.startswith('opt'		):
															SCREAMING_SNAKE_CASE__													= key.replace('opt'	,	'language'		)
										if key.startswith('t5'		):
															SCREAMING_SNAKE_CASE__													= key.replace('t5'	,	'language'		)
										SCREAMING_SNAKE_CASE__													= val

					# read in qv biases
					read_in_q_v_bias(UpperCamelCase_	,	UpperCamelCase_		)

					SCREAMING_SNAKE_CASE__						, SCREAMING_SNAKE_CASE__													= hf_model.load_state_dict(UpperCamelCase_	,	strict=UpperCamelCase_		)
					assert len(UpperCamelCase_		) == 0
					assert unexpected_keys == ["qformer.embeddings.position_ids"]

					SCREAMING_SNAKE_CASE__													= load_demo_image()
					SCREAMING_SNAKE_CASE__													= vis_processors['eval'](UpperCamelCase_		).unsqueeze(0		).to(UpperCamelCase_		)
					SCREAMING_SNAKE_CASE__													= tokenizer(['\n']	,	return_tensors='pt'		).input_ids.to(UpperCamelCase_		)

					# create processor
					SCREAMING_SNAKE_CASE__													= BlipImageProcessor(
					    size={'height': image_size, 'width': image_size}	,	image_mean=UpperCamelCase_	,	image_std=UpperCamelCase_		)
					SCREAMING_SNAKE_CASE__													= BlipaProcessor(image_processor=UpperCamelCase_	,	tokenizer=UpperCamelCase_		)
					SCREAMING_SNAKE_CASE__													= processor(images=UpperCamelCase_	,	return_tensors='pt'		).pixel_values.to(UpperCamelCase_		)

					# make sure processor creates exact same pixel values
					assert torch.allclose(UpperCamelCase_	,	UpperCamelCase_		)

					original_model.to(UpperCamelCase_		)
					hf_model.to(UpperCamelCase_		)
					with torch.no_grad():
										if "opt" in model_name:
															SCREAMING_SNAKE_CASE__													= original_model({'image': original_pixel_values, 'text_input': ['']}		).logits
															SCREAMING_SNAKE_CASE__													= hf_model(UpperCamelCase_	,	UpperCamelCase_		).logits
										else:
															SCREAMING_SNAKE_CASE__													= original_model(
															    {'image': original_pixel_values, 'text_input': ['\n'], 'text_output': ['\n']}		).logits
															SCREAMING_SNAKE_CASE__													= input_ids.masked_fill(input_ids == tokenizer.pad_token_id	,	-100		)
															SCREAMING_SNAKE_CASE__													= hf_model(UpperCamelCase_	,	UpperCamelCase_	,	labels=UpperCamelCase_		).logits

					assert original_logits.shape == logits.shape
					print('First values of original logits:'	,	original_logits[0, :3, :3]		)
					print('First values of HF logits:'	,	logits[0, :3, :3]		)

					# assert values
					if model_name == "blip2-flan-t5-xl":
										SCREAMING_SNAKE_CASE__													= torch.tensor(
										    [[-41.5_850, -4.4_440, -8.9_922], [-47.4_322, -5.9_143, -1.7_340]]	,	device=UpperCamelCase_		)
										assert torch.allclose(logits[0, :3, :3]	,	UpperCamelCase_	,	atol=1e-4		)
					elif model_name == "blip2-flan-t5-xl-coco":
										SCREAMING_SNAKE_CASE__													= torch.tensor(
										    [[-57.0_109, -9.8_967, -12.6_280], [-68.6_578, -12.7_191, -10.5_065]]	,	device=UpperCamelCase_		)
					else:
										# cast to same type
										SCREAMING_SNAKE_CASE__													= logits.dtype
										assert torch.allclose(original_logits.to(UpperCamelCase_		)	,	UpperCamelCase_	,	atol=1e-2		)
					print('Looks ok!'		)

					print('Generating a caption...'		)
					SCREAMING_SNAKE_CASE__													= ''
					SCREAMING_SNAKE_CASE__													= tokenizer(UpperCamelCase_	,	return_tensors='pt'		).input_ids.to(UpperCamelCase_		)

					SCREAMING_SNAKE_CASE__													= original_model.generate({'image': original_pixel_values}		)
					SCREAMING_SNAKE_CASE__													= hf_model.generate(
					    UpperCamelCase_	,	UpperCamelCase_	,	do_sample=UpperCamelCase_	,	num_beams=5	,	max_length=30	,	min_length=1	,	top_p=0.9	,	repetition_penalty=1.0	,	length_penalty=1.0	,	temperature=1	,	)
					print('Original generation:'	,	UpperCamelCase_		)
					SCREAMING_SNAKE_CASE__													= input_ids.shape[1]
					SCREAMING_SNAKE_CASE__													= processor.batch_decode(outputs[:, prompt_length:]	,	skip_special_tokens=UpperCamelCase_		)
					SCREAMING_SNAKE_CASE__													= [text.strip() for text in output_text]
					print('HF generation:'	,	UpperCamelCase_		)

					if pytorch_dump_folder_path is not None:
										processor.save_pretrained(UpperCamelCase_		)
										hf_model.save_pretrained(UpperCamelCase_		)

					if push_to_hub:
										processor.push_to_hub(F'nielsr/{model_name}'		)
										hf_model.push_to_hub(F'nielsr/{model_name}'		)


if __name__ == "__main__":
				__snake_case								=  argparse.ArgumentParser()
				__snake_case								=  [
				    """blip2-opt-2.7b""",
				    """blip2-opt-6.7b""",
				    """blip2-opt-2.7b-coco""",
				    """blip2-opt-6.7b-coco""",
				    """blip2-flan-t5-xl""",
				    """blip2-flan-t5-xl-coco""",
				    """blip2-flan-t5-xxl""",
				]
				parser.add_argument(
				    """--model_name""",
				    default="""blip2-opt-2.7b""",
				    choices=choices,
				    type=str,
				    help="""Path to hf config.json of model to convert""",
				)
				parser.add_argument("""--pytorch_dump_folder_path""", default=None, type=str, help="""Path to the output PyTorch model.""")
				parser.add_argument(
				    """--push_to_hub""",
				    action="""store_true""",
				    help="""Whether to push the model and processor to the hub after converting""",
				)

				__snake_case								=  parser.parse_args()

				convert_blipa_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)







def 							_lowercase							(     UpperCamelCase_	,	UpperCamelCase_		)		->		str:
					'''simple docstring'''


					if not isinstance(UpperCamelCase_	,	UpperCamelCase_		):
										raise ValueError('iterations must be defined as integers'		)
					if not isinstance(UpperCamelCase_	,	UpperCamelCase_		) or not number >= 1:
										raise ValueError(
										    'starting number must be\n                         and integer and be more than 0'		)
					if not iterations >= 1:
										raise ValueError('Iterations must be done more than 0 times to play FizzBuzz'		)

					SCREAMING_SNAKE_CASE__													= ''
					while number <= iterations:
										if number % 3 == 0:
															out += "Fizz"
										if number % 5 == 0:
															out += "Buzz"
										if 0 not in (number % 3, number % 5):
															out += str(UpperCamelCase_		)

										# print(out)
										number += 1
										out += " "
					return out


if __name__ == "__main__":
				import doctest

				doctest.testmod()





