实战Transformers模型量化Facebook OPT

基于上篇文章的理论知识,本文主要讲述了实战Transformers模型量化:介绍Facebook OPT模型的量化过程和相关技术。

Transformers 模型量化技术:GPTQ

Frantar等人发表了论文 GPTQ:Accurate Post-Training Quantization for Generative Pre-trained Transformers。作者详细介绍了一种训练后量化算法,适用于所有通用的预训练 Transformer模型,同时只有微小的性能下降。GPTQ算法需要通过对量化模型进行推理来校准模型的量化权重。其呈现的效果可以表达成Hugging Face + AutoGPTQ。

使用 GPTQ 量化模型

为了使用 auto-gptq 库量化一个模型,需要向量化器传递一个数据集。通常有两种方式构造数据集:

  • 量化器支持的默认数据集(包括[‘wikitext2’,‘c4’,‘c4-new’,‘ptb’,‘ptb-new’])
  • 一个字符串列表(这些字符串将被用作数据集)
    先安装好项目所依赖的包,如requirements。
torch>=2.1.2==2.3.0.dev20240116+cu121
transformers==4.37.2
ffmpeg==1.4
ffmpeg-python==0.2.0
timm==0.9.12
datasets==2.16.1
evaluate==0.4.1
scikit-learn==1.3.2
pandas==2.1.1
peft==0.7.1
accelerate==0.26.1
autoawq==0.2.2
optimum==1.17.0
auto-gptq==0.6.0
bitsandbytes>0.39.0==0.41.3.post2
jiwer==3.0.3
soundfile>=0.12.1==0.12.1
librosa==0.10.1
gradio==4.13.0
trl

然后进行加载requirements.txt内所有依赖包。

pip install -r requirements.txt

运行出来的界面如下图所示:
安装依赖包运行界面图

使用 GPTQ 算法支持的默认数据集来量化

对此,现使用"wikitext2"数据集将模型量化为4位精度,且支持的精度有[2, 4, 6, 8]。

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig
import torch

model_id = "facebook/opt-2.7b"

quantization_config = GPTQConfig(
     bits=4, # 量化精度
     group_size=128,
     dataset="c4",
     desc_act=False,
)

运行界面图

tokenizer =AutoTokenizer.from_pretrained(model_id)
quant_model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config, device_map='auto') 

运行参数界面
关于device_map参数,大家可以浏览huggingface的官方原文解释。
地址:https://huggingface.co/docs/transformers/v4.36.1/en/quantization
huggingface界面
上图为huggingface官方解释界面。

实测GPU显存占用:量化模型(峰值超过7GB)

运行图
由于电脑配置较低导致没有运行出来,笔者暂截取Github上的示例图。

检查量化模型正确性

通过检查线性层的属性来确保模型已正确量化,它们应该包含qweight和qzeros属性,这些属性应该是torch.int32数据类型。更简单地说,GPTQ简单的方法能够检查量化模型是否正确,是否有错误等,但该方法无法衡量模型的参数值被量化得非常好。即能够运行出来的模型到底有没有达到比较好的指标是无法被检查出来的。

quant_model.model.decoder.layers[0].self_attn.q_proj.__dict__

运行界面图
运行的界面图

使用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))

运行界面图

使用自定义数据集量化模型

下面演示通过传递自定义数据集来量化一个模型。通过字符串列表来自定义一个数据集,建议样本数不少于128(样本数太少会影响模型性能)

from transformers import AutoModelForCausalLM, GPTQConfig, 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 algorithm."]

custom_quantization_config = GPTQConfig(
    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))

示例图

Transformers 模型量化技术:AWQ

在AWQ:Activation-aware Weight Quantization for LLM Compression and Acceleration论文中,作者介绍了一种激活感知权重量化算法,可以用于压缩任何基于 Transformer 的语言模型,同时只有微小的性能下降。AWQ可以看成transformers + quantization综合表达的效果。

量化前模型测试文本生成任务

from transformers 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)

运行界面图

实测GPU显存占用:加载OPT-125m模型后

界面图

示例对比

generator("The woman worked as a")

运行结果
示例1 运行结果

generator("The man worked as a")

运行结果
示例2 运行结果

使用 AutoAWQ 量化模型

下面我们以 facebook opt-125m 模型为例,使用 AutoAWQ 库实现的 AWQ 算法实现模型量化。

from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer


quant_path = "models/opt-125m-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)

图

# 量化模型
model.quantize(tokenizer, quant_config=quant_config)

实测GPU显存使用:量化模型时峰值达到将近 4GB。

quant_config

界面

Transformers兼容性配置

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
# 保存模型权重

model.save_quantized(quant_path)
tokenizer.save_pretrained(quant_path)  # 保存分词器

界面图

Transformers 量化技术 BitsAndBytes

BitsAndBytes
bitsandbytes是将模型量化为8位和4位的最简单选择。

  • 8位量化将fp16中的异常值与int8中的非异常值相乘,将非异常值转换回fp16,然后将它们相加以返回fp16中的权重。这减少了异常值对模型性能产生的降级效果。
  • 4位量化进一步压缩了模型,并且通常与QLoRA一起用于微调量化LLM(低精度语言模型)。

异常值: 是指大于某个阈值的隐藏状态值,这些值是以fp16进行计算的。虽然这些值通常服从正态分布([-3.5, 3.5]),但对于大型模型来说,该分布可能会有很大差异([-60, 6]或[6, 60])。8位量化适用于约为5左右的数值,但超过此范围后将导致显著性能损失。一个好的默认阈值是6,但对于不稳定的模型(小型模型或微调)可能需要更低的阈值。

在 Transformers 中使用参数量化

使用 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)
model_4bit

示例图

# 获取当前模型占用的 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")

运行结果为:1457.52MiB,
而在显存中占用的初始结果为1774MiB。

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))

运行界面图

使用 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")

运行结果为:1457.52MiB
而在显存中占用的初始结果为3414MiB。

使用双量化加载模型

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")

运行结果为:1457.52MiB,
而在显存中占用的初始结果为:4910MiB

使用 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")

运行结果为:1457.52MiB。

<think>好的,我现在需要帮助用户下载并部署OPT模型到他们的服务器上。首先,我得确认用户的具体需求是什么。用户提到的是OPT模型,这可能指的是Meta的OPT(Open Pre-trained Transformers模型,属于大型语言模型的一种。用户可能想要在服务器上部署这个模型,以便进行推理或者进一步的训练。 接下来,我需要回顾用户提供的参考引用,看看有没有相关的部署步骤。引用[1]和[2]提到了Docker镜像的下载、保存和加载,以及Ollama的离线安装方法,而引用[3]涉及客户端安装,可能不太相关。不过,这些引用中的方法可能可以应用到OPT模型的部署中。 首先,我应该考虑OPT模型通常的部署方式。通常,使用Hugging Face的Transformers库是一个常见的选择,因为它支持直接下载预训练模型。但用户可能需要在无法访问互联网的服务器上部署,这时候可能需要离线下载模型文件,然后传输到服务器。 根据引用[1]的步骤,用户可能需要先在能够访问互联网的机器上下载模型,保存为文件,然后通过SCP传输到目标服务器,再加载。同样,引用[2]提到下载离线版本的Ollama,并修改安装脚本,这可能类似于下载模型文件的过程。 所以,步骤可能包括: 1. 在有互联网的机器上下载OPT模型,可能使用git lfs或者直接下载模型文件。 2. 将模型文件打包压缩,传输到目标服务器。 3. 在目标服务器上安装必要的依赖,如Python、PyTorchTransformers库等。 4. 加载模型并进行测试。 需要注意模型的大小可能很大,传输需要时间和足够的存储空间。另外,服务器是否需要GPU支持,以及CUDA版本的兼容性也是要考虑的。 另外,用户可能需要使用Docker来封装环境,确保依赖项正确,避免环境冲突。引用[1]中的Docker命令可以用来保存和加载镜像,这可能适用于封装模型和其运行环境。 可能的问题包括模型版本的选择、依赖项的正确安装、文件路径的配置,以及权限问题。此外,如果用户的内网服务器无法访问外部网络,必须确保所有依赖项都离线安装。 需要提醒用户检查服务器资源,如内存、存储和GPU,确保足够支持OPT模型的运行。例如,较大的OPT模型可能需要较高的显存,否则可能需要使用CPU模式,但这样会影响性能。 总结步骤: 1. 下载模型:使用Hugging Face的git仓库或直接下载模型文件。 2. 传输到服务器:使用SCP或rsync等工具。 3. 安装依赖:离线安装Python包,可能需要下载wheel文件。 4. 加载模型:编写Python脚本测试模型加载。 5. (可选)使用Docker容器化部署,便于环境管理。 在生成回答时,需要结合引用中的方法,比如使用Docker save/load,或者Ollama的离线步骤,但要根据OPT模型的具体情况进行调整。同时,确保用户清楚每个步骤的操作,避免出现目录权限或路径错误的问题。</think>### OPT模型下载与部署步骤 #### 一、下载OPT模型文件 1. **通过Hugging Face下载** 在可联网的机器上执行以下命令: ```bash git lfs install git clone https://huggingface.co/facebook/opt-125m # 以125M版本为例 ``` 若需其他版本(如2.7B、6.7B),替换链接中的模型名称[^1]。 2. **离线打包模型** 将模型目录压缩为文件: ```bash tar -czvf opt-125m.tar.gz opt-125m ``` --- #### 二、传输文件到服务器 1. **使用SCP传输** 从本地传输到服务器: ```bash scp opt-125m.tar.gz username@server_ip:/opt/models # 目标路径需提前创建 ``` 2. **服务器解压文件** 登录服务器后解压: ```bash cd /opt/models tar -xzvf opt-125m.tar.gz ``` --- #### 三、安装运行环境 1. **离线安装Python依赖** - 在可联网机器下载依赖包: ```bash pip download torch transformers -i https://pypi.org/simple ``` - 传输`.whl`文件到服务器后安装: ```bash pip install --no-index --find-links=/path/to/wheels torch transformers ``` 2. **Docker容器化部署(可选)** 参考引用[1]的方法构建包含模型和环境的镜像: ```bash # Dockerfile示例 FROM pytorch/pytorch:latest COPY opt-125m /app/models/opt-125m RUN pip install transformers ``` 构建并加载镜像: ```bash docker build -t opt-model . docker save -o opt-model.tar opt-model scp opt-model.tar server_ip:/opt # 传输到服务器后加载 docker load -i /opt/opt-model.tar ``` --- #### 四、验证模型加载 编写测试脚本`test_opt.py`: ```python from transformers import OPTForCausalLM, AutoTokenizer model_path = "/opt/models/opt-125m" model = OPTForCausalLM.from_pretrained(model_path) tokenizer = AutoTokenizer.from_pretrained(model_path) input_text = "Artificial intelligence is" inputs = tokenizer(input_text, return_tensors="pt") outputs = model.generate(**inputs, max_length=50) print(tokenizer.decode(outputs[0])) ``` 执行脚本: ```bash python test_opt.py ``` --- #### 五、性能优化建议 1. **GPU加速** 确保服务器安装NVIDIA驱动和CUDA工具包,使用`model.to('cuda')`启用GPU推理。 2. **量化压缩** 通过8位量化减少显存占用: ```python model = OPTForCausalLM.from_pretrained(model_path, load_in_8bit=True) ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whitney_mao

您的认可和鼓励是持续分享的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值