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

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

虚拟机Centos7安装MySQL数据库实践

《虚拟机Centos7安装MySQL数据库实践》用户分享在虚拟机安装MySQL的全过程及常见问题解决方案,包括处理GPG密钥、修改密码策略、配置远程访问权限及防火墙设置,最终通过关闭防火墙和停止Net... 目录安装mysql数据库下载wget命令下载MySQL安装包安装MySQL安装MySQL服务安装完成

SpringBoot整合(ES)ElasticSearch7.8实践

《SpringBoot整合(ES)ElasticSearch7.8实践》本文详细介绍了SpringBoot整合ElasticSearch7.8的教程,涵盖依赖添加、客户端初始化、索引创建与获取、批量插... 目录SpringBoot整合ElasticSearch7.8添加依赖初始化创建SpringBoot项