实战量化Facebook OPT模型
文章目录
- 实战量化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 torchmodel_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, AutoTokenizermodel_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 pipelinemodel_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, AutoModelForCausalLMtokenizer = 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 AutoModelForCausalLMmodel_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) # 转换为 MiBprint(f"{memory_footprint_mib:.2f}MiB")
3、使用模型
from transformers import AutoTokenizertokenizer = 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 BitsAndBytesConfignf4_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) # 转换为 MiBprint(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) # 转换为 MiBprint(f"{memory_footprint_mib:.2f}MiB")
5、使用 QLoRA 所有量化技术加载模型
# 使用 QLoRA 所有量化技术加载模型import torchqlora_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) # 转换为 MiBprint(f"{memory_footprint_mib:.2f}MiB")