机器学习平台是一套服务于专业算法工程师,整合云原生的工具+算力(GPU、CPU云服务器),进行一站式AI算法开发和迭代的平台。本方案将为您介绍如何在 MLP 对 Meta-Llama-3.1-8B 的开源模型进行GPTQ量化。
说明
在实践过程中,如果因网络等问题导致模型、数据集或量化工具等无法下载到TOS bucket,建议您可以先将其下载到开发机云盘中,再自行拷贝到TOS路径下。
本方案以对 Meta-Llama-3.1-8B 模型进行GPTQ量化为例,在开始执行操作前,请确认您已经完成以下准备工作:
已开通网络/TOS/CFS,具体操作详见更改预付费资源组的负载网络VPC--机器学习平台-火山引擎、控制台快速入门--对象存储-火山引擎、访问文件存储实例--大数据文件存储-火山引擎。
已购买 MLP 资源,详见创建资源组--机器学习平台-火山引擎。关于资源价格详情,请详见实例规格及定价--机器学习平台-火山引擎。
已创建开发机实例,其中关键参数配置如下。具体操作详见创建开发机--机器学习平台-火山引擎。
资源规格:配置以下资源规格。
CPU 实例:8C/64G/20GB云盘。
GPU 卡数:最佳实践采用 1 台 ml.gni3cgd。
挂载配置:挂载 TOS bucket 和 CFS,具体操作详见训练代码如何访问TOS--机器学习平台-火山引擎。
镜像地址:在自定义镜像处配置下方镜像,填写 SSH key 并挂载 TOS。由于拉取的镜像较大,首次创建开发机事件预计 20 分钟。
vemlp-demo-cn-shanghai.cr.volces.com/demo/quantization:1.0
进入开发机。
登陆 账号登录-火山引擎。
在左侧导航栏单击开发机,在开发机列表页面中单击待操作的开发机名称,进入对应开发机内。
通过 SSH 远程登录开发机,具体操作详见通过SSH远程连接开发机--机器学习平台-火山引擎。
配置 volc configure。具体操作详见使用文档--机器学习平台-火山引擎。
在 Terminal 中执行以下命令,通过镜像源下载 Llama-3.1-8B 模型,并打开挂载的存储桶路径。
cd /vemlp-demo-models mkdir model-llama-gptq cd model-llama-gptq pip3 install -U huggingface_hub export HF_ENDPOINT=https://hf-mirror.com huggingface-cli download --token $HF_TOKEN --resume-download meta-llama/Meta-Llama-3.1-8B-Instruct --local-dir $ORIGINAL_MODEL_PATH
其中运行 huggingface-cli 需要传入的参数列表说明如下:
参数 | 描述 |
---|---|
hf_token | 具有llama使用权限的Huggingface账号的hf_token。 |
original_model_path | 源safetensor路径。 |
说明
在 Terminal 执行以下命令,可以直接下载开源的 wikitext2 数据集,来帮助 GPTQ 做量化校准。
cd /vemlp-demo-models mkdir datasets-llama-gptq cd datasets-llama-gptq pip3 install -U huggingface_hub export HF_ENDPOINT=https://hf-mirror.com huggingface-cli download --repo-type dataset --resume-download carlosejimenez/wikitext__wikitext-2-raw-v1 --local-dir $CALIB_DATASET_PATH
参数说明如下:
参数 | 描述 |
---|---|
calib_dataset_path | 用来校验量化结果的数据集的路径。 |
cd /vemlp-demo-models touch gptq-quant.py
import os from transformers import AutoTokenizer from auto_gptq import AutoGPTQForCausalLM from auto_gptq import BaseQuantizeConfig def get_wikitext2_dataset(nsamples, seed, seqlen, tokenizer): import numpy as np import torch import torch.nn as nn from datasets import load_dataset traindata = load_dataset(dataset_path, split="train") testdata = load_dataset(dataset_path, split="test") trainenc = tokenizer("\n\n".join(traindata["text"]), return_tensors="pt") testenc = tokenizer("\n\n".join(testdata["text"]), return_tensors="pt") import random random.seed(seed) np.random.seed(0) torch.random.manual_seed(0) traindataset = [] for _ in range(nsamples): i = random.randint(0, trainenc.input_ids.shape[1] - seqlen - 1) j = i + seqlen inp = trainenc.input_ids[:, i:j] attention_mask = torch.ones_like(inp) traindataset.append({"input_ids": inp, "attention_mask": attention_mask}) return traindataset, testenc # 配置模型、数据集地址 os.environ['BASE_MODEL_PATH'] = '/vemlp-demo-models/model-llama-gptq/Meta-Llama-3.1-8B' os.environ['CALIB_DATASET_PATH'] = '/vemlp-demo-models/datasets-llama-gptq/' os.environ['QUANT_MODEL_PATH'] = '/vemlp-demo-models/model-quant-gptq' model_path = os.getenv('BASE_MODEL_PATH') dataset_path = os.getenv('CALIB_DATASET_PATH') quant_path = os.getenv('QUANT_MODEL_PATH') # 设置量化超参数 quantize_config = BaseQuantizeConfig( bits=4, # 使用GPTQ INT4量化 group_size=128, # GPTQ推荐的分组大小为128 desc_act=False, # 设置为False,可以显著加速推理,但模型困惑度可能会稍微变差 ) model = AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config) tokenizer = AutoTokenizer.from_pretrained(model_path) traindataset, testenc = get_wikitext2_dataset(128, 0, 2048, tokenizer) model.quantize(traindataset) model.save_quantized(quant_path, use_safetensors=True) tokenizer.save_pretrained(quant_path)
cd /vemlp-demo-models/ touch gptq-quant.sh
set -ex pip install git+https://gh-proxy.com/https://github.com/AutoGPTQ/AutoGPTQ.git@097dd04e2f python3 gptq-quant.py echo "Finished Model Quantization Task"
cd /vemlp-demo-models/ bash ./gptq-quant.sh
执行完成后,输出路径文件如下。
du -sh $BASE_MODEL_PATH $QUANT_MODEL_PATH
其中需要传入的参数列表说明如下:
参数 | 描述 |
---|---|
base_model_path | llama3-8b模型路径。 |
quant_model_path | 经过GPTQ量化后的模型路径。 |
对比结果如下:可见在模型容量上,经过 GPTQ 4bit 量化后模型大小约为量化前模型的1/3。
diff $QUANT_MODEL_PATH/config.json $BASE_MODEL_PATH/config.json
对比结果如下:可见量化后模型多了关于量化的信息 -- quantization_config。
进入自定义任务控制台
配置环境
vemlp-demo-cn-shanghai.cr.volces.com/demo/quantization:1.0
cat > gptq-quant.py <<EOF import os from transformers import AutoTokenizer from auto_gptq import AutoGPTQForCausalLM from auto_gptq import BaseQuantizeConfig def get_wikitext2_dataset(nsamples, seed, seqlen, tokenizer): import numpy as np import torch import torch.nn as nn from datasets import load_dataset traindata = load_dataset(dataset_path, split="train") testdata = load_dataset(dataset_path, split="test") trainenc = tokenizer("\n\n".join(traindata["text"]), return_tensors="pt") testenc = tokenizer("\n\n".join(testdata["text"]), return_tensors="pt") import random random.seed(seed) np.random.seed(0) torch.random.manual_seed(0) traindataset = [] for _ in range(nsamples): i = random.randint(0, trainenc.input_ids.shape[1] - seqlen - 1) j = i + seqlen inp = trainenc.input_ids[:, i:j] attention_mask = torch.ones_like(inp) traindataset.append({"input_ids": inp, "attention_mask": attention_mask}) return traindataset, testenc # 模型、数据集地址配置 os.environ['BASE_MODEL_PATH'] = '/vemlp-demo-models/model-llama/Meta-Llama-3.1-8B' os.environ['CALIB_DATASET_PATH'] = '/vemlp-demo-models/datasets-llama-quant/' os.environ['QUANT_MODEL_PATH'] = '/vemlp-demo-models/model-quant-gptq' model_path = os.getenv('BASE_MODEL_PATH') dataset_path = os.getenv('CALIB_DATASET_PATH') quant_path = os.getenv('QUANT_MODEL_PATH') # 设置量化超参数 quantize_config = BaseQuantizeConfig( bits=4, # 使用GPTQ INT4量化 group_size=128, # GPTQ推荐的分组大小为128 desc_act=False, # 设置为False,可以显著加速推理,但模型困惑度可能会稍微变差 ) model = AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config) tokenizer = AutoTokenizer.from_pretrained(model_path) traindataset, testenc = get_wikitext2_dataset(128, 0, 2048, tokenizer) model.quantize(traindataset) model.save_quantized(quant_path, use_safetensors=True) tokenizer.save_pretrained(quant_path) EOF pip install git+https://gh-proxy.com/https://github.com/AutoGPTQ/AutoGPTQ.git@097dd04e2f python3 gptq-quant.py
选择合适的资源,最佳实践所用机器为单机 8 卡 ml.gni3cgd。
挂载 TOS 和 CFS。需要注意:tos在开发机上挂载的路径与自定义任务中挂载的路径不一致,在环境变量中填写模型路径时需确保为自定义任务中挂载的路径。
import os from transformers import AutoTokenizer from auto_gptq import AutoGPTQForCausalLM from auto_gptq import BaseQuantizeConfig def get_wikitext2_dataset(nsamples, seed, seqlen, tokenizer): import numpy as np import torch import torch.nn as nn from datasets import load_dataset traindata = load_dataset(dataset_path, split="train") testdata = load_dataset(dataset_path, split="test") trainenc = tokenizer("\n\n".join(traindata["text"]), return_tensors="pt") testenc = tokenizer("\n\n".join(testdata["text"]), return_tensors="pt") import random random.seed(seed) np.random.seed(0) torch.random.manual_seed(0) traindataset = [] for _ in range(nsamples): i = random.randint(0, trainenc.input_ids.shape[1] - seqlen - 1) j = i + seqlen inp = trainenc.input_ids[:, i:j] attention_mask = torch.ones_like(inp) traindataset.append({"input_ids": inp, "attention_mask": attention_mask}) return traindataset, testenc # 配置模型、数据集地址 os.environ['BASE_MODEL_PATH'] = '/data/model-llama-gptq/Meta-Llama-3.1-8B' os.environ['CALIB_DATASET_PATH'] = '/data/datasets-llama-gptq/' os.environ['QUANT_MODEL_PATH'] = '/data/model-quant-gptq' model_path = os.getenv('BASE_MODEL_PATH') dataset_path = os.getenv('CALIB_DATASET_PATH') quant_path = os.getenv('QUANT_MODEL_PATH') # 设置量化超参数 quantize_config = BaseQuantizeConfig( bits=4, # 使用GPTQ INT4量化 group_size=128, # GPTQ推荐的分组大小为128 desc_act=False, # 设置为False,可以显著加速推理,但模型困惑度可能会稍微变差 ) model = AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config) tokenizer = AutoTokenizer.from_pretrained(model_path) traindataset, testenc = get_wikitext2_dataset(128, 0, 2048, tokenizer) model.quantize(traindataset) model.save_quantized(quant_path, use_safetensors=True) tokenizer.save_pretrained(quant_path)
cd /vemlp-demo-models/ touch gptq-quantization-task.yaml
TaskName: "Quant-Meta-Llama-3-1-8B-Instruct-GPTQ-INT4" Description: "Use GPTQ to quantize Meta-Llama-3.1-8B-Instruct in INT4 format" Entrypoint: | cd /data && bash ./gptq-quant.sh Tags: [] Envs: [] ResourceQueueID: "q-**************" #请替换为您自己的ResourceQueueID Framework: "PyTorchDDP" TaskRoleSpecs: #请替换为您自己的TaskRoleSpecs - RoleName: "worker" RoleReplicas: 1 Flavor: "custom" ResourceSpec: Family: "ml.gni3cgd" CPU: 165.000 Memory: 865.000 GPUNum: 8 ActiveDeadlineSeconds: 3600 EnableTensorBoard: False Storages: #请替换为您自己的Storages - Type: "Tos" MountPath: "/data" Bucket: "vemlp-demo-models" FsName": "testmodel" MetaCacheExpiryMinutes: "-1" ImageUrl: "vemlp-demo-cn-shanghai.cr.volces.com/demo/quantization:1.0" CacheType: "Cloudfs" RetryOptions: EnableRetry: False MaxRetryTimes: 5 IntervalSeconds: 120 PolicySets: []
volc ml_task submit --conf=/vemlp-demo-models/gptq-quantization-task.yaml