usrbinenv python codingutf8 2023 the huggingface inc team 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 orglicenseslicense2 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 mixin class for quantization config instantiates a quantizationconfigmixin from a python dictionary of parameters args configdict dictstr any dictionary that will be used to instantiate the configuration object returnunusedkwargs bool optional defaults to false whether or not to return a list of unused keyword arguments used for frompretrained method in pretrainedmodel kwargs dictstr any additional parameters from which to initialize the configuration object returns quantizationconfigmixin the configuration object instantiated from those parameters save this instance to a json file args jsonfilepath str or os pathlike path to the json file in which this configuration instance s parameters will be saved usediff bool optional defaults to true if set to true only the difference between the config instance and the default quantizationconfig is serialized to json file serializes this instance to a python dictionary returns dictstr any dictionary of all the attributes that make up this configuration instance serializes this instance to a json string args usediff bool optional defaults to true if set to true only the difference between the config instance and the default pretrainedconfig is serialized to json string returns str string containing all the attributes that make up this configuration instance in json format this is a wrapper class about all possible attributes and features that you can play with a model that has been loaded using bitsandbytes this replaces loadin8bit or loadin4bittherefore both options are mutually exclusive currently only supports llm int8 fp4 and nf4 quantization if more methods are added to bitsandbytes then more arguments will be added to this class args loadin8bit bool optional defaults to false this flag is used to enable 8bit quantization with llm int8 loadin4bit bool optional defaults to false this flag is used to enable 4bit quantization by replacing the linear layers with fp4nf4 layers from bitsandbytes llmint8threshold float optional defaults to 6 0 this corresponds to the outlier threshold for outlier detection as described in llm int8 8bit matrix multiplication for transformers at scale paper https arxiv orgabs2208 07339 any hidden states value that is above this threshold will be considered an outlier and the operation on those values will be done in fp16 values are usually normally distributed that is most values are in the range 3 5 3 5 but there are some exceptional systematic outliers that are very differently distributed for large models these outliers are often in the interval 60 6 or 6 60 int8 quantization works well for values of magnitude 5 but beyond that there is a significant performance penalty a good default threshold is 6 but a lower threshold might be needed for more unstable models small models finetuning llmint8skipmodules liststr optional an explicit list of the modules that we do not want to convert in 8bit this is useful for models such as jukebox that has several heads in different places and not necessarily at the last position for example for causallm models the last lmhead is kept in its original dtype llmint8enablefp32cpuoffload bool optional defaults to false this flag is used for advanced use cases and users that are aware of this feature if you want to split your model in different parts and run some parts in int8 on gpu and some parts in fp32 on cpu you can use this flag this is useful for offloading large models such as googleflant5xxl note that the int8 operations will not be run on cpu llmint8hasfp16weight bool optional defaults to false this flag runs llm int8 with 16bit main weights this is useful for finetuning as the weights do not have to be converted back and forth for the backward pass bnb4bitcomputedtype torch dtype or str optional defaults to torch float32 this sets the computational type which might be different than the input time for example inputs might be fp32 but computation can be set to bf16 for speedups bnb4bitquanttype str optional defaults to fp4 this sets the quantization data type in the bnb nn linear4bit layers options are fp4 and nf4 data types which are specified by fp4 or nf4 bnb4bitusedoublequant bool optional defaults to false this flag is used for nested quantization where the quantization constants from the first quantization are quantized again kwargs dictstr any optional additional parameters from which to initialize the configuration object if not isinstanceself llmint8threshold float raise valueerrorllmint8threshold must be a float if self llmint8skipmodules is not none and not isinstanceself llmint8skipmodules list raise valueerrorllmint8skipmodules must be a list of strings if not isinstanceself llmint8enablefp32cpuoffload bool raise valueerrorllmint8enablefp32cpuoffload must be a boolean if not isinstanceself llmint8hasfp16weight bool raise valueerrorllmint8hasfp16weight must be a boolean if self bnb4bitcomputedtype is not none and not isinstanceself bnb4bitcomputedtype torch dtype raise valueerrorbnb4bitcomputedtype must be torch dtype if not isinstanceself bnb4bitquanttype str raise valueerrorbnb4bitquanttype must be a string if not isinstanceself bnb4bitusedoublequant bool raise valueerrorbnb4bitusedoublequant must be a boolean if self loadin4bit and not version parseimportlib metadata versionbitsandbytes version parse 0 39 0 raise valueerror 4 bit quantization requires bitsandbytes0 39 0 please upgrade your bitsandbytes version def isquantizableself r returns true if the model is quantizable false otherwise if self loadin8bit return llmint8 elif self loadin4bit and self bnb4bitquanttype fp4 return fp4 elif self loadin4bit and self bnb4bitquanttype nf4 return nf4 else return none def todictself dictstr any output copy deepcopyself dict outputbnb4bitcomputedtype stroutputbnb4bitcomputedtype split 1 return output def reprself configdict self todict return fself class name json dumpsconfigdict indent2 sortkeystruen def todiffdictself dictstr any configdict self todict get the default config dict defaultconfigdict bitsandbytesconfig todict serializableconfigdict only serialize values that differ from the default config for key value in configdict items if value defaultconfigdictkey serializableconfigdictkey value return serializableconfigdict class exllamaversionint enum one 1 two 2 dataclass class gptqconfigquantizationconfigmixin def init self bits int tokenizer any none dataset optionalunionliststr str none groupsize int 128 damppercent float 0 1 descact bool false sym bool true truesequential bool true usecudafp16 bool false modelseqlen optionalint none blocknametoquantize optionalstr none modulenameprecedingfirstblock optionalliststr none batchsize int 1 padtokenid optionalint none useexllama optionalbool none maxinputlength optionalint none exllamaconfig optionaldictstr any none cacheblockoutputs bool true kwargs self quantmethod quantizationmethod gptq self bits bits self tokenizer tokenizer self dataset dataset self groupsize groupsize self damppercent damppercent self descact descact self sym sym self truesequential truesequential self usecudafp16 usecudafp16 self modelseqlen modelseqlen self blocknametoquantize blocknametoquantize self modulenameprecedingfirstblock modulenameprecedingfirstblock self batchsize batchsize self padtokenid padtokenid self useexllama useexllama self maxinputlength maxinputlength self exllamaconfig exllamaconfig self disableexllama kwargs popdisableexllama none self cacheblockoutputs cacheblockoutputs self postinit def getloadingattributesself attibutesdict copy deepcopyself dict loadingattibutes disableexllama useexllama exllamaconfig usecudafp16 maxinputlength loadingattibutesdict i j for i j in attibutesdict items if i in loadingattibutes return loadingattibutesdict def postinitself r safety checker that arguments are correct new default behaviour follow pattern of old config only happens if user explicitly passes in both arguments get compatible dict for optimum gptq config make it compatible with optimum config get compatible class with optimum gptq config dict switch to none to not trigger the warning this is a wrapper class about all possible attributes and features that you can play with a model that has been loaded using autoawq library awq quantization relying on autoawq backend args bits int optional defaults to 4 the number of bits to quantize to groupsize int optional defaults to 128 the group size to use for quantization recommended value is 128 and 1 uses percolumn quantization zeropoint bool optional defaults to true whether to use zero point quantization version awqlinearversion optional defaults to awqlinearversion gemm the version of the quantization algorithm to use gemm is better for big batchsize e g 8 otherwise gemv is better e g 8 backend awqbackendpackingmethod optional defaults to awqbackendpackingmethod autoawq the quantization backend some models might be quantized using llmawq backend this is useful for users that quantize their own models using llmawq library if not torch cuda isavailable raise valueerrorawq is only available on gpu if self backend not in awqbackendpackingmethod autoawq awqbackendpackingmethod llmawq raise valueerror fonly supported quantization backends in awqbackendpackingmethod autoawq and awqbackendpackingmethod llmawq not recognized backend self backend self version awqlinearversion fromstrself version if self version not in awqlinearversion gemm awqlinearversion gemv raise valueerror fonly supported versions are in awqlinearversion gemm awqlinearversion gemv not recognized version self version if self backend awqbackendpackingmethod llmawq computecapability torch cuda getdevicecapability major minor computecapability if major 8 raise valueerrorllmawq backend is only supported on gpus with compute capability 8 0 usr bin env python coding utf 8 2023 the huggingface inc team 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 mixin class for quantization config instantiates a quantizationconfigmixin from a python dictionary of parameters args config_dict dict str any dictionary that will be used to instantiate the configuration object return_unused_kwargs bool optional defaults to false whether or not to return a list of unused keyword arguments used for from_pretrained method in pretrainedmodel kwargs dict str any additional parameters from which to initialize the configuration object returns quantizationconfigmixin the configuration object instantiated from those parameters save this instance to a json file args json_file_path str or os pathlike path to the json file in which this configuration instance s parameters will be saved use_diff bool optional defaults to true if set to true only the difference between the config instance and the default quantizationconfig is serialized to json file serializes this instance to a python dictionary returns dict str any dictionary of all the attributes that make up this configuration instance serializes this instance to a json string args use_diff bool optional defaults to true if set to true only the difference between the config instance and the default pretrainedconfig is serialized to json string returns str string containing all the attributes that make up this configuration instance in json format this is a wrapper class about all possible attributes and features that you can play with a model that has been loaded using bitsandbytes this replaces load_in_8bit or load_in_4bit therefore both options are mutually exclusive currently only supports llm int8 fp4 and nf4 quantization if more methods are added to bitsandbytes then more arguments will be added to this class args load_in_8bit bool optional defaults to false this flag is used to enable 8 bit quantization with llm int8 load_in_4bit bool optional defaults to false this flag is used to enable 4 bit quantization by replacing the linear layers with fp4 nf4 layers from bitsandbytes llm_int8_threshold float optional defaults to 6 0 this corresponds to the outlier threshold for outlier detection as described in llm int8 8 bit matrix multiplication for transformers at scale paper https arxiv org abs 2208 07339 any hidden states value that is above this threshold will be considered an outlier and the operation on those values will be done in fp16 values are usually normally distributed that is most values are in the range 3 5 3 5 but there are some exceptional systematic outliers that are very differently distributed for large models these outliers are often in the interval 60 6 or 6 60 int8 quantization works well for values of magnitude 5 but beyond that there is a significant performance penalty a good default threshold is 6 but a lower threshold might be needed for more unstable models small models fine tuning llm_int8_skip_modules list str optional an explicit list of the modules that we do not want to convert in 8 bit this is useful for models such as jukebox that has several heads in different places and not necessarily at the last position for example for causallm models the last lm_head is kept in its original dtype llm_int8_enable_fp32_cpu_offload bool optional defaults to false this flag is used for advanced use cases and users that are aware of this feature if you want to split your model in different parts and run some parts in int8 on gpu and some parts in fp32 on cpu you can use this flag this is useful for offloading large models such as google flan t5 xxl note that the int8 operations will not be run on cpu llm_int8_has_fp16_weight bool optional defaults to false this flag runs llm int8 with 16 bit main weights this is useful for fine tuning as the weights do not have to be converted back and forth for the backward pass bnb_4bit_compute_dtype torch dtype or str optional defaults to torch float32 this sets the computational type which might be different than the input time for example inputs might be fp32 but computation can be set to bf16 for speedups bnb_4bit_quant_type str optional defaults to fp4 this sets the quantization data type in the bnb nn linear4bit layers options are fp4 and nf4 data types which are specified by fp4 or nf4 bnb_4bit_use_double_quant bool optional defaults to false this flag is used for nested quantization where the quantization constants from the first quantization are quantized again kwargs dict str any optional additional parameters from which to initialize the configuration object safety checker that arguments are correct also replaces some nonetype arguments with their default values returns true if the model is quantizable false otherwise this method returns the quantization method used for the model if the model is not quantizable it returns none serializes this instance to a python dictionary returns dict str any dictionary of all the attributes that make up this configuration instance removes all attributes from config which correspond to the default config attributes for better readability and serializes to a python dictionary returns dict str any dictionary of all the attributes that make up this configuration instance get the default config dict only serialize values that differ from the default config this is a wrapper class about all possible attributes and features that you can play with a model that has been loaded using optimum api for gptq quantization relying on auto_gptq backend args bits int the number of bits to quantize to supported numbers are 2 3 4 8 tokenizer str or pretrainedtokenizerbase optional the tokenizer used to process the dataset you can pass either a custom tokenizer object a string the model id of a predefined tokenizer hosted inside a model repo on huggingface co valid model ids can be located at the root level like bert base uncased or namespaced under a user or organization name like dbmdz bert base german cased a path to a directory containing vocabulary files required by the tokenizer for instance saved using the pretrainedtokenizer save_pretrained method e g my_model_directory dataset union list str optional the dataset used for quantization you can provide your own dataset in a list of string or just use the original datasets used in gptq paper wikitext2 c4 c4 new ptb ptb new group_size int optional defaults to 128 the group size to use for quantization recommended value is 128 and 1 uses per column quantization damp_percent float optional defaults to 0 1 the percent of the average hessian diagonal to use for dampening recommended value is 0 1 desc_act bool optional defaults to false whether to quantize columns in order of decreasing activation size setting it to false can significantly speed up inference but the perplexity may become slightly worse also known as act order sym bool optional defaults to true whether to use symetric quantization true_sequential bool optional defaults to true whether to perform sequential quantization even within a single transformer block instead of quantizing the entire block at once we perform layer wise quantization as a result each layer undergoes quantization using inputs that have passed through the previously quantized layers use_cuda_fp16 bool optional defaults to false whether or not to use optimized cuda kernel for fp16 model need to have model in fp16 model_seqlen int optional the maximum sequence length that the model can take block_name_to_quantize str optional the transformers block name to quantize module_name_preceding_first_block list str optional the layers that are preceding the first transformer block batch_size int optional defaults to 1 the batch size used when processing the dataset pad_token_id int optional the pad token id needed to prepare the dataset when batch_size 1 use_exllama bool optional whether to use exllama backend defaults to true if unset only works with bits 4 max_input_length int optional the maximum input length this is needed to initialize a buffer that depends on the maximum expected input length it is specific to the exllama backend with act order exllama_config dict str any optional the exllama config you can specify the version of the exllama kernel through the version key defaults to version 1 if unset cache_block_outputs bool optional defaults to true whether to cache block outputs to reuse as inputs for the succeeding block safety checker that arguments are correct you have entered a string value for dataset you can only choose between wikitext2 c4 c4 new ptb ptb new but we found self dataset dataset needs to be either a list of string or a value in wikitext2 c4 c4 new ptb ptb new but we found self dataset new default behaviour follow pattern of old config only happens if user explicitly passes in both arguments get compatible dict for optimum gptq config make it compatible with optimum config get compatible class with optimum gptq config dict switch to none to not trigger the warning this is a wrapper class about all possible attributes and features that you can play with a model that has been loaded using auto awq library awq quantization relying on auto_awq backend args bits int optional defaults to 4 the number of bits to quantize to group_size int optional defaults to 128 the group size to use for quantization recommended value is 128 and 1 uses per column quantization zero_point bool optional defaults to true whether to use zero point quantization version awqlinearversion optional defaults to awqlinearversion gemm the version of the quantization algorithm to use gemm is better for big batch_size e g 8 otherwise gemv is better e g 8 backend awqbackendpackingmethod optional defaults to awqbackendpackingmethod autoawq the quantization backend some models might be quantized using llm awq backend this is useful for users that quantize their own models using llm awq library safety checker that arguments are correct
import copy
import importlib.metadata
import json
import os
from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, List, Optional, Union

