LLM量化技术全景:GPTQ、QAT、AWQ、GGUF与GGML

01

引言

本文介绍的是在 LLM 讨论中经常听到的各种量化技术。本文的目的是提供一步一步的解释和代码,让大家可以自己使用这些技术来压缩模型。

图片

闲话少说,我们来研究一下吧!

02

Quantization

量化是指将高精度数字转换为低精度数字。低精度实体可以存储在磁盘上很小的空间内,从而减少内存需求。让我们从一个简单的量化例子开始,以澄清概念。

假设有 25 个 FP16 格式的权重值,如下图矩阵所示。

在这里插入图片描述

我们需要对这些值进行 int8 量化。具体步骤如下。

  • 旧数值的取值范围= fp16 格式的最大权重值 - fp16 格式的最小权重值 = 0.932-0.0609 = 0.871

  • 新数值的取值范围 = Int 8 包含 -128 至 127 的数字。因此,Range = 127-(-128) = 255

  • Scale: 新范围内的最大值/旧范围内的最大值=127/ 0.932 =136.2472498690413

  • 量化后的值: 计算公式为:

    Quantized Value = Round(Scale * Original Value)

经过上述转换,得到量化后的结果为:

在这里插入图片描述

  • 进而反量化操作的计算公式为:

    New Value = Quantized Value / Scale

在这里插入图片描述

  • 量化误差:

这里需要注意的一点是,当我们去量化回到 fp16 格式时,我们会发现数字似乎并不完全相同。第一个元素 0.5415 变成了 0.543。在大多数元素中都可以发现同样的问题。这就是量化-去量化过程中产生的误差。

既然我们已经了解了量化的核心思想,下面我们就来谈谈 LLM 的量化类型。

03

GPTQ原理‍

GPTQ是一种训练后量化方法。这意味着在获得预训练的大型语言模型(LLM)后,您只需将模型参数转换为较低精度即可。GPTQ更适用于GPU而非CPU。以下是GPTQ的几种主要变体:

  • 静态范围GPTQ:可将权重和激活值转换为较低精度。
  • 动态范围GPTQ:将权重转换为较低精度,并开发一个函数用于在推理过程中动态将激活值量化为较低精度。
  • 权重量化: 通过降低模型权重和/或激活值的精度来节省存储空间。在推理时,输入仍保持float32格式,因此需要将权重还原至与输入相同的精度进行计算。然而,由于舍入误差,这一过程会导致一定的精度损失。

我们首先来看下静态范围量化的过程:

  • 如果大家打算同时量化权重和激活,则需要一个样本校准数据集来进行 GPTQ。
  • 校准数据集 - 该数据集可以是从原始数据集中抽取的样本。例如,从原始预训练数据集中抽取 1000 个数据样本,作为整个数据集的代表性样本。
  • 校准数据集推理 - 接着将使用该校准数据集进行推理,以找到采样权重和相应激活的分布。该分布将作为量化的基础。 例如,特定层中激活值的范围是 0.2 至 0.9,权重的范围是 0.1 至 0.3。有了最小-最大值范围后,就可以使用本文之前解释的数学方法对该层进行量化。
  • 静态范围量化算法概述 :

在GPTQ算法中,我们逐层对神经网络进行量化,具体步骤如下:

a. 权重矩阵分组

将每一层的权重矩阵按列划分为若干组。

例如,若设置group_size=128,则权重矩阵会被划分为多个128列的组。

b. 迭代式量化处理

在每组(128列)中,先量化其中一列的数据。

量化后,调整该组剩余的权重,以补偿量化引入的误差。

c. 全局误差补偿

处理完当前组的所有列后,更新整个矩阵的其他列组(其他128列组),以进一步修正误差。这一完整过程也称为"惰性批量更新”(Lazy Batch Update)。

接下来,我们通过代码示例进一步说明。

04

GPTQ代码实现‍

