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

_UpperCAmelCase          =						logging.get_logger(__name__)




def 							UpperCamelCase		(			__lowercase		:					List[Any]		,__lowercase		:					Tuple		,__lowercase		:					List[Any]		,__lowercase		:					List[str]=None		,__lowercase		:					Any=None      ):
		'''simple docstring'''




		if "." in tensor_name:
				A_						:							List[str]      = tensor_name.split('.'      )
				for split in splits[:-1]:
						A_						:							str      = getattr(__lowercase		,__lowercase      )
						if new_module is None:
								raise ValueError(f'''{module} has no attribute {split}.'''      )
						A_						:							str      = new_module
				A_						:							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}.'''      )
		A_						:							int      = tensor_name in module._buffers
		A_						:							Optional[int]      = getattr(__lowercase		,__lowercase      )

		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}.'''      )

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

		if is_abit or is_abit:
				A_						:							Any      = module._parameters[tensor_name]
				if param.device.type != "cuda":
						if value is None:
								A_						:							Tuple      = old_value.to(__lowercase      )
						elif isinstance(__lowercase		,torch.Tensor      ):
								A_						:							Optional[int]      = value.to('cpu'      )
								if value.dtype == torch.inta:
										A_						:							Optional[Any]      = 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:
								A_						:							Any      = torch.tensor(__lowercase		,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		,__lowercase      ) and fpaa_statistics is None:
								A_						:							Optional[Any]      = new_value.T

						A_						:							Any      = old_value.__dict__
						if is_abit:
								A_						:							Optional[Any]      = bnb.nn.IntaParams(__lowercase		,requires_grad=__lowercase		,**__lowercase      ).to(__lowercase      )
						elif is_abit:
								A_						:							str      = bnb.nn.Paramsabit(__lowercase		,requires_grad=__lowercase		,**__lowercase      ).to(__lowercase      )

						A_						:							Optional[Any]      = new_value
						if fpaa_statistics is not None:
								setattr(module.weight		,'SCB'		,fpaa_statistics.to(__lowercase      )      )

		else:
				if value is None:
						A_						:							str      = old_value.to(__lowercase      )
				elif isinstance(__lowercase		,torch.Tensor      ):
						A_						:							Union[str, Any]      = value.to(__lowercase      )
				else:
						A_						:							Union[str, Any]      = torch.tensor(__lowercase		,device=__lowercase      )

				if is_buffer:
						A_						:							str      = new_value
				else:
						A_						:							Any      = nn.Parameter(__lowercase		,requires_grad=old_value.requires_grad      )
						A_						:							int      = new_value




def 							UpperCamelCase		(			__lowercase		:					List[Any]		,__lowercase		:					str=None		,__lowercase		:					Tuple=None		,__lowercase		:					Optional[int]=None		,__lowercase		:					Union[str, Any]=False      ):
		'''simple docstring'''




		for name, module in model.named_children():
				if current_key_name is None:
						A_						:							Tuple      = []
				current_key_name.append(__lowercase      )

				if (isinstance(__lowercase		,nn.Linear      ) or isinstance(__lowercase		,__lowercase      )) 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(__lowercase      ) for key in modules_to_not_convert      ):
								with init_empty_weights():
										if isinstance(__lowercase		,__lowercase      ):
												A_  ,     A_						:							Union[str, Any]      = module.weight.shape
										else:
												A_						:							Optional[int]      = module.in_features
												A_						:							Dict      = module.out_features

										if quantization_config.quantization_method() == "llm_int8":
												A_						:							Optional[int]      = bnb.nn.LinearabitLt(
												    __lowercase		,__lowercase		,module.bias is not None		,has_fpaa_weights=quantization_config.llm_inta_has_fpaa_weight		,threshold=quantization_config.llm_inta_threshold		,)
												A_						:							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:
														A_						:							List[Any]      = bnb.nn.Linearabit(
														    __lowercase		,__lowercase		,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		,)
														A_						:							List[Any]      = True
                    # Store the module class in case we need to transpose the weight later
										A_						:							Union[str, Any]      = type(__lowercase      )
										# Force requires grad to False to avoid unexpected errors
										model._modules[name].requires_grad_(__lowercase      )
				if len(list(module.children()      )      ) > 0:
						A_  ,     A_						:							int      = _replace_with_bnb_linear(
						    __lowercase		,__lowercase		,__lowercase		,__lowercase		,has_been_replaced=__lowercase		,)
				# Remove the last key for recursion
				current_key_name.pop(-1      )
		return model, has_been_replaced




