AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


手把手!量化大模型!什么是量化?有哪些方法?免费算力跑起来!附代码!day3
发布日期:2024-05-11 07:27:28 浏览次数: 1816


hi~

这几天都在忙项目的事,这个系列,加速干完!

前两篇,雄哥基于llama3,做了大模型微调+MoE模型合并

许多小朋友留言,问,本地算力不够,如何量化?

网上的量化模型都有什么区别?想系统学

临时加餐!

今天,雄哥会把常见的量化方案,一边跑实践,一边讲基础方式!

挑战一天干完这个系列!

天很蓝,抱着笔电,坐在石桌上,快哉!

整个系列是这样的:

day3:手把手量化大模型!有什么方法?什么是量化?【本篇】

day4:手把手GPTQ量化大模型!有什么区别?优势?

day5:手把手GGML量化大模型!与llama.cpp异曲同工?

day6:手把手使用ExLlamaV2量化!精炼后的GPTQ?

在野外,没有算力,全程使用colab免费算力完成!所有代码同步上传会员盘,仅意友圈成员专享!目前420+付费成员!

获取知识星球优惠,或遇到问题需解答!或加群?末尾找技术助手小胖!

如果你还未加入,在这里备注申请!

学AI应该是一件非常开心的事,见证时代,无论你是否加入,一定持续学下去!肯定会遇到问题,别放弃!

人的专注力只有10分钟!那,话不多说!

① 主流量化的技术有哪些流派?

② 浮点数表示的背景,是什么影响算力资源?

③ 跑一个量化实例!边跑边聊细节!

整个系列是这样的,大模型系列更完,我们做RAG,做本地数据化处理!


第一部分:主流量化技术有哪些?


两大主流!

训练后量化(PTQ):简单技术!把已训练模型权重转为低精度,无需重新训练!算力要求低,易于实现!但模型性能会下降!#后天减肥副作用

量化感知训练(QAT):在预训练或微调阶段结合权重转换过程,增强模型性能!QAT的计算成本很高,需要具有高质量训练数据!#从小keep好身材

本篇!雄哥会用PTQ方法来实践!

先不对比GPTQ、GGML、EXL2!后面跑完了,雄哥再总结,更深刻!


第二部分:什么影响计算资源?


为什么要量化?

是什么影响了大模型需要的资源?

不得不科普,就是!

浮点数表示!

数据类型决定了所需的计算资源量,直接影响模型运行速度+效率!

在深度学习应用,平衡精度和性能,一直很重要!更高精度意味着要吃更多算力!

在多种数据类型中,由于浮点数能够以高精度表示广泛的值,因而在深度学习中得到应用!

一个浮点数使用位来存储数值。这些位进一步被划分为三个不同的部分:

符号位:符号位指示数字的正负性质。它使用一个位,其中0表示正数,1表示负数。

指数:指数是一段位,表示基数的幂(在二进制表示中通常是2)。指数可以是正数或负数,允许数字表示非常大或非常小的值。

尾数/有效数字:剩余的位用于存储尾数,也称为有效数字。这表示数字的显著位数。数值的精度在很大程度上取决于尾数的长度。

表示公式为:

便于理解,跟着雄哥深入!

深度学习中一些最常用的数据类型:

float32 (FP32)、float16 (FP16) 、 bfloat16 (BF16)

FP32/用32位表示1个数字:

1位用于符号,8位用于指数,其余 23位用于有效数!1+8+23=32!高精度!意味着 FP32需要超高算力和内存占用!

FP16/用16位表示1个数字:

1 位用于符号,5 位用于指数,10 位用于有效数!这种省内存+加快推理速度,但不稳定性,影响模型性能!

BF16/用16位表示1个数字:

符号有 1 位,指数有 8 位,有效数有 7 位。与 FP16 相比,BF16 扩大了可表示范围,从而降低下溢和溢出风险!虽然有效位较少而导致精度降低,但 BF16 通常不会显着影响模型性能,并且是深度学习任务的有用折衷方案。

说再多,不如一张图,示意如下:

FP32 通常被称为“全精度”(4 字节),而 BF16 和 FP16 是“半精度”(2 字节)

那,有没有可能用单个字节存储权重?

YES!

 INT8 !

稍后,跟着雄哥跑起来!将 FP32 权重转换为 INT8 !


第三部分:跑一个实例,边跑边聊细节!


在本节中,我们将实现两种量化技术:

绝对最大值(absmax)量化:量化对称技术!

零点量化:非对称技术!

不管哪种!目标都是映射 FP32 张量 ?(原始权重)到 INT8 张??uant(量化权重)!

3.1 绝对最大值量化(absmax)

原始数字除以张量的绝对最大值,乘以比例因子 (127),将输入映射到范围内 [-127, 127]。为了检索原始 FP16 值,将 INT8 数字除以量化因子,确认由于舍入而导致的精度损失!

