GPU八卡A100使用INT4-W4A16量化大模型实验

A100 * 8 量化Meta-llama8B模型实验

简介

本实验旨在探索在 NVIDIA A100 × 8 GPU 环境下,对 Meta-LLaMA-8B 大语言模型进行权重量化的可行性、效率与性能影响。通过采用 llmcompressor 工具集成 GPTQ 算法,实现对所有线性层的权重量化(W4A16 方案)。最终通过 lm-eval 工具在 GSM8K 任务上对压缩模型进行评估。

实验步骤(含遇到的问题,解决方案)

一:使用 transformers 加载模型和分词器:

  • 使用 device_map=“auto” 自动分配多卡显存。
  • torch_dtype=“auto” 让模型根据硬件选择 FP16 。
    在这里插入图片描述

二:构建校准数据集:

  • Modelscope 下载 UltraChat 200k 数据集(最好使用与你的部署数据紧密匹配的校准数据)
    在这里插入图片描述
    在使用datasets加载数据集时遇到了一个问题:
    在这里插入图片描述
    这个问题出现的原因是数据集的 dataset_info.json 文件中的 features 字段格式不正确——它试图构造 Value 类型,但缺少 dtype 字段。
    解决方法:
    删除数据集目录下的 dataset_infos.json 文件,让 datasets 自动推断特征。

三:运行量化

  • 通过 llmcompressor 中的 GPTQModifier,将模型线性层权重压缩为 INT4(W4A16 格式)
  • 使用 one-shot 方法进行静态量化
  • 排除 lm_head,避免因极端权重量化精度损失
    在这里插入图片描述

实验结果

  • 量化过程
    在这里插入图片描述
  • 在量化到第31个迭代时,出现了OOM错误:
    在这里插入图片描述
  • 使用nvidia-smi观察了一下,发现好几张卡有其他进程在使用:
    在这里插入图片描述

量化的是8B的模型,其实不需要太多卡,那么如何修改代码,来指定运行量化的代码呢?
解决方法:设置环境变量,只暴露闲置的卡:

os.environ["CUDA_VISIBLE_DEVICES"] = "4,5,6"

然后重新量化:
在这里插入图片描述

可以看到,这样就只在这三张卡上运行量化了。
在这里插入图片描述
发现卡4使用率较高,而另外两张卡使用率很低,什么原因呢?
百度一下原因大致是:使用device_map=“auto” 在量化时选择了更多计算密集的层放到这张卡上(卡4)。
如何解决:可以通过手动配置 device_map 或使用 数据并行 等方式来更好地平衡负载,使得 GPU 4、5、6 的使用率更加均匀。
运行了大概二十多分钟就量化完成了,具体时间没有记录(后悔)。
在这里插入图片描述

我们使用du -sh简单看一下量化前和量化后的模型文件总大小:
15G Meta-Llama-3-8B-Instruct/
5.4G disk0-W4A16-G128/

这里5.4G 是合理的 GPTQ 4bit 模型大小,虽然不是完美的四分之一,但相比原始模型已经大大减小(接近 1/3)
为什么不是四分之一,截取一下gpt的回答,有错误欢迎指正:
在这里插入图片描述

部署推理及模型评估

  • 通过 lm-eval 工具(lm_eval 是一个用于评估语言模型性能的 Python 库,使用pip install安装即可),对量化模型在 GSM8K 数据集(gsm8k是数学推理任务,可以用你的目标任务替换)上的 zero-shot/few-shot 表现进行评估;
  • 评估中使用 vllm 作为推理框架,使用 huggingface 也可以;
lm_eval --model vllm \
  --model_args pretrained="./Meta-Llama-3-8B-Instruct-W4A16-G128",add_bos_token=true \
  --tasks gsm8k \
  --num_fewshot 5 \
  --limit 250

执行评估报错,这里也是因为显存的问题:
在这里插入图片描述
设置环境变量,用空闲的卡进行评估:

export CUDA_VISIBLE_DEVICES=4

在这里插入图片描述
可以看到这里四号卡在进行评估了,评估结果:
在这里插入图片描述
然后使用相同的方法评估一下量化前我们的llama 8B模型的准确率:
在这里插入图片描述

可见量化模型在 gsm8k 上 5-shot 的 exact match 达到 74.8%准确率,而量化前的模型准确率只有73.2%,这是什么原因呢(手动狗头)

这听起来违反直觉,但其实在实际应用中,这种现象并不罕见,原因可能包括:

  • GPTQ 的误差感知机制实际提升了模型“对任务有用”部分的表示能力;
  • 校准数据集(ultrachat_200k)与目标任务分布更贴近,反而帮助模型对某些推理任务表现得更好;
  • 测试集样本较少(你用的是 --limit 250),有统计波动;
  • 推理时的实现细节(如 BOS token 添加、tokenizer 或输入截断策略)可能略有差异;
  • 原始模型输出过于“冗长或不精确”,而量化后的模型输出更简洁,有利于 strict match。

对于实际的原因,可能要进一步实验和验证,这里就不继续了,要下班了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

huafeng.

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值