QLoRA原理分析
QLoRA是LoRA的量化版本,在LoRA的基础上,对权重W进行量化,如图2所示,以进一步减少对GPU显存的需求。
1、算法论文及代码
- 论文
《QLORA: Efficient Finetuning of Quantized LLMs》
https://arxiv.org/pdf/2305.14314
- 代码
https://github.com/artidoro/qlora
2、QLoRA原理
图1将QLoRA与其他微调方式进行了对比,从中可发现QLoRA相较LoRA,多了一个与CPU内存进行页交换的功能,从而能支持更大参数量的模型微调。QLoRA的核心实现,是在peft库里,qlora官方源码里只是去调用peft库实现的NF4类型,以及双重量化和训练模型时的页交换功能。
图1 QLoRA与其他微调方式对比
图2从公式角度,对比了LoRA与QLoRA原理差异:
1)W权重矩阵类型由FP16,转换为NF4(Normal Float 4bit),空间大约降为原来的1/4;
2)A、B矩阵的类型,由FP16转换为BF16(Brain Float 16 bit),空间和原来一样,但浮点的表示范围比原来大了,但表示精度较原来有所下降。
图2 LoRA与QLoRA原理对比
从图2中可看出,QLoRA的主要意图是进一步降低微调大模型所需的GPU显存,同时保证精度与原来差不多,实现这种效果的关键,在于NF4类型的引入。
3、NF4(Normal Float)
NF4是一种统计数据类型,只取固定的几个数值,这几个数值是某种分布的分位数,其数值大小在[-1.0, 1.0],如图13所示,NF4有16个分位数,权重W中的元素,经过归一化等处理后,只能取这16个数值中的某一个数值的索引。
图3 NF4的取值范围
图4以8位量化为例,描述了权重W中的元素,是如何转换为NF4数据类型。图14中的权重矩阵W形状为[1, 4],QLoRA首先对W进行分块处理,块(Block)大小为2,然后以块为单位,对每个块内的元素选取最大值,并用该最大值除以该块内所有元素,达到归一化的效果,最后查表,将W中所有元素,使用一个与元素值最相近的值的索引,来替换W中原有元素的值,由于表索引只有8位,相较原来的FP16或FP32,减少的存储空间相当可观。
图4 NF4的取值计算流程
4、双重量化(Double Quantization)
第3小节描述的是W权重元素如何从FP16转换为4Bit的NF4,这只是第一次量化,随后还需进行引二次量化,因为第一次量化,需保存各分块内部元素的最大值c_max,以便于后续将NF4还原为FP16或BF16,这就导致会产生数量比较大的c_max集合,占用的存储空间也比较可观,比如一个模型参数有6B,假设每个参数的权重形状一样,均为[4096, 4096],以块大小64进行NF4转换,则可以得到64 * 64 * 109 个块最大值,如果块最大值的数据类型为FP16,则需占用2 * 64 * 64 * 109,约8192GB的存储空间,所以需要对c_max集合做量化,量化的方式参见图16,量化过程也是先分块,再在块内寻找最大值,然后归一化。
图5 双重量化之第二次量化过程
图6 c_max集合量化过程
对c_max集合进行量化后,c_max集合占用的空间,从2*64*64*109=8,192GB,降到64*64*109 +4*109=4096+4 GB = 4,100GB,所需存储空间降幅(8192-4100)/8192≈50%。
图7描述了QLoRA双重量化的较完整流程。
图7 QLoRA双重量化原理
关注更多安卓开发、AI技术、股票分析技术及个股诊断等理财、生活分享等资讯信息,请关注本人公众号(木圭龙的知识小屋)