Smooth Quant

April 24, 2024 · View on GitHub

  1. Introduction
  2. Example
  3. Validated Models
  4. Supported Framework Matrix

Introduction

Quantization is a common compression operation to reduce memory and accelerate inference by converting the floating point matrix to an integer matrix. For large language models (LLMs) with gigantic parameters, the systematic outliers make quantification of activations difficult. SmoothQuant, a training free post-training quantization (PTQ) solution, offline migrates this difficulty from activations to weights with a mathematically equivalent transformation.

Smoothquant introduces a hyperparameter α\alpha as a smooth factor to calculate the conversion per-channel scale and balance the quantization difficulty of activation and weight. A larger α\alpha value could be used on models with more significant activation outliers to migrate more quantization difficulty to weights.

SmoothQuant method aims to split the quantization difficulty of weight and activation by using a fixed-value α\alpha for an entire model. However, as the distributions of activation outliers vary not only across different models but also across different layers within a model, Intel® Compressor propose a method to obtain layer-wise optimal α\alpha values with the ability to tune automatically.

Example

We have extended the from_pretrained function so that quantization_config can accept SmoothQuantConfig, We provide built-in calibration function with calibration dataset NeelNanda/pile-10k and calib_iters 100, if you would like to use built-in calibration function, tokenizer is necessary, if you would like to use customer calibration function, please provide calibration function to parameter calib_func directly.

Let us set the sq_config with SmoothQuantConfig first, SmoothQuantConfig provides many parameters, please see definition.

from intel_extension_for_transformers.transformers import SmoothQuantConfig, AutoTokenizer
model_name_or_path = "Intel/neural-chat-7b-v1-1"
output_dir = "saved_results"
# use built-in calibration function
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
sq_config = SmoothQuantConfig(tokenizer=tokenizer, alpha=0.5)
# customer calibration function format
def calib_func(model):
    for index, input in enumerate(calib_dataloader):
        if index > 100:
            break
        model(**input)  # if the input is dictionary
sq_config = SmoothQuantConfig(calib_func=calib_func, alpha=0.5)

After setting the sq_config, we can do quantization, save, load and inference it.

from intel_extension_for_transformers.transformers import AutoConfig, AutoModelForCausalLM
sq_model = AutoModelForCausalLM.from_pretrained(
                                                model_name_or_path,
                                                quantization_config=sq_config,
                                                )
# save
config = AutoConfig.from_pretrained(model_name_or_path)
config.save_pretrained(output_dir)
sq_model.save(output_dir)
# load
sq_model = TSModelForCausalLM.from_pretrained(output_dir, file_name="best_model.pt")
# int8 model generation
generate_kwargs = dict(do_sample=False, temperature=0.9, num_beams=4)
prompt = "Once upon a time, a little girl"
input_ids = tokenizer(prompt, return_tensors="pt").input_ids
gen_ids = sq_model.generate(input_ids, max_new_tokens=32, **generate_kwargs)
gen_text = tokenizer.batch_decode(gen_ids, skip_special_tokens=True)
print(gen_text)

Validated Models

Intel extension for transformers: 1.2

Neural Compressor: 2.1

IPEX (Intel Extension for PyTorch): 2.0/2.1

Dataset: lambada_openai

Task: text-generation

alpha [0.4, 0.6] is sweet spot region in SmoothQuant paper.

A list of models that achieved a <1% accuracy drop is shown below.

Model/Last token accuracyFP32 AccuracyINT8 (w/ SmoothQuant)Notes
bigscience/bloom-560m0.3540.3542alpha=0.5, Ipex 2.1
bigscience/bloom-1b70.46340.4936alpha=0.5, Ipex 2.0
bigscience/bloom-3b0.5180.5185alpha=0.8, Ipex 2.1
bigscience/bloom-7b10.57640.5977alpha=0.5, Ipex 2.0
bigscience/bloomz-560m0.39470.3930alpha=0.8, Ipex 2.1
bigscience/bloomz-1b70.48280.4906alpha=0.5, Ipex 2.1
bigscience/bloomz-3b0.50180.4980alpha=0.5, Ipex 2.1
bigscience/bloomz-7b10.55930.5552alpha=0.5, Ipex 2.1
facebook/opt-125m0.3790.3757alpha=0.5, Ipex 2.1
facebook/opt-350m0.45160.4533alpha=0.8, Ipex 2.1
facebook/opt-1.3b0.57890.5742alpha=0.8, Ipex 2.0
facebook/opt-2.7b0.63650.6404alpha=0.5, Ipex 2.0
facebook/opt-6.7b0.67690.6804alpha=0.5, Ipex 2.0
facebook/opt-13b0.68720.6814alpha=0.5, Ipex 2.1
facebook/opt-30b0.71490.7128alpha=0.5, Ipex 2.1
facebook/opt-66b0.73980.7326alpha=0.5, Ipex 2.1
LLaMa-7b0.73610.7357alpha=0.8, Ipex 2.1
LLaMa-13b0.76270.7590alpha=0.7, Ipex 2.1
LLaMa-30b0.77590.7840alpha=0.7, Ipex 2.1
LLaMa-65b0.79080.7957alpha=0.9, Ipex 2.1
LLaMa-2-7b0.7369/0.72620.7330alpha=Auto, Ipex 2.1/Pytorch
EleutherAI/gpt-j-6B0.68310.6821alpha=1.0, Ipex 2.1
MBZUAI/LaMini-GPT-124m0.38040.3887alpha=0.5, Ipex 2.1
MBZUAI/LaMini-GPT-774m0.50480.5057alpha=0.5, Ipex 2.1
MBZUAI/LaMini-GPT-1.5b0.54430.5436alpha=0.5, Ipex 2.1
mosaicml/mpt-7b-chat0.6550.6499alpha=0.7, Ipex 2.1
stabilityai/stablelm-base-alpha-3b0.41720.4149alpha=0.6, Ipex 2.1
togethercomputer/RedPajama-INCITE-Base-3B-v10.65420.6735alpha=0.5, Ipex 2.1
togethercomputer/RedPajama-INCITE-Chat-3B-v10.67180.6740alpha=0.5, Ipex 2.0
togethercomputer/RedPajama-INCITE-Instruct-3B-v10.65690.6621alpha=0.5, Ipex 2.0
togethercomputer/RedPajama-INCITE-Base-7B-v0.10.71430.7221alpha=0.5, Ipex 2.0
togethercomputer/RedPajama-INCITE-Instruct-7B-v0.10.68950.6953alpha=0.5, Ipex 2.0
databricks/dolly-v1-6b0.68660.6895alpha=0.8, Ipex 2.1
databricks/dolly-v2-3b0.62970.6247alpha=0.5, Ipex 2.1
tiiuae/falcon-7b-instruct0.64370.6392alpha=0.7, Pytorch

Supported Framework Matrix

FrameworkAlphaFolding
PyTorch[0-1] / 'auto'False
IPEX[0-1] / 'auto'True / False(Version>2.1)