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_    :		Union[str, Any]							=	logging.get_logger(__name__)
def 							lowerCAmelCase(     __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase=None				,    __lowerCamelCase=None						):
					# Recurse if needed
					if "." in tensor_name:
										__a		 =       tensor_name.split('.'						)
										for split in splits[:-1]:
															__a		 =       getattr(__lowerCamelCase				,    __lowerCamelCase						)
															if new_module is None:
																				raise ValueError(f'''{module} has no attribute {split}.'''						)
															__a		 =       new_module
										__a		 =       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		 =       tensor_name in module._buffers
					__a		 =       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}.'''						)

					__a		 =       False
					__a		 =       False
					if is_buffer or not is_bitsandbytes_available():
										__a		 =       False
										__a		 =       False
					else:
										__a		 =       hasattr(bnb.nn				,    'Params4bit'						) and isinstance(module._parameters[tensor_name]				,    bnb.nn.Paramsabit						)
										__a		 =       isinstance(module._parameters[tensor_name]				,    bnb.nn.IntaParams						)

					if is_abit or is_abit:
										__a		 =       module._parameters[tensor_name]
										if param.device.type != "cuda":
															if value is None:
																				__a		 =       old_value.to(__lowerCamelCase						)
															elif isinstance(__lowerCamelCase				,    torch.Tensor						):
																				__a		 =       value.to('cpu'						)
																				if value.dtype == torch.inta:
																									__a		 =       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		 =       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:
																				__a		 =       new_value.T

															__a		 =       old_value.__dict__
															if is_abit:
																				__a		 =       bnb.nn.IntaParams(__lowerCamelCase				,    requires_grad=__lowerCamelCase				,    **__lowerCamelCase						).to(__lowerCamelCase						)
															elif is_abit:
																				__a		 =       bnb.nn.Paramsabit(__lowerCamelCase				,    requires_grad=__lowerCamelCase				,    **__lowerCamelCase						).to(__lowerCamelCase						)

															__a		 =       new_value
															if fpaa_statistics is not None:
																				setattr(module.weight				,    'SCB'				,    fpaa_statistics.to(__lowerCamelCase						)						)

					else:
										if value is None:
															__a		 =       old_value.to(__lowerCamelCase						)
										elif isinstance(__lowerCamelCase				,    torch.Tensor						):
															__a		 =       value.to(__lowerCamelCase						)
										else:
															__a		 =       torch.tensor(__lowerCamelCase				,    device=__lowerCamelCase						)

										if is_buffer:
															__a		 =       new_value
										else:
															__a		 =       nn.Parameter(__lowerCamelCase				,    requires_grad=old_value.requires_grad						)
															__a		 =       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:
															__a		 =       []
										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						):
																														__a ,				__a		 =       module.weight.shape
																									else:
																														__a		 =       module.in_features
																														__a		 =       module.out_features

																									if quantization_config.quantization_method() == "llm_int8":
																														__a		 =       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				,    )
																														__a		 =       True
																									else:
																														if (
																														    quantization_config.llm_inta_skip_modules is not None
																														    and name in quantization_config.llm_inta_skip_modules
																														):
																																			pass
																														else:
																																			__a		 =       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				,    )
																																			__a		 =       True
                    # Store the module class in case we need to transpose the weight later
																									__a		 =       type(__lowerCamelCase						)
																									# Force requires grad to False to avoid unexpected errors
																									model._modules[name].requires_grad_(__lowerCamelCase						)
										if len(list(module.children()						)						) > 0:
															__a ,				__a		 =       _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						):
					__a		 =       ['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
					__a ,				__a		 =       _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						):
					__a		 =       deepcopy(__lowerCamelCase						)  # this has 0 cost since it is done inside `init_empty_weights` context manager`
					tied_model.tie_weights()

					__a		 =       find_tied_parameters(__lowerCamelCase						)
					# For compatibility with Accelerate < 0.18
					if isinstance(__lowerCamelCase				,    __lowerCamelCase						):
										__a		 =       sum(list(tied_params.values()						)				,    []						) + list(tied_params.keys()						)
					else:
										__a		 =       sum(__lowerCamelCase				,    []						)
					__a		 =       len(__lowerCamelCase						) > 0

					# Check if it is a base model
					__a		 =       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
					__a		 =       list(model.named_children()						)
					__a		 =       [list_modules[-1][0]]

					# add last module together with tied weights
					__a		 =       set(__lowerCamelCase						) - set(__lowerCamelCase						)
					__a		 =       list(set(__lowerCamelCase						)						) + list(__lowerCamelCase						)

					# remove ".weight" from the keys
					__a		 =       ['.weight', '.bias']
					__a		 =       []
					for name in list_untouched:
										for name_to_remove in names_to_remove:
															if name_to_remove in name:
																				__a		 =       name.replace(__lowerCamelCase				,    ''						)
										filtered_module_names.append(__lowerCamelCase						)

					return filtered_module_names






from typing import TYPE_CHECKING

from ...file_utils import _LazyModule, is_tokenizers_available, is_torch_available
from ...utils import OptionalDependencyNotAvailable


lowerCamelCase_    :		Union[str, Any]							=	{"""configuration_gpt_neox""": ["""GPT_NEOX_PRETRAINED_CONFIG_ARCHIVE_MAP""", """GPTNeoXConfig"""]}

try:
	if not is_tokenizers_available():
		raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
	pass
else:
	lowerCamelCase_    :		Union[str, Any]							=	["""GPTNeoXTokenizerFast"""]

try:
	if not is_torch_available():
		raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
	pass
else:
	lowerCamelCase_    :		List[str]							=	[
	    """GPT_NEOX_PRETRAINED_MODEL_ARCHIVE_LIST""",
	    """GPTNeoXForCausalLM""",
	    """GPTNeoXForQuestionAnswering""",
	    """GPTNeoXForSequenceClassification""",
	    """GPTNeoXForTokenClassification""",
	    """GPTNeoXLayer""",
	    """GPTNeoXModel""",
	    """GPTNeoXPreTrainedModel""",
	]


if TYPE_CHECKING:
	from .configuration_gpt_neox import GPT_NEOX_PRETRAINED_CONFIG_ARCHIVE_MAP, GPTNeoXConfig

	try:
		if not is_tokenizers_available():
			raise OptionalDependencyNotAvailable()
	except OptionalDependencyNotAvailable:
		pass
	else:
		from .tokenization_gpt_neox_fast import GPTNeoXTokenizerFast

	try:
		if not is_torch_available():
			raise OptionalDependencyNotAvailable()
	except OptionalDependencyNotAvailable:
		pass
	else:
		from .modeling_gpt_neox import (
		    GPT_NEOX_PRETRAINED_MODEL_ARCHIVE_LIST,
		    GPTNeoXForCausalLM,
		    GPTNeoXForQuestionAnswering,
		    GPTNeoXForSequenceClassification,
		    GPTNeoXForTokenClassification,
		    GPTNeoXLayer,
		    GPTNeoXModel,
		    GPTNeoXPreTrainedModel,
		)


else:
	import sys

	lowerCamelCase_    :		Dict							=	_LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)




