


'''simple docstring'''


import importlib.metadata
import warnings
from copy import deepcopy

from packaging import version

from ..utils import logging
from .import_utils import is_accelerate_available, is_bitsandbytes_available


if is_bitsandbytes_available():
						import bitsandbytes as bnb
						import torch
						import torch.nn as nn

						from ..pytorch_utils import ConvaD

if is_accelerate_available():
						from accelerate import init_empty_weights
						from accelerate.utils import find_tied_parameters

lowerCamelCase__    	=     logging.get_logger(__name__)






def  __lowerCAmelCase (__lowerCAmelCase      , __lowerCAmelCase      , __lowerCAmelCase      , __lowerCAmelCase=None      , __lowerCAmelCase=None   ):
		# Recurse if needed
		if "." in tensor_name:
				_UpperCAmelCase		:       Optional[Any]								=      tensor_name.split("."   )
				for split in splits[:-1]:
						_UpperCAmelCase		:       int								=      getattr(__lowerCAmelCase      , __lowerCAmelCase   )
						if new_module is None:
								raise ValueError(F"""{module} has no attribute {split}."""   )
						_UpperCAmelCase		:       Optional[Any]								=      new_module
				_UpperCAmelCase		:       Dict								=      splits[-1]

		if tensor_name not in module._parameters and tensor_name not in module._buffers:
				raise ValueError(F"""{module} does not have a parameter or a buffer named {tensor_name}."""   )
		_UpperCAmelCase		:       List[str]								=      tensor_name in module._buffers
		_UpperCAmelCase		:       Optional[int]								=      getattr(__lowerCAmelCase      , __lowerCAmelCase   )

		if old_value.device == torch.device("meta"   ) and device not in ["meta", torch.device("meta"   )] and value is None:
				raise ValueError(F"""{tensor_name} is on the meta device, we need a `value` to put in on {device}."""   )

		_UpperCAmelCase		:       List[str]								=      False
		_UpperCAmelCase		:       List[Any]								=      False
		if is_buffer or not is_bitsandbytes_available():
				_UpperCAmelCase		:       Dict								=      False
				_UpperCAmelCase		:       str								=      False
		else:
				_UpperCAmelCase		:       Tuple								=      hasattr(bnb.nn      , "Params4bit"   ) and isinstance(module._parameters[tensor_name]      , bnb.nn.Paramsabit   )
				_UpperCAmelCase		:       Dict								=      isinstance(module._parameters[tensor_name]      , bnb.nn.IntaParams   )

		if is_abit or is_abit:
				_UpperCAmelCase		:       List[Any]								=      module._parameters[tensor_name]
				if param.device.type != "cuda":
						if value is None:
								_UpperCAmelCase		:       str								=      old_value.to(__lowerCAmelCase   )
						elif isinstance(__lowerCAmelCase      , torch.Tensor   ):
								_UpperCAmelCase		:       Optional[int]								=      value.to("cpu"   )
								if value.dtype == torch.inta:
										_UpperCAmelCase		:       str								=      version.parse(importlib.metadata.version("bitsandbytes"   )   ) > version.parse(
										    "0.37.2"   )
										if not is_abit_serializable:
												raise ValueError(
												    "Detected int8 weights but the version of bitsandbytes is not compatible with int8 serialization. "
												    "Make sure to download the latest `bitsandbytes` version. `pip install --upgrade bitsandbytes`."   )
						else:
								_UpperCAmelCase		:       List[str]								=      torch.tensor(__lowerCAmelCase      , device="cpu"   )

						# Support models using `Conv1D` in place of `nn.Linear` (e.g. gpt2) by transposing the weight matrix prior to quantization.
						# Since weights are saved in the correct "orientation", we skip transposing when loading.
						if issubclass(module.source_cls      , __lowerCAmelCase   ) and fpaa_statistics is None:
								_UpperCAmelCase		:       str								=      new_value.T

						_UpperCAmelCase		:       Union[str, Any]								=      old_value.__dict__
						if is_abit:
								_UpperCAmelCase		:       Dict								=      bnb.nn.IntaParams(__lowerCAmelCase      , requires_grad=__lowerCAmelCase      , **__lowerCAmelCase   ).to(__lowerCAmelCase   )
						elif is_abit:
								_UpperCAmelCase		:       Tuple								=      bnb.nn.Paramsabit(__lowerCAmelCase      , requires_grad=__lowerCAmelCase      , **__lowerCAmelCase   ).to(__lowerCAmelCase   )

						_UpperCAmelCase		:       List[str]								=      new_value
						if fpaa_statistics is not None:
								setattr(module.weight      , "SCB"      , fpaa_statistics.to(__lowerCAmelCase   )   )

		else:
				if value is None:
						_UpperCAmelCase		:       Optional[int]								=      old_value.to(__lowerCAmelCase   )
				elif isinstance(__lowerCAmelCase      , torch.Tensor   ):
						_UpperCAmelCase		:       Optional[Any]								=      value.to(__lowerCAmelCase   )
				else:
						_UpperCAmelCase		:       List[Any]								=      torch.tensor(__lowerCAmelCase      , device=__lowerCAmelCase   )

				if is_buffer:
						_UpperCAmelCase		:       str								=      new_value
				else:
						_UpperCAmelCase		:       Optional[Any]								=      nn.Parameter(__lowerCAmelCase      , requires_grad=old_value.requires_grad   )
						_UpperCAmelCase		:       Any								=      new_value