def 							UpperCamelCase		(			__lowercase		:					Union[str, Any]		,__lowercase		:					List[str]=None		,__lowercase		:					int=None		,__lowercase		:					Dict=None      ):
		'''simple docstring'''




		A_						:							Dict      = ['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
		A_  ,     A_						:							List[str]      = _replace_with_bnb_linear(
		    __lowercase		,__lowercase		,__lowercase		,__lowercase      )

		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 							UpperCamelCase		(			*__lowercase		:					List[Any]		,**__lowercase		:					Union[str, Any]      ):
		'''simple docstring'''




		warnings.warn(
		    '`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead'		,__lowercase		,)
		return replace_with_bnb_linear(*__lowercase		,**__lowercase      )




def 							UpperCamelCase		(			*__lowercase		:					str		,**__lowercase		:					Any      ):
		'''simple docstring'''




		warnings.warn(
		    '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'		,__lowercase		,)
		return set_module_quantized_tensor_to_device(*__lowercase		,**__lowercase      )




def 							UpperCamelCase		(			__lowercase		:					Optional[Any]      ):
		'''simple docstring'''




		A_						:							Optional[Any]      = deepcopy(__lowercase      )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
		tied_model.tie_weights()

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

		# Check if it is a base model
		A_						:							Optional[Any]      = not hasattr(__lowercase		,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
		A_						:							str      = list(model.named_children()      )
		A_						:							List[Any]      = [list_modules[-1][0]]

		# add last module together with tied weights
		A_						:							Union[str, Any]      = set(__lowercase      ) - set(__lowercase      )
		A_						:							Optional[Any]      = list(set(__lowercase      )      ) + list(__lowercase      )

		# remove ".weight" from the keys
		A_						:							Any      = ['.weight', '.bias']
		A_						:							List[str]      = []
		for name in list_untouched:
				for name_to_remove in names_to_remove:
						if name_to_remove in name:
								A_						:							Optional[int]      = name.replace(__lowercase		,''      )
				filtered_module_names.append(__lowercase      )

		return filtered_module_names







from collections import OrderedDict
from typing import Mapping

from packaging import version

from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfig
from ...utils import logging


_UpperCAmelCase          =						logging.get_logger(__name__)

_UpperCAmelCase          =						{
    """facebook/deit-base-distilled-patch16-224""": (
        """https://huggingface.co/facebook/deit-base-patch16-224/resolve/main/config.json"""
    ),
    # See all DeiT models at https://huggingface.co/models?filter=deit
}





class UpperCAmelCase		(   __A    ):


				'''simple docstring'''






				lowerCamelCase_        =   '''deit'''
				def __init__(		self						,      lowercase=7_6_8						,      lowercase=1_2						,      lowercase=1_2						,      lowercase=3_0_7_2						,      lowercase="gelu"						,      lowercase=0.0						,      lowercase=0.0						,      lowercase=0.02						,      lowercase=1E-12						,      lowercase=2_2_4						,      lowercase=1_6						,      lowercase=3						,      lowercase=True						,      lowercase=1_6						,      **lowercase						,      ):



						"""simple docstring"""





						super().__init__(**lowercase   )

						A_						:							Dict      = hidden_size
						A_						:							List[Any]      = num_hidden_layers
						A_						:							Optional[int]      = num_attention_heads
						A_						:							List[str]      = intermediate_size
						A_						:							int      = hidden_act
						A_						:							Optional[int]      = hidden_dropout_prob
						A_						:							str      = attention_probs_dropout_prob
						A_						:							List[str]      = initializer_range
						A_						:							List[Any]      = layer_norm_eps
						A_						:							List[str]      = image_size
						A_						:							str      = patch_size
						A_						:							str      = num_channels
						A_						:							Dict      = qkv_bias
						A_						:							Optional[Any]      = encoder_stride





class UpperCAmelCase		(   __A    ):


				'''simple docstring'''






				lowerCamelCase_        =   version.parse('''1.11'''    )
				@property
				def     lowerCAmelCase_  (		self   ):



						"""simple docstring"""





						return OrderedDict(
						    [
						        ('pixel_values', {0: 'batch', 1: 'num_channels', 2: 'height', 3: 'width'}),
						    ]   )







				@property
				def     lowerCAmelCase_  (		self   ):



						"""simple docstring"""





						return 1E-4






