【大模型學習 | BERT 量化學習 (1)】

BERT 情感分析

一、 數據集加載與模型訓練

from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset
import torch
import numpy as np
from sklearn.metrics import accuracy_score
mode_name_or_path = '/root/autodl-tmp/bert-base-uncased'# 1. 加載 SST-2 數據集
dataset = load_dataset("glue", "sst2")
model = BertForSequenceClassification.from_pretrained("bert-base-uncased").to('cuda')
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
model.save_pretrained(mode_name_or_path)
tokenizer.save_pretrained(mode_name_or_path)
# 2. 數據預處理(tokenization)
def preprocess(example):return tokenizer(example["sentence"], truncation=True, padding="max_length", max_length=128)encoded_dataset = dataset.map(preprocess, batched=True)
encoded_dataset = encoded_dataset.rename_column("label", "labels")
encoded_dataset.set_format(type="torch", columns=["input_ids", "attention_mask", "labels"])# 4. 訓練參數
training_args = TrainingArguments(output_dir="./output",# evaluation_strategy="epoch",per_device_train_batch_size=16,per_device_eval_batch_size=32,num_train_epochs=1,logging_dir="./logs",
)# 5. 定義指標
def compute_metrics(p):preds = np.argmax(p.predictions, axis=1)return {"accuracy": accuracy_score(p.label_ids, preds)}print(encoded_dataset["train"])
# 6. 啟動訓練器
trainer = Trainer(model=model,args=training_args,train_dataset=encoded_dataset["train"],eval_dataset=encoded_dataset["validation"],compute_metrics=compute_metrics,
)trainer.train()
trainer.evaluate()

二、HUGGING FACE 量化

from transformers import AutoModelForSequenceClassification, AutoTokenizer
import torch
from analyze import *# 1. 加載訓練后BERT模型和tokenizer
model_name = "./output/checkpoint-2105/"
tokenizer = AutoTokenizer.from_pretrained(model_name)
original_model = AutoModelForSequenceClassification.from_pretrained(model_name).to('cuda')# 2. 8-bit量化加載模型
quantized_model = AutoModelForSequenceClassification.from_pretrained(model_name,device_map="auto",  # 自動分配到可用設備load_in_8bit=True,  # 啟用8-bit量化
)
  • 比較模型大小

模型大小大幅度降低,降低了近3-4倍;

def print_model_size(model, model_name):param_size = 0for param in model.parameters():param_size += param.nelement() * param.element_size()buffer_size = 0for buffer in model.buffers():buffer_size += buffer.nelement() * buffer.element_size()size_all_mb = (param_size + buffer_size) / 1024**2print(f"{model_name} size: {size_all_mb:.3f}MB")print_model_size(original_model, "Original BERT")
print_model_size(quantized_model, "Quantized 8-bit BERT")
#Original BERT size: 417.655MB
#Quantized 8-bit BERT size: 127.269MB
  • 模型精度比較

在大小降低的同時,在驗證集上的精度也大幅度降低;

def evaluate(model, dataset, labels):model.eval()preds = []with torch.no_grad():for i in range(0, len(dataset), 32):  # batch size = 32batch = dataset[i:i + 32]input_ids = batch["input_ids"].to(model.device)attention_mask = batch["attention_mask"].to(model.device)outputs = model(input_ids=input_ids, attention_mask=attention_mask)logits = outputs.logitsbatch_preds = torch.argmax(logits, dim=1).cpu()preds.extend(batch_preds.tolist())correct = sum([int(p == t) for p, t in zip(preds, labels)])acc = correct / len(labels)return acc
def preprocess(example):return tokenizer(example["sentence"], truncation=True, padding="max_length", max_length=128)from datasets import load_dataset
dataset = load_dataset("glue", "sst2")
val_dataset = dataset["validation"]encoded_val_dataset = val_dataset.map(preprocess, batched=True)
encoded_val_dataset.set_format(type="torch", columns=["input_ids", "attention_mask"])
labels = torch.tensor(val_dataset["label"])acc_fp32 = evaluate(original_model, encoded_val_dataset, labels)
acc_int8 = evaluate(quantized_model, encoded_val_dataset, labels)print(f"Original FP32 model accuracy: {acc_fp32:.4f}")
print(f"Quantized INT8 model accuracy: {acc_int8:.4f}")#Original FP32 model accuracy: 0.9300
#Quantized INT8 model accuracy: 0.5482
  • 量化分析

👉 這種量化方式雖然簡單,但存在一個明顯的問題,這是方式是 HuggingFace 基于 bitsandbytes 庫 實現的輕量量化方式,背后用的是:

  1. bitsandbytes8-bit optimizers
  2. 權重是 FP16 或 INT8 存儲,但不是 PyTorch 的量化張量(QTensor)
  3. 目的是節省 顯存內存

🎯 為此,該方法無法通過調用tensor.q_scale() , tensor.q_zero_point()進行逐層分析

三、PYTORCH Eager Mode 量化

import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer# 1. 加載原始模型
model_name = "./output/checkpoint-2105/"
model = AutoModelForSequenceClassification.from_pretrained(model_name).eval()
tokenizer = AutoTokenizer.from_pretrained(model_name)# 2. 將模型移到 CPU(Eager 模式量化推薦在 CPU 上執行)
model.to('cpu')# 3. 準備量化配置 (動態量化)
quantized_model = torch.quantization.quantize_dynamic(model,{torch.nn.Linear},  # 指定要量化的模塊類型dtype=torch.qint8   # 量化類型
)
  • 量化后大小比較,結果比huggingface量化方式大一點
# 大小比較
# Original BERT size: 417.655MB
# Quantized 8-bit BERT size: 127.269MB# 精度比較
# Original FP32 model accuracy: 0.9300
# Quantized INT8 model accuracy: 0.5482 不變

四、PYTORCH EXPORT 量化 (存在bug)

目前的這種量化方式還有bug存在,并且還找不到錯誤,希望有大哥幫助一下,主要的問題是模型可以成功量化,但是量化后的模型推理時會報錯誤,而且量化結果的大小也很奇怪:Original BERT size: 417.655MB ; Quantized 8-bit BERT size: 0.001MB

import torch
from torch.export import export
from torch.ao.quantization.quantize_pt2e import prepare_pt2e, convert_pt2e
from torch.ao.quantization.quantizer.xnnpack_quantizer import get_symmetric_quantization_config
from torch.ao.quantization.quantizer.x86_inductor_quantizer import X86InductorQuantizer
from transformers import AutoModelForSequenceClassification, AutoTokenizer
model_name = "./output/checkpoint-2105/"
# 1. 加載原始模型
model = AutoModelForSequenceClassification.from_pretrained(model_name).eval().cuda()
tokenizer = AutoTokenizer.from_pretrained(model_name)# 2. 準備樣例輸入
example = tokenizer("This movie is great!", return_tensors="pt", padding="max_length", max_length=128)
example = {k: v.cuda() for k, v in example.items()}
example_inputs = (example["input_ids"], example["attention_mask"])# 3. 導出模型
ep = export(model, args=example_inputs,dynamic_shapes=None)
gm = ep.graph_module# 4. 準備量化器
quantizer = X86InductorQuantizer()
quantizer.set_global(get_symmetric_quantization_config(is_per_channel=True))# 5. 插入 observer
prepared = prepare_pt2e(gm, quantizer)
quantity_model = convert_pt2e(prepared)# 報錯信息forward() missing 203 required positional arguments: 'p_bert_embeddings_position_embeddings_weight', 'p_bert_embeddings_layernorm_weight', 'p_bert_embeddings_layernorm_bias',  

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86666.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86666.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86666.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用低通濾波優化串口或485 通信指示燈電路

