


# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import importlib.metadata
import json
import os
from dataclasses import dataclass
from typing import Any, Dict, Union

from packaging import version

from ..utils import is_torch_available, logging


if is_torch_available():
       import torch


__lowerCamelCase        =     logging.get_logger(__name__)


@dataclass
class   a__	:

       def __init__(   self      :     Tuple      ,							lowerCamelCase_      :     List[Any]=False      ,							lowerCamelCase_      :     List[Any]=False      ,							lowerCamelCase_      :     Union[str, Any]=6.0      ,							lowerCamelCase_      :     Dict=None      ,							lowerCamelCase_      :     int=False      ,							lowerCamelCase_      :     Tuple=False      ,							lowerCamelCase_      :     Tuple=None      ,							lowerCamelCase_      :     int="fp4"      ,							lowerCamelCase_      :     str=False      ,							**lowerCamelCase_      :     int      ,							):
            a_    :     int										=    load_in_abit
            a_    :     List[str]										=    load_in_abit
            a_    :     Union[str, Any]										=    llm_inta_threshold
            a_    :     Optional[int]										=    llm_inta_skip_modules
            a_    :     List[str]										=    llm_inta_enable_fpaa_cpu_offload
            a_    :     List[Any]										=    llm_inta_has_fpaa_weight
            a_    :     str										=    bnb_abit_quant_type
            a_    :     int										=    bnb_abit_use_double_quant

            if bnb_abit_compute_dtype is None:
                 a_    :     List[Any]										=    torch.floataa
            elif isinstance(lowerCamelCase_      ,							lowerCamelCase_    ):
                 a_    :     str										=    getattr(lowerCamelCase_      ,							lowerCamelCase_    )
            elif isinstance(lowerCamelCase_      ,							torch.dtype    ):
                 a_    :     str										=    bnb_abit_compute_dtype
            else:
                 raise ValueError("""bnb_4bit_compute_dtype must be a string or a torch.dtype"""    )

            self.post_init()

       def 						UpperCAmelCase(   self      :     str    ):
            if not isinstance(self.llm_inta_threshold      ,							lowerCamelCase_    ):
                 raise ValueError("""llm_int8_threshold must be a float"""    )

            if self.llm_inta_skip_modules is not None and not isinstance(self.llm_inta_skip_modules      ,							lowerCamelCase_    ):
                 raise ValueError("""llm_int8_skip_modules must be a list of strings"""    )
            if not isinstance(self.llm_inta_enable_fpaa_cpu_offload      ,							lowerCamelCase_    ):
                 raise ValueError("""llm_int8_enable_fp32_cpu_offload must be a boolean"""    )

            if not isinstance(self.llm_inta_has_fpaa_weight      ,							lowerCamelCase_    ):
                 raise ValueError("""llm_int8_has_fp16_weight must be a boolean"""    )

            if self.bnb_abit_compute_dtype is not None and not isinstance(self.bnb_abit_compute_dtype      ,							torch.dtype    ):
                 raise ValueError("""bnb_4bit_compute_dtype must be torch.dtype"""    )

            if not isinstance(self.bnb_abit_quant_type      ,							lowerCamelCase_    ):
                 raise ValueError("""bnb_4bit_quant_type must be a string"""    )

            if not isinstance(self.bnb_abit_use_double_quant      ,							lowerCamelCase_    ):
                 raise ValueError("""bnb_4bit_use_double_quant must be a boolean"""    )

            if self.load_in_abit and not version.parse(importlib.metadata.version("""bitsandbytes"""    )    ) >= version.parse(
                """0.39.0"""    ):
                 raise ValueError(
                     """4 bit quantization requires bitsandbytes>=0.39.0 - please upgrade your bitsandbytes version"""    )

       def 						UpperCAmelCase(   self      :     List[Any]    ):
            return self.load_in_abit or self.load_in_abit

       def 						UpperCAmelCase(   self      :     Optional[int]    ):
            if self.load_in_abit:
                 return "llm_int8"
            elif self.load_in_abit and self.bnb_abit_quant_type == "fp4":
                 return "fp4"
            elif self.load_in_abit and self.bnb_abit_quant_type == "nf4":
                 return "nf4"
            else:
                 return None

       @classmethod
       def 						UpperCAmelCase(   cls      :     Dict      ,							lowerCamelCase_      :     List[str]      ,							lowerCamelCase_      :     str      ,							**lowerCamelCase_      :     int    ):
            a_    :     Optional[Any]										=    cls(**lowerCamelCase_    )

            a_    :     Dict										=    []
            for key, value in kwargs.items():
                 if hasattr(lowerCamelCase_      ,							lowerCamelCase_    ):
                      setattr(lowerCamelCase_      ,							lowerCamelCase_      ,							lowerCamelCase_    )
                      to_remove.append(lowerCamelCase_    )
            for key in to_remove:
                 kwargs.pop(lowerCamelCase_      ,							lowerCamelCase_    )

            if return_unused_kwargs:
                 return config, kwargs
            else:
                 return config

       def 						UpperCAmelCase(   self      :     List[Any]      ,							lowerCamelCase_      :     Union[str, os.PathLike]    ):
            with open(lowerCamelCase_      ,							"""w"""      ,							encoding="""utf-8"""    ) as writer:
                 a_    :     List[Any]										=    self.to_dict()
                 a_    :     Tuple										=    json.dumps(lowerCamelCase_      ,							indent=2      ,							sort_keys=lowerCamelCase_    ) + """\n"""

                 writer.write(lowerCamelCase_    )

       def 						UpperCAmelCase(   self      :     int    ):
            a_    :     Any										=    copy.deepcopy(self.__dict__    )
            a_    :     Dict										=    str(output["""bnb_4bit_compute_dtype"""]    ).split("""."""    )[1]

            return output

       def __repr__(   self      :     Tuple    ):
            return F'''{self.__class__.__name__} {self.to_json_string()}'''

       def 						UpperCAmelCase(   self      :     Optional[int]      ,							lowerCamelCase_      :     bool = True    ):
            if use_diff is True:
                 a_    :     Any										=    self.to_diff_dict()
            else:
                 a_    :     Tuple										=    self.to_dict()
            return json.dumps(lowerCamelCase_      ,							indent=2      ,							sort_keys=lowerCamelCase_    ) + "\n"

       def 						UpperCAmelCase(   self      :     List[Any]    ):
            a_    :     Optional[int]										=    self.to_dict()

            # get the default config dict
            a_    :     Tuple										=    BitsAndBytesConfig().to_dict()

            a_    :     int										=    {}

            # only serialize values that differ from the default config
            for key, value in config_dict.items():
                 if value != default_config_dict[key]:
                      a_    :     List[Any]										=    value

            return serializable_config_dict







