






"""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 				snake_case      (   A__	,A__	,A__	,A__=None	,A__=None						):
			# Recurse if needed
			if "." in tensor_name:
						UpperCAmelCase_     : int			     =					tensor_name.split("."						)
						for split in splits[:-1]:
									UpperCAmelCase_     : str			     =					getattr(A__	,A__						)
									if new_module is None:
												raise ValueError(F"""{module} has no attribute {split}."""						)
									UpperCAmelCase_     : int			     =					new_module
						UpperCAmelCase_     : Any			     =					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[Any]			     =					tensor_name in module._buffers
			UpperCAmelCase_     : Optional[int]			     =					getattr(A__	,A__						)

			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_     : Tuple			     =					False
			UpperCAmelCase_     : Optional[Any]			     =					False
			if is_buffer or not is_bitsandbytes_available():
						UpperCAmelCase_     : str			     =					False
						UpperCAmelCase_     : Optional[int]			     =					False
			else:
						UpperCAmelCase_     : Tuple			     =					hasattr(bnb.nn	,"Params4bit"						) and isinstance(module._parameters[tensor_name]	,bnb.nn.Paramsabit						)
						UpperCAmelCase_     : List[str]			     =					isinstance(module._parameters[tensor_name]	,bnb.nn.IntaParams						)

			if is_abit or is_abit:
						UpperCAmelCase_     : List[str]			     =					module._parameters[tensor_name]
						if param.device.type != "cuda":
									if value is None:
												UpperCAmelCase_     : List[Any]			     =					old_value.to(A__						)
									elif isinstance(A__	,torch.Tensor						):
												UpperCAmelCase_     : List[Any]			     =					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_     : Optional[int]			     =					torch.tensor(A__	,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	,A__						) and fpaa_statistics is None:
												UpperCAmelCase_     : str			     =					new_value.T

									UpperCAmelCase_     : Optional[int]			     =					old_value.__dict__
									if is_abit:
												UpperCAmelCase_     : int			     =					bnb.nn.IntaParams(A__	,requires_grad=A__	,**A__						).to(A__						)
									elif is_abit:
												UpperCAmelCase_     : Optional[int]			     =					bnb.nn.Paramsabit(A__	,requires_grad=A__	,**A__						).to(A__						)

									UpperCAmelCase_     : str			     =					new_value
									if fpaa_statistics is not None:
												setattr(module.weight	,"SCB"	,fpaa_statistics.to(A__						)						)

			else:
						if value is None:
									UpperCAmelCase_     : Tuple			     =					old_value.to(A__						)
						elif isinstance(A__	,torch.Tensor						):
									UpperCAmelCase_     : str			     =					value.to(A__						)
						else:
									UpperCAmelCase_     : Any			     =					torch.tensor(A__	,device=A__						)

						if is_buffer:
									UpperCAmelCase_     : List[str]			     =					new_value
						else:
									UpperCAmelCase_     : str			     =					nn.Parameter(A__	,requires_grad=old_value.requires_grad						)
									UpperCAmelCase_     : Optional[int]			     =					new_value

def 				snake_case      (   A__	,A__=None	,A__=None	,A__=None	,A__=False						):
			for name, module in model.named_children():
						if current_key_name is None:
									UpperCAmelCase_     : int			     =					[]
						current_key_name.append(A__						)

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

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

def 				snake_case      (   A__	,A__=None	,A__=None	,A__=None						):
			UpperCAmelCase_     : int			     =					["lm_head"] if modules_to_not_convert is None else modules_to_not_convert
			UpperCAmelCase_     ,	UpperCAmelCase_     : Union[str, Any]			     =					_replace_with_bnb_linear(
			    A__	,A__	,A__	,A__						)

			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 				snake_case      (   *A__	,**A__						):
			warnings.warn(
			    "`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead"	,A__	,)
			return replace_with_bnb_linear(*A__	,**A__						)

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




def 				snake_case      (   A__						):
			UpperCAmelCase_     : int			     =					deepcopy(A__						)  # this has 0 cost since it is done inside `init_empty_weights` context manager`
			tied_model.tie_weights()

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

			# Check if it is a base model
			UpperCAmelCase_     : Tuple			     =					not hasattr(A__	,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_     : List[Any]			     =					list(model.named_children()						)
			UpperCAmelCase_     : int			     =					[list_modules[-1][0]]

			# add last module together with tied weights
			UpperCAmelCase_     : Tuple			     =					set(A__						) - set(A__						)
			UpperCAmelCase_     : Any			     =					list(set(A__						)						) + list(A__						)

			# remove ".weight" from the keys
			UpperCAmelCase_     : Optional[int]			     =					[".weight", ".bias"]
			UpperCAmelCase_     : Dict			     =					[]
			for name in list_untouched:
						for name_to_remove in names_to_remove:
									if name_to_remove in name:
												UpperCAmelCase_     : Dict			     =					name.replace(A__	,""						)
						filtered_module_names.append(A__						)

			return filtered_module_names











"""simple docstring"""
def 				snake_case      (   A__	,A__	,A__	,A__	,A__						):
			if index == number_of_items:
						return 0
			UpperCAmelCase_     : str			     =					0
			UpperCAmelCase_     : Dict			     =					0
			UpperCAmelCase_     : Tuple			     =					knapsack(A__	,A__	,A__	,A__	,index + 1						)
			if weights[index] <= max_weight:
						UpperCAmelCase_     : Union[str, Any]			     =					values[index] + knapsack(
						    A__	,A__	,A__	,max_weight - weights[index]	,index + 1						)
			return max(A__	,A__						)


if __name__ == "__main__":
			import doctest

			doctest.testmod()



