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

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

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

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

            UpperCAmelCase__	:      Any     							=					new_value
            if fpaa_statistics is not None:
                setattr(module.weight    ,'SCB'    ,fpaa_statistics.to(_snake_case ) )

    else:
        if value is None:
            UpperCAmelCase__	:      int     							=					old_value.to(_snake_case )
        elif isinstance(_snake_case    ,torch.Tensor ):
            UpperCAmelCase__	:      List[str]     							=					value.to(_snake_case )
        else:
            UpperCAmelCase__	:      List[str]     							=					torch.tensor(_snake_case    ,device=_snake_case )

        if is_buffer:
            UpperCAmelCase__	:      List[Any]     							=					new_value
        else:
            UpperCAmelCase__	:      int     							=					nn.Parameter(_snake_case    ,requires_grad=old_value.requires_grad )
            UpperCAmelCase__	:      Optional[Any]     							=					new_value
def 					lowerCamelCase   (     _snake_case    ,_snake_case=None    ,_snake_case=None    ,_snake_case=None    ,_snake_case=False ):
    for name, module in model.named_children():
        if current_key_name is None:
            UpperCAmelCase__	:      Optional[int]     							=					[]
        current_key_name.append(_snake_case )

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

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

    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   (     *_snake_case    ,**_snake_case ):
    warnings.warn(
        '`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead'    ,_snake_case    ,)
    return replace_with_bnb_linear(*_snake_case    ,**_snake_case )
def 					lowerCamelCase   (     *_snake_case    ,**_snake_case ):
    warnings.warn(
        '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'    ,_snake_case    ,)
    return set_module_quantized_tensor_to_device(*_snake_case    ,**_snake_case )

def 					lowerCamelCase   (     _snake_case ):
    UpperCAmelCase__	:      Any     							=					deepcopy(_snake_case )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
    tied_model.tie_weights()

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

    # Check if it is a base model
    UpperCAmelCase__	:      List[Any]     							=					not hasattr(_snake_case    ,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__	:      Union[str, Any]     							=					[list_modules[-1][0]]

    # add last module together with tied weights
    UpperCAmelCase__	:      Any     							=					set(_snake_case ) - set(_snake_case )
    UpperCAmelCase__	:      Dict     							=					list(set(_snake_case ) ) + list(_snake_case )

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

    return filtered_module_names



"""simple docstring"""



UpperCamelCase__          =	{
    'meter': 'm',
    'kilometer': 'km',
    'megametre': 'Mm',
    'gigametre': 'Gm',
    'terametre': 'Tm',
    'petametre': 'Pm',
    'exametre': 'Em',
    'zettametre': 'Zm',
    'yottametre': 'Ym',
}
# Exponent of the factor(meter)
UpperCamelCase__          =	{
    'm': 0,
    'km': 3,
    'Mm': 6,
    'Gm': 9,
    'Tm': 12,
    'Pm': 15,
    'Em': 18,
    'Zm': 21,
    'Ym': 24,
}
def 					lowerCamelCase   (     _snake_case    ,_snake_case    ,_snake_case ):
    UpperCAmelCase__	:      int     							=					from_type.lower().strip('s' )
    UpperCAmelCase__	:      List[Any]     							=					to_type.lower().strip('s' )

    UpperCAmelCase__	:      Optional[int]     							=					UNIT_SYMBOL.get(_snake_case    ,_snake_case )
    UpperCAmelCase__	:      Optional[Any]     							=					UNIT_SYMBOL.get(_snake_case    ,_snake_case )

    if from_sanitized not in METRIC_CONVERSION:
        UpperCAmelCase__	:      Optional[int]     							=					(
            F'''Invalid \'from_type\' value: {from_type!r}.\n'''
            F'''Conversion abbreviations are: {', '.join(_snake_case )}'''
        )
        raise ValueError(_snake_case )
    if to_sanitized not in METRIC_CONVERSION:
        UpperCAmelCase__	:      int     							=					(
            F'''Invalid \'to_type\' value: {to_type!r}.\n'''
            F'''Conversion abbreviations are: {', '.join(_snake_case )}'''
        )
        raise ValueError(_snake_case )
    UpperCAmelCase__	:      str     							=					METRIC_CONVERSION[from_sanitized]
    UpperCAmelCase__	:      Optional[int]     							=					METRIC_CONVERSION[to_sanitized]
    UpperCAmelCase__	:      int     							=					1

    if from_exponent > to_exponent:
        UpperCAmelCase__	:      List[str]     							=					from_exponent - to_exponent
    else:
        UpperCAmelCase__	:      int     							=					-(to_exponent - from_exponent)

    return value * pow(10    ,_snake_case )


if __name__ == "__main__":
    from doctest import testmod

    testmod()