def  __lowerCAmelCase (__lowerCAmelCase      , __lowerCAmelCase=None      , __lowerCAmelCase=None      , __lowerCAmelCase=None      , __lowerCAmelCase=False   ):
		for name, module in model.named_children():
				if current_key_name is None:
						_UpperCAmelCase		:       str								=      []
				current_key_name.append(__lowerCAmelCase   )

				if (isinstance(__lowerCAmelCase      , nn.Linear   ) or isinstance(__lowerCAmelCase      , __lowerCAmelCase   )) and name not in modules_to_not_convert:
						# Check if the current key is not in the `modules_to_not_convert`
						if not any(key in ".".join(__lowerCAmelCase   ) for key in modules_to_not_convert   ):
								with init_empty_weights():
										if isinstance(__lowerCAmelCase      , __lowerCAmelCase   ):
												_UpperCAmelCase					,    _UpperCAmelCase		:       Any								=      module.weight.shape
										else:
												_UpperCAmelCase		:       Optional[Any]								=      module.in_features
												_UpperCAmelCase		:       str								=      module.out_features

										if quantization_config.quantization_method() == "llm_int8":
												_UpperCAmelCase		:       Optional[int]								=      bnb.nn.LinearabitLt(
												    __lowerCAmelCase      , __lowerCAmelCase      , module.bias is not None      , has_fpaa_weights=quantization_config.llm_inta_has_fpaa_weight      , threshold=quantization_config.llm_inta_threshold      , )
												_UpperCAmelCase		:       Optional[int]								=      True
										else:
												if (
												    quantization_config.llm_inta_skip_modules is not None
												    and name in quantization_config.llm_inta_skip_modules
												):
														pass
												else:
														_UpperCAmelCase		:       Dict								=      bnb.nn.Linearabit(
														    __lowerCAmelCase      , __lowerCAmelCase      , module.bias is not None      , quantization_config.bnb_abit_compute_dtype      , compress_statistics=quantization_config.bnb_abit_use_double_quant      , quant_type=quantization_config.bnb_abit_quant_type      , )
														_UpperCAmelCase		:       Optional[Any]								=      True
                    # Store the module class in case we need to transpose the weight later
										_UpperCAmelCase		:       List[Any]								=      type(__lowerCAmelCase   )
										# Force requires grad to False to avoid unexpected errors
										model._modules[name].requires_grad_(__lowerCAmelCase   )
				if len(list(module.children()   )   ) > 0:
						_UpperCAmelCase					,    _UpperCAmelCase		:       str								=      _replace_with_bnb_linear(
						    __lowerCAmelCase      , __lowerCAmelCase      , __lowerCAmelCase      , __lowerCAmelCase      , has_been_replaced=__lowerCAmelCase      , )
				# Remove the last key for recursion
				current_key_name.pop(-1   )
		return model, has_been_replaced