假设最大值为 3.2。权重 0.1 将被量化为round(0.1 x 127/3.2)=4,我们会得到4/ 127/3.2=0.008,这意味着误差为 0.008!

Python实现:

import torchdef absmax_quantize(X):
# 计算比例scale = 127 / torch.max(torch.abs(X))
# 量化X_quant = (scale * X).round()
X_dequant = X_quant / scale
return X_quant.to(torch.int8), X_dequant


3.2 零点量化

有了零点联网!我们可以考虑不对称的输入分布,输入值首先按值的总范围 (255) 除以最大值和最小值之间的差值进行缩放!

然后,该分布将偏移零点,以将其映射到范围 [-128, 127]

(注意!对比一下 absmax 的值)

首先,我们计算比例因子和零点值:

然后,用这些变量来量化或去量化权重:

Python实现:

def zeropoint_quantize(X):    # 计算值范围(分母)    x_range = torch.max(X) - torch.min(X)    x_range = 1 if x_range == 0 else x_range    # 计算缩放比例    scale = 255 / x_range    # 通过零点进行移位    zeropoint = (-scale * torch.min(X) - 128).round()
# 缩放并四舍五入输入 X_quant = torch.clip((X * scale + zeropoint).round(), -128, 127) # 逆量化 X_dequant = (X_quant - zeropoint) / scale
return X_quant.to(torch.int8), X_dequant


3.3 跑起来吧!

看再多,不如动起手来!

首先,你在会员盘下载雄哥上传的代码,把他上传到colab即可!

如果不知道怎样上传,自己查下攻略,难不倒你!

本地跑的朋友,同样的,你配置好本地环境,然后打开jupyter!在这里配!

第四天!0基础微调大模型+知识库,部署在微信!手把手安装AI必备环境!4/45

话不多说!跑起来!

我们首先加载 GPT-2 的模型和分词器,这是一个非常小的模型,你可以换其他的!或者你本地的!

后面雄哥还要跑其他实践,节省时间,就用它示例!

先安装依赖!

!pip install -q bitsandbytes>=0.39.0!pip install -q git+https://github.com/huggingface/accelerate.git!pip install -q git+https://github.com/huggingface/transformers.git

先看看模型GPT2的模型信息!大小!

看到->模型大小: 510,342,192 字节

from transformers import AutoModelForCausalLM, AutoTokenizerimport torchtorch.manual_seed(0)# 暂时将设备设置为CPUdevice = 'cpu'
# 加载模型和分词器model_id = 'gpt2'model = AutoModelForCausalLM.from_pretrained(model_id).to(device)tokenizer = AutoTokenizer.from_pretrained(model_id)# 打印模型大小print(f"模型大小: {model.get_memory_footprint():,} 字节")

使用上面介绍的两种方法量化模型!

# 提取第一层的权重weights = model.transformer.h[0].attn.c_attn.weight.dataprint("原始权重:")print(weights)# 使用absmax量化方法量化层weights_abs_quant, _ = absmax_quantize(weights)print("\nAbsmax量化后的权重:")print(weights_abs_quant)# 使用零点量化方法量化层weights_zp_quant, _ = zeropoint_quantize(weights)print("\n零点量化后的权重:")print(weights_zp_quant)

来吧,现在开始量化!

import numpy as npfrom copy import deepcopy# 存储原始权重weights = [param.data.clone() for param in model.parameters()]
# 创建模型以进行量化model_abs = deepcopy(model)
# 量化所有模型权重weights_abs = []for param in model_abs.parameters(): _, dequantized = absmax_quantize(param.data) param.data = dequantized weights_abs.append(dequantized)# 创建模型以进行量化model_zp = deepcopy(model)
# 量化所有模型权重weights_zp = []for param in model_zp.parameters(): _, dequantized = zeropoint_quantize(param.data) param.data = dequantized weights_zp.append(dequantized)

这里,雄哥为了对比原始权重和量化后的权重相差,做了一个图,这里不展开,我们让原始的模型和量化后的两个模型,都生成对话,看看质量!

# 使用原始模型和量化模型生成文本original_text = generate_text(model, "I have a dream")absmax_text   = generate_text(model_abs, "I have a dream")zp_text       = generate_text(model_zp, "I have a dream")
print(f"Original model:\n{original_text}")print("-" * 50)print(f"Absmax model:\n{absmax_text}")print("-" * 50)print(f"Zeropoint model:\n{zp_text}")

有点奇怪!原始模型的生成,反而比量化后的还差些!

不科学!你可以多试几组!

雄哥在代码的后面,又跑了另外一个int8的量化方案,篇幅原因,这里不介绍!

下一篇,我们用GPTQ的方法来量化模型!

加群+遇到问题,需要知识星球优惠券,联系技术助手-小胖!


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询