这种量化方法需要使用GPU。起初,我尝试对一个7B分片的Mistral模型进行量化,但失败了。这是因为模型在下载后首先加载到CPU上,而T4显卡的CPU内存不足以支持。最终,我选择了一个较小的模型,可以在Google Colab的免费T4实例中容纳。这个模型是来自HF仓库的bigscience/bloom-3b。

!pip install auto_gptq
import torch
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import TextGenerationPipeline
from transformers import AutoTokenizer
pretrained_model_name = "bigscience/bloom-3b" 
quantize_config = BaseQuantizeConfig(bits=4, group_size=128)
# Tensors of bloom are of float16. Hence, torch_dtype=torch.float16. Do not leave torch_dtype as "auto" as this leads to a warning of implicit dtype conversion
model = AutoGPTQForCausalLM.from_pretrained(pretrained_model_name, quantize_config, trust_remote_code=False, device_map="auto", torch_dtype=torch.float16)  # changing device map to "cuda" does not have any impact on T4 GPU mem usage.
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name)
# Calibration
examples = [tokenizer("Automated machine learning is the process of automating the tasks of applying machine learning to real-world problems. AutoML potentially includes every stage from beginning with a raw dataset to building a machine learning model ready for deployment.")
]  # giving only 1 example here for testing. In an real world scenario, you might want to give 500-1000 samples.
model.quantize(examples)
quantized_model_dir = "bloom3b_q4b_gs128"
model.save_quantized(quantized_model_dir)

从下面的图片可以注意到一个重要的点:在量化过程中,GPU内存其实并没有被充分利用,虽然GPU是进行量化的前提条件。

在这里插入图片描述

我们使用以下代码测试下量化模型的输出:

# Inference with quantized model
device = "cuda:0"  # make use of GPU for inference.
model = AutoGPTQForCausalLM.from_quantized(quantized_model_dir, device=device, torch_dtype=torch.float16)
pipeline = TextGenerationPipeline(model=model, tokenizer=tokenizer, max_new_tokens=50)  
print(pipeline("Automated machine learning is")[0]["generated_text"])
# Sequence length of a model (bloom has seq length of 2048) is total tokens in input & output; 
# max_new_tokens is number of output tokens
# Do note that there is a warning while executing this code that model's sequence length was not in model config. However, what i could find any option to pass the seq length of bloom in configurations.
# The warnings related to fused modules & unsupported model is not valid. The links that i used to validate this are in references.

结果如下:

在这里插入图片描述

当执行推理代码(上图)时,GPU 的使用率会上升。这意味着量化模型正从 CPU 转移到 GPU,从而增加了 GPU 内存消耗。

在这里插入图片描述

至此,GPTQ 结束。

05

GGUF | GGML‍

GGUF是GGML的升级版本。GGML作为LLM库的C++实现,支持LLaMA系列、Falcon等多种大语言模型。基于该库的模型可运行于苹果自研芯片(Mac OS系统)——这种由苹果独创的处理器创新性地集成了CPU与GPU功能。

GGUF格式同时兼容Windows和Linux操作系统,这意味着普通CPU环境也能运行这些模型。当CPU性能不足时,用户还可将部分模型层卸载至GPU运算。该格式提供从2比特到8比特的多级量化选项,具体操作流程为:先获取原始LLaMA模型,将其转换为GGUF格式,最终对GGUF格式进行低精度量化处理。

  • 将模型转换为 GGML 格式的代码

# Install llama.cpp
!git clone https://github.com/ggerganov/llama.cpp
!cd llama.cpp && git pull && make clean && LLAMA_CUBLAS=1 make
!pip install -r llama.cpp/requirements.txt
# Download model
!git lfs install
!git clone https://huggingface.co/Siddharthvij10/MistralSharded2
# Convert weights to fp16
!python llama.cpp/convert.py MistralSharded2 --outtype f16 --outfile "MistralSharded2/mistralsharded2.fp16.bin"
# Quantization - Requires GPU RAM as a mandate. However, does not use much of it.
# As per info on https://huggingface.co/TheBloke/Llama-2-13B-chat-GGML, q4_k_m uses Q6_K for half of the attention.wv and feed_forward.w2 tensors, else Q4_K!./llama.cpp/quantize "MistralSharded2/mistralsharded2.fp16.bin" "MistralSharded2/mistralsharded2.Q4_K_M.gguf" q4_k_m

