【大模型入门指南 07】量化技术浅析

news2025/1/12 0:04:43

【大模型入门指南】系列文章:

  • 【大模型入门指南 01】深度学习入门
  • 【大模型入门指南 02】LLM大模型基础知识
  • 【大模型入门指南 03】提示词工程
  • 【大模型入门指南 04】Transformer结构
  • 【大模型入门指南 05】LLM技术选型
  • 【大模型入门指南 06】LLM数据预处理
  • 【大模型入门指南 07】量化技术解析
  • 【大模型入门指南 08】微调和分布式训练
  • 【大模型入门指南 09】LLM和多模态模型高效推理实践
  • 【大模型入门指南 10】LLM 部署
  • 【大模型入门指南 11】大模型自动评估理论和实战
  • 【大模型入门指南 12】LISA微调技术解析
  • 【大模型入门指南 13】从 OpenAI-O1 看大模型的复杂推理能力
  • 【大模型入门指南 14】Agent微调实战
  • 【More…】

本文目录

  • 量化是什么
  • AutoGPTQ
  • Bitsandbytes
  • GGML
  • AWQ
  • NLP 大模型高频面题汇总
  • NLP基础篇
        • BERT 模型面
    • LLMs 微调面


量化是什么

前文中我们提到,模型的推理过程是一个复杂函数的计算过程,这个计算一般以矩阵乘法为主,也就是涉及到了并行计算。一般来说,单核CPU可以进行的计算种类更多,速度更快,但一般都是单条计算;而显卡能进行的都是基础的并行计算,做矩阵乘法再好不过。如果把所有的矩阵都加载到显卡上,就会导致显卡显存的占用大量增加,尤其是LLM模型大小从7b、14b、34b到几百b不等,占用显存的大小就是惊人的数字,如何在减少运算量和显存占用的条件下,做到推理效果不下降太多呢?在这里需要引入浮点数和定点数的概念。

双精度浮点数:在PyTorch中用torch.float64表示,或者在其他语言中也称为double类型,在LLM训练中一般比较少用

全精度浮点数:在PyTorch中用torch.float32表示

低精度浮点数:在PyTorch中用torch.bfloat16和torch.float16表示。这两个浮点数的差别在上图中可以表示:

  1. bfloat16的小数部分较短,整数部分较长,这会有利于在训练中减少梯度爆炸的情况(即梯度累加值超过了最大值),但是这种数据类型是在N系列显卡Ampere系列才支持的,即30系列显卡。
  2. float16的小数部分较长,这意味着在精度控制上float16更好,但整数部分较短,比较容易梯度爆炸。

那么是否有更加减少显存占用和计算量的数值表达方式呢?那么可以考虑是否把浮点数转换为定点数(整数),整数计算更快更省显存,如果计算精度下降不大就很完美了。这种用整数计算代替浮点数计算的方法就是量化

量化的基本原理是根据每个tensor的浮点型最大值和最小值,将其映射为一个固定范围的整形数值集合,比如[-127~127]。假设一个简单的公式:qweight=round(weight/scale),其中qweight代表量化后权重,weight代表量化前权重,scale代表缩放因子,可以看到在进行缩放后为了将浮点型转换为整数过程中增加了round操作丢失了小数部分。在后续计算或反量化为浮点型时存在无法完全还原的情况,这就是精度损失。

按照量化发生的步骤区分,可以划分为PTQ(训练后量化,或离线量化)和QAT(训练感知型量化,或在线量化)。PTQ量化可以分为data-free和calibration两种,前者不使用数据集进行校准直接计算量化因子,后者会根据少量真实数据进行统计分析并对量化因子进行额外校准,但耗费的时间更长。QAT量化会先在待量化的算子上增加一个伪量化结构,并在训练时模拟量化过程并实时更新计算量化因子(类似反向传播过程)及原始权重。QAT由于较为复杂一般作为辅助措施存在,用于改进PTQ量化的技术手段。

按照量化方法可以划分为线性量化、非线性量化(如对数量化)等多种方式,目前较为常用的是线性量化。其中线性量化又可以按照对称性划分为对称量化和非对称量化,非对称量化为了解决weight分布不均匀问题,其在公式中增加了zero_point项:qweight=round(weight/scale + zero_point),使稠密数据部分可以得到更宽泛的数值范围。

按照量化粒度划分可以分为**逐层量化(每层使用一套量化因子)、逐组量化(在每层中按照group使用一套量化因子)、逐通道量化(按channel划分量化因子)**等几种方式。

按照量化最大值的阈值区分,可以分为饱和量化和不饱和量化两种。不饱和量化按照浮点数最大值和量化后最大值的比例计算量化因子,由于原始weight的非均匀性会导致某些整形数值范围存在权重空缺。饱和量化会计算一个中间值以计算出量化因子,因此会舍弃一部分不重要数据,将重要数据尽量均匀的分布到量化数值范围内。

