





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 						lowerCamelCase__     (     )			-> int:



					'''simple docstring'''




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

					return image





def 						lowerCamelCase__     (     UpperCamelCase__			:       Any						)			-> List[str]:



					'''simple docstring'''




					_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 						lowerCamelCase__     (     UpperCamelCase__			:       List[Any]       ,    UpperCamelCase__			:       List[str]       ,    UpperCamelCase__			:       Optional[int]						)			-> Optional[int]:



					'''simple docstring'''




					_snake_case									=				dct.pop(UpperCamelCase__						)
					_snake_case									=				val





def 						lowerCamelCase__     (     UpperCamelCase__			:       Optional[int]       ,    UpperCamelCase__			:       List[Any]						)			-> List[str]:



					'''simple docstring'''




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

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





def 						lowerCamelCase__     (     UpperCamelCase__			:       List[Any]       ,    UpperCamelCase__			:       Optional[Any]						)			-> int:



					'''simple docstring'''




					_snake_case									=				364 if 'coco' in model_name else 224
					_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:
										_snake_case									=				OPTConfig.from_pretrained('facebook/opt-2.7b'       ,    eos_token_id=UpperCamelCase__						).to_dict()
					elif "opt-6.7b" in model_name:
										_snake_case									=				OPTConfig.from_pretrained('facebook/opt-6.7b'       ,    eos_token_id=UpperCamelCase__						).to_dict()
					elif "t5-xl" in model_name:
										_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:
										_snake_case									=				TaConfig.from_pretrained('google/flan-t5-xxl'       ,    dense_act_fn='gelu'       ,    bos_token_id=1						).to_dict()

					_snake_case									=				BlipaConfig(vision_config=UpperCamelCase__       ,    text_config=UpperCamelCase__						)

					return config, image_size





@torch.no_grad()
def 						lowerCamelCase__     (     UpperCamelCase__			:       Union[str, Any]       ,    UpperCamelCase__			:       Union[str, Any]=None       ,    UpperCamelCase__			:       Dict=False						)			-> Optional[Any]:



					'''simple docstring'''




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

					_snake_case									=				BlipaForConditionalGeneration(UpperCamelCase__						).eval()

					_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'),
					}

					_snake_case							,     _snake_case									=				model_name_to_original[model_name]

					# load original model
					print('Loading original model...'						)
					_snake_case									=				'cuda' if torch.cuda.is_available() else 'cpu'
					_snake_case							,     _snake_case							,     _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
					_snake_case									=				original_model.state_dict()
					_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():
										_snake_case									=				state_dict.pop(UpperCamelCase__						)
										if key.startswith('Qformer.bert'						):
															_snake_case									=				key.replace('Qformer.bert'       ,    'qformer'						)
										if "attention.self" in key:
															_snake_case									=				key.replace('self'       ,    'attention'						)
										if "opt_proj" in key:
															_snake_case									=				key.replace('opt_proj'       ,    'language_projection'						)
										if "t5_proj" in key:
															_snake_case									=				key.replace('t5_proj'       ,    'language_projection'						)
										if key.startswith('opt'						):
															_snake_case									=				key.replace('opt'       ,    'language'						)
										if key.startswith('t5'						):
															_snake_case									=				key.replace('t5'       ,    'language'						)
										_snake_case									=				val

					# read in qv biases
					read_in_q_v_bias(UpperCamelCase__       ,    UpperCamelCase__						)

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

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

					# create processor
					_snake_case									=				BlipImageProcessor(
					    size={'height': image_size, 'width': image_size}       ,    image_mean=UpperCamelCase__       ,    image_std=UpperCamelCase__						)
					_snake_case									=				BlipaProcessor(image_processor=UpperCamelCase__       ,    tokenizer=UpperCamelCase__						)
					_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:
															_snake_case									=				original_model({'image': original_pixel_values, 'text_input': ['']}						).logits
															_snake_case									=				hf_model(UpperCamelCase__       ,    UpperCamelCase__						).logits
										else:
															_snake_case									=				original_model(
															    {'image': original_pixel_values, 'text_input': ['\n'], 'text_output': ['\n']}						).logits
															_snake_case									=				input_ids.masked_fill(input_ids == tokenizer.pad_token_id       ,    -100						)
															_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":
										_snake_case									=				torch.tensor(
										    [[-41.5850, -4.4440, -8.9922], [-47.4322, -5.9143, -1.7340]]       ,    device=UpperCamelCase__						)
										assert torch.allclose(logits[0, :3, :3]       ,    UpperCamelCase__       ,    atol=1e-4						)
					elif model_name == "blip2-flan-t5-xl-coco":
										_snake_case									=				torch.tensor(
										    [[-57.0109, -9.8967, -12.6280], [-68.6578, -12.7191, -10.5065]]       ,    device=UpperCamelCase__						)
					else:
										# cast to same type
										_snake_case									=				logits.dtype
										assert torch.allclose(original_logits.to(UpperCamelCase__						)       ,    UpperCamelCase__       ,    atol=1e-2						)
					print('Looks ok!'						)

					print('Generating a caption...'						)
					_snake_case									=				''
					_snake_case									=				tokenizer(UpperCamelCase__       ,    return_tensors='pt'						).input_ids.to(UpperCamelCase__						)

					_snake_case									=				original_model.generate({'image': original_pixel_values}						)
					_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__						)
					_snake_case									=				input_ids.shape[1]
					_snake_case									=				processor.batch_decode(outputs[:, prompt_length:]       ,    skip_special_tokens=UpperCamelCase__						)
					_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__":
					UpperCAmelCase_      							=						argparse.ArgumentParser()
					UpperCAmelCase_      							=						[
					    """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""",
					)

					UpperCAmelCase_      							=						parser.parse_args()

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










