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.pswp.cn/bicheng/78448.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78448.shtml
英文地址,請注明出處:http://en.pswp.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)四、 持久化的“黃金三角” 🔱:三者缺一不可!五、 來,完整的代碼示例(整合持久化和確認機制…