常見的通信指示燈電路就是簡單的把LED 連到TXD 和RXD 上,一有動靜就閃一下。問題是,如果波特率很高,一次通信時間很短,相當于占空比很低,LED 閃爍的亮度就很弱,不容易觀察。比如MODBUS 通信,波特…

【純干貨】調整word目錄中的行距以及右對齊頁碼

1.問題展現 目錄生成會遇到一些奇葩現象 所以到了展現技術力的時候了【doge】 2.解決word目錄中的行距問題 選中目錄中的文字-》段落 此時你可能勾選了圖片中的一個以上,把他們都取消了, 由于一個目錄的標題對應一個樣式,第一個也可以取消 …

pandas 優雅處理值類型為list的列的csv讀寫問題

文章目錄 直接存儲join list 變成字符串存儲json.dumps序列化存儲以及json.loads反序列化讀取總結 之所以分析這個問題,是因為讀者在跟第三方數據供應商對接數據的時候,老是會遇到數據加載都會出錯的問題,其中一個原因就是list類型數據沒有正確儲存,于是筆者在這篇文章里面詳細…

一種解決 OpenWrt 安裝 docker 之后局域網的設備之間無法互相訪問通信的方法

文章目錄 一、問題背景二、解決方案(方法一)修改全局設置的 轉發( forward) 為 接受(ACCEPT)(方法二)設置 net.bridge.bridge-nf-call-iptables0 并將 docker 的容器網絡設置為host …

Leetcode百題斬-貪心

貪心也是一個很有意思的專題,能遇到很多神奇的思路。 但這個專題,leetcode也沒放Hard,果然是怕這種玄學專題上點難度大家罩不住。那就很快了,直接過 763. Partition Labels[Medium] 思路:將字母串分組,相…

基于多徑信道的分集接收技術性能優化與仿真分析

