



# 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


UpperCAmelCase_		 =					logging.get_logger(__name__)


@dataclass
class 	lowerCamelCase__	:



 """simple docstring"""

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

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

    self.post_init()

 def     snake_case_      (    self					:					Optional[Any]      )   ->	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     snake_case_      (    self					:					Dict      )   ->	str:
    return self.load_in_abit or self.load_in_abit

 def     snake_case_      (    self					:					Union[str, Any]      )   ->	Tuple:
    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     snake_case_      (    cls					:					List[Any]			,						__lowerCAmelCase					:					List[Any]			,						__lowerCAmelCase					:					Optional[Any]			,						**__lowerCAmelCase					:					Optional[Any]      )   ->	Optional[Any]:
    _A      =       cls(**__lowerCAmelCase      )

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

       writer.write(__lowerCAmelCase      )

 def     snake_case_      (    self					:					Optional[int]      )   ->	Dict[str, Any]:
    _A      =       copy.deepcopy(self.__dict__      )
    _A      =       str(output['''bnb_4bit_compute_dtype''']      ).split('''.'''      )[1]

    return output

 def __repr__(    self					:					Optional[int]      )   ->	List[str]:
    return f'''{self.__class__.__name__} {self.to_json_string()}'''

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

 def     snake_case_      (    self					:					Tuple      )   ->	Dict[str, Any]:
    _A      =       self.to_dict()

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

    _A      =       {}

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

    return serializable_config_dict





import argparse
import collections
import os
import re

from transformers.utils import direct_transformers_import


# All paths are set with the intent you should run this script from the root of the repo with the command
# python utils/check_table.py
__lowerCAmelCase     :	Dict       			=  'src/transformers'
__lowerCAmelCase     :	List[Any]       			=  'docs/source/en'
__lowerCAmelCase     :	str       			=  '.'

def a__       (			A_,	A_,	A_   ):






  '''simple docstring'''





  with open(A_,	"""r""",	encoding="""utf-8""",	newline="""\n"""   ) as f:
    __magic_name__								=			f.readlines()
  # Find the start prompt.
  __magic_name__								=			0
  while not lines[start_index].startswith(A_   ):
    start_index += 1
  start_index += 1

  __magic_name__								=			start_index
  while not lines[end_index].startswith(A_   ):
    end_index += 1
  end_index -= 1

  while len(lines[start_index]   ) <= 1:
    start_index += 1
  while len(lines[end_index]   ) <= 1:
    end_index -= 1
  end_index += 1
  return "".join(lines[start_index:end_index]   ), start_index, end_index, lines


# Add here suffixes that are used to identify models, separated by |
__lowerCAmelCase     :	str       			=  'Model|Encoder|Decoder|ForConditionalGeneration'
# Regexes that match TF/Flax/PT model names.
__lowerCAmelCase     :	List[str]       			=  re.compile(R'TF(.*)(?:Model|Encoder|Decoder|ForConditionalGeneration)')
__lowerCAmelCase     :	Any       			=  re.compile(R'Flax(.*)(?:Model|Encoder|Decoder|ForConditionalGeneration)')
# Will match any TF or Flax model too so need to be in an else branch afterthe two previous regexes.
__lowerCAmelCase     :	Optional[int]       			=  re.compile(R'(.*)(?:Model|Encoder|Decoder|ForConditionalGeneration)')


# This is to make sure the transformers module imported is the one in the repo.
__lowerCAmelCase     :	Union[str, Any]       			=  direct_transformers_import(TRANSFORMERS_PATH)

def a__       (			A_   ):






  '''simple docstring'''





  __magic_name__								=			re.finditer(""".+?(?:(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|$)""",	A_   )
  return [m.group(0   ) for m in matches]

def a__       (			A_,	A_   ):






  '''simple docstring'''





  __magic_name__								=			2 if text == """✅""" or text == """❌""" else len(A_   )
  __magic_name__								=			(width - text_length) // 2
  __magic_name__								=			width - text_length - left_indent
  return " " * left_indent + text + " " * right_indent

