Qwen大模型实践之量化

Qwen大模型实践之量化

接上篇内容。

1. AutoGPTQ量化

提供了基于AutoGPTQ的量化方案,并开源了Int4和Int8量化模型。量化模型的效果损失很小,但能显著降低显存占用并提升推理速度。

以下我们提供示例说明如何使用Int4量化模型。在开始使用前,请先保证满足要求(如torch 2.0及以上,transformers版本为4.32.0及以上,等等),并安装所需安装包:

pip install auto-gptq optimum

效果测试:

# 通过程序下载Qwen/Qwen-14B-Chat-Int4模型,并将模型放到测试脚本路径下。
# Int4量化模型文件相比原模型文件小很多
(base) root@intern-studio-50014188:~/Qwen# du -sh ./Qwen-14B-Chat/
27G     ./Qwen-14B-Chat/
(base) root@intern-studio-50014188:~/Qwen# du -sh ./Qwen-14B-Chat-Int4/
9.1G    ./Qwen-14B-Chat-Int4/

# 修改web_demo.py,使用Qwen-14B-Chat-Int4模型。然后运行程序
(qwen) root@intern-studio-50014188:~/Qwen# python3 web_demo.py 

经过测试显存占用明显降低,约10G;使用相同问答,推理速度提示较明显,包括第一个令牌时间(TTFT)和输出令牌吞吐量都提升明显,接近于可接受的水平。

附官网BF16,Int8和Int4模型在基准评测,量化模型效果损失较小,结果如下所示:

QuantizationMMLUCEval (val)GSM8KHumaneval
Qwen-1.8B-Chat (BF16)43.355.633.726.2
Qwen-1.8B-Chat (Int8)43.155.833.027.4
Qwen-1.8B-Chat (Int4)42.952.831.225.0
Qwen-7B-Chat (BF16)55.859.750.337.2
Qwen-7B-Chat (Int8)55.459.448.334.8
Qwen-7B-Chat (Int4)55.159.249.729.9
Qwen-14B-Chat (BF16)64.669.860.143.9
Qwen-14B-Chat (Int8)63.668.660.048.2
Qwen-14B-Chat (Int4)63.369.059.845.7
Qwen-72B-Chat (BF16)74.480.176.464.6
Qwen-72B-Chat (Int8)73.580.173.562.2
Qwen-72B-Chat (Int4)73.480.175.361.6

2. KV cache量化

修改web_demo.py程序开启KV cache量化:

(qwen) root@intern-studio-50014188:~/Qwen# vim web_demo.py
...
    model = AutoModelForCausalLM.from_pretrained(
        args.checkpoint_path,
        device_map=device_map,
        trust_remote_code=True,
        resume_download=True,
        use_cache_quantization=True,
        use_cache_kernel=True,
        use_flash_attn=False,
    ).eval()
...

运行程序后,模型加载完毕,显存占用9G左右,有降低。但是问答测试过程中本机测试遇到如下问题待解决:

    return forward_call(*args, **kwargs)
  File "/root/.cache/huggingface/modules/transformers_modules/Qwen-14B-Chat-Int4/modeling_qwen.py", line 505, in forward
    torch.ones((key.size(1), key.size(1)), dtype=torch.bool, device=key.device)
