怎么做网站的界面,手机网站开发技术,朔州如何做百度的网站,眼镜厂官网GPTQ 量化大模型
GPTQ 算法
GPTQ 算法由 Frantar 等人 (2023) 提出#xff0c;它从 OBQ 方法中汲取灵感#xff0c;但进行了重大改进#xff0c;可以将其扩展到#xff08;非常#xff09;大型的语言模型。
步骤 1#xff1a;任意顺序量化
OBQ 方法选择权重按特定顺序…GPTQ 量化大模型
GPTQ 算法
GPTQ 算法由 Frantar 等人 (2023) 提出它从 OBQ 方法中汲取灵感但进行了重大改进可以将其扩展到非常大型的语言模型。
步骤 1任意顺序量化
OBQ 方法选择权重按特定顺序进行量化该顺序由增加的额外误差最小决定。然而GPTQ 观察到对于大型模型以任何固定顺序量化权重都可以获得同样好的效果。这是因为即使某些权重可能单独引入更多误差但它们会在流程后期量化此时剩下的其他权重很少这可能会增加误差。所以顺序并不像我们想象的那么重要。
基于这一见解GPTQ 旨在以相同的顺序量化矩阵所有行的所有权重。这使得该过程更快因为某些计算只需对每列进行一次而不是对每个权重进行一次。
步骤 2惰性批量更新
这种方案速度不快因为它需要更新一个巨大的矩阵而每个块的计算量却很少。这种类型的操作无法充分利用 GPU 的计算能力并且会因内存限制内存吞吐量瓶颈而变慢。
为了解决这个问题GPTQ 引入了“惰性批量更新”。事实证明列的最终量化仅受对该列更新的影响而不会受后续列的影响。因此GPTQ 可以一次将算法应用于一批列例如 128 列仅更新这些列和矩阵的相应块。在处理完一个块后该算法会对整个矩阵执行全局更新。
步骤 3Cholesky 重构
然而还有一个问题需要解决。当算法扩展到非常大的模型时数值不准确可能会成为一个问题。具体来说重复应用某一操作可能会累积数值误差。
为了解决这个问题GPTQ 使用了Cholesky 分解这是一种解决某些数学问题的数值稳定方法。它涉及使用 Cholesky 方法从矩阵中预先计算一些所需信息。这种方法与轻微的“阻尼”在矩阵的对角元素中添加一个小常数相结合有助于算法避免数值问题。
完整的算法可以概括为几个步骤 GPTQ 算法首先对 Hessian 逆进行 Cholesky 分解该矩阵有助于决定如何调整权重 然后它循环运行一次处理一批列。 对于批次中的每一列它量化权重计算误差并相应地更新块中的权重。 处理批次后它会根据块的错误更新所有剩余的权重。
使用 AutoGPTQ 库实现 GPTQ 算法并量化 GPT-2 模型
# 导入随机数模块
import random# 导入AutoGPTQ库中的类用于量化模型
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig# 导入load_dataset函数用于加载数据集
from datasets import load_dataset# 导入PyTorch库
import torch# 导入transformers库中的AutoTokenizer用于文本编码
from transformers import AutoTokenizer# 定义基础模型名称和量化后模型的输出目录
model_id gpt2 # 使用gpt2作为基础模型
out_dir model_id -GPTQ # 输出目录为模型ID加上-GPTQ# 加载量化配置、模型和分词器
# 量化配置设置4位量化组大小为128阻尼百分比为0.01不使用激活函数量化
quantize_config BaseQuantizeConfig(bits4,group_size128,damp_percent0.01,desc_actFalse,
)
# 从预训练模型加载并应用量化配置
model AutoGPTQForCausalLM.from_pretrained(model_id, quantize_config)
# 加载与模型匹配的分词器
tokenizer AutoTokenizer.from_pretrained(model_id)# 加载数据并进行分词处理
# 使用allenai的c4数据集限制加载的数据文件和数据条数
n_samples 1024
data load_dataset(allenai/c4, data_filesen/c4-train.00001-of-01024.json.gz, splitftrain[:{n_samples*5}])
# 将文本数据连接并使用分词器进行编码
tokenized_data tokenizer(\n\n.join(data[text]), return_tensorspt)# 格式化分词后的样本
# 初始化一个空列表来存储格式化后的样本
examples_ids []
# 遍历以创建n_samples个样本
for _ in range(n_samples):# 随机选择起始索引确保序列长度不超过模型最大长度i random.randint(0, tokenized_data.input_ids.shape[1] - tokenizer.model_max_length - 1)j i tokenizer.model_max_length # 计算结束索引# 提取输入ID和创建相应的注意力掩码input_ids tokenized_data.input_ids[:, i:j]attention_mask torch.ones_like(input_ids) # 注意力掩码全为1表示所有token都需要被模型注意# 将输入ID和注意力掩码添加到样本列表中examples_ids.append({input_ids: input_ids, attention_mask: attention_mask})# 计时开始
%%time# 使用GPTQ进行量化
# 使用前面准备的样本、指定的batch_size和启用Triton优化进行量化
model.quantize(examples_ids,batch_size1,use_tritonTrue,
)# 保存量化后的模型和分词器到指定目录
# 使用safetensors格式保存模型权重该格式更安全且更易于分享
model.save_quantized(out_dir, use_safetensorsTrue)
tokenizer.save_pretrained(out_dir) # 保存分词器到同一目录以便之后使用量化后的效果
# 定义基础模型名称和量化后模型的输出目录
model_id gpt2 # 使用gpt2作为基础模型
out_dir model_id -GPTQ # 输出目录为模型ID加上-GPTQ# 设定设备为CUDA如果可用否则使用CPU
device cuda:0 if torch.cuda.is_available() else cpu
# 这行代码检查是否有GPU可以使用如果有则在GPU上运行后续的模型操作否则在CPU上运行。# 重新加载模型和分词器
model AutoGPTQForCausalLM.from_quantized(out_dir, # 指定之前保存的量化模型目录devicedevice, # 使用之前设定的设备use_tritonTrue, # 启用Triton加速如果安装并配置了Triton推理服务器use_safetensorsTrue, # 指定使用safetensors格式加载模型权重
)
# 从量化模型的保存目录加载分词器
tokenizer AutoTokenizer.from_pretrained(out_dir)# 导入transformers库中的pipeline功能
from transformers import pipeline# 创建一个文本生成的pipeline使用刚加载的模型和分词器
generator pipeline(text-generation, modelmodel, tokenizertokenizer)# 使用pipeline生成文本输入为I have a dream开启采样以增加多样性限制生成的最大长度为50
result generator(I have a dream , do_sampleTrue, max_length50)[0][generated_text]# 打印生成的文本结果
print(result)