01.主要内容
QLoRA 本身讲的是模型本身用 4bit 加载,训练时把数值反量化到 bf16 后进行训练,利用 LoRA 可以锁定原模型参数不参与训练,只训练少量 LoRA 参数的特性使得训练所需的显存大大减少。
例如 33B 的 LLaMA 模型经过这种方式可以在 24 GB 的显卡上训练,也就是说单卡 4090、3090 都可以实现,大大降低了微调的门槛。
比较重要的是这么几个点:
- 4bit NormalFloat 量化
- 双重量化
- LoRA
- Page Optimizer
02.4bit NormalFloat
这篇文章的对量化方法的改进是挺重要的一个点,其实感觉这个单拿出来写一篇也不是不行。
它的量化方法基于之前的一篇 8bit 量化文章中提到的 Block-wise Quantization 和 Quantile Quantization.
Block-wise Quantization
假设我们把 float32 的值量化到 int8,本质上我们是把数值从一个更大的范围映射到一个较小的范围。
我们可以使用一个常数 c 来成比例的将数值缩小。这样一来我们也可以很容易的使用这个常数 c 将量化后的数值反量化成原样(近似的)。
但是假如我们的数据中有一些 outliner,这会影响我们选取 c,而且会导致其他值坍缩在一个小的范围内。
Block-wise 对此的解决方案是一批一批的量化,每一批(block)使用独立的 c。在本文中 block 的大小被设为 64。
Quantile Quantization
什么是 Quantile Quantization?假设我们要把参数量化到 4bit,那在 4bit 的情况下我们呢最多可以使用的数字就是 2^4 也就是 16 个。我们最简单的量化方法一般是取最接近的那个值,或者直接 round。
但是这样做的话其实没有充分利用我们有的数位,很有可能大部分原始数值都被量化到同一个 4bit 数上了,原本有的差异或者说信息在这个量化过程中就丢掉了。
更极端的情况,假如原始的 float32 浮点数都在 0 上下波动,可能量化完全变成零,那就没有意义了。
所以如何才能充分利用我们仅剩的 16 个数?最直观的想法就是,我把所有数字由小到大排列,再分成十六等分,最小的一块映射到量化后的第一个数,第二块映射到量化后的第二个数,以此类推。
这样做原始数据在量化后的数字上分布就是均匀的。这样的做法就是 Quantile Quantization。
这里的 Quantile 意思是分位,我们平常说的中位数,四分之一位数,都是一种分位。
既然现在我们只有十六个数,我们可以做一个 map,key 是 0~15,value 则是能最低化量化误差的浮点数。
存储的时候只存储 key,计算的时候使用 value 来计算。出于计算方便考量,可以下面这个公式计算出合适的 Value。
NormalFloat
看到上面的情况之后我们会觉得这个 Quantile Quantization 好烦啊,每一批数字过来我都要计算对应的分位,开销太大了。
是的,尽管有一些加速的方法像 SRAM,但是又会引进新的误差。而在 QLoRA 里则给出了另一种解决方法。
文章中指出,预训练的参数基本上是符合均值为 0 的正态分布的,因此可以直接缩放到指定的范围内,在文章中使用的是 [-1, 1] 的范围。
接着它的做法是,把正态分布 N(0,1)按 quatile quantization 的方法找出 2^k 个量化值,再缩放到 [-1, 1] 范围,以此进行量化。
这样的做法存在一个缺点,0 这个值可能会被映射到一个不为零的数值上,损失了 0 的特殊性质。
为了解决这点,文章改进了这个方法,用两个 2^{k-1} 的 [0, 1] 范围分别代表正负 0~1,再去掉重叠的一个 0 值,组成最终的 Data Type。
03.双重量化
在 block-wise quantization 当中我们提到,每一个 block 有自己的一个常量 c,这其实是个额外的负担,假如 c 使用 float32,block 大小为 64,那么摊到每个参数上的额外开销就是 32/64 = 0.5bit。
对于 4bit 量化来说额外的 0.5bit 相当于多 12.5% 的显存耗用,还是比较可观的。
因此文章中提出了双重量化,对 c 再进行一次量化,考虑到 c 一般出现 outliner 的概率较小,使用 256 作为 block 大小再量化一次 c 得到 8bit 的 c’。
改进过后每个参数的额外消耗为:
8/64 + 32/(64 * 256) = 0.127 bit
04.Page Optimizer
Page Optimizer 机制使得在 GPU 显存吃紧的时候可以把 optimizer 转移到内存上,在需要更新 optimizer 状态时再加载回来,据说可以有效减少 GPU 显存的峰值占用,文章称想要达到在 24gb 上训练 33B 参数模型这个机制是必须的。
05.LoRA
关于 lora 的机制已经有许多介绍的文章了,这里就不多赘述。
简单理解的话可以这样考虑,微调实际上是得到一个在原来基础参数上的 ΔW, 形状大小和原参数是一样的,但是假如我们可以把它分解成 AB=ΔW,A 矩阵和B矩阵的参数量可以远小于 W。
LoRA 的用意就是在冻结原模型的情况下训练 AB 两个矩阵而不是整个 W,这样所需的计算量会大大减小。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。