AttributeError: 'tuple' object has no attribute 'size'
User: 你好
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/gradio/queueing.py", line 527, in process_events
    response = await route_utils.call_process_api(
  File "/usr/local/lib/python3.8/dist-packages/gradio/route_utils.py", line 270, in call_process_api
    output = await app.get_blocks().process_api(

在模型推理时,我们可以将中间结果key以及value的值量化后压缩存储,这样便可以在相同的卡上存储更多的key以及value,增加样本吞吐。

config.json里提供了use_cache_quantizationuse_cache_kernel两个参数来控制是否启用KV cache量化,具体使用方法如下:

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen-7B-Chat",
     device_map="auto",
     trust_remote_code=True,
     use_cache_quantization=True,
     use_cache_kernel=True,
     use_flash_attn=False
)

注意:
当前该功能不支持与flash attention同时开启,如果你开了KV cache量化的同时又开了flash attention(use_flash_attn=True, use_cache_quantization=True, use_cache_kernel=True),程序默认将关闭use_flash_attn。

效果方面,我们验证过Int8 KV Cache的使用对模型整体的精度指标基本无损。我们做了针对显存占用的性能测试。评测运行于单张A100-SXM4-80G GPU,模型默认使用BF16格式,默认生成1024个token,其中OOM表示内存不足。

开启了KV cache量化之后,模型在推理的时候可以开启更大的batch size (bs)。

USE KV Cachebs=1bs=4bs=16bs=32bs=64bs=100
No16.3GB24.1GB31.7GB48.7GBoomoom
Yes15.5GB17.2GB22.3GB30.2GB48.2GB72.4GB

开启了KV cache量化之后,模型在推理时可在生成更长的序列(sl,生成的token数)时,节约更多的显存。

USE KV Cachesl=512sl=1024sl=2048sl=4096sl=8192
no15.2GB16.3GB17.6GB19.5GB23.2GB
yes15GB15.5GB15.8GB16.6GB17.6GB

开启KV cache量化后,模型在推理时会将原始存进layer-past的float格式的key/value转换成int8格式,同时存储量化部分的参数。

具体操作如下:

  1. 将key/value进行量化操作
    qv,scale,zero_point=quantize_cache_v(v)
  1. 存入layer_past中:

量化格式的layer-past:

    layer_past=((q_key,key_scale,key_zero_point),
                (q_value,value_scale,value_zero_point))

原始格式的layer-past:

    layer_past=(key,value)

如果需要将layer-past中存好的key,value直接取出使用,可以使用反量化操作将Int8格式的key/value转回float格式:

    v=dequantize_cache_torch(qv,scale,zero_point)

3. 推理性能测试

本机使用官网脚本测试遇到如下问题,待解决:

  File "/root/Qwen/profile.py", line 45, in <module>
    from auto_gptq import AutoGPTQForCausalLM
ImportError: cannot import name 'AutoGPTQForCausalLM' from partially initialized module 'auto_gptq' (most likely due to a circular import) (/usr/local/lib/python3.8/dist-packages/auto_gptq/__init__.py)

这里附官网数据和方法:

这一部分将介绍模型推理的速度和显存占用的相关数据。下文的性能测算使用 此脚本 完成。

我们测算了BF16、Int8和Int4模型在生成2048个token时的平均推理速度(tokens/s)和显存使用。结果如下所示:

Model SizeQuantizationSpeed (Tokens/s)GPU Memory Usage
1.8BBF1654.094.23GB
Int855.563.48GB
Int471.072.91GB
7BBF1640.9316.99GB
Int837.4711.20GB
Int450.098.21GB
14BBF1632.2230.15GB
Int829.2818.81GB
Int438.7213.01GB
72BBF168.48144.69GB (2xA100)
Int89.0581.27GB (2xA100)
Int411.3248.86GB
72B + vLLMBF1617.602xA100

评测运行于单张A100-SXM4-80G GPU(除非提到使用2xA100),使用PyTorch 2.0.1、CUDA 11.8和Flash-Attention2。(72B + vLLM 使用 PyTorch 2.1.0和Cuda 11.8.)推理速度是生成2048个token的速度均值。

注意:以上Int4/Int8模型生成速度使用autogptq库给出,当前AutoModelForCausalLM.from_pretrained载入的模型生成速度会慢大约20%。我们已经将该问题汇报给HuggingFace团队,若有解决方案将即时更新。

我们还测量了不同上下文长度、生成长度、Flash-Attention版本的推理速度和 GPU 内存使用情况。可以在 Hugging Face 或 ModelScope 上的相应的模型介绍页面找到结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lldhsds

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值