GGML 量化过程中的内存使用情况:

在这里插入图片描述

比较原始模型和 GGML 模型的大小:

在这里插入图片描述

  • 使用 GGML 模型进行推理的代码

推理代码如下:

import os# There are 32 layers in mistral 7B. Hence offloading all 32 layers to GPU while loading for inference below.!./llama.cpp/main -m "MistralSharded2/mistralsharded2.Q4_K_M.gguf" -n 35 --color -ngl 32 -p "Automated machine learning"

结果如下:

在这里插入图片描述

推理过程中 GPU 的使用情况:

在这里插入图片描述

06

QAT‍

我们开始进行量化感知训练(QAT)时,会使用一个预训练模型或后训练量化(PTQ)模型作为基础。若采用PTQ模型,QAT微调的主要目的是恢复因PTQ过程造成的精度损失。QAT会改变模型的前向传播过程,但保持反向传播不受影响。在QAT中,我们只对那些参数量化后不会导致精度显著下降的网络层实施量化操作,而对量化会负面影响精度的层则保留其原始精度。

QAT的核心思想是根据每层权重的精度要求,将输入数据量化为较低精度。同时,若下一层需要更高精度,QAT还会负责将权重与输入相乘后的输出重新转换回高精度。这种先将输入降精度、再将计算输出恢复高精度的过程被称为"伪量化节点插入"——之所以称为"伪量化",是因为它既执行量化又执行反量化,最终还原为基础运算。

QAT在前向传播中引入量化误差,这些误差会累积并通过反向传播中的优化器进行调整。通过这种方式,模型能够学习如何通过减小量化引入的误差来优化自身性能。

  • QAT 代码

请注意,TensorFlow 官网上提供了几段代码示例,其中一段使用标准 TensorFlow,另一段使用 tf-nightly。我在使用标准 TensorFlow 时遇到了“模型中的某些层不支持 QAT”的错误,因此切换到了 nightly 版本。此外,我还移除了 Keras 模型中的所有复杂层(如自定义层或高级结构)。由于这只是一个演示用的简单模型,代码是在 CPU 上运行的。

! pip uninstall -y tensorflow
! pip install -q tf-nightly  # Use tf-nightly instead of tensorflow since it gets updated with fixes every day
! pip install -q tensorflow-model-optimization  # this lib is used for QAT
import numpy as np
import pandas as pd
import tensorflow as tf
import tensorflow_model_optimization as tfmot
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
### Sample Keras model - Code generated by ChatGPT
# Generate sample data
np.random.seed(0)
data = pd.DataFrame(np.random.rand(1000, 5), columns=['Feature1', 'Feature2', 'Feature3', 'Feature4', 'Feature5'])
target = pd.Series(np.random.randint(0, 2, size=1000), name='Target')
# Split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=42)
# Standardize features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Define the Keras model
model = tf.keras.Sequential([tf.keras.layers.Dense(64, activation='relu', input_shape=(5,)),tf.keras.layers.Dense(32, activation='relu'),tf.keras.layers.Dense(1, activation='sigmoid')
])
# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Train the model
model.fit(X_train_scaled, y_train, epochs=10, batch_size=32, validation_split=0.2)
# Evaluate the model
test_loss, test_accuracy = model.evaluate(X_test_scaled, y_test)
print(f'Test Loss: {test_loss}, Test Accuracy: {test_accuracy}')
quant_aware_model = tfmot.quantization.keras.quantize_model(model)
quant_aware_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Fine tune to create a quant aware model
quant_aware_model.fit(X_train_scaled, y_train, epochs=10, batch_size=32, validation_split=0.2)
# Evaluate the quant aware model
test_loss, test_accuracy = quant_aware_model.evaluate(X_test_scaled, y_test)
print(f'Test Loss: {test_loss}, Test Accuracy: {test_accuracy}')