from packaging import version

from ..utils import is_torch_available, logging


if is_torch_available():
    import torch


logger = logging.get_logger(__name__)


class QuantizationMethod(str, Enum):
    BITS_AND_BYTES = "bitsandbytes"
    GPTQ = "gptq"
    AWQ = "awq"


class AWQLinearVersion(str, Enum):
    GEMM = "gemm"
    GEMV = "gemv"

    @staticmethod
    def from_str(version: str):
        version = version.lower()
        if version == "gemm":
            return AWQLinearVersion.GEMM
        elif version == "gemv":
            return AWQLinearVersion.GEMV
        else:
            raise ValueError(f"Unknown AWQLinearVersion {version}")


class AwqBackendPackingMethod(str, Enum):
    AUTOAWQ = "autoawq"
    LLMAWQ = "llm-awq"


@dataclass
class QuantizationConfigMixin:
    

    quant_method: QuantizationMethod

    @classmethod
    def from_dict(cls, config_dict, return_unused_kwargs=False, **kwargs):
        

        config = cls(**config_dict)

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

        if return_unused_kwargs:
            return config, kwargs
        else:
            return config

    def to_json_file(self, json_file_path: Union[str, os.PathLike]):
        
        with open(json_file_path, "w", encoding="utf-8") as writer:
            config_dict = self.to_dict()
            json_string = json.dumps(config_dict, indent=2, sort_keys=True) + "\n"

            writer.write(json_string)

    def to_dict(self) -> Dict[str, Any]:
        
        return copy.deepcopy(self.__dict__)

    def __repr__(self):
        return f"{self.__class__.__name__} {self.to_json_string()}"

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


