Press "Enter" to skip to content

使用🤗 PEFT 进行参数高效微调

动机

基于Transformer架构的大型语言模型(LLMs),如GPT、T5和BERT,在各种自然语言处理(NLP)任务中取得了最先进的结果。它们还开始进军其他领域,如计算机视觉(CV)(VIT、稳定扩散、LayoutLM)和音频(Whisper、XLS-R)。传统范式是在通用的网络规模数据上进行大规模预训练,然后对下游任务进行微调。与直接使用预训练的LLMs(例如零样本推理)相比,将这些预训练的LLMs在下游数据集上进行微调可以获得巨大的性能提升。

然而,随着模型变得越来越大,完全微调在消费者硬件上变得不可行。此外,为每个下游任务独立存储和部署微调模型非常昂贵,因为微调模型与原始预训练模型的大小相同。参数高效微调(PEFT)方法旨在解决这两个问题!

PEFT方法仅微调少量(额外的)模型参数,同时冻结预训练LLMs的大部分参数,从而大大降低计算和存储成本。这也克服了LLMs在完全微调过程中出现的灾难性遗忘问题。PEFT方法在低数据范围内也表现出优于微调的效果,并更好地推广到领域外场景。它可以应用于各种模态,例如图像分类和稳定扩散梦之间。

它还有助于可移植性,用户可以使用PEFT方法调整模型,以获得几MB大小的小检查点,与完全微调的大检查点相比,例如bigscience/mt0-xxl占用40GB的存储空间,完全微调将导致每个下游数据集的40GB检查点,而使用PEFT方法,每个下游数据集只需几MB,同时实现与完全微调相当的性能。PEFT方法中的小训练权重添加到预训练的LLMs之上。因此,可以通过添加小权重而无需替换整个模型来使用相同的LLMs进行多个任务。

简而言之,PEFT方法使您能够获得与完全微调相当的性能,同时只需少量可训练参数。

今天,我们很高兴介绍🤗 PEFT库,它与🤗 Transformers和🤗 Accelerate完美集成,提供最新的参数高效微调技术。这使得可以使用Transformers中最受欢迎和性能最好的模型,同时结合Accelerate的简单性和可扩展性。下面是当前支持的PEFT方法,更多方法即将推出:

  1. LoRA: LORA: 大型语言模型的低秩自适应
  2. Prefix Tuning: P-Tuning v2: 提示调整在各种规模和任务上可与微调相媲美
  3. Prompt Tuning: 多尺度参数高效提示调整的强大力量
  4. P-Tuning: GPT也懂

应用案例

我们在这里探索了许多有趣的应用案例。以下是其中几个最有趣的案例:

  1. 使用🤗 PEFT LoRA在消费者硬件上对bigscience/T0_3B模型(30亿个参数)进行调优,硬件配置为拥有11GB RAM的Nvidia GeForce RTX 2080 Ti、Nvidia GeForce RTX 3080等,使用🤗 Accelerate的DeepSpeed集成:peft_lora_seq2seq_accelerate_ds_zero3_offload.py。这意味着您可以在Google Colab上对这样大的LLMs进行调优。

  2. 将前面的例子提升一个档次,使用🤗 PEFT LoRA和bitsandbytes在Google Colab上启用OPT-6.7b模型(67亿个参数)的INT8调优:使用🤗 PEFT 进行参数高效微调 四海 第1张

  3. 在拥有11GB RAM的消费者硬件上使用🤗 PEFT进行稳定扩散梦之间的训练,例如Nvidia GeForce RTX 2080 Ti、Nvidia GeForce RTX 3080等。尝试Space演示,应在T4实例(16GB GPU)上无缝运行:smangrul/peft-lora-sd-dreambooth。

使用🤗 PEFT 进行参数高效微调 四海 第2张 PEFT LoRA Dreambooth Gradio Space

使用🤗 PEFT训练您的模型

让我们以使用LoRA对bigscience/mt0-large进行微调的案例为例。

  1. 让我们获取必要的导入
  from transformers import AutoModelForSeq2SeqLM
+ from peft import get_peft_model, LoraConfig, TaskType
  model_name_or_path = "bigscience/mt0-large"
  tokenizer_name_or_path = "bigscience/mt0-large"
  1. 创建与PEFT方法对应的配置
peft_config = LoraConfig(
    task_type=TaskType.SEQ_2_SEQ_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1
)
  1. 通过调用get_peft_model来包装基本的🤗 Transformers模型
  model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path)
+ model = get_peft_model(model, peft_config)
+ model.print_trainable_parameters()
# 输出:可训练参数:2359296 || 所有参数:1231940608 || 可训练%:0.19151053100118282

就是这样!训练循环的其余部分保持不变。请参考示例peft_lora_seq2seq.ipynb获取端到端示例。

  1. 当您准备好保存用于推理的模型时,只需执行以下操作。
model.save_pretrained("output_dir") 
# model.push_to_hub("my_awesome_peft_model")也可以使用

这只会保存已训练的增量PEFT权重。例如,您可以在此处找到使用LoRA对twitter_complaints数据集上的bigscience/T0_3B进行微调的模型:smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM。请注意,它只包含2个文件:adapter_config.json和adapter_model.bin,后者只有19MB。

  1. 要加载它进行推理,请按照下面的代码片段进行操作:
  from transformers import AutoModelForSeq2SeqLM
+ from peft import PeftModel, PeftConfig

  peft_model_id = "smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM"
  config = PeftConfig.from_pretrained(peft_model_id)
  model = AutoModelForSeq2SeqLM.from_pretrained(config.base_model_name_or_path)
+ model = PeftModel.from_pretrained(model, peft_model_id)
  tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path)

  model = model.to(device)
  model.eval()
  inputs = tokenizer("Tweet text : @HondaCustSvc Your customer service has been horrible during the recall process. I will never purchase a Honda again. Label :", return_tensors="pt")

  with torch.no_grad():
      outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=10)
      print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])
# 'complaint'

下一步

我们已经发布了PEFT作为在下游任务和领域上调整大型LLM的高效方式,节省了大量的计算资源和存储空间,同时实现了与完全微调相当的性能。在接下来的几个月中,我们将探索更多的PEFT方法,例如(IA)3和瓶颈适配器。此外,我们还将专注于新的用例,例如在Google Colab中对whisper-large模型进行INT8训练,以及使用PEFT方法对策略和排序器等RLHF组件进行微调。

在此期间,我们非常期待看到行业从业者将PEFT应用于他们的用例 – 如果您有任何问题或反馈,请在我们的GitHub存储库上提出问题🤗。

祝您进行参数高效微调!

Leave a Reply

Your email address will not be published. Required fields are marked *