import dataclasses
import json
import warnings
from dataclasses import dataclass, field
from time import time
from typing import List

from ..utils import logging


__lowerCamelCase        =     logging.get_logger(__name__)



def  _a			(						__UpperCamelCase=None  ,  __UpperCamelCase=None ):
     return field(default_factory=lambda: default  ,  metadata=__UpperCamelCase )


@dataclass
class   a__	:
       lowerCamelCase__:     List[str]							    =     list_field(
           default=[]						,       metadata={
               """help""": (
                   """Model checkpoints to be provided to the AutoModel classes. Leave blank to benchmark the base version"""
                   """ of all available models"""
               )
           }						,       )

       lowerCamelCase__:     List[int]							    =     list_field(
           default=[8]						,       metadata={"""help""": """List of batch sizes for which memory and time performance will be evaluated"""}    )

       lowerCamelCase__:     List[int]							    =     list_field(
           default=[8, 32, 128, 512]						,       metadata={"""help""": """List of sequence lengths for which memory and time performance will be evaluated"""}						,       )

       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={"""help""": """Whether to benchmark inference of model. Inference can be disabled via --no-inference."""}						,       )
       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={"""help""": """Whether to run on available cuda devices. Cuda can be disabled via --no-cuda."""}						,       )
       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={"""help""": """Whether to run on available tpu devices. TPU can be disabled via --no-tpu."""}    )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Use FP16 to accelerate inference."""}    )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Benchmark training of model"""}    )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Verbose memory tracing"""}    )
       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={"""help""": """Whether to perform speed measurements. Speed measurements can be disabled via --no-speed."""}						,       )
       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={
               """help""": """Whether to perform memory measurements. Memory measurements can be disabled via --no-memory"""
           }						,       )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Trace memory line by line"""}    )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Save result to a CSV file"""}    )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Save all print statements in a log file"""}    )
       lowerCamelCase__:     bool							    =     field(default=lowerCAmelCase_						,       metadata={"""help""": """Whether to print environment information"""}    )
       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={
               """help""": (
                   """Whether to use multiprocessing for memory and speed measurement. It is highly recommended to use"""
                   """ multiprocessing for accurate CPU and GPU memory measurements. This option should only be disabled"""
                   """ for debugging / testing and on TPU."""
               )
           }						,       )
       lowerCamelCase__:     str							    =     field(
           default=F"""inference_time_{round(time()    )}.csv"""						,       metadata={"""help""": """CSV filename used if saving time results to csv."""}						,       )
       lowerCamelCase__:     str							    =     field(
           default=F"""inference_memory_{round(time()    )}.csv"""						,       metadata={"""help""": """CSV filename used if saving memory results to csv."""}						,       )
       lowerCamelCase__:     str							    =     field(
           default=F"""train_time_{round(time()    )}.csv"""						,       metadata={"""help""": """CSV filename used if saving time results to csv for training."""}						,       )
       lowerCamelCase__:     str							    =     field(
           default=F"""train_memory_{round(time()    )}.csv"""						,       metadata={"""help""": """CSV filename used if saving memory results to csv for training."""}						,       )
       lowerCamelCase__:     str							    =     field(
           default=F"""env_info_{round(time()    )}.csv"""						,       metadata={"""help""": """CSV filename used if saving environment information."""}						,       )
       lowerCamelCase__:     str							    =     field(
           default=F"""log_{round(time()    )}.csv"""						,       metadata={"""help""": """Log filename used if print statements are saved in log."""}						,       )
       lowerCamelCase__:     int							    =     field(default=3						,       metadata={"""help""": """Times an experiment will be run."""}    )
       lowerCamelCase__:     bool							    =     field(
           default=lowerCAmelCase_						,       metadata={
               """help""": (
                   """Instead of loading the model as defined in `config.architectures` if exists, just load the pretrain"""
                   """ model weights."""
               )
           }						,       )

       def 						UpperCAmelCase(   self      :     Any    ):
            warnings.warn(
                F'''The class {self.__class__} is deprecated. Hugging Face Benchmarking utils'''
                """ are deprecated in general and it is advised to use external Benchmarking libraries """
                """ to benchmark Transformer models."""      ,							lowerCamelCase_      ,							)

       def 						UpperCAmelCase(   self      :     Union[str, Any]    ):
            return json.dumps(dataclasses.asdict(self    )      ,							indent=2    )

       @property
       def 						UpperCAmelCase(   self      :     List[str]    ):
            if len(self.models    ) <= 0:
                 raise ValueError(
                     """Please make sure you provide at least one model name / model identifier, *e.g.* `--models"""
                     """ bert-base-cased` or `args.models = ['bert-base-cased']."""    )
            return self.models

       @property
       def 						UpperCAmelCase(   self      :     Union[str, Any]    ):
            if not self.multi_process:
                 return False
            elif self.is_tpu:
                 logger.info("""Multiprocessing is currently not possible on TPU."""    )
                 return False
            else:
                 return True