结果如下:

在这里插入图片描述

07

AWQ‍

AWQ适用于 GPU 或 CPU。其核心思想是不量化所有权重,而是选择性量化对模型性能影响较小的权重,从而保持模型的有效性。

算法流程:

a. 校准(Calibration)

向预训练的大语言模型(LLM)输入样本数据,分析权重和激活值的分布。

识别关键激活值及其对应的权重(即对模型输出影响较大的部分)。

b. 缩放(Scaling)

放大关键权重(提高其数值范围),同时对非关键权重进行低精度量化。

由于重要权重被保留(甚至增强),而次要权重被压缩,量化带来的精度损失被最小化。

c. 权重格式要求(SafeTensor)

AWQ 要求模型权重从 PyTorch 的 .bin 格式转换为 SafeTensor(.safetensors)格式。转换方法可参考官方指南:

链接:https://huggingface.co/spaces/safetensors/convert
在这里插入图片描述

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

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

相关文章

IP的基础知识以及相关机制

IP地址 1.IP地址的概念 IP地址是分配给连接到互联网或局域网中的每一个设备的唯一标识符 也就是说IP地址是你设备在网络中的定位~ 2.IP版本~ IP版本分为IPv4和IPv6,目前我们最常用的还是IPv4~~但是IPv4有个缺点就是地址到现在为止,已经接近枯竭~~&…

本地使用Ollama部署DeepSeek

以下是在本地使用Ollama部署DeepSeek的详细教程,涵盖安装、修改安装目录、安装大模型以及删除大模型的操作步骤。 安装Ollama 1. 系统要求 确保你的系统满足以下条件: 操作系统:macOS、Linux或者Windows。足够的磁盘空间和内存。 2. 安装…

开源项目实战学习之YOLO11:ultralytics-cfg-datasets-Objects365、open-images-v7.yaml文件(六)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 medical - pills.yaml 通常用于配置与医学药丸检测任务相关的参数和信息 Objects365.yaml 用于配置与 Objects365 数据集相关信息的文件。Objects365 数据集包含 365 个不同的物体类别…

23种设计模式-行为型模式之策略模式(Java版本)

Java 策略模式(Strategy Pattern)详解 🧠 什么是策略模式? 策略模式是一种行为型设计模式,它定义了一系列算法,把它们一个个封装起来,并且使它们可以互相替换。策略模式让算法独立于使用它的客…

使用 AI Agent 改善师生互动的设计文档

使用 AI Agent 改善师生互动的设计文档 一、引言 1.1 研究背景 当前教育领域的师生互动存在诸多挑战,如教师负担过重、学生个体差异大导致难以满足所有人的需求,以及信息传递延迟等问题。引入AI-Agent能够有效缓解这些问题,通过自动化手段协…

2、Ubuntu 环境下安装RabbitMQ

⼀. 安装Erlang RabbitMqRabbitMq需要Erlang语⾔的⽀持,在安装rabbitMq之前需要安装erlang需要Erlang语⾔的⽀持,在安装rabitMq之前需要安装erlang。 安装erlang # 更新软件包 sudo apt-get update # 安装 erlang sudo apt-get install erlang 查看er…

Node.js 操作 ElasticSearch 完整指南:从安装到实战

本文将手把手教你如何搭建 ElasticSearch 环境,并通过 Node.js 实现高效数据检索。包含 10 个可直接复用的代码片段,助你快速掌握搜索、聚合等核心功能! 环境搭建篇 1. ElasticSearch 安装要点 下载 es下载连接 下载下来后,进…

硬核科普丨2025年安全、高效网络准入控制系统深度解析

阳途网络准入控制系统(Network Access Control,简称NAC)是当代网络安全领域的重要工具,有效防止未经授权的访问和数据泄露,保障网络资源的安全性和完整性。本文将深入探讨阳途网络准入控制系统的的重要性和作用。 一、…

搜索二叉树-key的搜索模型

