Weight Only Quantization (WOQ) 项目介绍
介绍
随着大型语言模型(LLMs)的广泛应用,开发高效的量化方法以平衡计算需求和模型准确性变得至关重要。Weight Only Quantization(WOQ)专注于仅量化模型的权重,而保持或甚至提高模型的准确性,是一种有前途的折中方法。本文档介绍了支持的不同量化方法,提供了针对不同设备的示例,并解释了如何使用这些方法。
支持的算法
支持设备 | RTN | AWQ | TEQ | GPTQ | AutoRound |
---|---|---|---|---|---|
Intel CPU | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
Intel GPU | ✔️ | 静待更新 | 静待更新 | ✔️ | ✔️ |
-
RTN(Rounding to Nearest):一种简单直观的方法,将值四舍五入为最近的整数。它不需要额外的数据集,量化速度快,适用于W4G32或W8配置,但在较低精度级别下效果不如先进算法。
-
AWQ(Activation-aware Weight Quantization):一种流行的方法,通过在手工设计的空间中探索权重的最小-最大值和等效变换来进行量化。尽管有效,但等效变换对模型架构有一定要求,可能会增加工程工作量。
-
TEQ(Trainable Equivalent Transformation):一种新的训练等效变换方法,通过模型级别的损失进行量化,可能需要更多的内存,并对模型架构有一定要求。
-
GPTQ(Generalized Post-Training Quantization):一种基于最佳脑外科手术的广泛采用的方法,通过对权重块进行量化,并微调未量化的权重来减少量化误差。偶尔会出现非正半定矩阵,可能需要调整超参数。
-
AutoRound:利用符号梯度下降优化权重的四舍五入值和最小-最大值,仅需200步便展示出优异的性能,相比GPTQ/AWQ方法更具优势。然而,由于其依赖于梯度反向传播,目前不适用于像ONNX这样的后端。
示例
对于 CPU 和 CUDA
CPU 设备示例
使用 RtnConfig
、AwqConfig
、TeqConfig
、GPTQConfig
或 AutoRoundConfig
在 CPU 上进行 4-bit/8-bit 推理:
from intel_extension_for_transformers.transformers import AutoModelForCausalLM, RtnConfig
from transformers import AutoTokenizer, TextStreamer
model_name_or_path = "Intel/neural-chat-7b-v3-3"
woq_config = RtnConfig(bits=4, compute_dtype="int8")
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, quantization_config=woq_config)
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True)
prompt = "Once upon a time, a little girl"
inputs = tokenizer(prompt, return_tensors="pt").input_ids
streamer = TextStreamer(tokenizer)
outputs = model.generate(inputs, streamer=streamer, max_new_tokens=300)
print(outputs)
CUDA GPU 设备示例
准备模型名称和生成参数:
from transformers import AutoTokenizer
model_name_or_path = "Intel/neural-chat-7b-v3-3"
generate_kwargs = dict(do_sample=False, temperature=0.9, num_beams=4)
prompt = "Once upon a time, a little girl"
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
input_ids = tokenizer(prompt, return_tensors="pt").input_ids
使用 Huggingface Transformers BitsAndBytesConfig
进行 CUDA GPU 上的 4-bit/8-bit 推理:
from intel_extension_for_transformers.transformers import AutoModelForCausalLM, BitsAndBytesConfig
woq_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4")
woq_model = AutoModelForCausalLM.from_pretrained(model_name_or_path, quantization_config=woq_config)
gen_ids = woq_model.generate(input_ids, max_new_tokens=32, **generate_kwargs)
gen_text = tokenizer.batch_decode(gen_ids, skip_special_tokens=True)
print(gen_text)
对于 Intel GPU
- 安装 OneAPI 包
安装 OneAPI DPCPP 编译器,以编译 intel-extension-for-pytorch。请遵循 OneAPI 安装指南 安装到 "/opt/intel" 文件夹中。
- 构建和安装 PyTorch 和 Intel-extension-for-pytorch
python -m pip install torch==2.1.0a0 -f https://developer.intel.com/ipex-whl-stable-xpu
source /opt/intel/oneapi/setvars.sh
git clone https://github.com/intel/intel-extension-for-pytorch.git ipex-gpu
cd ipex-gpu
git submodule update --init --recursive
export USE_AOT_DEVLIST='pvc,ats-m150' # 如果编译 MT-L 设备,注释此行
export BUILD_WITH_CPU=OFF
pip install -r requirements.txt
python setup.py install
- 安装 Intel-extension-for-transformers 和 Neural-compressor
pip install neural-compressor
pip install intel-extension-for-transformers
- 量化模型和推理
import intel_extension_for_pytorch as ipex
from intel_extension_for_transformers.transformers.modeling import AutoModelForCausalLM
from transformers import AutoTokenizer
import torch
device = "xpu"
model_name = "Qwen/Qwen-7B"
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
prompt = "Once upon a time, there existed a little girl,"
inputs = tokenizer(prompt, return_tensors="pt").input_ids.to(device)
qmodel = AutoModelForCausalLM.from_pretrained(model_name, load_in_4bit=True, device_map="xpu", trust_remote_code=True)
qmodel = ipex.optimize_transformers(qmodel, inplace=True, dtype=torch.float16, quantization_config={}, device="xpu")
output = qmodel.generate(inputs)
-
保存和加载量化模型
- 量化并保存模型
from intel_extension_for_transformers.transformers.modeling import AutoModelForCausalLM qmodel = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B", load_in_4bit=True, device_map="xpu", trust_remote_code=True) qmodel.save_pretrained("saved_dir")
- 加载模型并推理
loaded_model = AutoModelForCausalLM.from_pretrained("saved_dir", trust_remote_code=True) loaded_model = ipex.optimize_transformers(loaded_model, inplace=True, dtype=torch.float16, quantization_config={}, device="xpu") output = loaded_model.generate(inputs)
-
使用示例脚本
python run_generation_gpu_woq.py --woq --benchmark
注意:
- 保存量化模型应该在调用
optimize_transformers
函数之前执行。 optimize_transformers
函数旨在优化 Transformer 模型,特别关注大型语言模型(LLMs)。有关optimize_transformers
的详细信息,请参考 官方文档。
- 保存量化模型应该在调用
AutoRound 在 Intel GPU 上的示例
import torch
import intel_extension_for_pytorch as ipex
from transformers import AutoConfig, AutoTokenizer
from intel_extension_for_transformers.transformers import (
AutoModelForCausalLM,
AutoRoundConfig,
)
device = "xpu"
model_name = "meta-llama/Llama-2-7b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
prompt = "Once upon a time, a little girl"
inputs = tokenizer(prompt, return_tensors="pt").input_ids.to(device)
quantization_config = AutoRoundConfig(
tokenizer=tokenizer,
bits=4,
group_size=32,
max_input_length=2048,
compute_dtype="fp16",
scale_dtype="fp16",
weight_dtype="int4", # int4 == int4_clip
calib_iters=2,
calib_len=32,
nsamples=2,
lr=0.0025,
minmax_lr=0.0025,
)
qmodel = AutoModelForCausalLM.from_pretrained(
model_name,
device_map=device,
quantization_config=quantization_config,
trust_remote_code=True,
torch_dtype=torch.float16,
)
qmodel = ipex.optimize_transformers(
qmodel, inplace=True, dtype=torch.float16, quantization_config=True, device
=device
)
output = qmodel.generate(inputs)
print(output)
总结
Weight Only Quantization (WOQ) 是提高大规模模型推理效率的一种有效方法。通过合理选择量化算法并根据目标设备进行优化,WOQ 可以在保证模型精度的同时显著减少计算资源消耗。希望本文档能帮助您快速入门并成功实现模型量化。如果有任何问题或需要进一步的帮助,请随时联系支持团队。