UpperCAmelCase_      							=     range(2, 20 + 1)
UpperCAmelCase_      							=     [10**k for k in range(ks[-1] + 1)]
UpperCAmelCase_      							=     {}





def 						lowerCamelCase__     (     UpperCamelCase__			:       Optional[Any]       ,    UpperCamelCase__			:       List[Any]       ,    UpperCamelCase__			:       Union[str, Any]       ,    UpperCamelCase__			:       str						)			-> List[str]:



					'''simple docstring'''




					_snake_case									=				sum(a_i[j] for j in range(UpperCamelCase__       ,    len(UpperCamelCase__						)						)						)
					_snake_case									=				sum(a_i[j] * base[j] for j in range(min(len(UpperCamelCase__						)       ,    UpperCamelCase__						)						)						)

					_snake_case							,     _snake_case									=				0, 0
					_snake_case									=				n - i

					_snake_case									=				memo.get(UpperCamelCase__						)

					if sub_memo is not None:
										_snake_case									=				sub_memo.get(UpperCamelCase__						)

										if jumps is not None and len(UpperCamelCase__						) > 0:
															# find and make the largest jump without going over
															_snake_case									=				-1
															for _k in range(len(UpperCamelCase__						) - 1       ,    -1       ,    -1						):
																				if jumps[_k][2] <= k and jumps[_k][1] <= max_dn:
																									_snake_case									=				_k
																									break

															if max_jump >= 0:
																				_snake_case							,     _snake_case							,     _snake_case									=				jumps[max_jump]
																				# since the difference between jumps is cached, add c
																				_snake_case									=				diff + c
																				for j in range(min(UpperCamelCase__       ,    len(UpperCamelCase__						)						)						):
																									_snake_case							,     _snake_case									=				divmod(UpperCamelCase__       ,    10						)
																				if new_c > 0:
																									add(UpperCamelCase__       ,    UpperCamelCase__       ,    UpperCamelCase__						)

										else:
															_snake_case									=				[]
					else:
										_snake_case									=				{c: []}
										_snake_case									=				sub_memo

					if dn >= max_dn or c + diff >= base[k]:
										return diff, dn

					if k > ks[0]:
										while True:
															# keep doing smaller jumps
															_snake_case							,     _snake_case									=				next_term(UpperCamelCase__       ,    k - 1       ,    i + dn       ,    UpperCamelCase__						)
															diff += _diff
															dn += terms_jumped

															if dn >= max_dn or c + diff >= base[k]:
																				break
					else:
										# would be too small a jump, just compute sequential terms instead
										_snake_case							,     _snake_case									=				compute(UpperCamelCase__       ,    UpperCamelCase__       ,    i + dn       ,    UpperCamelCase__						)
										diff += _diff
										dn += terms_jumped

					_snake_case									=				sub_memo[c]

					# keep jumps sorted by # of terms skipped
					_snake_case									=				0
					while j < len(UpperCamelCase__						):
										if jumps[j][1] > dn:
															break
										j += 1

					# cache the jump for this value digitsum(b) and c
					sub_memo[c].insert(UpperCamelCase__       ,    (diff, dn, k)						)
					return (diff, dn)





def 						lowerCamelCase__     (     UpperCamelCase__			:       str       ,    UpperCamelCase__			:       str       ,    UpperCamelCase__			:       List[str]       ,    UpperCamelCase__			:       Union[str, Any]						)			-> Optional[Any]:



					'''simple docstring'''




					if i >= n:
										return 0, i
					if k > len(UpperCamelCase__						):
										a_i.extend([0 for _ in range(k - len(UpperCamelCase__						)						)]						)

					# note: a_i -> b * 10^k + c
					# ds_b -> digitsum(b)
					# ds_c -> digitsum(c)
					_snake_case									=				i
					_snake_case							,     _snake_case							,     _snake_case									=				0, 0, 0
					for j in range(len(UpperCamelCase__						)						):
										if j >= k:
															ds_b += a_i[j]
										else:
															ds_c += a_i[j]

					while i < n:
										i += 1
										_snake_case									=				ds_c + ds_b
										diff += addend
										_snake_case									=				0
										for j in range(UpperCamelCase__						):
															_snake_case									=				a_i[j] + addend
															_snake_case							,     _snake_case									=				divmod(UpperCamelCase__       ,    10						)

															ds_c += a_i[j]

										if addend > 0:
															break

					if addend > 0:
										add(UpperCamelCase__       ,    UpperCamelCase__       ,    UpperCamelCase__						)
					return diff, i - start_i





def 						lowerCamelCase__     (     UpperCamelCase__			:       Any       ,    UpperCamelCase__			:       Union[str, Any]       ,    UpperCamelCase__			:       Optional[Any]						)			-> Any:



					'''simple docstring'''




					for j in range(UpperCamelCase__       ,    len(UpperCamelCase__						)						):
										_snake_case									=				digits[j] + addend
										if s >= 10:
															_snake_case							,     _snake_case									=				divmod(UpperCamelCase__       ,    10						)
															_snake_case									=				addend // 10 + quotient
										else:
															_snake_case									=				s
															_snake_case									=				addend // 10

										if addend == 0:
															break

					while addend > 0:
										_snake_case							,     _snake_case									=				divmod(UpperCamelCase__       ,    10						)
										digits.append(UpperCamelCase__						)





def 						lowerCamelCase__     (     UpperCamelCase__			:       int = 10**15						)			-> int:



					'''simple docstring'''




					_snake_case									=				[1]
					_snake_case									=				1
					_snake_case									=				0
					while True:
										_snake_case							,     _snake_case									=				next_term(UpperCamelCase__       ,    20       ,    i + dn       ,    UpperCamelCase__						)
										dn += terms_jumped
										if dn == n - i:
															break

					_snake_case									=				0
					for j in range(len(UpperCamelCase__						)						):
										a_n += digits[j] * 10**j
					return a_n


if __name__ == "__main__":
					print(F"{solution() = }")



