

import copy
import os
from typing import Union

from ...configuration_utils import PretrainedConfig
from ...models.auto.modeling_auto import MODEL_FOR_CAUSAL_LM_MAPPING_NAMES
from ...utils import logging
from ..auto import CONFIG_MAPPING


lowerCAmelCase__	   = logging.get_logger(__name__)

lowerCAmelCase__	   = {
    """salesforce/blip2-opt-2.7b""": """https://huggingface.co/salesforce/blip2-opt-2.7b/resolve/main/config.json""",
}

class 					a__						(					snake_case			):
			"""simple docstring"""







			__lowerCamelCase        =       'blip_2_vision_model'


			def __init__(    self      ,      lowercase=1408      ,      lowercase=6144      ,      lowercase=39      ,      lowercase=16      ,      lowercase=224      ,      lowercase=14      ,      lowercase="gelu"      ,      lowercase=0.0_0001      ,      lowercase=0.0      ,      lowercase=1e-10      ,      lowercase=True      ,      **lowercase      ,      )  ->						int:
							'''simple docstring'''






							super().__init__(**lowercase       )

							A__        =			hidden_size
							A__        =			intermediate_size
							A__        =			num_hidden_layers
							A__        =			num_attention_heads
							A__        =			patch_size
							A__        =			image_size
							A__        =			initializer_range
							A__        =			attention_dropout
							A__        =			layer_norm_eps
							A__        =			hidden_act
							A__        =			qkv_bias


			@classmethod
			def      UpperCamelCase		(    cls      ,      lowercase      ,      **lowercase       )  ->						"PretrainedConfig":
							'''simple docstring'''






							cls._set_token_in_kwargs(lowercase       )

							A__    ,				A__        =			cls.get_config_dict(lowercase      ,      **lowercase       )

							# get the vision config dict if we are loading from Blip2Config
							if config_dict.get("model_type"       ) == "blip-2":
											A__        =			config_dict["vision_config"]

							if "model_type" in config_dict and hasattr(cls      ,      "model_type"       ) and config_dict["model_type"] != cls.model_type:
											logger.warning(
											    F'You are using a model of type {config_dict["model_type"]} to instantiate a model of type '
											    F'{cls.model_type}. This is not supported for all configurations of models and can yield errors.'       )

							return cls.from_dict(lowercase      ,      **lowercase       )

class 					a__						(					snake_case			):
			"""simple docstring"""







			__lowerCamelCase        =       'blip_2_qformer'


			def __init__(    self      ,      lowercase=30522      ,      lowercase=768      ,      lowercase=12      ,      lowercase=12      ,      lowercase=3072      ,      lowercase="gelu"      ,      lowercase=0.1      ,      lowercase=0.1      ,      lowercase=512      ,      lowercase=0.02      ,      lowercase=1e-12      ,      lowercase=0      ,      lowercase="absolute"      ,      lowercase=2      ,      lowercase=1408      ,      **lowercase      ,      )  ->						Optional[int]:
							'''simple docstring'''






							super().__init__(pad_token_id=lowercase      ,      **lowercase       )

							A__        =			vocab_size
							A__        =			hidden_size
							A__        =			num_hidden_layers
							A__        =			num_attention_heads
							A__        =			hidden_act
							A__        =			intermediate_size
							A__        =			hidden_dropout_prob
							A__        =			attention_probs_dropout_prob
							A__        =			max_position_embeddings
							A__        =			initializer_range
							A__        =			layer_norm_eps
							A__        =			position_embedding_type
							A__        =			cross_attention_frequency
							A__        =			encoder_hidden_size


			@classmethod
			def      UpperCamelCase		(    cls      ,      lowercase      ,      **lowercase       )  ->						"PretrainedConfig":
							'''simple docstring'''






							cls._set_token_in_kwargs(lowercase       )

							A__    ,				A__        =			cls.get_config_dict(lowercase      ,      **lowercase       )

							# get the qformer config dict if we are loading from Blip2Config
							if config_dict.get("model_type"       ) == "blip-2":
											A__        =			config_dict["qformer_config"]

							if "model_type" in config_dict and hasattr(cls      ,      "model_type"       ) and config_dict["model_type"] != cls.model_type:
											logger.warning(
											    F'You are using a model of type {config_dict["model_type"]} to instantiate a model of type '
											    F'{cls.model_type}. This is not supported for all configurations of models and can yield errors.'       )

							return cls.from_dict(lowercase      ,      **lowercase       )