@dataclass
class BitsAndBytesConfig(QuantizationConfigMixin):
    

    def __init__(
        self,
        load_in_8bit=False,
        load_in_4bit=False,
        llm_int8_threshold=6.0,
        llm_int8_skip_modules=None,
        llm_int8_enable_fp32_cpu_offload=False,
        llm_int8_has_fp16_weight=False,
        bnb_4bit_compute_dtype=None,
        bnb_4bit_quant_type="fp4",
        bnb_4bit_use_double_quant=False,
        **kwargs,
    ):
        self.quant_method = QuantizationMethod.BITS_AND_BYTES
        self.load_in_8bit = load_in_8bit
        self.load_in_4bit = load_in_4bit
        self.llm_int8_threshold = llm_int8_threshold
        self.llm_int8_skip_modules = llm_int8_skip_modules
        self.llm_int8_enable_fp32_cpu_offload = llm_int8_enable_fp32_cpu_offload
        self.llm_int8_has_fp16_weight = llm_int8_has_fp16_weight
        self.bnb_4bit_quant_type = bnb_4bit_quant_type
        self.bnb_4bit_use_double_quant = bnb_4bit_use_double_quant

        if bnb_4bit_compute_dtype is None:
            self.bnb_4bit_compute_dtype = torch.float32
        elif isinstance(bnb_4bit_compute_dtype, str):
            self.bnb_4bit_compute_dtype = getattr(torch, bnb_4bit_compute_dtype)
        elif isinstance(bnb_4bit_compute_dtype, torch.dtype):
            self.bnb_4bit_compute_dtype = bnb_4bit_compute_dtype
        else:
            raise ValueError("bnb_4bit_compute_dtype must be a string or a torch.dtype")

        self.post_init()

    def post_init(self):
        r
        if not isinstance(self.llm_int8_threshold, float):
            raise ValueError("llm_int8_threshold must be a float")

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

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

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

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

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

        if self.load_in_4bit 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 is_quantizable(self):
        r
        return self.load_in_8bit or self.load_in_4bit

    def quantization_method(self):
        r
        if self.load_in_8bit:
            return "llm_int8"
        elif self.load_in_4bit and self.bnb_4bit_quant_type == "fp4":
            return "fp4"
        elif self.load_in_4bit and self.bnb_4bit_quant_type == "nf4":
            return "nf4"
        else:
            return None

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

        return output

    def __repr__(self):
        config_dict = self.to_dict()
        return f"{self.__class__.__name__} {json.dumps(config_dict, indent=2, sort_keys=True)}\n"

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

        
        default_config_dict = BitsAndBytesConfig().to_dict()

        serializable_config_dict = {}

        
        for key, value in config_dict.items():
            if value != default_config_dict[key]:
                serializable_config_dict[key] = value

        return serializable_config_dict


