量化
量化使用更少的比特来表示数据,使其成为减少内存使用和加速推理的实用技术,尤其是在大型语言模型 (LLM) 方面。有多种方法可以量化模型,包括
- 使用 AWQ 算法优化哪些模型权重被量化
- 使用 GPTQ 算法独立地量化权重矩阵的每一行
- 使用 bitsandbytes 库量化到 8 位和 4 位精度
- 使用 AQLM 算法量化到低至 2 位的精度
但是,在模型量化后,通常不会针对下游任务对其进行进一步训练,因为由于权重和激活的精度较低,训练可能不稳定。但由于 PEFT 方法仅添加了额外的可训练参数,因此允许您在量化模型之上训练 PEFT 适配器!将量化与 PEFT 相结合可能是训练即使是最庞大模型在单个 GPU 上的良好策略。例如,QLoRA 是一种将模型量化到 4 位然后使用 LoRA 对其进行训练的方法。此方法允许您在一个 48GB 的单个 GPU 上微调一个 650 亿参数的模型!
在本指南中,您将了解如何将模型量化到 4 位并使用 LoRA 对其进行训练。
量化模型
bitsandbytes 是一个具有 Transformers 集成的量化库。通过此集成,您可以将模型量化到 8 位或 4 位,并通过配置 BitsAndBytesConfig 类来启用许多其他选项。例如,您可以
- 设置
load_in_4bit=True
以在加载模型时将其量化到 4 位 - 设置
bnb_4bit_quant_type="nf4"
以对从正态分布初始化的权重使用特殊的 4 位数据类型 - 设置
bnb_4bit_use_double_quant=True
以使用嵌套量化方案来量化已量化的权重 - 设置
bnb_4bit_compute_dtype=torch.bfloat16
以使用 bfloat16 进行更快的计算
import torch
from transformers import BitsAndBytesConfig
config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=torch.bfloat16,
)
将 config
传递给 from_pretrained 方法。
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", quantization_config=config)
接下来,您应该调用 prepare_model_for_kbit_training() 函数来预处理量化模型以进行训练。
from peft import prepare_model_for_kbit_training
model = prepare_model_for_kbit_training(model)
现在量化模型已准备就绪,让我们设置一个配置。
LoraConfig
使用以下参数创建一个 LoraConfig(或选择您自己的)
from peft import LoraConfig
config = LoraConfig(
r=16,
lora_alpha=8,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
然后使用 get_peft_model() 函数从量化模型和配置创建 PeftModel。
from peft import get_peft_model
model = get_peft_model(model, config)
您已准备好使用您喜欢的任何训练方法进行训练!
LoftQ 初始化
LoftQ 初始化 LoRA 权重,使量化误差最小化,并且在训练量化模型时可以提高性能。要开始使用,请按照 这些说明 进行操作。
通常,为了使 LoftQ 能够发挥最佳效果,建议尽可能多地将 LoRA 应用于更多层,因为未应用 LoRA 的层无法应用 LoftQ。这意味着传递 LoraConfig(..., target_modules="all-linear")
最有可能获得最佳结果。此外,在使用 4 位量化时,您应该在量化配置中使用 nf4
作为量化类型,即 BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4")
。
QLoRA 风格训练
QLoRA 将可训练权重添加到 Transformer 架构中的所有线性层。由于这些线性层的属性名称在不同的架构之间可能有所不同,因此将 target_modules
设置为 "all-linear"
以将 LoRA 添加到所有线性层
config = LoraConfig(target_modules="all-linear", ...)
AQLM 量化
语言模型的加性量化(AQLM)是一种大型语言模型压缩方法。它将多个权重一起量化,并利用它们之间的相互依赖关系。AQLM 将 8-16 个权重的组表示为多个向量代码的总和。这使得它能够将模型压缩到低至 2 位,并且准确率损失非常低。
由于 AQLM 量化过程在计算上代价很高,因此建议使用预量化模型。可在官方 aqlm 存储库 中找到可用模型的部分列表。
这些模型支持 LoRA 适配器微调。要微调量化模型,您需要安装 aqlm
推理库:pip install aqlm>=1.0.2
。微调的 LoRA 适配器应单独保存,因为无法将它们与 AQLM 量化权重合并。
quantized_model = AutoModelForCausalLM.from_pretrained(
"BlackSamorez/Mixtral-8x7b-AQLM-2Bit-1x16-hf-test-dispatch",
torch_dtype="auto", device_map="auto", low_cpu_mem_usage=True,
)
peft_config = LoraConfig(...)
quantized_model = get_peft_model(quantized_model, peft_config)
您可以参考 Google Colab 示例以概述 AQLM+LoRA 微调。
EETQ 量化
您也可以对 EETQ 量化模型执行 LoRA 微调。EETQ 包提供了一种简单有效的方法来执行 8 位量化,据称它比 LLM.int8()
算法更快。首先,确保您拥有与 EETQ 兼容的 Transformers 版本(例如,通过从最新的 pypi 或源代码安装)。
import torch
from transformers import EetqConfig
config = EetqConfig("int8")
将 config
传递给 from_pretrained 方法。
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", quantization_config=config)
并创建一个 LoraConfig
并将其传递给 get_peft_model
from peft import LoraConfig, get_peft_model
config = LoraConfig(
r=16,
lora_alpha=8,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, config)
HQQ 量化
使用半二次量化大型机器学习模型(HQQ)量化的模型支持 LoRA 适配器微调。要微调量化模型,您需要使用以下命令安装 hqq
库:pip install hqq
。
from hqq.engine.hf import HQQModelForCausalLM
quantized_model = HQQModelForCausalLM.from_quantized(save_dir_or_hfhub, device='cuda')
peft_config = LoraConfig(...)
quantized_model = get_peft_model(quantized_model, peft_config)
或使用与 HQQ 兼容的 Transformers 版本(例如,通过从最新的 pypi 或源代码安装)。
from transformers import HqqConfig, AutoModelForCausalLM
quant_config = HqqConfig(nbits=4, group_size=64)
quantized_model = AutoModelForCausalLM.from_pretrained(save_dir_or_hfhub, device_map=device_map, quantization_config=quant_config)
peft_config = LoraConfig(...)
quantized_model = get_peft_model(quantized_model, peft_config)
后续步骤
如果您有兴趣了解更多关于量化的信息,以下内容可能会有所帮助
- 详细了解 QLoRA,并在 使用 bitsandbytes、4 位量化和 QLoRA 使 LLM 更易访问 博客文章中查看其影响的一些基准测试。
- 在 Transformers 量化 指南中阅读更多关于不同量化方案的信息。