文章目錄
- 實戰量化Facebook OPT模型
- Facebook OPT模型介紹
- auto-gptq方式量化
- 1、定義量化配置
- 2、加載模型量化
- 3、檢查量化正確性
- 4、保存量化後的模型權重
- 5、使用量化模型進行文本生成
- 6、使用自定義的數據集進行量化
- autoawq方式量化
- 0、未量化時測試文本生成任務
- 1、加載模型
- 2、量化模型
- 3、Transformers 兼容性配置
- 4、保存模型權重
- 5、加載使用量化模型
- BitsAndBytes(BnB)方式量化
- 1、介紹
- 2、使用load加載模型量化使用
- 1、加載
- 2、查看加載耗盡的GPU顯存
- 3、使用模型
- 3、使用NF4方式加載模型量化使用
- 4、使用雙重量化加載模型
- 5、使用 QLoRA 所有量化技術加載模型
實戰量化Facebook OPT模型
Facebook OPT模型介紹
facebook/opt-2.7b 是 Meta AI 發佈的 OPT 系列模型中的一個成員。OPT 的全稱是 Open Pre-trained Transformer,其核心目標是為研究社區提供一個與 GPT-3 性能和規模相當,但完全開放(開源代碼和權重)的預訓練語言模型。
auto-gptq方式量化
1、定義量化配置
通常有兩種方式構造數據集:
- 量化器支持的默認數據集(包括 [‘wikitext2’, ‘c4’, ‘c4-new’, ‘ptb’, ‘ptb-new’])
- 一個字符串列表(這些字符串將被用作數據集)
from transformers import AutoMode1ForCausalLM, AutoTokenizer, GPTQConfig
import torch
model_name_or_path = "facebook/opt-2.7b"
quantization_config = GPTQConfig(
bits=4, # 量化精度
group_size=128,
dataset="wikitext2",
desc_act=False,
)
2、加載模型量化
quant_model = AutoMode[ForCausalM.from_pretrained(
model_name_or_path,
quantization_config=quantization_config,
device_map='auto')
3、檢查量化正確性
通過檢查模型的線性層屬性來驗證量化是否成功:
quant_model.model.decoder.layers[0].self_attn.q_proj.__dict__
正確量化的模型應該包含以下特殊屬性:這些屬性是GPTQ量化特有的,在原始FP32模型中不存在,屬性的存在表明模型已成功轉換為量化格式,可以使用更少的內存進行推理
qweight- 量化後的權重
- 數據類型:
torch.int32 - 存儲壓縮後的4位權重數據
qzeros- 量化零點
- 數據類型:
torch.int32 - 用於反量化計算
scales- 縮放因子
- 數據類型:浮點數
- 用於將量化值轉換回原始數值範圍
4、保存量化後的模型權重
# 保存模型權重
quant_model.save_pretrained("models/opt-2.7b-gptq")
5、使用量化模型進行文本生成
# 使用 GPU 加載模型並生成文本
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
text = "Merry Christmas! I'm glad to"
inputs = tokenizer(text, return_tensors="pt").to(0)
out = quant_model.generate(**inputs, max_new_tokens=64)
print(tokenizer.decode(out[0], skip_special_tokens=True))
輸出
Merry Christmas! I'm glad to see you're still here.
Thank you! I'm glad to be here too.
6、使用自定義的數據集進行量化
使用自定義數據集量化模型,靈活可擴展,前提是準備好數據,如果使用很少的數據會影響模型性能,建議樣本數不少於128,如下使用一句話作為數據集,使模型性能變得很差。
from transformers import AutoModelForCausalLM, GPTQCConfig, AutoTokenizer
model_name_or_path = "facebook/opt-2.7b"
custom_dataset = ["auto-gptq is an easy-to-use model quantization library with user-friendly apis, based on GPTQ at 1"]
custom_quantization_config = GPTQCConfig(
bits=4,
group_size=128,
desc_act=False,
dataset=custom_dataset
)
custom_quant_model = AutoModelForCausalLM.from_pretrained(model_name_or_path,
quantization_config=custom_quantization_config,
torch_dtype=torch.float16,
device_map="auto")
相比使用默認數據集,未經精心準備的自定義數據集會明顯降低模型性能
text = "Merry Christmas! I'm glad to"
inputs = tokenizer(text, return_tensors="pt").to(0)
out = custom_quant_model.generate(inputs, max_new_tokens=64)
# 輸出的內容會很差
print(tokenizer.decode(out[0], skip_special_tokens=True))
autoawq方式量化
0、未量化時測試文本生成任務
from transforms import pipeline
model_path = "facebook/opt-125m"
# 使用 GPU 加載原始的 OPT-125m 模型
generator = pipeline('text-generation',
model=model_path,
device=0,
do_sample=True, # 自動跑他的樣例
num_return_sequences=3)
1、加載模型
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
# 定義路徑和配置
model_path = "facebook/opt-2.7b" # 原始模型路徑
quant_path = "models/opt-2.7b-awq" # 量化後保存路徑
quant_config = {"zero_point": True, "q_group_size": 128, "w_bit": 4, "version": "GEMM"}
# 加載模型和分詞器
model = AutoAWQForCausalLM.from_pretrained(model_path, device_map="cuda")
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
2、量化模型
model.quantize(tokenizer, quant_config=quant_config)
3、Transformers 兼容性配置
為了使 quant_config 與 transformers 兼容,我們需要修改配置文件:使用 Transformers.AwqConfig 來實例化量化模型配置
from transformers import AwqConfig, AutoConfig
# 修改配置文件以使其編譯到transformers集成兼容
quantization_config = AwqConfig(
bits=quant_config["w_bit"],
group_size=quant_config["q_group_size"],
zero_point=quant_config["zero_point"],
version=quant_config["version"].lower(),
).to_dict()
# 預訓練的transformers模型存儲在model屬性中,我們需要傳遞一個字典
model.model.config.quantization_config = quantization_config
4、保存模型權重
model.save_quantized(quant_path)
tokenizer.save_pretrained(quant_path) # 保存分詞器
5、加載使用量化模型
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained(quant_path)
model = AutoModelForCausalLM.from_pretrained(quant_path, device_map="cuda").to(0)
def generate_text(text):
inputs = tokenizer(text, return_tensors="pt").to(0)
out = model.generate(inputs, max_new_tokens=64)
return tokenizer.decode(out[0], skip_special_tokens=True)
result = generate_text("Merry ChristrHS! I'm glad to")
print(result)
BitsAndBytes(BnB)方式量化
1、介紹
bitsandbytes 是將模型量化為8位和4位的最簡單選擇。
2、使用load加載模型量化使用
1、加載
使用 Transformers 庫的 model.from_pretrained() 方法中的 load_in_8bit 或 load_in_4bit 參數,便可以對模型進行量化。只要模型支持使用Accelerate加載幷包含torch.nn.Linear層,這幾乎適用於任何模態的任何模型。
from transformers import AutoModelForCausalLM
model_id = "facebook/opt-2.7b"
model_4bit = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", load_in_4bit=True)
2、查看加載耗盡的GPU顯存
計算 GPU 內存佔用(使用 PyTorch 模型)
memory_footprint_bytes = model_4bit.get_memory_footprint()
memory_footprint_mib = memory_footprint_bytes / (1024 ** 2) # 轉換為 MiB
print(f"{memory_footprint_mib:.2f}MiB")
3、使用模型
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_id)
text = "Merry Christmas! I'm glad to"
inputs = tokenizer(text, return_tensors="pt").to(0)
out = model_4bit.generate(inputs, max_new_tokens=64)
print(tokenizer.decode(out[0], skip_special_tokens=True))
3、使用NF4方式加載模型量化使用
from transformers import BitsAndBytesConfig
nf4_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
)
model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=nf4_config)
# 獲取當前模型佔用的 GPU顯存(差值為預留給 PyTorch 的顯存)
memory_footprint_bytes = model_nf4.get_memory_footprint()
memory_footprint_mib = memory_footprint_bytes / (1024 ** 2) # 轉換為 MiB
print(f"{memory_footprint_mib:.2f}MiB")
4、使用雙重量化加載模型
# 使用雙重量化加載模型
double_quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
model_double_quant = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=double_quant_config)
# 獲取當前模型佔用的 GPU 內存(差值為預留給 PyTorch 的顯存)
memory_footprint_bytes = model_double_quant.get_memory_footprint()
memory_footprint_mib = memory_footprint_bytes / (1024 ** 2) # 轉換為 MiB
print(f"{memory_footprint_mib:.2f}MiB")
5、使用 QLoRA 所有量化技術加載模型
# 使用 QLoRA 所有量化技術加載模型
import torch
qlora_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
)
model_qlora = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=qlora_config)
# 獲取當前模型佔用的 GPU 顯存(差值為預留給 PyTorch 的顯存)
memory_footprint_bytes = model_qlora.get_memory_footprint()
memory_footprint_mib = memory_footprint_bytes / (1024 ** 2) # 轉換為 MiB
print(f"{memory_footprint_mib:.2f}MiB")