基于多徑信道的分集接收技術性能優化與仿真分析 一、多徑信道建模與仿真 1. 多徑信道建模(MATLAB實現) classdef MultipathChannel < handlepropertiesSampleRate = 1e6; % 采樣率 (Hz)MaxDoppler = 100; % 最大多普勒頻移 (Hz)DelayVector = [0

LeetCode 713.乘積小于K的子數組

給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回子數組內所有元素的乘積嚴格小于 k 的連續子數組的數目。 示例 1&#xff1a; 輸入&#xff1a;nums [10,5,2,6], k 100 輸出&#xff1a;8 解釋&#xff1a;8 個乘積小于 100 的子數組分別為&#xff1a;[10]、[5…

打破網絡安全孤島:實現防御數據協作

作者&#xff1a;來自 Elastic Crossley McEwen, Oksana Abramovych 現代網絡戰場不再受組織邊界的限制。在各類防御網絡中&#xff0c;關鍵的結構化、非結構化和半結構化數據分布在不同的專業環境中&#xff0c;形成孤島 —— 從機密情報系統到作戰指揮平臺&#xff0c;再到戰…

給定一個沒有重復元素的數組,寫出生成這個數組的MaxTree的函數

題目&#xff1a; 給定一個沒有重復元素的數組arr&#xff0c;寫出生成這個數組的MaxTree的 函數&#xff0c;要求如果數組長度為N&#xff0c;則時間復雜度為O(N)、額外空間復雜度 為O(N)。 一個數組的MaxTree定義如下。 ● 數組必須沒有重復元素。 ● MaxTree是一棵二叉…

iOS 抓包實戰:時間戳偏差導致的數據同步異常排查記錄

“這條數據不是我填的”“我的更新被覆蓋了”“兩個設備顯示不一致”——這些是產品上線后最令人頭疼的反饋。 最近我們在一次用戶同步問題排查中&#xff0c;發現表面是“數據丟失”問題&#xff0c;實則是多端數據提交時間戳處理不一致&#xff0c;導致后臺認為老數據為新&a…

一款支持多日志器、多級別、多落地方式的同異步日志系統

文章目錄 簡介項目特點項目實現基礎功能模塊實現文件操作以及日期時間獲取日志等級日志信息描述 異步功能模塊實現緩沖區實現異步線程實現 核心功能模塊實現日志格式解析落地操作實現日志器實現 測試測試環境測試參數測試結果性能分析 附件 簡介 在現代軟件開發與系統運維領域…

加固筆記本在戶外勘探行業的應用:探索與科技的融合

在自然資源勘探、地質調查、石油天然氣開發、礦產資源測繪等戶外勘探行業中&#xff0c;作業環境常常復雜多變&#xff1a;風沙漫天的戈壁、雨雪交加的山區、濕熱潮濕的叢林&#xff0c;甚至是極寒與高溫并存的極端氣候條件。面對這些挑戰&#xff0c;普通的辦公設備早已無法勝…

MySQL 連接指定端口后,為什么實際仍是 3306?

文章目錄 MySQL 連接指定端口后&#xff0c;為什么實際仍是 3306&#xff1f;問題現象復現原因分析沒有指定 -h&#xff0c;默認走的是本地 Unix Socket多實例環境中未顯式指定目標地址 正確的連接方法方法一&#xff1a;添加 -h 127.0.0.1方法二&#xff1a;添加 --protocolTC…

【Android當用戶兩次打斷息屏操作后,屏幕將會在10分鐘內無法熄滅并持續點亮(關閉Android13新增的dim功能)】

UndimDetectorWakeLock持鎖導致屏幕不滅問題處理SOP 問題描述 在Android T版本中&#xff0c;系統新增了SCREEN_BRIGHT_WAKE_LOCK&#xff08;UndimDetectorWakeLock&#xff09;機制。當設備處于低亮度&#xff08;dim&#xff09;狀態時&#xff0c;用戶兩次打斷屏幕熄滅操…

Tailwind CSS自定義用法

文章目錄 前言? 一、集成 Tailwind CSS 到 React 項目1. 安裝依賴2. 配置 tailwind.config.js3. 創建全局樣式文件&#xff08;如 src/index.css&#xff09;tailwind base;tailwind components;tailwind utilities; 4. 在 main.tsx 或 main.jsx 中引入樣式 ? 二、自定義樣式…

linux面試常考

常用指令 常見題

Spring Boot 2.2.6調用DeepSeek API并通過SSE將流式響應推送給前端的完整實現

1. 添加依賴 (pom.xml) <dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- SSE 支持 --><depe…

LM1117-ADJ 簡單介紹

LM1117-ADJ是一款可調輸出電壓的低壓差線性穩壓器&#xff08;LDO&#xff09;&#xff0c;具有以下關鍵特性和應用要點&#xff1a; 核心特性 可調輸出電壓 通過外部分壓電阻&#xff08;R1和R2&#xff09;調節輸出電壓&#xff0c;范圍為1.25V至13.8V。輸出電壓公式&#…

知名流體控制解決方案供應商“永盛科技”與商派ShopeX達成B2B商城項目合作

2025年6月&#xff0c;全球知名的工業流體控制解決方案服務商——永盛科技&#xff08;股票&#xff1a;874497&#xff09;&#xff0c;與商派ShopeX正式達成B2B商城項目合作。 此次合作將共同推動永盛科技B2B業務的數字化變革&#xff0c;提高B2B業務運營效率&#xff0c;同…

jvm簡單八股

1、jvm中內存分為那幾個區域&#xff0c;1.7和1.8 jvm 中主要有 程序計數器、虛擬機棧、本地方法棧、堆、方法區、直接內存。 線程私有的有&#xff1a;程序計數器、虛擬機棧、本地方法棧 線程共有的有&#xff1a;堆、方法區、直接內存 堆空間又可以分為&#xff1a;新時代、…