按照量化后的比特数划分,可以分为2比特量化,4比特量化,8比特量化等类型。

一般来说,PyTorch中量化模块的forward过程会先对量化权重进行反量化后使用浮点数进行计算。

下面介绍几种常用的量化库。

AutoGPTQ

该库需要引入额外的校准数据集进行量化校准。相比bitsandbytes量化精度较高,推理速度较快,但训练后不支持合并adapter

# 例子来自于https://github.com/PanQiWei/AutoGPTQ
from modelscope import AutoTokenizer, snapshot_download
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
import logging
import shutil
import os

logging.basicConfig(
    format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S"
)

pretrained_model_dir = snapshot_download("qwen/Qwen-1_8B-Chat")
quantized_model_dir = "qwen-1_8B-4bit"

shutil.rmtree(quantized_model_dir, ignore_errors=True)
shutil.copytree(pretrained_model_dir, quantized_model_dir)
for _file in os.listdir(quantized_model_dir):
    if ".safetensors" in _file or ".bin" in _file:
        os.remove(os.path.join(quantized_model_dir, _file))

tokenizer = AutoTokenizer.from_pretrained(pretrained_model_dir, use_fast=True, trust_remote_code=True)
examples = [
    tokenizer(
        "auto-gptq is an easy-to-use model quantization library with user-friendly apis, based on GPTQ algorithm."
    )
]

quantize_config = BaseQuantizeConfig(
    bits=4,  # quantize model to 4-bit
    group_size=128,  # it is recommended to set the value to 128
    desc_act=False,  # set to False can significantly speed up inference but the perplexity may slightly bad
)

# load un-quantized model, by default, the model will always be loaded into CPU memory
model = AutoGPTQForCausalLM.from_pretrained(pretrained_model_dir, quantize_config, trust_remote_code=True).to(0)

# quantize model, the examples should be list of dict whose keys can only be "input_ids" and "attention_mask"
model.quantize(examples)

# save quantized model
model.save_quantized(quantized_model_dir)

# save quantized model using safetensors
model.save_quantized(quantized_model_dir, use_safetensors=True)

# load quantized model to the first GPU
model = AutoGPTQForCausalLM.from_quantized(quantized_model_dir, device="cuda:0", trust_remote_code=True)
# inference with model.generate
print(tokenizer.decode(model.generate(**tokenizer("auto_gptq is", return_tensors="pt").to(model.device))[0]))

在SWIFT中,可以使用已经量化好的AutoGPTQ模型直接进行训练:

swift sft --model_id_or_path qwen/Qwen-7B-Chat-Int4 --model_revision master --sft_type lora --tuner_backend swift --template_type qwen --dtype fp16 --output_dir output --dataset leetcode-python-en --train_dataset_sample -1 --num_train_epochs 1 --max_length 512 --check_dataset_strategy warning --lora_rank 8 --lora_alpha 32 --lora_dropout_p 0.05 --lora_target_modules ALL --gradient_checkpointing true --batch_size 1 --weight_decay 0.01 --learning_rate 1e-4

上面的命令行中,qwen/Qwen-7B-Chat-Int4是已经量化好的Qwen-7B-Chat模型。

Bitsandbytes

bitsandbytes是一种data-free的量化库。该量化方法速度较快(因为其不需要数据校准),因此可以在模型加载时动态量化,且该方法训练速度较快,因此训练兼容性较好,一般用于QLoRA训练中,且训练后可以合并adapter。当由于其没有数据校准过程,因此精度较AutoGPTQ较低。

from modelscope import AutoModelForCausalLM, AutoTokenizer
import torch

model = AutoModelForCausalLM.from_pretrained(
  'qwen/Qwen-1_8B-Chat',
  load_in_8bit=True,
  trust_remote_code=True)

tokenizer = AutoTokenizer.from_pretrained('qwen/Qwen-1_8B-Chat', trust_remote_code=True)

print(model(**tokenizer('how are you?', return_tensors='pt')))

GGML

GGML和GGUF是GGML C++推理库的两种量化格式,其中GGUF格式较新,可以保留模型版本等其他自定义信息。这两种格式也是PTQ形式的量化算法,但GGML和GGUF格式的量化算法更适配于CPU推理,因此在CPU上运行更快,而GPTQ量化对GPU更加友好,两者的推理精度相仿。因此,*.cpp类型使用了GGML推理库的推理框架都更适配于CPU推理。

AWQ

AWQ量化方式假设不是所有权重都影响模型性能,因此在量化过程中会对特殊权重进行特殊处理以减轻量化过程中的精度损失。因此在和GPTQ量化保持类似推理速度的同时可以具备更好的精度。

目前VLLM对AWQ的支持较好, 可以考虑在推理加速时使用AWQ量化方式。