二叉搜索树(Binary Search Tree, BST)是一种重要的数据结构,它有两种基本模型:Key模型和Key/Value模型。 一、Key模型 1.基本概念 Key模型是二叉搜索树中最简单的形式,每个节点只存储一个键值(key),没有额外的数据值(value)。这…

安卓四大组件之ContentProvider

目录 实现步骤 代码分析 onCreate insert query ContextHolder Cursor 作用与用法 基本步骤: 可能的面试题:为什么使用Cursor? 为什么使用Cursor 使用Cursor的好处 静态内部类实现单例模式 AnndroidManifest.xml配置信息 注释的…

【HTML】【Web开发】滑动条挑战

最近在思考如何开发一些入门级的迷你游戏,于是抽空写了个HTML的滑动条小游戏。 游戏规则如下: 在[0, 100]区间内随机生成一个目标值,显示为:X% 倒计时 3 秒过后,出现 10 秒的挑战倒计时和【停止】按钮 挑战倒计时结…

面试踩过的坑

1、 “”和equals 的区别 “”是运算符,如果是基本数据类型,则比较存储的值;如果是引用数据类型,则比较所指向对象的地址值。equals是Object的方法,比较的是所指向的对象的地址值,一般情况下,重…

专业软件开发全流程实践指南

作为一家拥有十余年行业积淀的专业软件开发服务提供商,我们见证了太多项目从无到有的全过程。今天,我们就用最朴实的语言,跟大家聊聊一个软件产品从构思到上线的完整历程。这些经验不仅适用于自建技术团队的企业,对正在寻找软件外…

聊透多线程编程-线程互斥与同步-12. C# Monitor类实现线程互斥

目录 一、什么是临界区? 二、Monitor类的用途 三、Monitor的基本用法 四、Monitor的工作原理 五、使用示例1-保护共享变量 解释: 六、使用示例2-线程间信号传递 解释: 七、注意事项 八、总结 在多线程编程中,线程之间的…

第R4周:LSTM-火灾温度预测

文章目录 一、前期准备工作1.导入数据2. 数据集可视化 二、构建数据集1. 数据集预处理2. 设置X, y3. 划分数据集 三、模型训练1. 构建模型2. 定义训练函数3. 定义测试函数4. 正式训练模型 四、模型评估1. Loss图片2. 调用模型进行预测3. R2值评估 总结: &#x1f36…

toCharArray作用

toCharArray() 是 Java 中 String 类的一个方法,其作用是将字符串对象转换为一个字符数组。下面为你详细介绍其用法、原理和示例。 方法定义 toCharArray() 方法在 java.lang.String 类里被定义,方法签名如下 public char[] toCharArray() 此方法没有…

STM32八股【6】-----CortexM3的双堆栈(MSP、PSP)设计

STM32的线程模式(Thread Mode)和内核模式(Handler Mode)以及其对应的权级和堆栈指针 线程模式: 正常代码执行时的模式(如 main 函数、FreeRTOS任务) 可以是特权级(使用MSP&#xff…

驱动支持的最高CUDA版本与实际安装的Runtime版本

查看电脑上安装的CUDA版本的多种方法,适用于不同系统和场景。 方法一:通过命令行工具 1. 查看CUDA Driver API版本(显卡驱动支持的CUDA版本) 命令:nvidia-smi操作: 打开终端(Windows为CMD/Pow…

Python CT图像预处理——基于ITK-SNAP

Python CT图像预处理——nii格式读取、重采样、窗宽窗位设置_python读取nii-CSDN博客 基于原文指出以下几个问题:文件路径设置模糊;nilabel里面使用的get_data() 方法已经过时;需要导入scikit-image,还要导入一个matplotlib。 一…

【MQ篇】RabbitMQ之消息持久化!

目录 一、 交换机持久化 (Exchange Persistence)二、 队列持久化 (Queue Persistence)三、 消息持久化 (Message Persistence)四、 持久化的“黄金三角” 🔱:三者缺一不可!五、 来,完整的代码示例(整合持久化和确认机制…