
什么是PEFT
随着类似GPT-3.5、LLaMA2和PaLM2等大型语言模型越来越大,将它们在下游的自然语言处理(NLP)任务上进行微调变得越来越计算密集和内存密集。
参数高效微调(PEFT)方法通过仅对少量额外参数进行微调,同时冻结大部分预训练模型来解决这些问题。这可以防止大型模型灾难性遗忘,并实现有限计算资源的微调。
PEFT已经证明在图像分类和文本生成等任务中非常有效,同时只使用了一小部分参数。这些微调的小权重可以简单地添加到原始的预训练权重中。
你甚至可以使用4位量化和PEFT技术QLoRA在免费版的Google Colab上微调LLMs。
PEFT的模块化特性还允许通过添加小的任务特定权重来为多个任务调整相同的预训练模型,避免了存储完整副本的需要。
PEFT库集成了流行的PEFT技术,如LoRA、Prefix Tuning、AdaLoRA、Prompt Tuning、MultiTask Prompt Tuning和LoHa,结合了Transformers和Accelerate。这为高效和可扩展的微调提供了轻松访问最前沿的大型语言模型。
什么是LoRA
在本教程中,我们将使用最流行的参数高效微调(PEFT)技术之一,称为LoRA(大型语言模型的低秩适应)。LoRA是一种显著加速大型语言模型微调过程并消耗更少内存的技术。
LoRA的关键思想是使用通过低秩分解获得的两个较小的矩阵来表示权重更新。这些矩阵可以根据新数据进行训练并适应,同时最小化总体修改数量。原始权重矩阵保持不变,不再进行任何进一步的调整。最终结果通过将原始权重和调整后的权重进行组合来获得。
使用LoRA有几个优势。首先,它通过减少可训练参数的数量大大提高了微调的效率。此外,LoRA与其他各种参数高效方法兼容,并且可以与它们相结合使用。使用LoRA进行微调的模型表现与完全微调的模型相当。重要的是,LoRA不会引入任何额外的推理延迟,因为适配器权重可以与基础模型无缝合并。
用途案例
PEFT有许多用途,从语言模型到图像分类器。你可以在官方文档中查看所有用途的教程。
- StackLLaMA:用RLHF训练LLaMA的实用指南
- Finetune-opt-bnb-peft
- 使用LoRA和Hugging Face进行高效flan-t5-xxl训练
- 使用LoRA进行DreamBooth微调
- 使用LoRA进行图像分类
使用PEFT训练LLMs
在本节中,我们将学习如何使用`bitsandbytes`和`peft`库加载和包装我们的变形金刚模型。我们还将介绍如何加载保存的精调QLoRA模型并进行推理。
入门
首先,我们将安装所有必要的库。
%capture%pip install accelerate peft transformers datasets bitsandbytes
然后,我们将导入基本模块并命名基础模型(Llama-2-7b-chat-hf),以便使用mlabonne/guanaco-llama2-1k数据集进行精调。
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfigfrom peft import get_peft_model, LoraConfigimport torchmodel_name = "NousResearch/Llama-2-7b-chat-hf"dataset_name = "mlabonne/guanaco-llama2-1k"
PEFT配置
创建PEFT配置,我们将使用它来包装或训练我们的模型。
peft_config = LoraConfig( lora_alpha=16, lora_dropout=0.1, r=64, bias="none", task_type="CAUSAL_LM",)
4位量化
在消费者或Colab GPU上加载LLMs存在重大挑战。然而,我们可以通过使用BitsAndBytes实现一个4位量化技术(NF4类型配置)来克服这个问题。通过采用这种方法,我们可以有效地加载我们的模型,从而节省内存并防止机器崩溃。
compute_dtype = getattr(torch, "float16")bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=compute_dtype, bnb_4bit_use_double_quant=False,)
包装基础变形金刚模型
为了使我们的模型参数高效,我们将使用`get_peft_model`来包装基础变形金刚模型。
model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto")model = get_peft_model(model, peft_config)model.print_trainable_parameters()
我们的可训练参数比基础模型少,这使我们可以使用更少的内存并更快地对模型进行精调。
trainable params: 33,554,432 || all params: 6,771,970,048 || trainable%: 0.49548996469513035
下一步是训练模型。您可以按照4位量化和QLoRA指南进行操作。
保存模型
训练完成后,您可以将模型保存到本地。
model.save_pretrained("llama-2-7b-chat-guanaco")
或者,将其推送到Hugging Face Hub。
!huggingface-cli login --token $secret_value_0
model.push_to_hub("llama-2-7b-chat-guanaco")
从我们可以看到,模型采用者只有134MB,而基本的LLaMA 2 7B模型大小约为13GB。

加载模型
为了运行模型推理,我们首先需要使用4位精度量化加载模型,然后将训练后的PEFT权重与基础(LlaMA 2)模型合并。
from transformers import AutoModelForCausalLMfrom peft import PeftModel, PeftConfigimport torchpeft_model = "kingabzpro/llama-2-7b-chat-guanaco"base_model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto")model = PeftModel.from_pretrained(base_model, peft_model)tokenizer = AutoTokenizer.from_pretrained(model_name)model = model.to("cuda")model.eval()
推理
为了运行推理,我们需要按照guanaco-llama2-1k数据集的格式编写提示语句(“<s>[INST] {prompt} [/INST]”),否则您将得到不同语言的回复。
prompt = "什么是Hacktoberfest?"inputs = tokenizer(f"<s>[INST] {prompt} [/INST]", return_tensors="pt")with torch.no_grad(): outputs = model.generate( input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=100 ) print( tokenizer.batch_decode( outputs.detach().cpu().numpy(), skip_special_tokens=True )[0] )
输出看起来很完美。
[INST] 什么是Hacktoberfest? [/INST] Hacktoberfest是一个于10月举行的开源软件开发活动。它由非营利组织开源软件研究所(OSSI)于2017年创建。该活动旨在鼓励人们贡献开源项目,目标是增加贡献者数量并改善开源软件的质量。在Hacktoberfest期间,鼓励参与者贡献开源项目
注意:如果您在Colab中加载模型时遇到困难,您可以查看我的笔记本:PEFT概览。
结论
像LoRA这样的参数高效微调技术可以仅使用一小部分参数来对大型语言模型进行高效微调。这避免了昂贵的完全微调,提供了有限计算资源的训练能力。PEFT的模块化特性允许为多个任务进行模型适应。4位精度等量化方法可以进一步减少内存使用。总体而言,PEFT将大型语言模型的能力开放给更广泛的受众。
****[Abid Ali Awan](https://www.polywork.com/kingabzpro)**** (@1abidaliawan) 是一位认证的数据科学家专业人士,热衷于构建机器学习模型。目前,他专注于内容创作,并在机器学习和数据科学技术方面撰写技术博客。Abid拥有技术管理硕士学位和电信工程学士学位。他的愿景是利用图神经网络为心理疾病困扰下的学生构建AI产品。