NLP 大模型高频面题汇总

NLP基础篇

  • 【NLP 面试宝典 之 模型分类】 必须要会的高频面题
  • 【NLP 面试宝典 之 神经网络】 必须要会的高频面题
  • 【NLP 面试宝典 之 主动学习】 必须要会的高频面题
  • 【NLP 面试宝典 之 超参数优化】 必须要会的高频面题
  • 【NLP 面试宝典 之 正则化】 必须要会的高频面题
  • 【NLP 面试宝典 之 过拟合】 必须要会的高频面题
  • 【NLP 面试宝典 之 Dropout】 必须要会的高频面题
  • 【NLP 面试宝典 之 EarlyStopping】 必须要会的高频面题
  • 【NLP 面试宝典 之 标签平滑】 必须要会的高频面题
  • 【NLP 面试宝典 之 Warm up 】 必须要会的高频面题
  • 【NLP 面试宝典 之 置信学习】 必须要会的高频面题
  • 【NLP 面试宝典 之 伪标签】 必须要会的高频面题
  • 【NLP 面试宝典 之 类别不均衡问题】 必须要会的高频面题
  • 【NLP 面试宝典 之 交叉验证】 必须要会的高频面题
  • 【NLP 面试宝典 之 词嵌入】 必须要会的高频面题
  • 【NLP 面试宝典 之 One-Hot】 必须要会的高频面题
BERT 模型面
  • 【NLP 面试宝典 之 BERT模型】 必须要会的高频面题
  • 【NLP 面试宝典 之 BERT变体】 必须要会的高频面题
  • 【NLP 面试宝典 之 BERT应用】 必须要会的高频面题

LLMs 微调面

  • 【NLP 面试宝典 之 LoRA微调】 必须要会的高频面题
  • 【NLP 面试宝典 之 Prompt】 必须要会的高频面题
  • 【NLP 面试宝典 之 提示学习微调】 必须要会的高频面题
  • 【NLP 面试宝典 之 PEFT微调】 必须要会的高频面题
  • 【NLP 面试宝典 之 Chain-of-Thought微调】 必须要会的高频面题
  • ......
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线工具箱源码优化版

在线工具箱 前言效果图部分源码源码下载部署教程下期更新 前言 来自缤纷彩虹天地优化后的我爱工具网源码,百度基本全站收录,更能基本都比较全,个人使用或是建站都不错,挑过很多工具箱,这个比较简洁,非常实…

@LocalBuilder装饰器: 维持组件父子关系

一、前言 当开发者使用Builder做引用数据传递时,会考虑组件的父子关系,使用了bind(this)之后,组件的父子关系和状态管理的父子关系并不一致。为了解决组件的父子关系和状态管理的父子关系保持一致的问题,引入LocalBuilder装饰器。…

C 语言内存探秘:数据存储的字节密码

文章目录 一、数据在内存中的存储1、基本数据类型存储2、数组存储3、结构体存储1、基本存储规则2、举例说明3、查看结构体大小和成员偏移量的方法 二、大小端字节序三、字节序的判断 一、数据在内存中的存储 1、基本数据类型存储 整型:如int类型,通常在…

双因素身份验证技术在NPI区域邮件安全管控上的解决思路

在制造业中,NPI(New Product Introduction,新产品导入)区域是指专门负责新产品从概念到市场推出全过程的部门或团队。NPI 的目标是确保新产品能够高效、高质量地投入生产,并顺利满足市场需求。在支撑企业持续创新和竞争…

浙江安吉成新的分布式光伏发电项目应用

摘 要:分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上,利用太阳能进行发电的一种可再生能源利用方式,与传统的大型集中式光伏电站相比,分布式光伏发电具有更灵活的布局、更低的建设成本和更高…

更新Office后,LabVIEW 可执行程序生成失败

问题描述: 在计算机中,LabVIEW 开发的源程序运行正常,但在生成可执行程序时提示以下错误: ​ A VI broke during the build process from being saved without a block diagram. Either open the build specification to include…

mysql-operator容器化部署mysql8

基础组件容器化 前一段时间容器化了容器的s3和pika。由于已经有开源方案,本次mysql直接以operator容器化。使用的是[presslabs的mysql-operator]https://github.com/presslabs/mysql-operator。 主要特征 presslabs/mysql-operator自动化搭建主从集群。使用XtraBack…

web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理

web-app uniapp监测屏幕大小的变化对数组一行展示数据作相应处理 1.uni.getSystemInfoSync().screenWidth; 获取屏幕宽度 2.uni.onWindowResize() 实时监测屏幕宽度变化 3.根据宽度的大小拿到每行要展示的数量itemsPerRow 4.为了确保样式能够根据 items…

[OPEN SQL] 限定选择行数