def  __lowerCAmelCase (__lowerCAmelCase      , __lowerCAmelCase=None      , __lowerCAmelCase=None      , __lowerCAmelCase=None   ):
		_UpperCAmelCase		:       List[Any]								=      ["lm_head"] if modules_to_not_convert is None else modules_to_not_convert
		_UpperCAmelCase					,    _UpperCAmelCase		:       Any								=      _replace_with_bnb_linear(
		    __lowerCAmelCase      , __lowerCAmelCase      , __lowerCAmelCase      , __lowerCAmelCase   )

		if not has_been_replaced:
				logger.warning(
				    "You are loading your model in 8bit or 4bit but no linear modules were found in your model."
				    " Please double check your model architecture, or submit an issue on github if you think this is"
				    " a bug."   )

		return model






def  __lowerCAmelCase (*__lowerCAmelCase      , **__lowerCAmelCase   ):
		warnings.warn(
		    "`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead"      , __lowerCAmelCase      , )
		return replace_with_bnb_linear(*__lowerCAmelCase      , **__lowerCAmelCase   )






def  __lowerCAmelCase (*__lowerCAmelCase      , **__lowerCAmelCase   ):
		warnings.warn(
		    "`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead"      , __lowerCAmelCase      , )
		return set_module_quantized_tensor_to_device(*__lowerCAmelCase      , **__lowerCAmelCase   )






def  __lowerCAmelCase (__lowerCAmelCase   ):
		_UpperCAmelCase		:       Dict								=      deepcopy(__lowerCAmelCase   )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
		tied_model.tie_weights()

		_UpperCAmelCase		:       Tuple								=      find_tied_parameters(__lowerCAmelCase   )
		# For compatibility with Accelerate < 0.18
		if isinstance(__lowerCAmelCase      , __lowerCAmelCase   ):
				_UpperCAmelCase		:       List[str]								=      sum(list(tied_params.values()   )      , []   ) + list(tied_params.keys()   )
		else:
				_UpperCAmelCase		:       Optional[int]								=      sum(__lowerCAmelCase      , []   )
		_UpperCAmelCase		:       Union[str, Any]								=      len(__lowerCAmelCase   ) > 0

		# Check if it is a base model
		_UpperCAmelCase		:       Any								=      not hasattr(__lowerCAmelCase      , model.base_model_prefix   )

		# Ignore this for base models (BertModel, GPT2Model, etc.)
		if (not has_tied_params) and is_base_model:
				return []

		# otherwise they have an attached head
		_UpperCAmelCase		:       Optional[Any]								=      list(model.named_children()   )
		_UpperCAmelCase		:       Dict								=      [list_modules[-1][0]]

		# add last module together with tied weights
		_UpperCAmelCase		:       Dict								=      set(__lowerCAmelCase   ) - set(__lowerCAmelCase   )
		_UpperCAmelCase		:       int								=      list(set(__lowerCAmelCase   )   ) + list(__lowerCAmelCase   )

		# remove ".weight" from the keys
		_UpperCAmelCase		:       List[Any]								=      [".weight", ".bias"]
		_UpperCAmelCase		:       Union[str, Any]								=      []
		for name in list_untouched:
				for name_to_remove in names_to_remove:
						if name_to_remove in name:
								_UpperCAmelCase		:       Any								=      name.replace(__lowerCAmelCase      , ""   )
				filtered_module_names.append(__lowerCAmelCase   )

		return filtered_module_names







'''simple docstring'''


from typing import List, Optional, Union

from ...image_utils import ImageInput
from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding, PaddingStrategy, PreTokenizedInput, TextInput, TruncationStrategy
from ...utils import TensorType