def a__       (			):






  '''simple docstring'''





  __magic_name__								=			transformers_module.models.auto.configuration_auto.CONFIG_MAPPING_NAMES
  __magic_name__								=			{
      name: config_maping_names[code]
      for code, name in transformers_module.MODEL_NAMES_MAPPING.items()
      if code in config_maping_names
  }
  __magic_name__								=			{name: config.replace("""Config""",	""""""   ) for name, config in model_name_to_config.items()}

  # Dictionaries flagging if each model prefix has a slow/fast tokenizer, backend in PT/TF/Flax.
  __magic_name__								=			collections.defaultdict(A_   )
  __magic_name__								=			collections.defaultdict(A_   )
  __magic_name__								=			collections.defaultdict(A_   )
  __magic_name__								=			collections.defaultdict(A_   )
  __magic_name__								=			collections.defaultdict(A_   )

  # Let's lookup through all transformers object (once).
  for attr_name in dir(A_   ):
    __magic_name__								=			None
    if attr_name.endswith("""Tokenizer"""   ):
      __magic_name__								=			slow_tokenizers
      __magic_name__								=			attr_name[:-9]
    elif attr_name.endswith("""TokenizerFast"""   ):
      __magic_name__								=			fast_tokenizers
      __magic_name__								=			attr_name[:-13]
    elif _re_tf_models.match(A_   ) is not None:
      __magic_name__								=			tf_models
      __magic_name__								=			_re_tf_models.match(A_   ).groups()[0]
    elif _re_flax_models.match(A_   ) is not None:
      __magic_name__								=			flax_models
      __magic_name__								=			_re_flax_models.match(A_   ).groups()[0]
    elif _re_pt_models.match(A_   ) is not None:
      __magic_name__								=			pt_models
      __magic_name__								=			_re_pt_models.match(A_   ).groups()[0]

    if lookup_dict is not None:
      while len(A_   ) > 0:
        if attr_name in model_name_to_prefix.values():
          __magic_name__								=			True
          break
        # Try again after removing the last word in the name
        __magic_name__								=			"""""".join(camel_case_split(A_   )[:-1]   )

    # Let's build that table!
  __magic_name__								=			list(model_name_to_config.keys()   )
  model_names.sort(key=str.lower   )
  __magic_name__								=			["""Model""", """Tokenizer slow""", """Tokenizer fast""", """PyTorch support""", """TensorFlow support""", """Flax Support"""]
  # We'll need widths to properly display everything in the center (+2 is to leave one extra space on each side).
  __magic_name__								=			[len(A_   ) + 2 for c in columns]
  __magic_name__								=			max([len(A_   ) for name in model_names]   ) + 2

  # Build the table per se
  __magic_name__								=			"""|""" + """|""".join([_center_text(A_,	A_   ) for c, w in zip(A_,	A_   )]   ) + """|\n"""
  # Use ":-----:" format to center-aligned table cell texts
  table += "|" + "|".join([""":""" + """-""" * (w - 2) + """:""" for w in widths]   ) + "|\n"

  __magic_name__								=			{True: """✅""", False: """❌"""}
  for name in model_names:
    __magic_name__								=			model_name_to_prefix[name]
    __magic_name__								=			[
        name,
        check[slow_tokenizers[prefix]],
        check[fast_tokenizers[prefix]],
        check[pt_models[prefix]],
        check[tf_models[prefix]],
        check[flax_models[prefix]],
    ]
    table += "|" + "|".join([_center_text(A_,	A_   ) for l, w in zip(A_,	A_   )]   ) + "|\n"
  return table

def a__       (			A_=False   ):






  '''simple docstring'''





  __magic_name__	,       __magic_name__	,       __magic_name__	,       __magic_name__								=			_find_text_in_file(
      filename=os.path.join(A_,	"""index.md"""   ),	start_prompt="""<!--This table is updated automatically from the auto modules""",	end_prompt="""<!-- End table-->""",	)
  __magic_name__								=			get_model_table_from_auto_modules()

  if current_table != new_table:
    if overwrite:
      with open(os.path.join(A_,	"""index.md"""   ),	"""w""",	encoding="""utf-8""",	newline="""\n"""   ) as f:
        f.writelines(lines[:start_index] + [new_table] + lines[end_index:]   )
    else:
      raise ValueError(
          """The model table in the `index.md` has not been updated. Run `make fix-copies` to fix this."""   )


if __name__ == "__main__":
    __lowerCAmelCase     :	Tuple       			=  argparse.ArgumentParser()
    parser.add_argument('--fix_and_overwrite', action='store_true', help='Whether to fix inconsistencies.')
    __lowerCAmelCase     :	Optional[Any]       			=  parser.parse_args()

    check_model_table(args.fix_and_overwrite)