本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航班用户(SCUSTOM) 该数据库表中的部分值如下所示 指定查询多少行数据&#xff0c;我们可以使用语法UP TO n ROWS来实现对数据前n项的查询 语法格式 SELECT * FROM <dbtab> UP TO n ROWS 参数说明 db…

金融项目实战 02|接口测试分析、设计以及实现

目录 ⼀、接口相关理论 二、接口测试 1、待测接口&#xff1a;投资业务 2、接口测试流程 3、设计用例理论 1️⃣设计方法 2️⃣工具 4、测试点提取 5、测试用例&#xff08;只涉及了必测的&#xff09; 1️⃣注册图⽚验证码、注册短信验证码 2️⃣注册 3️⃣登录 …

74 mysql having 的实现

前言 这里 我们主要是 看一下 having 的相关实现 having 经常是配合 group by 这边进行使用, 进行一个基于 group by 之后的结果的一个, 条件限定 我们这里 以最简单的 group by having 来进行调试, 他会分为 两个阶段, 一个阶段是 group by 之后的结果输出到临时表, 另外…

Google发布图像生成新工具Whisk:无需复杂提示词,使用图像和人工智能将想法可视化并重新混合

Whisk 是 Google Labs 的一项新实验&#xff0c;可使用图像进行快速而有趣的创作过程。Whisk不会生成带有长篇详细文本提示的图像&#xff0c;而是使用图像进行提示。只需拖入图像&#xff0c;即可开始创建。 whisk总结如下&#xff1a; Whisk 是 Google 实验室最新的生成图像实…

K8s Pod OOMKilled,监控却显示内存资源并未打满

1. 问题现象 pod一直重启&#xff0c;通过grafana查看&#xff0c;发现内存使用率并没有100%。 2. 排查过程 2.1 describe查看pod最新一次的状态 可以明显看到&#xff0c;最近一次的重启就是因为内存不足导致的。 2.2 describe 查看node节点状态 找到原因了&#xff0c;原来…

33.3K 的Freqtrade:开启加密货币自动化交易之旅

“ 如何更高效、智能地进行交易成为众多投资者关注的焦点。” Freqtrade 是一款用 Python 编写的免费开源加密货币交易机器人。它就像一位不知疲倦的智能交易助手&#xff0c;能够连接到众多主流加密货币交易所&#xff0c;如 Binance、Bitmart、Bybit 等&#xff08;支…

vscode开启调试模式,结合Delve调试器调试golang项目详细步骤

1.前期准备 (1).在vs code中的扩展程序中搜索并安装Go扩展程序 (2).安装 Delve 调试器 go install github.com/go-delve/delve/cmd/dlvlatest (3).打开vs code的命令面板&#xff0c;输入Go: Install/Update Tools&#xff0c;并单击该命令执行&#xff0c;安装或更新Go语…

Postman接口测试03|执行接口测试、全局变量和环境变量、接口关联、动态参数、断言

目录 七、Postman 1、安装 2、postman的界面介绍 八、Postman执行接口测试 1、请求页签 3、响应页签 九、Postman的环境变量和全局变量 1、创建环境变量和全局变量可以解决的问题 2、postman中的操作-全局变量 1️⃣手动设置 2️⃣代码设置 3️⃣界面获取 4️⃣代…

Python Matplotlib教程-Matplotlib 多子图布局

Python Matplotlib 多子图布局 Matplotlib 是 Python 中最常用的数据可视化库&#xff0c;它提供了强大的功能来绘制不同类型的图表。在实际应用中&#xff0c;通常需要将多个图表绘制在同一个画布上&#xff0c;这就需要用到 多子图布局。本篇文章将详细介绍如何使用 Matplot…

【Java项目】基于SpringBoot的【校园新闻系统】

【Java项目】基于SpringBoot的【校园新闻系统】 技术简介&#xff1a;本系统使用采用B/S架构、Spring Boot框架、MYSQL数据库进行开发设计。 系统简介&#xff1a;主要包括二大功能模块&#xff0c;即用户功能模块和管理员功能模块。系统中的核心用户是管理员&#xff0c;管理员…

c++入门之 命名空间与输入输出

1、命名空间 1.1使用命名空间的原因 先看一个例子&#xff1a; #include <iostream>int round 0;int main() {printf("%d", round);return 0; }请问&#xff0c;这个程序能跑起来吗&#xff1f; 答案是否定的 原因是&#xff0c;当我们想创建一个全局变量 …

【网络安全渗透测试零基础入门】之XSS攻击获取用户cookie和用户密码(实战演示)

前言 大家好&#xff0c;我是demon 这是demon给粉丝盆友们整理的网络安全渗透测试入门阶段XSS攻击教程。 本阶段主要讲解XSS攻击获取用户cookie和用户密码。 喜欢的朋友们&#xff0c;记得给晓晓点赞支持和收藏一下&#xff0c;关注我&#xff0c;学习黑客技术。 简介 该…