class 					a__						(					snake_case			):
			"""simple docstring"""







			__lowerCamelCase        =       'blip-2'
			__lowerCamelCase        =       True


			def __init__(    self      ,      lowercase=None      ,      lowercase=None      ,      lowercase=None      ,      lowercase=32      ,      **lowercase       )  ->						Union[str, Any]:
							'''simple docstring'''






							super().__init__(**lowercase       )

							if vision_config is None:
											A__        =			{}
											logger.info("vision_config is None. initializing the Blip2VisionConfig with default values."       )

							if qformer_config is None:
											A__        =			{}
											logger.info("qformer_config is None. Initializing the Blip2QFormerConfig with default values."       )

							if text_config is None:
											A__        =			{}
											logger.info("text_config is None. Initializing the text config with default values (`OPTConfig`)."       )

							A__        =			BlipaVisionConfig(**lowercase       )
							A__        =			BlipaQFormerConfig(**lowercase       )
							A__        =			text_config["model_type"] if "model_type" in text_config else "opt"
							A__        =			CONFIG_MAPPING[text_model_type](**lowercase       )

							A__        =			self.text_config.tie_word_embeddings
							A__        =			self.text_config.is_encoder_decoder

							A__        =			num_query_tokens
							A__        =			self.vision_config.hidden_size
							A__        =			self.text_config.model_type in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES
							A__        =			1.0
							A__        =			0.02


			@classmethod
			def      UpperCamelCase		(    cls      ,      lowercase      ,      lowercase      ,      lowercase      ,      **lowercase      ,      )  ->						Tuple:
							'''simple docstring'''






							return cls(
							    vision_config=vision_config.to_dict()      ,      qformer_config=qformer_config.to_dict()      ,      text_config=text_config.to_dict()      ,      **lowercase      ,      )


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






							A__        =			copy.deepcopy(self.__dict__       )
							A__        =			self.vision_config.to_dict()
							A__        =			self.qformer_config.to_dict()
							A__        =			self.text_config.to_dict()
							A__        =			self.__class__.model_type
							return output




lowerCAmelCase__	   = """ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"""



def 					lowerCAmelCase__							(	SCREAMING_SNAKE_CASE_:							bytes      )			->      bytes:




				'''simple docstring'''





				if not isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ):
								A__        =			F'a bytes-like object is required, not \'{data.__class__.__name__}\''
								raise TypeError(SCREAMING_SNAKE_CASE_      )

				A__        =			"".join(bin(SCREAMING_SNAKE_CASE_      )[2:].zfill(8      ) for byte in data      )

				A__        =			len(SCREAMING_SNAKE_CASE_      ) % 6 != 0

				if padding_needed:
								# The padding that will be added later
								A__        =			b"=" * ((6 - len(SCREAMING_SNAKE_CASE_      ) % 6) // 2)

								# Append binary_stream with arbitrary binary digits (0's by default) to make its
								# length a multiple of 6.
								binary_stream += "0" * (6 - len(SCREAMING_SNAKE_CASE_      ) % 6)
				else:
								A__        =			b""

				# Encode every 6 binary digits to their corresponding Base64 character
				return (
				    "".join(
				        B64_CHARSET[int(binary_stream[index : index + 6]	,       2      )]
				        for index in range(0	,       len(SCREAMING_SNAKE_CASE_      )	,       6      )      ).encode()
				    + padding
				)



def 					lowerCAmelCase__							(	SCREAMING_SNAKE_CASE_:							str      )			->      bytes:




				'''simple docstring'''





				if not isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ) and not isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ):
								A__        =			(
								    "argument should be a bytes-like object or ASCII string, "
								    F'not \'{encoded_data.__class__.__name__}\''
								)
								raise TypeError(SCREAMING_SNAKE_CASE_      )

				# In case encoded_data is a bytes-like object, make sure it contains only
				# ASCII characters so we convert it to a string object
				if isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ):
								try:
												A__        =			encoded_data.decode("utf-8"      )
								except UnicodeDecodeError:
												raise ValueError("base64 encoded data should only contain ASCII characters"      )

				A__        =			encoded_data.count("="      )

				# Check if the encoded string contains non base64 characters
				if padding:
								assert all(
								    char in B64_CHARSET for char in encoded_data[:-padding]      ), "Invalid base64 character(s) found."
				else:
								assert all(
								    char in B64_CHARSET for char in encoded_data      ), "Invalid base64 character(s) found."

				# Check the padding
				assert len(SCREAMING_SNAKE_CASE_      ) % 4 == 0 and padding < 3, "Incorrect padding"

				if padding:
								# Remove padding if there is one
								A__        =			encoded_data[:-padding]

								A__        =			"".join(
								    bin(B64_CHARSET.index(SCREAMING_SNAKE_CASE_      )      )[2:].zfill(6      ) for char in encoded_data      )[: -padding * 2]
				else:
								A__        =			"".join(
								    bin(B64_CHARSET.index(SCREAMING_SNAKE_CASE_      )      )[2:].zfill(6      ) for char in encoded_data      )

				A__        =			[
				    int(binary_stream[index : index + 8]	,       2      )
				    for index in range(0	,       len(SCREAMING_SNAKE_CASE_      )	,       8      )
				]

				return bytes(SCREAMING_SNAKE_CASE_      )


if __name__ == "__main__":
	import doctest

	doctest.testmod()