class ExllamaVersion(int, Enum):
    ONE = 1
    TWO = 2


@dataclass
class GPTQConfig(QuantizationConfigMixin):
    

    def __init__(
        self,
        bits: int,
        tokenizer: Any = None,
        dataset: Optional[Union[List[str], str]] = None,
        group_size: int = 128,
        damp_percent: float = 0.1,
        desc_act: bool = False,
        sym: bool = True,
        true_sequential: bool = True,
        use_cuda_fp16: bool = False,
        model_seqlen: Optional[int] = None,
        block_name_to_quantize: Optional[str] = None,
        module_name_preceding_first_block: Optional[List[str]] = None,
        batch_size: int = 1,
        pad_token_id: Optional[int] = None,
        use_exllama: Optional[bool] = None,
        max_input_length: Optional[int] = None,
        exllama_config: Optional[Dict[str, Any]] = None,
        cache_block_outputs: bool = True,
        **kwargs,
    ):
        self.quant_method = QuantizationMethod.GPTQ
        self.bits = bits
        self.tokenizer = tokenizer
        self.dataset = dataset
        self.group_size = group_size
        self.damp_percent = damp_percent
        self.desc_act = desc_act
        self.sym = sym
        self.true_sequential = true_sequential
        self.use_cuda_fp16 = use_cuda_fp16
        self.model_seqlen = model_seqlen
        self.block_name_to_quantize = block_name_to_quantize
        self.module_name_preceding_first_block = module_name_preceding_first_block
        self.batch_size = batch_size
        self.pad_token_id = pad_token_id
        self.use_exllama = use_exllama
        self.max_input_length = max_input_length
        self.exllama_config = exllama_config
        self.disable_exllama = kwargs.pop("disable_exllama", None)
        self.cache_block_outputs = cache_block_outputs
        self.post_init()

    def get_loading_attributes(self):
        attibutes_dict = copy.deepcopy(self.__dict__)
        loading_attibutes = ["disable_exllama", "use_exllama", "exllama_config", "use_cuda_fp16", "max_input_length"]
        loading_attibutes_dict = {i: j for i, j in attibutes_dict.items() if i in loading_attibutes}
        return loading_attibutes_dict

    def post_init(self):
        r
        if self.bits not in [2, 3, 4, 8]:
            raise ValueError(f"Only support quantization to [2,3,4,8] bits but found {self.bits}")
        if self.group_size != -1 and self.group_size <= 0:
            raise ValueError("group_size must be greater than 0 or equal to -1")
        if not (0 < self.damp_percent < 1):
            raise ValueError("damp_percent must between 0 and 1.")
        if self.dataset is not None:
            if isinstance(self.dataset, str):
                if self.dataset not in ["wikitext2", "c4", "c4-new", "ptb", "ptb-new"]:
                    raise ValueError(
                        f
                    )
            elif not isinstance(self.dataset, list):
                raise ValueError(
                    f
                )

        if self.disable_exllama is None and self.use_exllama is None:
            
            self.use_exllama = True
        elif self.disable_exllama is not None and self.use_exllama is None:
            
            logger.warning(
                "Using `disable_exllama` is deprecated and will be removed in version 4.37. Use `use_exllama` instead and specify the version with `exllama_config`."
                "The value of `use_exllama` will be overwritten by `disable_exllama` passed in `GPTQConfig` or stored in your config file."
            )
            self.use_exllama = not self.disable_exllama
            self.disable_exllama = None
        elif self.disable_exllama is not None and self.use_exllama is not None:
            
            raise ValueError("Cannot specify both `disable_exllama` and `use_exllama`. Please use just `use_exllama`")

        if self.exllama_config is None:
            self.exllama_config = {"version": ExllamaVersion.ONE}
        else:
            if "version" not in self.exllama_config:
                raise ValueError("`exllama_config` needs to have a `version` key.")
            elif self.exllama_config["version"] not in [ExllamaVersion.ONE, ExllamaVersion.TWO]:
                exllama_version = self.exllama_config["version"]
                raise ValueError(
                    f"Only supported versions are in [ExllamaVersion.ONE, ExllamaVersion.TWO] - not recognized version {exllama_version}"
                )

        if self.bits == 4 and self.use_exllama:
            if self.exllama_config["version"] == ExllamaVersion.ONE:
                logger.info(
                    "You have activated exllama backend. Note that you can get better inference "
                    "speed using exllamav2 kernel by setting `exllama_config`."
                )
            elif self.exllama_config["version"] == ExllamaVersion.TWO:
                optimum_version = version.parse(importlib.metadata.version("optimum"))
                autogptq_version = version.parse(importlib.metadata.version("auto_gptq"))
                if optimum_version <= version.parse("1.13.2") or autogptq_version <= version.parse("0.4.2"):
                    raise ValueError(
                        f"You need optimum > 1.13.2 and auto-gptq > 0.4.2 . Make sure to have that version installed - detected version : optimum {optimum_version} and autogptq {autogptq_version}"
                    )

    def to_dict(self):
        config_dict = super().to_dict()
        config_dict.pop("disable_exllama", None)
        return config_dict

    def to_dict_optimum(self):
        
        quant_dict = self.to_dict()
        
        quant_dict["disable_exllama"] = not self.use_exllama
        return quant_dict

    @classmethod
    def from_dict_optimum(cls, config_dict):
        

        if "disable_exllama" in config_dict:
            config_dict["use_exllama"] = not config_dict["disable_exllama"]
            
            config_dict["disable_exllama"] = None

        config = cls(**config_dict)
        return config


@dataclass
class AwqConfig(QuantizationConfigMixin):
    

    def __init__(
        self,
        bits: int = 4,
        group_size: int = 128,
        zero_point: bool = True,
        version: AWQLinearVersion = AWQLinearVersion.GEMM,
        backend: AwqBackendPackingMethod = AwqBackendPackingMethod.AUTOAWQ,
        **kwargs,
    ):
        self.quant_method = QuantizationMethod.AWQ

        self.bits = bits
        self.group_size = group_size
        self.zero_point = zero_point
        self.version = version
        self.backend = backend

        self.post_init()

    def post_init(self):
        r
        if not torch.cuda.is_available():
            raise ValueError("AWQ is only available on GPU")

        if self.backend not in [AwqBackendPackingMethod.AUTOAWQ, AwqBackendPackingMethod.LLMAWQ]:
            raise ValueError(
                f"Only supported quantization backends in {AwqBackendPackingMethod.AUTOAWQ} and {AwqBackendPackingMethod.LLMAWQ} - not recognized backend {self.backend}"
            )

        self.version = AWQLinearVersion.from_str(self.version)
        if self.version not in [AWQLinearVersion.GEMM, AWQLinearVersion.GEMV]:
            raise ValueError(
                f"Only supported versions are in [AWQLinearVersion.GEMM, AWQLinearVersion.GEMV] - not recognized version {self.version}"
            )

        if self.backend == AwqBackendPackingMethod.LLMAWQ:
            compute_capability = torch.cuda.get_device_capability()
            major, minor = compute_capability
            if major < 8:
                raise ValueError("LLM-AWQ backend is only supported on GPUs with compute capability >= 8.0")