2. 简介¶
TopsCompressor 是一个大模型量化压缩工具包,旨在提供便捷python api帮助模型开发人员进行模型量化压缩等任务。
3. 安装使用说明¶
TopsCompressor支持Python3.8及以上版本,可以从whl包直接安装。
3.1. 使用预编译的whl包安装¶
pip3 install topscompressor-<version>-py3-none-any.whl
GPU量化: 依赖于pytorch gpu及对应版本torchvision
GCU量化: 依赖于pytorch cpu及torch-gcu和对应版本torchvision
通过如下命令检查相关依赖是否已经安装:
python3 -m pip list | grep torch-gcu
python3 -m pip list | grep torch
python3 -m pip list | grep torchvision
如果已经正常安装,可以显示如下内容:
torch-gcu 2.5.1+<version>
torch 2.5.1+cpu
torchvision 0.20.1+cpu
如果未安装,可以通过以下方式安装依赖包:
python3 -m pip install torch==2.5.1+cpu -i https://download.pytorch.org/whl/cpu
python3 -m pip install torchvision==0.20.1 -i https://download.pytorch.org/whl/cpu
python3 -m pip install torch_gcu-2.5.1+<version>*.whl
4. 用户使用说明¶
TopsCompressor可以支持基于Huggingface models的LLM类模型量化和基于onnx格式的传统模型量化两种场景。LLM类模型量化当前提供awq、gptq、w8a16、w8a8和int8 kvcache量化功能。传统模型量化当前支持PTQ量化功能。
4.1. 支持范围¶
LLM类模型量化¶
支持Huggingface模型格式。
AWQ量化
W4A16:只支持group size是64或64整数倍的模型量化。
其余配置暂不支持。
GPTQ量化
W4A16:只支持group size是64或64整数倍的模型量化。
当前算子实现不支持g_idx是乱序情况,即量化时,desc_act=True, static_groups=False的情况。
W8A16量化
当前量化方式:per-channel,group size=-1的int8对称量化。
W8A8量化
当前量化方式:权重支持per-channel的int8对称量化,激活支持per-tensor的int8对称量化。
Int8 KVCache量化
当前量化支持int8对称和非对称量化,当前量化int8 kv需要在原模型基础上与上述量化分开执行。
传统模型量化¶
支持onnx模型格式。
支持PTQ量化方式。
校准过程中的数据分布统计,支持kl散度、mixmax、移动平均、百分位数等方式
支持FP32+FP16+INT8混精
4.2. 功能列表¶
LLM类模型量化¶
AWQ量化
GPTQ量化
W8A16量化
W8A8量化
Int8 kvcache量化
自定义数据集
AWQ量化¶
使用python api量化方式¶
from topscompressor.quantization.quantize import quantize, save_quantized_model
from topscompressor.quantization.config import QuantConfig
# create awq quant config
quant_config = QuantConfig.create_config("awq")
# create calibration dataset, such as 'wikitext'
calib_data_name = 'wikitext'
calib_data_config = {
'name': 'wikitext-2-raw-v1',
'split': 'validation',
}
# quantize model, such as LLaMA2 7b, the model name can be local or online checkpoint (hf format).
model = quantize(
"Llama-2-7b-hf",
quant_config,
calib_data=calib_data_name,
calib_data_load_fn_kwargs=calib_data_config,
calib_data_max_len=512,
n_samples=128,
device='gcu'
)
# save quantized model
save_quantized_model(model, quant_config, "saved_dir")
GPTQ量化¶
上述代码只需修改quant_config部分
# create gptq quant config
quant_config = QuantConfig.create_config("gptq")
W8A16量化¶
上述代码只需修改quant_config部分
# create w8a16 quant config
quant_config = QuantConfig.create_config("w8a16")
W8A8量化¶
上述代码只需修改quant_config部分
# create w8a8 quant config
quant_config = QuantConfig.create_config("w8a8")
Int8 kvcache量化¶
from topscompressor.quantization.quantize import quantize, save_kvcache_params, accelerate_gptq_pack_model
from topscompressor.quantization.config import QuantConfig
def main(args):
accelerate_gptq_pack_model()
kv_config = QuantConfig.create_config('int8_kv')
kv_config.sym_quant_kv = False
kv_config.is_quantized_model = False
calib_data_name = 'wikitext'
calib_data_config = {
'name': 'wikitext-2-raw-v1',
'split': 'validation',
}
model = quantize(
"Llama-2-7b-hf",
kv_config,
calib_data=calib_data_name,
calib_data_load_fn_kwargs=calib_data_config,
calib_data_max_len=512,
n_samples=128,
device='gcu'
)
save_kvcache_params(model, quant_config, "saved_dir")
自定义数据集¶
对于自定义数据集,当前支持一种简单方式,将文本保存到list中,然后传递给quantize函数。
calib_data = [
'sample 1',
'sample 2',
...,
'sample n'
]
...
quantize(
model,
quant_config,
calib_data=calib_data,
...
)
量化后模型¶
模型量化后以Huggingface models形式组织,将原始模型中其余相关文件(tokenizer等)拷贝到量化模型目录下即可使用。
传统模型量化¶
PTQ量化¶
使用python api量化方式¶
import onnxruntime
from topscompressor.onnx.quantization.quantize import quantize, CalibrationDataReader, QuantFormat, QuantType,CalibrationMethod, QuantizationMode
class InceptionV3DataReader(CalibrationDataReader):
def __init__(self, calibration_image_folder, size_limit=0,augmented_model_path='augmented_model.onnx'):
self.image_folder = calibration_image_folder
self.augmented_model_path = augmented_model_path
self.sizelimit = size_limit
self.datasize, self.enum_data_dicts = self._preproc()
def _preproc(self):
EP_list = ['CPUExecutionProvider']
session = onnxruntime.InferenceSession(self.augmented_model_path, None, providers=EP_list)
(_, _, height, width) = session.get_inputs()[0].shape
nhwc_data_list = preprocess_func(self.image_folder, height, width, self.sizelimit)
input_name = session.get_inputs()[0].name
return len(nhwc_data_list), iter([{input_name: nhwc_data} for nhwc_data in nhwc_data_list])
def get_next(self):
return next(self.enum_data_dicts, None)
def preprocess_func(images_folder, height, width, size_limit=0):
...
# create calibration DataReader, such as 'imagenet'
# using 1000 image samples to do calibration
dr = InceptionV3DataReader("path_to_imagenet",1000 ,"inception_v3-torchvision-op13-fp32-N.onnx")
# int8 model will be saved as inception_v3_quant.onnx
quantize("inception_v3-torchvision-op13-fp32-N.onnx",
"inception_v3_quant.onnx",
dr,
quant_format=QuantFormat.PTQ,
per_channel=True,
nodes_to_exclude=['Gemm_261'],
activation_type=QuantType.QInt8,
nodes_to_maxthreshold=[],
weight_type=QuantType.QInt8,
calibrate_method=CalibrationMethod.Entropy,
quantization_mode = QuantizationMode.QuantOps)
量化后模型¶
模型量化后以onnx形式组织,可用于在燧原推理软件栈(或其他已对接燧原量化op的平台)上推理。