class 	lowerCAmelCase__			(			UpperCAmelCase__	):
			lowerCAmelCase :	Any          =     ["image_processor", "tokenizer"]
			lowerCAmelCase :	List[Any]          =     "BlipImageProcessor"
			lowerCAmelCase :	Union[str, Any]          =     "AutoTokenizer"




			def __init__(		self  :     Any	,  lowerCamelCase__  :     Tuple	,  lowerCamelCase__  :     int )   ->Optional[int]:



					'''simple docstring'''







					_UpperCAmelCase		:       Optional[int]								=      False
					super().__init__(lowerCamelCase__	,  lowerCamelCase__ )
					_UpperCAmelCase		:       Tuple								=      self.image_processor




			def __call__(		self  :     Dict	,  lowerCamelCase__  :     ImageInput = None	,  lowerCamelCase__  :     Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None	,  lowerCamelCase__  :     bool = True	,  lowerCamelCase__  :     Union[bool, str, PaddingStrategy] = False	,  lowerCamelCase__  :     Union[bool, str, TruncationStrategy] = None	,  lowerCamelCase__  :     Optional[int] = None	,  lowerCamelCase__  :     int = 0	,  lowerCamelCase__  :     Optional[int] = None	,  lowerCamelCase__  :     Optional[bool] = None	,  lowerCamelCase__  :     bool = False	,  lowerCamelCase__  :     bool = False	,  lowerCamelCase__  :     bool = False	,  lowerCamelCase__  :     bool = False	,  lowerCamelCase__  :     bool = False	,  lowerCamelCase__  :     bool = True	,  lowerCamelCase__  :     Optional[Union[str, TensorType]] = None	,  **lowerCamelCase__  :     Tuple	,  )   ->BatchEncoding:



					'''simple docstring'''







					if images is None and text is None:
							raise ValueError("You have to specify either images or text." )

					# Get only text
					if images is None:
							_UpperCAmelCase		:       Optional[int]								=      self.tokenizer
							_UpperCAmelCase		:       List[Any]								=      self.tokenizer(
							    text=lowerCamelCase__	,  add_special_tokens=lowerCamelCase__	,  padding=lowerCamelCase__	,  truncation=lowerCamelCase__	,  max_length=lowerCamelCase__	,  stride=lowerCamelCase__	,  pad_to_multiple_of=lowerCamelCase__	,  return_attention_mask=lowerCamelCase__	,  return_overflowing_tokens=lowerCamelCase__	,  return_special_tokens_mask=lowerCamelCase__	,  return_offsets_mapping=lowerCamelCase__	,  return_token_type_ids=lowerCamelCase__	,  return_length=lowerCamelCase__	,  verbose=lowerCamelCase__	,  return_tensors=lowerCamelCase__	,  **lowerCamelCase__	,  )
							return text_encoding

					# add pixel_values
					_UpperCAmelCase		:       Optional[int]								=      self.image_processor(lowerCamelCase__	,  return_tensors=lowerCamelCase__ )

					if text is not None:
							_UpperCAmelCase		:       Dict								=      self.tokenizer(
							    text=lowerCamelCase__	,  add_special_tokens=lowerCamelCase__	,  padding=lowerCamelCase__	,  truncation=lowerCamelCase__	,  max_length=lowerCamelCase__	,  stride=lowerCamelCase__	,  pad_to_multiple_of=lowerCamelCase__	,  return_attention_mask=lowerCamelCase__	,  return_overflowing_tokens=lowerCamelCase__	,  return_special_tokens_mask=lowerCamelCase__	,  return_offsets_mapping=lowerCamelCase__	,  return_token_type_ids=lowerCamelCase__	,  return_length=lowerCamelCase__	,  verbose=lowerCamelCase__	,  return_tensors=lowerCamelCase__	,  **lowerCamelCase__	,  )
					else:
							_UpperCAmelCase		:       int								=      None

					if text_encoding is not None:
							encoding_image_processor.update(lowerCamelCase__ )

					return encoding_image_processor




			def 							lowerCAmelCase__    (		self  :     List[Any]	,  *lowerCamelCase__  :     Optional[int]	,  **lowerCamelCase__  :     Dict )   ->Optional[Any]:



					'''simple docstring'''







					return self.tokenizer.batch_decode(*lowerCamelCase__	,  **lowerCamelCase__ )




			def 							lowerCAmelCase__    (		self  :     int	,  *lowerCamelCase__  :     Dict	,  **lowerCamelCase__  :     str )   ->Optional[int]:



					'''simple docstring'''







					return self.tokenizer.decode(*lowerCamelCase__	,  **lowerCamelCase__ )






			@property
			# Copied from transformers.models.blip.processing_blip.BlipProcessor.model_input_names
			def 							lowerCAmelCase__    (		self  :     Any )   ->Optional[int]:



					'''simple docstring'''







					_UpperCAmelCase		:       Optional[Any]								=      self.tokenizer.model_input_names
					_UpperCAmelCase		:       Dict								=      self.image_processor.model_input_names
					return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names ) )



