微信扫码
与创始人交个朋友
我要投稿
本文重点:
量化是门技术活,就像是给大型语言模型(LLM)和其他神经网络模型做了一次“瘦身”,让它们变得更加轻巧,运行起来也更加迅速。这个过程就是把模型里那些高精度的数字,比如 32 位的浮点数,变成精度低一些的格式,比如 8 位的整数。这有点像我们平时做预算,把每一笔开销都精确到分,变成了只记到元,虽然会少一些细节,但大体的收支情况还是能把握住的。
(图片来自 medium 上的原图)
以 LLaMA 3.1–70B 模型为例,这是一个具有 70 亿参数的高性能LLM(小编另一篇科普,Meta Llama 3.1 : 开源是人工智能前进的道路),其在推理过程中对内存的需求高达140 GB。这样的资源消耗水平,通常需要依赖多个高端图形处理单元(GPU)来实现有效的运算处理。
线性量化作为一种在神经网络模型中广泛应用的压缩技术,它通过减少模型参数的表示精度来实现模型尺寸的显著缩减。这种方法特别适用于资源受限的环境,因为它能够在不牺牲太多模型准确度的前提下,提高模型在这些环境下的运行效率。该技术涉及通过四步过程将浮点权重映射到定点值,这里将对下图进行详细介绍。
(图片来自 medium 上的原图)
第 2 步:缩放和零点计算
在此步骤中,计算缩放因子 ( s ) 和零点 ( z ),以使每个张量的值适合目标整数范围。缩放因子决定量化的粒度,而零点会移动值的范围,以确保量化值以零为中心。目标是找到最佳比例和零点,以最小化量化误差,同时确保值适合目标整数范围。
(图片来自 medium 上的原图)
计算过程:比例因子 s 用于将输入数据的范围映射到量化值的范围。它计算为 q 的范围 / x 波动范围,那么当前 s = (127 - (-128)) / (1.0 - (-1.0)) = 127.5。零点 z 用于量化尺度上的原点,它将输入数据的零点映射到量化值的一个特定点。它计算为 z = q (min) - round (s * x(min)),其中 round 就是四舍五入,那么当前 z = -128 - round(127.5 * - 1.0) = 0。
步骤 3:将浮点值量化为低精度整数
计算出比例和零点后,使用以下公式将浮点值量化为低精度整数。其中 x是原始浮点值,q 是量化整数值,s 是缩放因子,z 是零点。此等式将浮点值映射到一组离散的整数值,从而降低了 LLM 的精度和内存要求。
计算过程:q = round(127.5 * 0.5+0) = round(63.75) = 64
步骤 4:推理过程中进行去量化,以实现精确计算
在推理过程中,使用以下公式将量化的整数值反量化回浮点值。其中 x̂ 是重建的浮点值。此反量化步骤可确保推理期间执行的计算精确且准确,同时仍受益于量化模型减少的内存占用和计算要求。
(图片来自 medium 上的原图)
计算过程:x̂ = (64 - 0) / 127.5 = 0.5
再讲解一下,来个图例说明了 2 位线性对称量化,其中 4 * 4 权重用作校准数据来确定量化参数,特别是缩放因子 s 和零点 z。
(图片来自 medium 上的原图)
非对称量化与对称量化
对称量化是一种在量化过程中将零点置于量化范围中点的方法,使得正负量化间隔围绕零点对称分布。这种量化策略因其实现简单和计算效率高而被广泛采用。以 8 位对称量化为例,量化级别从 -127 到 127,覆盖了范围 [-0.8, 0.9],其中零点正好位于 0,对应于量化范围的中点(参考前面例子)。对称量化特别适合于那些在零点附近对称分布的权重数据。
然而,对于分布不对称的数据,对称量化可能无法充分利用整个量化范围,导致表示精度下降。相比之下,非对称量化能够根据数据的实际分布调整量化间隔,从而在数据正负值范围差异显著时,提供更精确的表示。这种灵活性通常有助于在量化后保持模型的性能。在实现 n 位非对称量化时,通常会保留一个特殊的量化级别来表示零点,这通常意味着量化范围的一侧会少一个可用的级别。例如,在 8 位对称量化中,可以表示从 -127 到127 的浮点数,这是因为我们牺牲了一个级别来表示零点。这种量化方法允许将浮点数的范围 [-absmax(x), absmax(x)] 映射到整数范围 [-(2^(n-1)-1), 2^(n-1)-1]。
(图片来自 medium 上的原图)
(图片来自 medium 上的原图)
有几种策略可以将量化应用于深度学习模型的不同组件,每种策略都有其自己的优点和用例。
权重:减少模型大小和内存占用
激活:节省内存,尤其是与权重量化结合时
KV Cache:加速处理长序列的模型的序列生成(KV Cache 在量化策略中可能指的是对 Transformer 模型中自注意力机制使用的键和值的缓存进行量化,以优化模型的内存和计算效率)
梯度:减少大规模训练中的通信开销,并可能加速训练
LLM 量化的类型:
LLM 量化主要包括两种方法:QAT 和 PTQ。
(图片来自 medium 上的原图)
QAT(量化感知训练)
PTQ(训练后量化)
PTQ 不需要重新训练模型,而量化则直接应用于预训练模型。它更简单、更快速,非常适合快速部署。PTQ 分析权重分布、确定量化参数并将权重转换为较低精度。虽然它快速且节省资源,但它可能会略微降低模型性能,尤其是在较小的模型或具有异常值的模型中。
训练时量化:在模型训练的时候,权重和激活值会被模拟量化,也就是说,它们会被暂时转换成整数形式,然后再转换回浮点数进行计算。
调整模型:通过这种方式,模型在学习过程中会逐渐适应量化,从而在真正量化后保持较好的性能。
需要训练数据:QAT需要原始的训练数据,因为它本质上还是一个训练过程。
PTQ 是一种在模型训练完成后进行量化的方法。这就像是你有一个已经训练好的模型,现在你想要让它在资源受限的设备上运行,比如手机。你不需要重新训练模型,只需要对模型的权重进行量化。
训练后量化:在模型训练完成后,你直接对模型的权重进行量化,通常是将32位浮点数转换为8位整数。
校准:为了确保量化后的模型性能不会太差,你需要通过一些样本数据来校准量化的参数,这个过程不需要大量的训练数据,只需要少量的代表性数据。
快速部署:PTQ的优点是快速,你不需要重新训练模型,只需要进行一次量化过程,就可以将模型部署到新的平台上。
LLM 中应用的具体量化技术
Generative Pre-trained Transformer Quantization 是一项针对大型语言模型的先进训练后量化技术。该技术通过显著降低模型权重的位宽至 3 至 4 位,同时保持模型性能,实现了高效的模型压缩。GPTQ 引入了一种创新的一次性权重量化方法,并结合 Cholesky 分解以提高计算效率。如下图,白色部分正在量化,因为它们还未进行量化的权重矩阵或块。这些权重保持在全精度状态,即它们还没有被转换成低精度的表示形式。最终会变成蓝色部分,这些已经带有量化的权重。
下图是一个递归过程,这个过程在每个块内进行:当前正在量化的白色中间列,其周围的权重(蓝色部分)会在量化步骤结束时进行更新。这种方法允许算法在保持较高精度的同时,对大型模型进行有效的量化。简而言之,这个过程利用 Cholesky 算法,就像是在做一个大型的拼图游戏,每次处理一部分拼图块,同时调整周围的块以确保整体的准确性。
这种技术能够在数小时内完成对如 GPT-3(拥有1750亿参数)这样的大规模模型的量化过程,与现有基线方法相比,压缩比提升了两倍以上。
(图片来自附录文献上的原图)
from transformers import AutoModelForCausalLM, AutoTokenizer
from optimum.gptq import GPTQQuantizer
import torch
model_path = 'meta-llama/Meta-Llama-3-8B'
b = 4
quant_path = 'Meta-Llama-3-8B-gptq-'+str(b)+'bit'
tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=True)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16, device_map="auto")
quantizer = GPTQQuantizer(bits=b, dataset="c4", model_seqlen = 2048)
quantized_model = quantizer.quantize_model(model, tokenizer)
quantized_model.save_pretrained("./"+quant_path, safetensors=True)
tokenizer.save_pretrained("./"+quant_path)
Cholesky
用白话来说,就像是把一个大的数学问题(特别是涉及到矩阵的运算)拆分成更小、更容易解决的部分的一种方法。想象一下,你有一个由许多小方块组成的复杂拼图,每个小方块上都有数字,你需要找到一种方法来排列这些方块,使得每一行和每一列的数字之和满足一定的规则。在数学中,矩阵可以被看作是一个由数字排列成的表格。Cholesky 分解专门针对的是所谓的“正定矩阵”,这是一类具有特殊性质的矩阵,比如所有的行和列的数字之和都是正数。
假设你有一个大型的建筑项目,需要计算建筑的稳定性。这个稳定性可以通过解决一个复杂的数学方程来确定,这个方程可以表示为一个矩阵 A。如果 A 是正定的( 数学矩阵中专有名词,可以去查,有 n 多条件,这里不多解释),你可以使用 Cholesky 分解来简化问题。
步骤 1:将矩阵 A 分解为两个下三角矩阵 L 和 LT。
步骤 2:解决两个更简单的问题,即 L 和 LT 相关的计算。
步骤 3:通过这两个更简单的问题的解,你可以得到原始问题的答案。
MLP
Multilayer Perceptron 多层感知机是一种基础的前馈神经网络,它由至少三层节点组成:一个输入层、一个或多个隐藏层以及一个输出层。每层由多个神经元(或节点)组成,这些神经元可以对输入数据进行加权求和,并通过一个非线性激活函数来产生输出。
GGML(由 Georgi Gerganov 开发)是一个用 C 语言编写的库,它为机器学习应用提供了一套强大的工具和功能,特别是在支持 LLM 的构建和部署方面。GGML 的设计重点在于提供深度学习所需的基础构件,如张量,这些是进行复杂数学运算和模型训练的核心元素。
Rotary Positional Encoding(RoPE)
NF4
关于 QLoRA,低秩请看这篇文章中间推导, 一文了解 2024 China 谷歌 IO AI 技术点
Bitsandbytes
Hugging Face 的 Transformers 库,作为一个在自然语言处理领域内广受好评的工具集,极大地简化了预训练语言模型的运用。该库通过与 Bitsandbytes 库的紧密结合,进一步降低了模型量化的门槛,使得用户可以以极低的编程复杂度来构建和优化模型。Bitsandbytes 库作为一个 Python 接口,为 CUDA 自定义函数提供了便捷的封装,使得开发者能够轻松地利用 GPU 加速量化过程。它包括了一系列高效的工具,如 8 位优化器、矩阵乘法(如下图,通过 LLM.int8() 方法实现)以及 8 位和 4 位量化功能。这些工具共同构成了一个强大的量化解决方案,使得LLM 能够即时量化,而无需经历重新训练或调整模型结构的复杂过程。
要将模型量化为 4 位,请使用以下代码:
AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", load_in_4bit=True)
与 GPTQ 相比,Bitsandbytes 在 4 位量化方面提供了更好的结果,这要归功于它使用的 NormalFloat4 数据类型,该类型优于 GPTQ 的 INT4。但是,使用 bitsandbytes 有两个明显的缺点:
有限的量化支持:Bitsandbytes 仅支持量化为 8 位和 4 位,这可能会限制其适用性。
推理速度较慢:使用 bitsandbytes 量化的模型的推理速度可能较慢,这可能会影响某些应用程序的性能。
尽管存在这些限制,bitsandbytes 仍然提供了一种方便有效的方法来减少 LLaMA 3 等大型 LLM 的内存占用。
总结回顾下,这些量化技术代表了应对压缩 LLM 挑战的不同方法。GPTQ 提供了一种高效的后训练方法,GGML 为量化模型提供了一种通用格式,NF4 引入了一种用于平衡压缩的专用数据类型,bitsandbytes 提供了一个用于实现各种量化策略的综合库。
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-12-21
一文回顾OpenAI系列发布会:从工具到AGI,OpenAI的12天进化论
2024-12-19
强化微调技术详解:开启AI模型定制的新篇章
2024-12-18
OpenAI 年底「百亿补贴」来了,满血 o1 API 开放,成本暴跌,定制升级
2024-12-18
腾讯AI团队:用Ray分布式计算效率提升800%
2024-12-18
OpenAI 新货详解:大量接口更新,还有 Go/Java SDK
2024-12-18
聊聊对强化微调(RFT)的理解及看法
2024-12-18
提升大模型 Function Calling 准确性
2024-12-18
OpenAI Day9丨o1实时API全面开放,音频价格降低60%
2024-09-18
2024-07-11
2024-07-11
2024-07-09
2024-06-11
2024-10-20
2024-07-23
2024-07-20
2024-07-26
2024-07-12