The result is generated using this script, batch size of input is 1, decode strategy is beam search and enforce the model to generate 512 tokens, speed metric is tokens/s (the larger, the better).
The quantized model is loaded using the setup that can gain the fastest inference speed.
model
GPU
num_beams
fp16
gptq-int4
llama-7b
1xA100-40G
1
18.87
25.53
llama-7b
1xA100-40G
4
68.79
91.30
moss-moon 16b
1xA100-40G
1
12.48
15.25
moss-moon 16b
1xA100-40G
4
OOM
42.67
moss-moon 16b
2xA100-40G
1
06.83
06.78
moss-moon 16b
2xA100-40G
4
13.10
10.80
gpt-j 6b
1xRTX3060-12G
1
OOM
29.55
gpt-j 6b
1xRTX3060-12G
4
OOM
47.36
Perplexity
For perplexity comparison, you can turn to here and here
Installation
Quick Installation
You can install the latest stable release of AutoGPTQ from pip with pre-built wheels compatible with PyTorch 2.0.1:
For CUDA 11.7: pip install auto-gptq --extra-index-url https://huggingface.github.io/autogptq-index/whl/cu117/
For CUDA 11.8: pip install auto-gptq --extra-index-url https://huggingface.github.io/autogptq-index/whl/cu118/
For RoCm 5.4.2: pip install auto-gptq --extra-index-url https://huggingface.github.io/autogptq-index/whl/rocm542/
Warning: These wheels are not expected to work on PyTorch nightly. Please install AutoGPTQ from source when using PyTorch nightly.
disable cuda extensions
By default, cuda extensions will be installed when torch and cuda is already installed in your machine, if you don't want to use them, using:
BUILD_CUDA_EXT=0 pip install auto-gptq
And to make sure autogptq_cuda is not ever in your virtual environment, run:
pip uninstall autogptq_cuda -y
to support triton speedup
To integrate with triton, using:
warning: currently triton only supports linux; 3-bit quantization is not supported when using triton
pip install auto-gptq[triton]
Install from source
click to see details
Clone the source code:
git clone https://github.com/PanQiWei/AutoGPTQ.git && cd AutoGPTQ
Then, install from source:
pip install .
Like quick installation, you can also set BUILD_CUDA_EXT=0 to disable pytorch extension building.
Use .[triton] if you want to integrate with triton and it's available on your operating system.
To install from source for AMD GPUs supporting RoCm, please specify the ROCM_VERSION environment variable. The compilation can be speeded up by specifying the PYTORCH_ROCM_ARCH variable (reference), for example gfx90a for MI200 series devices. Example:
ROCM_VERSION=5.6 pip install .
For RoCm systems, the packages rocsparse-dev, hipsparse-dev, rocthrust-dev, rocblas-dev and hipblas-dev are required to build.
Quick Tour
Quantization and Inference
warning: this is just a showcase of the usage of basic apis in AutoGPTQ, which uses only one sample to quantize a much small model, quality of quantized model using such little samples may not good.
Below is an example for the simplest use of auto_gptq to quantize a model and inference after quantization:
python
1from transformers import AutoTokenizer, TextGenerationPipeline
2from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
3import logging
45logging.basicConfig(6format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"7)89pretrained_model_dir ="facebook/opt-125m"10quantized_model_dir ="opt-125m-4bit"1112tokenizer = AutoTokenizer.from_pretrained(pretrained_model_dir, use_fast=True)13examples =[14 tokenizer(15"auto-gptq is an easy-to-use model quantization library with user-friendly apis, based on GPTQ algorithm."16)17]1819quantize_config = BaseQuantizeConfig(20 bits=4,# quantize model to 4-bit21 group_size=128,# it is recommended to set the value to 12822 desc_act=False,# set to False can significantly speed up inference but the perplexity may slightly bad23)2425# load un-quantized model, by default, the model will always be loaded into CPU memory26model = AutoGPTQForCausalLM.from_pretrained(pretrained_model_dir, quantize_config)2728# quantize model, the examples should be list of dict whose keys can only be "input_ids" and "attention_mask"29model.quantize(examples)3031# save quantized model32model.save_quantized(quantized_model_dir)3334# save quantized model using safetensors35model.save_quantized(quantized_model_dir, use_safetensors=True)3637# push quantized model to Hugging Face Hub.38# to use use_auth_token=True, Login first via huggingface-cli login.39# or pass explcit token with: use_auth_token="hf_xxxxxxx"40# (uncomment the following three lines to enable this feature)41# repo_id = f"YourUserName/{quantized_model_dir}"42# commit_message = f"AutoGPTQ model for {pretrained_model_dir}: {quantize_config.bits}bits, gr{quantize_config.group_size}, desc_act={quantize_config.desc_act}"43# model.push_to_hub(repo_id, commit_message=commit_message, use_auth_token=True)4445# alternatively you can save and push at the same time46# (uncomment the following three lines to enable this feature)47# repo_id = f"YourUserName/{quantized_model_dir}"48# commit_message = f"AutoGPTQ model for {pretrained_model_dir}: {quantize_config.bits}bits, gr{quantize_config.group_size}, desc_act={quantize_config.desc_act}"49# model.push_to_hub(repo_id, save_dir=quantized_model_dir, use_safetensors=True, commit_message=commit_message, use_auth_token=True)5051# load quantized model to the first GPU52model = AutoGPTQForCausalLM.from_quantized(quantized_model_dir, device="cuda:0")5354# download quantized model from Hugging Face Hub and load to the first GPU55# model = AutoGPTQForCausalLM.from_quantized(repo_id, device="cuda:0", use_safetensors=True, use_triton=False)5657# inference with model.generate58print(tokenizer.decode(model.generate(**tokenizer("auto_gptq is", return_tensors="pt").to(model.device))[0]))5960# or you can also use pipeline61pipeline = TextGenerationPipeline(model=model, tokenizer=tokenizer)62print(pipeline("auto-gptq is")[0]["generated_text"])
For more advanced features of model quantization, please reference to this script
Customize Model
Below is an example to extend `auto_gptq` to support `OPT` model, as you will see, it's very easy:
python
1from auto_gptq.modeling import BaseGPTQForCausalLM
234classOPTGPTQForCausalLM(BaseGPTQForCausalLM):5# chained attribute name of transformer layer block6 layers_block_name ="model.decoder.layers"7# chained attribute names of other nn modules that in the same level as the transformer layer block8 outside_layer_modules =[9"model.decoder.embed_tokens","model.decoder.embed_positions","model.decoder.project_out",10"model.decoder.project_in","model.decoder.final_layer_norm"11]12# chained attribute names of linear layers in transformer layer module13# normally, there are four sub lists, for each one the modules in it can be seen as one operation,14# and the order should be the order when they are truly executed, in this case (and usually in most cases),15# they are: attention q_k_v projection, attention output projection, MLP project input, MLP project output16 inside_layer_modules =[17["self_attn.k_proj","self_attn.v_proj","self_attn.q_proj"],18["self_attn.out_proj"],19["fc1"],20["fc2"]21]
After this, you can use OPTGPTQForCausalLM.from_pretrained and other methods as shown in Basic.
Evaluation on Downstream Tasks
You can use tasks defined in auto_gptq.eval_tasks to evaluate model's performance on specific down-stream task before and after quantization.
The predefined tasks support all causal-language-models implemented in 🤗 transformers and in this project.
Below is an example to evaluate `EleutherAI/gpt-j-6b` on sequence-classification task using `cardiffnlp/tweet_sentiment_multilingual` dataset:
python
1from functools import partial
23import datasets
4from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
56from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
7from auto_gptq.eval_tasks import SequenceClassificationTask
8910MODEL ="EleutherAI/gpt-j-6b"11DATASET ="cardiffnlp/tweet_sentiment_multilingual"12TEMPLATE ="Question:What's the sentiment of the given text? Choices are {labels}.\nText: {text}\nAnswer:"13ID2LABEL ={140:"negative",151:"neutral",162:"positive"17}18LABELS =list(ID2LABEL.values())192021defds_refactor_fn(samples):22 text_data = samples["text"]23 label_data = samples["label"]2425 new_samples ={"prompt":[],"label":[]}26for text, label inzip(text_data, label_data):27 prompt = TEMPLATE.format(labels=LABELS, text=text)28 new_samples["prompt"].append(prompt)29 new_samples["label"].append(ID2LABEL[label])3031return new_samples
323334# model = AutoModelForCausalLM.from_pretrained(MODEL).eval().half().to("cuda:0")35model = AutoGPTQForCausalLM.from_pretrained(MODEL, BaseQuantizeConfig())36tokenizer = AutoTokenizer.from_pretrained(MODEL)3738task = SequenceClassificationTask(39 model=model,40 tokenizer=tokenizer,41 classes=LABELS,42 data_name_or_path=DATASET,43 prompt_col_name="prompt",44 label_col_name="label",45**{46"num_samples":1000,# how many samples will be sampled to evaluation47"sample_max_len":1024,# max tokens for each sample48"block_max_len":2048,# max tokens for each data block49# function to load dataset, one must only accept data_name_or_path as input50# and return datasets.Dataset51"load_fn": partial(datasets.load_dataset, name="english"),52# function to preprocess dataset, which is used for datasets.Dataset.map,53# must return Dict[str, list] with only two keys: [prompt_col_name, label_col_name]54"preprocess_fn": ds_refactor_fn,55# truncate label when sample's length exceed sample_max_len56"truncate_prompt":False57}58)5960# note that max_new_tokens will be automatically specified internally based on given classes61print(task.run())6263# self-consistency64print(65 task.run(66 generation_config=GenerationConfig(67 num_beams=3,68 num_return_sequences=3,69 do_sample=True70)71)72)
Learn More
tutorials provide step-by-step guidance to integrate auto_gptq with your own project and some best practice principles.
examples provide plenty of example scripts to use auto_gptq in different ways.
Supported Models
you can use model.config.model_type to compare with the table below to check whether the model you use is supported by auto_gptq.
for example, model_type of WizardLM, vicuna and gpt4all are all llama, hence they are all supported by auto_gptq.