LLM大模型量化原理

大型语言模型(LLM)可以用于文本生成、翻译、问答任务等。但是,LLM 也非常大(显然,大型语言模型)并且需要大量内存。 这对于手机和平板电脑等小型设备来说可能具有挑战性。

可以将参数乘以所选的精度大小以确定模型大小(以字节为单位)。 假设我们选择的精度是 float16(16 位 = 2 字节)。 假设我们想使用 BLOOM-176B 模型。 我们需要 1760 亿个参数 * 2 字节 = 352GB 来加载模型!

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 

换句话说,要加载所有参数权重,我们需要 12 x 32GB 显存的机器! 如果我们想让LLM具有可移植性,这就太过分了。 减少LLM内存占用的技术就是为了克服这一难题而开发的。 最流行的技术包括:

  • 量化(quantization),涉及将 LLM 的权重转换为较低精度的格式,从而减少存储它们所需的内存。
  • 知识蒸馏(knowledge distillation),涉及训练较小的LLM来模仿较大的LLM的行为。 这可以通过将知识从较大的LLM转移到较小的LLM来完成。

这些技术使得LLM能够适应小内存。 这为在各种设备上使用LLM开辟了新的可能性。 今天我们来聊聊量化(敬请关注知识蒸馏)。

1、量化简介

让我们从一个简单的例子开始。 我们需要将 2023 转换为二进制:

如你所见,该过程相对简单。 为了存储数字 2023,我们需要 12位(1 位用于 + 或 - 符号)。 对于数字,我们可以使用 int16 类型。

将 int 存储为二进制和将 float 存储为二进制之间存在很大差异。 让我们尝试将 20.23 转换为二进制:

可以看到,浮点部分(尾数:mantissa)是按 1/2^n 的组合计算的,即使有 10 位专用于浮点部分,也无法非常精确地计算。 指数部分(指数:exponent)设置为 5 位,涵盖 32 以内的所有数字。总的来说,我们使用 16 位 (FP16) 来存储最接近 20.23 的值,但这是否是保持最接近 20.23 的最有效方法? 漂浮? 如果整个数字更大(例如 202.3)怎么办?

如果我们查看标准浮点类型,我们会注意到要存储 202.3,我们需要使用 FP32,从计算角度来看,这远远不合理。 相反,我们可以使用 bfloat16 将范围(指数)保存为 8 位,将精度(尾数)保存为 7 位。 这使我们能够扩大可能的小数范围,而不会损失太多精度。

需要明确的是,在进行训练时,我们需要尽可能达到的精度。 但是,将速度和大小优先于小数点后第六位对于推理来说是有意义的。

我们可以将内存使用量从 bfloat16 减少到 int8 吗?

2、零点量化和绝对最大量化

事实上,我们可以,并且有几种量化方法:

零点量化(zero-point quantization)通过将定点范围 (-1, 1) 转换为 int8 (-127, 127),然后将 int8 转换回 bfloat16 来节省一半的内存。

绝对最大量化(abs-max quantization)与零点量化类似,但我们没有设置自定义范围 (-1,1),而是将其设置为 (-abs(max), abs(max))。

让我们看一下这些量化如何在矩阵乘法的示例中使用,注意结果矩阵中数值的损失。首先看下未量化的精确矩阵乘法:

零点量化后的矩阵乘法:

绝对最大量化后的矩阵乘法:

3、异常数值分离计算

可以注意到,计算结果中较大的数值如 [-1579, -1780],量化后计算的损失比较大(零点量化后得到 [-1579, -1752],绝对最大量化后得到 [-1565,-1786])。 为了克服这些问题,我们可以单独处理离群的异常值:

正如你所看到的,结果更接近真实值。

4、量化到4个比特

但有没有一种方法可以在不损失太多质量的情况下使用更少的空间呢?

令我惊讶的是,有办法! 如果我们不是独立地将每个数字转换为较低类型,而是考虑错误并将其用于调整,会怎么样? 这种技术称为 GPTQ。

与之前的量化一样,我们尽可能找到最接近的小数匹配,使总转换误差尽可能接近于零。

下面是GPTQ近似的第一步:

我们以这种方式逐行填充矩阵:

结果与异常值分离计算相结合,提供了相当不错的结果:

5、量化方法比较

我们现在可以比较各种量化方法:

LLM.int8() 方法表现得非常好! GPTQ 方法会损失质量,但允许使用两倍于 int8 方法的 GPU 内存。

6、BitsAndBytes量化参数

在代码中,你可能会发现类似于以下内容:

from transformers import BitsAndBytesConfig# Configure BitsAndBytesConfig for 4-bit quantization
bnb_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_use_double_quant=True,bnb_4bit_quant_type="nf4",bnb_4bit_compute_dtype=torch.bfloat16,
)
# Loading model in pre-set configuration
pretrained_model = AutoModelForCausalLM.from_pretrained(model_id,quantization_config=bnb_config,
)

参数说明如下:

  • load_in_4bit 标志指定模型应以 4 位精度加载。  
  • bnb_4bit_use_double_quant 标志指定应使用双量化。
  • bnb_4bit_quant_type 标志指定量化类型。
  • bnb_4bit_compute_dtype 标志指定计算数据类型。

7、结束语

总而言之,我们了解了小数如何存储在内存中、如何通过一些精度损失来减少内存占用,以及如何通过 4 位量化运行选定的模型。


原文链接:LLM的量化 - BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/190156.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python接口自动化测试之token参数关联!

前言 在做自动化接口测试时,有时候会遇到token的动态关联,例如查询余额接口,需要关联登录接口的token动态值,如何利用python脚本进行接口token关联呢?今天我们爱学习一下吧! 一:获取登录接口返回的token…

【计算机基础】优雅的PPT就应该这样设计

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

《全程软件测试 第三版》拆书笔记

第一章 对软件测试的全面认识,测试不能是穷尽的 软件测试的作用: 1.产品质量评估;2.持续质量反馈;3.客户满意度提升;4.缺陷的预防 正反思维:正向思维(广度,良好覆盖面)逆…

力扣每日一题-数位和相等数对的最大和-2023.11.18

力扣每日一题:数位和相等数对的最大和 开篇 这道每日一题还是挺需要思考的,我绕晕了好久,根据题解的提示才写出来。 题目链接:2342.数位和相等数对的最大和 题目描述 代码思路 1.创建一个数组存储每个数位的数的最大值,创建一…

gti拉取普通idea Java项目module没有build的问题

在不断完成一个项目的时候,会有不断新加的module,我们用git拉取时会发生没有识别新module的情况。 解决方法是右键项目名称,然后点击Open Module Settings 接下来,点击Module,加号,新建Module的名字就是在g…

C#WPF中的实现读取和写入文件的几种方式

说明:C#中实现读取和写入的类根据需要来选择。 1、File类 File类是用于操作文件的工具类,提供了对文件进行创建、复制、删除、移动和打开单一文件的静态方法。但需要注意的是,WPF中使用File的类,需要先引用System.IO下的命名空间。…

U盘如何自定义图标?

1、准备一张图片,转换为.ico格式,转换格式的工具推荐一个ToYcon 转换好后放到拷贝到u盘里面。 2、在u盘里面新建一个文本文档,在文档里面写入以下内容,注意,这里的test为图片的名称。 根据自己图片名称做一下修改。 […

【Linux】C文件系统详解(二)——什么是fd文件描述符以及理解“一切皆文件“

文章目录 fd-文件描述符如何深度理解"一切皆文件"**我们使用OS的本质:**FILEFILE是什么?谁提供的?和我们刚刚讲的内核的struct有关系吗FILE是一个结构体.该结构体内部一定要有以下字段:FILE是C语言标准库提供的.FILE和我们刚刚讲的内核的struct没有关系,最多就是上…

Redis(哈希Hash和发布订阅模式)

哈希是一个字符类型字段和值的映射表。 在Redis中,哈希是一种数据结构,用于存储键值对的集合。哈希可以理解为一个键值对的集合,其中每个键都对应一个值。哈希在Redis中的作用主要有以下几点: 1. 存储对象:哈希可以用…

PDU是什么?

PDU,即功率分配单元(Power Distribution Unit),它是一种能够对电源进行管理、监控来保障电力质量与供电可靠性的电源扩展设备。它广泛应用于数据中心、IT机房、机房领域等,可以实现对电源进行远程监控、电源管理和电源分配,为IT设…

springboot+vue+element简单实现教学课程申报管理系统

目录 一、项目预览 二、项目效果图及说明 1.项目说明 1.登录 2.欢迎页 3.教师管理 4.课程申报 ​5.管理员管理 三、代码实现 1.后端项目结构图 2.数据库表脚本 3.路由配置 四、总结 一、项目预览 在线预览:点击访问其他项目访问:点击访问后端实…

庖丁解牛:NIO核心概念与机制详解

文章目录 Pre输入/输出Why NIO流与块的比较通道和缓冲区概述什么是缓冲区?缓冲区类型什么是通道?通道类型 NIO 中的读和写概述Demo : 从文件中读取1. 从FileInputStream中获取Channel2. 创建ByteBuffer缓冲区3. 将数据从Channle读取到Buffer中 Demo : 写…