





# 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


_snake_case    :       Dict		       =    logging.get_logger(__name__)



@dataclass
class 							_UpperCAmelCase       :

  """simple docstring"""


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

     if bnb_abit_compute_dtype is None:
        __lowerCAmelCase				      =      torch.floataa
     elif isinstance(lowerCAmelCase_   ,    lowerCAmelCase_	):
        __lowerCAmelCase				      =      getattr(lowerCAmelCase_   ,    lowerCAmelCase_	)
     elif isinstance(lowerCAmelCase_   ,    torch.dtype	):
        __lowerCAmelCase				      =      bnb_abit_compute_dtype
     else:
        raise ValueError('bnb_4bit_compute_dtype must be a string or a torch.dtype'	)

     self.post_init()






  def 							lowercase						(							self					:						List[str]	)				->		int:
     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 							lowercase						(							self					:						int	)				->		int:
     return self.load_in_abit or self.load_in_abit






  def 							lowercase						(							self					:						Optional[Any]	)				->		Any:
     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 							lowercase						(							cls					:						Optional[int]   ,    lowerCAmelCase_					:						Any   ,    lowerCAmelCase_					:						str   ,    **lowerCAmelCase_					:						Optional[Any]	)				->		Any:
     __lowerCAmelCase				      =      cls(**lowerCAmelCase_	)

     __lowerCAmelCase				      =      []
     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 							lowercase						(							self					:						str   ,    lowerCAmelCase_					:						Union[str, os.PathLike]	)				->		Any:
     with open(lowerCAmelCase_   ,    'w'   ,    encoding='utf-8'	) as writer:
        __lowerCAmelCase				      =      self.to_dict()
        __lowerCAmelCase				      =      json.dumps(lowerCAmelCase_   ,    indent=2   ,    sort_keys=lowerCAmelCase_	) + '\n'

        writer.write(lowerCAmelCase_	)






  def 							lowercase						(							self					:						Any	)				->		Dict[str, Any]:
     __lowerCAmelCase				      =      copy.deepcopy(self.__dict__	)
     __lowerCAmelCase				      =      str(output['bnb_4bit_compute_dtype']	).split('.'	)[1]

     return output






  def __repr__(							self					:						Optional[int]	)				->		Union[str, Any]:
     return f"""{self.__class__.__name__} {self.to_json_string()}"""






  def 							lowercase						(							self					:						int   ,    lowerCAmelCase_					:						bool = True	)				->		str:
     if use_diff is True:
        __lowerCAmelCase				      =      self.to_diff_dict()
     else:
        __lowerCAmelCase				      =      self.to_dict()
     return json.dumps(lowerCAmelCase_   ,    indent=2   ,    sort_keys=lowerCAmelCase_	) + "\n"






  def 							lowercase						(							self					:						Any	)				->		Dict[str, Any]:
     __lowerCAmelCase				      =      self.to_dict()

     # get the default config dict
     __lowerCAmelCase				      =      BitsAndBytesConfig().to_dict()

     __lowerCAmelCase				      =      {}

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

     return serializable_config_dict




# Copyright 2021 The HuggingFace 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.

from pathlib import Path

import torch

from ...utils import is_npu_available, is_xpu_available
from .config_args import ClusterConfig, default_json_config_file
from .config_utils import SubcommandHelpFormatter


UpperCamelCase__		 =     '''Create a default config file for Accelerate with only a few flags set.'''







def 						lowerCamelCase__      ( __A    :List[Any]="no"	,__A    :str = default_json_config_file	,__A    :bool = False		):


       """simple docstring"""




       __snake_case       	=							Path(__A		)
       path.parent.mkdir(parents=__A	,exist_ok=__A		)
       if path.exists():
              print(
                  F'Configuration already exists at {save_location}, will not override. Run `accelerate config` manually or pass a different `save_location`.'		)
              return False
       __snake_case       	=							mixed_precision.lower()
       if mixed_precision not in ["no", "fp16", "bf16", "fp8"]:
              raise ValueError(
                  F'`mixed_precision` should be one of \'no\', \'fp16\', \'bf16\', or \'fp8\'. Received {mixed_precision}'		)
       __snake_case       	=							{
           """compute_environment""": """LOCAL_MACHINE""",
           """mixed_precision""": mixed_precision,
       }
       if torch.cuda.is_available():
              __snake_case       	=							torch.cuda.device_count()
              __snake_case       	=							num_gpus
              __snake_case       	=							False
              if num_gpus > 1:
                     __snake_case       	=							"""MULTI_GPU"""
              else:
                     __snake_case       	=							"""NO"""
       elif is_xpu_available() and use_xpu:
              __snake_case       	=							torch.xpu.device_count()
              __snake_case       	=							num_xpus
              __snake_case       	=							False
              if num_xpus > 1:
                     __snake_case       	=							"""MULTI_XPU"""
              else:
                     __snake_case       	=							"""NO"""
       elif is_npu_available():
              __snake_case       	=							torch.npu.device_count()
              __snake_case       	=							num_npus
              __snake_case       	=							False
              if num_npus > 1:
                     __snake_case       	=							"""MULTI_NPU"""
              else:
                     __snake_case       	=							"""NO"""
       else:
              __snake_case       	=							0
              __snake_case       	=							True
              __snake_case       	=							1
              __snake_case       	=							"""NO"""
       __snake_case       	=							ClusterConfig(**__A		)
       config.to_json_file(__A		)
       return path







def 						lowerCamelCase__      ( __A    :Dict	,__A    :List[Any]		):


       """simple docstring"""




       __snake_case       	=							parser.add_parser("""default"""	,parents=__A	,help=__A	,formatter_class=__A		)
       parser.add_argument(
           """--config_file"""	,default=__A	,help=(
               """The path to use to store the config file. Will default to a file named default_config.yaml in the cache """
               """location, which is the content of the environment `HF_HOME` suffixed with 'accelerate', or if you don't have """
               """such an environment variable, your cache directory ('~/.cache' or the content of `XDG_CACHE_HOME`) suffixed """
               """with 'huggingface'."""
           )	,dest="""save_location"""	,)

       parser.add_argument(
           """--mixed_precision"""	,choices=["""no""", """fp16""", """bf16"""]	,type=__A	,help="""Whether or not to use mixed precision training. """
           """Choose between FP16 and BF16 (bfloat16) training. """
           """BF16 training is only supported on Nvidia Ampere GPUs and PyTorch 1.10 or later."""	,default="""no"""	,)
       parser.set_defaults(func=__A		)
       return parser







def 						lowerCamelCase__      ( __A    :Optional[Any]		):


       """simple docstring"""




       __snake_case       	=							write_basic_config(args.mixed_precision	,args.save_location		)
       if config_file:
              print(F'accelerate configuration saved at {config_file}'		)

