Qwen大模型实践之量化

2024-05-08 21:12
文章标签 实践 模型 量化 qwen

本文主要是介绍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)和输出令牌吞吐量都提升明显,接近于可接受的水平。

alt

附官网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 上的相应的模型介绍页面找到结果。

本文由 mdnice 多平台发布

这篇关于Qwen大模型实践之量化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/971445

相关文章

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee