Qwen量化脚本run_gptq.py解析

2024-04-18 14:12
文章标签 解析 py 脚本 量化 run qwen gptq

本文主要是介绍Qwen量化脚本run_gptq.py解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Qwen量化脚本run_gptq.py解析

代码路径 https://github.com/QwenLM/Qwen/
run_gptq.py路径 https://github.com/QwenLM/Qwen/blob/main/run_gptq.py

代码解析:

import argparse
import json
from typing import Dict
import loggingimport torch
import transformers
from transformers import AutoTokenizer
from transformers.trainer_pt_utils import LabelSmoother
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
IGNORE_TOKEN_ID = LabelSmoother.ignore_index#其中json文件格式如下
# [
#   {
#     "id": "identity_0",
#     "conversations": [
#       {
#         "from": "user",
#         "value": "xxxx"
#       },
#       {
#         "from": "assistant",
#         "value": "xxx"
#       }
#     ]
#   },
#   {
#     "id": "identity_1",
#     "conversations": [
#       {
#         "from": "user",
#         "value": "xxx"
#       },
#       {
#         "from": "assistant",
#         "value": "xxx"
#       }
#     ]
#   },
# ]def preprocess(sources,tokenizer: transformers.PreTrainedTokenizer,max_len: int,system_message: str = "You are a helpful assistant."
) -> Dict:"""preprocess函数接收一个包含对话数据的json列表作为输入,\n通过调用transformers库中的tokenizer对数据进行编码,\n并按照特定格式构建输入ID序列和目标ID序列.\n返回一个包含预处理数据的列表,这些数据已转换为PyTorch张量,适合于后续模型训练或推断"""#roles字典:为对话中的角色("user"和"assistant")分配特殊的前缀标签,用于区分对话双方roles = {"user": "<|im_start|>user", "assistant": "<|im_start|>assistant"}#im_start和im_end:指定tokenizer中im_start_id和im_end_id对应的整数ID。im_start = tokenizer.im_start_idim_end = tokenizer.im_end_id#nl_tokens:存储tokenizer处理换行符\n得到的输入ID序列。nl_tokens = tokenizer('\n').input_ids#_system、_user和_assistant:分别存储经过tokenizer处理后的"system"、"user"和"assistant"标签及其后的换行符对应的输入ID序列。_system = tokenizer('system').input_ids + nl_tokens_user = tokenizer('user').input_ids + nl_tokens_assistant = tokenizer('assistant').input_ids + nl_tokens# Apply prompt templates 定义空列表data,用于存放预处理后的数据样本data = []# input_ids, targets = [], []#遍历输入数据sources中的每个样本(source)for i, source in enumerate(sources):source = source["conversations"]#检查首个对话是否由用户发起(即source[0]["from"]是否为"user"),如果不是,则从源数据中移除首个对话。#过滤无效的identityif roles[source[0]["from"]] != roles["user"]:source = source[1:]#初始化空列表input_id和target,分别用于存储当前样本的输入ID序列和目标ID序列input_id, target = [], []#添加系统消息:将系统消息(包含system_message内容)转换为ID序列,添加到input_id和target中。system = [im_start] + _system + tokenizer(system_message).input_ids + [im_end] + nl_tokensinput_id += system#target中的非关键部分(如系统标签和消息内容)用IGNORE_TOKEN_ID填充。target += [im_start] + [IGNORE_TOKEN_ID] * (len(system)-3) + [im_end] + nl_tokensassert len(input_id) == len(target)#遍历源数据中的每个对话(sentence)for j, sentence in enumerate(source):# 提取角色和消息内容,并转换为ID序列role = roles[sentence["from"]]_input_id = tokenizer(role).input_ids + nl_tokens + \tokenizer(sentence["value"]).input_ids + [im_end] + nl_tokens#添加到input_id中input_id += _input_id#根据角色类型,生成对应_target的目标ID序列,_target只提取assistant的对话内容,忽略user的对话内容。if role == '<|im_start|>user':#若角色为"user",则目标ID序列仅包含开始标签和结束标签,用忽略ID填充对话内容。_target = [im_start] + [IGNORE_TOKEN_ID] * (len(_input_id)-3) + [im_end] + nl_tokens#若角色为"assistant",则目标ID序列包含开始标签、忽略ID填充(仅对角色标签)、对话内容(不包括角色标签和结束标签)、结束标签elif role == '<|im_start|>assistant':_target = [im_start] + [IGNORE_TOKEN_ID] * len(tokenizer(role).input_ids) + \_input_id[len(tokenizer(role).input_ids)+1:-2] + [im_end] + nl_tokenselse:raise NotImplementedErrortarget += _targetassert len(input_id) == len(target)#截取并转换为张量:#截取input_id和target至最大长度max_leninput_id = torch.tensor(input_id[:max_len], dtype=torch.int)target = torch.tensor(target[:max_len], dtype=torch.int)#创建一个字典,包含键input_ids(存储输入张量)和attention_mask(等于输入张量,用于指示非填充位置)。将该字典添加到data列表中data.append(dict(input_ids=input_id, attention_mask=input_id.ne(tokenizer.pad_token_id)))return dataif __name__ == "__main__":parser = argparse.ArgumentParser("Model Quantization using AutoGPTQ")parser.add_argument("--model_name_or_path", type=str, help="model path")parser.add_argument("--data_path", type=str, help="calibration data path")parser.add_argument("--out_path", type=str, help="output path of the quantized model")parser.add_argument("--max_len", type=int, default=8192, help="max length of calibration data")parser.add_argument("--bits", type=int, default=4, help="the bits of quantized model. 4 indicates int4 models.")parser.add_argument("--group-size", type=int, default=128, help="the group size of quantized model")args = parser.parse_args()quantize_config = BaseQuantizeConfig(bits=args.bits,group_size=args.group_size,damp_percent=0.01,desc_act=False,  # set to False can significantly speed up inference but the perplexity may slightly badstatic_groups=False,sym=True,true_sequential=True,model_name_or_path=None,model_file_base_name="model")#使用AutoTokenizer类从给定路径args.model_name_or_path加载预训练的tokenizertokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path, trust_remote_code=True)tokenizer.pad_token_id = tokenizer.eod_id#加载json数据文件,调用process函数预处理数据,返回处理后的数据data = preprocess(json.load(open(args.data_path)), tokenizer, args.max_len)#加载预训练的模型model = AutoGPTQForCausalLM.from_pretrained(args.model_name_or_path, quantize_config, device_map="auto", trust_remote_code=True)logging.basicConfig(format="%(asctime)s %(levelname)s [%(name)s] %(message)s", level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S")#对模型进行量化,不在GPU上缓存示例数据model.quantize(data, cache_examples_on_gpu=False)#保存量化后的模型model.save_quantized(args.out_path, use_safetensors=True)#将tokenizer保存到输出路径tokenizer.save_pretrained(args.out_path)

这篇关于Qwen量化脚本run_gptq.py解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/915011

相关文章

shell脚本自动删除30天以前的文件(最新推荐)

《shell脚本自动删除30天以前的文件(最新推荐)》该文章介绍了如何使用Shell脚本自动删除指定目录下30天以前的文件,并通过crontab设置定时任务,此外,还提供了如何使用Shell脚本删除E... 目录shell脚本自动删除30天以前的文件linux按照日期定时删除elasticsearch索引s

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

10个Python自动化办公的脚本分享

《10个Python自动化办公的脚本分享》在日常办公中,我们常常会被繁琐、重复的任务占据大量时间,本文为大家分享了10个实用的Python自动化办公案例及源码,希望对大家有所帮助... 目录1. 批量处理 Excel 文件2. 自动发送邮件3. 批量重命名文件4. 数据清洗5. 生成 PPT6. 自动化测试

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

10个Python Excel自动化脚本分享

《10个PythonExcel自动化脚本分享》在数据处理和分析的过程中,Excel文件是我们日常工作中常见的格式,本文将分享10个实用的Excel自动化脚本,希望可以帮助大家更轻松地掌握这些技能... 目录1. Excel单元格批量填充2. 设置行高与列宽3. 根据条件删除行4. 创建新的Excel工作表5

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC