FSDP-QLoRA
FSDP-QLoRA 结合了数据并行性(FSDP 允许将模型参数、优化器状态和梯度在 GPU 之间进行分片)、4 位量化和 LoRA,可以在双 24GB GPU 系统上训练高达 70B 参数的 LLM。该技术由 Answer.AI 与 bitsandbytes 合作发布,旨在使 LLM 的训练更高效,并使每个人都能更容易地访问 LLM。
本指南简要介绍了 bitsandbytes 如何支持将量化权重存储以启用 FSDP-QLoRA,以及如何使用 Hugging Face 库运行训练。
bitsandbytes 为支持 FSDP-QLoRA 所需的其他更改,例如从量化元数据重建权重,以及在将已量化权重从 CPU 移动到 GPU 时阻止量化已量化权重,已在此 Pull Request 中记录,并在 Enabling 70B Finetuning on Consumer GPUs 博客文章中进行了描述。我们强烈建议您阅读这些资源,以更好地了解 FSDP-QLoRA!
量化数据存储
FSDP 仅支持分片浮点数据类型,这可能存在问题,因为量化权重通常存储为整数数据类型(uint8)。bitsandbytes 没有这个问题,因为它使用 StoreChar
来读取和写入量化权重,而不管数据类型存储是什么。这使得在 Linear4bit 和 Params4bit 类中添加 quant_storage
参数并将其设置为 torch.uint8
变得非常简单,从而保持与代码库的向后兼容性。使用 quant_storage
参数,您可以选择任何 FSDP 支持的数据类型来分片 Linear4bit,例如 bfloat16、float16 或 float32。
您通常会从 transformers.BitsAndBytesConfig 中访问和配置此选项,方法是设置 bnb_4bit_quant_storage
参数。非常 重要的是 quant_storage
数据类型与模型中使用的其他数据类型匹配,因为 FSDP 只能包装具有相同浮点数据类型的层和模块。确保数据类型一致将确保模型被正确地分片。
compute_dtype
是在 CUDA 内核中用于计算的数据类型,其中 4 位量化权重从 quant_storage
中的数据类型解包并反量化为 compute_dtype
。我们建议使用 torch.bfloat16(如果您的硬件支持)以获得更好的数值稳定性。
from transformers import BitsAndBytesConfig, AutoModelForCausalLM
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_quant_storage=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-70b",
quantization_config=bnb_config,
torch_dtype=torch.bfloat16,
)
查看 PEFT 文档中的此 部分,了解用于运行 FSDP-QLoRA 训练的配置文件和训练代码。
训练
FSDP 是一个分布式训练框架,需要使用诸如 Accelerate 或 torchrun 之类的库作为分布式训练作业启动。本节提供的启动命令使用 Accelerate 启动训练脚本。
bitsandbytes 与 Hugging Face 生态系统深度集成,使其易于与 Transformers、PEFT 和 TRL 之类的库一起使用。
PEFT 提供了一个配置文件 (fsdp_config_qlora.yaml)、启动命令 (run_peft_qlora_fsdp.sh) 和训练脚本 (train.py),用于运行 FSDP-QLoRA。要了解更多信息,请查看 Use PEFT QLoRA and FSDP for finetuning large models on multiple GPUs 文档。本节简要介绍了运行 FSDP-QLoRA 训练的步骤。
在开始之前,请确保你已经安装了最新的库。
pip install -U bitsandbytes accelerate transformers peft trl
启用 FSDP-QLoRA 训练的重要更改是 BitsAndBytesConfig 类中的 bnb_4bit_quant_storage
参数。这允许你将量化权重的存储数据类型设置为浮点数据类型。
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_storage=torch.bfloat16,
)
将 BitsAndBytesConfig 传递给模型以设置 FSDP-QLoRA。你应该将 torch_dtype
参数设置为与 bnb_4bit_quant_storage
相匹配,以便 Linear4bit 层与 Linear
层相同。如果存储类型不匹配,那么每个 Linear4bit 层将单独包装。
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-70b",
quantization_config=bnb_config,
torch_dtype=torch.bfloat16,
)
通过设置 target_modules="all-linear"
来配置 ~peft.LoraConfig
类以进行 QLoRA 训练。
from peft import LoraConfig
peft_config = LoraConfig(
lora_alpha=16,
lora_dropout=0.1,
r=64,
bias="none",
task_type="CAUSAL_LM",
target_modules="all-linear",
)
现在你可以将所有内容传递给 SFTTrainer 进行训练。
from trl import SFTTrainer
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
peft_config=peft_config,
dataset_text_field="text",
max_seq_length=max_seq_length,
tokenizer=tokenizer,
args=training_arguments,
)
trainer.train()
资源
要了解更多关于 FSDP 和 QLoRA 的信息,请查看以下资源
- The AnswerDotAI/fsdp_qlora 仓库。
- Answer.AI 的介绍性文章 You can now train a 70b language model at home。
- 要了解 FSDP 的介绍,请阅读 Introducing PyTorch Fully Sharded Data Parallel (FSDP) API 博客文章。
- 有关 QLoRA 的更多详细信息,请查看 Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA 博客文章。