量化大型语言模型(llm)是减少这些模型大小和加快推理速度的最流行的方法。在这些技术中,GPTQ在gpu上提供了惊人的性能。与非量化模型相比,该方法使用的VRAM几乎减少了3倍,同时提供了相似的精度水平和更快的生成速度。
ExLlamaV2是一个旨在从GPTQ中挤出更多性能的库。由于新的内核,它还经过了优化,可以进行(非常)快速的推理。并且它还引入了一种新的量化格式EXL2,它为如何存储权重带来了很大的灵活性。
在本文中,我们将介绍如何量化EXL2格式的基本模型,以及如何运行它们。当然如果你喜欢使用现有的已经量化好的模型,TheBloke 仍然是第一选择。
首先需要安装ExLlamaV2库:
pip install exllamav2
#为了使用官方的一些脚本,我们还要把官方的代码clone到本地
git clone https://github.com/turboderp/exllamav2
我们使用出色的zephyr-7B-beta,这是一种使用DPO进行微调的Mistral-7B模型。它声称在MT测试台上的表现优于Llama-2 70b的效果,这对于一个小十倍的模型来说是非常好的结果。
使用以下命令下载zephyr-7B-beta(这可能需要一段时间,因为模型大约是15gb):
git lfs install
git clone https://huggingface.co/HuggingFaceH4/zephyr-7b-beta
GPTQ还需要一个校准数据集,该数据集用于通过比较基本模型及其量化版本的输出来衡量量化过程的影响。我们将使用wikitext数据集,直接下载测试文件如下:
wget https://huggingface.co/datasets/wikitext/resolve/9a9e482b5987f9d25b3a9b2883fc6cc9fd8071b3/wikitext-103-v1/wikitext-test.parquet
准备工作完成后,就可以利用ExLlamaV2库提供的convert.py脚本来进行量化了,主要的参数是:
-i:以HF格式(FP16)转换的基模型路径。
-o:存放临时文件和最终输出的工作目录路径。
-c:校准数据集的路径(Parquet格式)。
-b:目标平均加权位数(bpw)。例如,4.0 bpw将给出4位精度的存储权重。
让我们使用带有以下参数的convert.py脚本开始量化过程:
mkdir deephub-quant
python python exllamav2/convert.py \
-i base_model \
-o deephub-quant \
-c wikitext-test.parquet \
-b 5.0
这里就需要一个GPU来量化这个模型。根据官方文档指出,7B型号需要大约8 GB的VRAM, 70B型号需要大约24 GB的VRAM。zephyr-7b-beta在白嫖的谷歌Colab的T4 GPU,经过了2小时10分钟完成了量化。
ExLlamaV2利用GPTQ算法来降低权重的精度,同时最大限度地减少对输出的影响。GPTQ算法的更多详细信息可以参考我们以前的文章。
量化过程使用现有脚本非常的简单。那么还有最后一个问题,为什么要使用“EXL2”格式而不是常规的GPTQ格式呢?EXL2带来了哪些新功能?
它支持不同级别的量化:它不局限于4位精度,可以处理2、3、4、5、6和8位量化。
它可以在一个模型和每一层中混合不同的精度,以保留最重要的权重和具有更多bit的层。
ExLlamaV2在量化过程中使用了这种额外的灵活性。它会自动尝试不同的量化参数,并测量了它们引入的误差。除了尽量减少错误之外,ExLlamaV2还会将必须达到平均位数作为参数(这个我们在以前文章中也有介绍)。所以我们可以创建一个混合的量化模型,例如,每个权重的平均位数为3.5或4.5。
ExLlamaV2另外一个好处是它创建的不同参数的基准被保存在measurement.json文件中。我们可以直接看到具体的信息:
"key": "model.layers.0.self_attn.q_proj",
"numel": 16777216,
"options": [
{
"desc": "0.05:3b/0.95:2b 32g s4",
"bpw": 2.1878662109375,
"total_bits": 36706304.0,
"err": 0.011161142960190773,
"qparams": {
"group_size": 32,
"bits": [
3,
2
],
"bits_prop": [
0.05,
0.95
],
"scale_bits": 4
}
},
比如上面的内容,ExLlamaV2使用了5%的3位精度和95%的2位精度,平均值为2.188 bpw,组大小为32。这导致了一个明显的误差,所以在选择最佳参数时要考虑到这个误差,通过查看json文件的结果,我们可以判断出这次量化是否符合我们的要求,并且进行调整。
模型已经量子化了,下面就是使用模型进行推理了。首先需要将基本配置文件从base_model目录复制到新的deephub-quant目录,代码如下:
!rm -rf deephub-quant/out_tensor
!rsync -av --exclude='*.safetensors' --exclude='.*' ./base_model/ ./deephub-quant/
最直接的方法是使用ExLlamaV2 repo中的test_inference.py脚本(注意,我在这里没有使用聊天模板):
python exllamav2/test_inference.py -m quant/ -p "I have a dream"
与GGUF/llama.cpp或GPTQ等其他量化技术和工具相比,生成速度也非常快(在T4 GPU上每秒56.44个令牌)。
也可以使用chatcode.py脚本的聊天版本来获得更大的灵活性:
python exllamav2/examples/chatcode.py -m deephub-quant -mode llama
ExLlamaV2已经被集成到几个常见的后端中,比如oobabooga的文本生成web UI。但是它需要FlashAttention 2和CUDA 12.1(这在windows中可能需要费一些时间)。
ExLlamaV2与GPTQ或llama.cpp等其他解决方案相比,可以自定义量化我们的模型。在量化之后,它每秒提供的令牌数量更多(更快)。这对于定制化的需求来说是非常有帮助的。
最后,本文代码:
https://avoid.overfit.cn/post/ce9c31f9650943bfa220f48f3ee2f430
作者:Maxime Labonne