
"""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

UpperCamelCase	:				str  	= logging.get_logger(__name__)






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

 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				  =       False
 __UpperCamelCase				  =       False
 if is_buffer or not is_bitsandbytes_available():
  __UpperCamelCase				  =       False
  __UpperCamelCase				  =       False
 else:
  __UpperCamelCase				  =       hasattr(bnb.nn				,					'Params4bit'		) and isinstance(module._parameters[tensor_name]				,					bnb.nn.Paramsabit		)
  __UpperCamelCase				  =       isinstance(module._parameters[tensor_name]				,					bnb.nn.IntaParams		)

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

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

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

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

  if is_buffer:
   __UpperCamelCase				  =       new_value
  else:
   __UpperCamelCase				  =       nn.Parameter(_UpperCAmelCase				,					requires_grad=old_value.requires_grad		)
   __UpperCamelCase				  =       new_value






def 							A						(				snake_case      :Tuple				,					snake_case      :Union[str, Any]=None				,					snake_case      :List[Any]=None				,					snake_case      :str=None				,					snake_case      :Union[str, Any]=False		)      ->	Dict:
 for name, module in model.named_children():
  if current_key_name is None:
   __UpperCamelCase				  =       []
  current_key_name.append(_UpperCAmelCase		)

  if (isinstance(_UpperCAmelCase				,					nn.Linear		) or isinstance(_UpperCAmelCase				,					_UpperCAmelCase		)) 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(_UpperCAmelCase		) for key in modules_to_not_convert		):
    with init_empty_weights():
     if isinstance(_UpperCAmelCase				,					_UpperCAmelCase		):
      __UpperCamelCase				  =       module.weight.shape
     else:
      __UpperCamelCase				  =       module.in_features
      __UpperCamelCase				  =       module.out_features

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






def 							A						(				snake_case      :Tuple				,					snake_case      :int=None				,					snake_case      :Union[str, Any]=None				,					snake_case      :Any=None		)      ->	Tuple:
 __UpperCamelCase				  =       ["""lm_head"""] if modules_to_not_convert is None else modules_to_not_convert
 __UpperCamelCase				  =       _replace_with_bnb_linear(
     _UpperCAmelCase				,					_UpperCAmelCase				,					_UpperCAmelCase				,					_UpperCAmelCase		)

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






def 							A						(				*snake_case      :str				,					**snake_case      :Optional[int]		)      ->	Optional[int]:
 warnings.warn(
     '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'				,					_UpperCAmelCase				,					)
 return set_module_quantized_tensor_to_device(*_UpperCAmelCase				,					**_UpperCAmelCase		)






def 							A						(				snake_case      :int		)      ->	Union[str, Any]:
 __UpperCamelCase				  =       deepcopy(_UpperCAmelCase		)  # this has 0 cost since it is done inside `init_empty_weights` context manager`
 tied_model.tie_weights()

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

 # Check if it is a base model
 __UpperCamelCase				  =       not hasattr(_UpperCAmelCase				,					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(model.named_children()		)
 __UpperCamelCase				  =       [list_modules[-1][0]]

 # add last module together with tied weights
 __UpperCamelCase				  =       set(_UpperCAmelCase		) - set(_UpperCAmelCase		)
 __UpperCamelCase				  =       list(set(_UpperCAmelCase		)		) + list(_UpperCAmelCase		)

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

 return filtered_module_names







'''simple docstring'''







A__:    Tuple					    =       '''
# Installazione di Transformers
! pip install transformers datasets
# Per installare dalla fonte invece dell\'ultima versione rilasciata, commenta il comando sopra e
# rimuovi la modalità commento al comando seguente.
# ! pip install git+https://github.com/huggingface/transformers.git
'''

A__:    Tuple					    =       [{'''type''': '''code''', '''content''': INSTALL_CONTENT}]
A__:    Any					    =       {
    '''{processor_class}''': '''FakeProcessorClass''',
    '''{model_class}''': '''FakeModelClass''',
    '''{object_class}''': '''FakeObjectClass''',
}


