? PEFT: 在低資源硬體上對十億規模模型進行引數高效微調

HuggingFace發表於2023-03-07

動機

基於 Transformers 架構的大型語言模型 (LLM),如 GPT、T5 和 BERT,已經在各種自然語言處理 (NLP) 任務中取得了最先進的結果。此外,還開始涉足其他領域,例如計算機視覺 (CV) (VIT、Stable Diffusion、LayoutLM) 和音訊 (Whisper、XLS-R)。傳統的正規化是對通用網路規模資料進行大規模預訓練,然後對下游任務進行微調。與使用開箱即用的預訓練 LLM (例如,零樣本推理) 相比,在下游資料集上微調這些預訓練 LLM 會帶來巨大的效能提升。

然而,隨著模型變得越來越大,在消費級硬體上對模型進行全部引數的微調變得不可行。此外,為每個下游任務獨立儲存和部署微調模型變得非常昂貴,因為微調模型與原始預訓練模型的大小相同。引數高效微調(PEFT) 方法旨在解決這兩個問題!

PEFT 方法僅微調少量 (額外) 模型引數,同時凍結預訓練 LLM 的大部分引數,從而大大降低了計算和儲存成本。這也克服了 災難性遺忘 的問題,這是在 LLM 的全引數微調期間觀察到的一種現象。 PEFT 方法也顯示出在低資料狀態下比微調更好,可以更好地泛化到域外場景。它可以應用於各種模態,例如 影像分類 以及 Stable diffusion dreambooth

PEFT 方法還有助於提高輕便性,其中使用者可以使用 PEFT 方法調整模型,以獲得與完全微調的大型檢查點相比,大小僅幾 MB 的微小檢查點。例如, bigscience/mt0-xxl 佔用 40GB 的儲存空間,全引數微調將導致每個下游資料集有對應 40GB 檢查點。而使用 PEFT 方法,每個下游資料集只佔用幾 MB 的儲存空間,同時實現與全引數微調相當的效能。來自 PEFT 方法的少量訓練權重被新增到預訓練 LLM 頂層。因此,同一個 LLM 可以透過新增小的權重來用於多個任務,而無需替換整個模型。

簡而言之,PEFT 方法使您能夠獲得與全引數微調相當的效能,同時只有少量可訓練引數。

今天,我們很高興地介紹 ? PEFT 庫。它提供了最新的引數高效微調技術,與 ? Transformers 和 ? Accelerate 無縫整合。這使得能夠使用來自 Transformers 的最流行和高效能的模型,以及 Accelerate 的簡單性和可擴充套件性。以下是目前支援的 PEFT 方法,即將推出更多:

  1. LoRA: LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
  2. Prefix Tuning: P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks
  3. Prompt Tuning: The Power of Scale for Parameter-Efficient Prompt Tuning
  4. P-Tuning: GPT Understands, Too

用例

我們在 GitHub PEFT 庫中 探索了許多有趣的用例。以下羅列的是其中最有趣的:

  1. 使用 ? PEFT LoRA 在具有 11GB RAM 的消費級硬體上調整 bigscience/T0_3B 模型 (30 億個引數),例如 Nvidia GeForce RTX 2080 Ti、Nvidia GeForce RTX 3080 等,並且使用 ? Accelerate 的 DeepSpeed 整合: peft_lora_seq2seq_accelerate_ds_zero3_offload.py。這意味著您可以在 Google Colab 中調整如此大的 LLM。
  2. 透過使用 ? PEFT LoRA 和 bitsandbytes 在 Google Colab 中啟用 OPT-6.7b 模型 (67 億個引數) 的 INT8 調整,將前面的示例提升一個檔次: Colab 地址
  3. 在具有 11GB RAM 的消費級硬體上使用 ? PEFT 進行穩定的 Diffusion Dreambooth 訓練,例如 Nvidia GeForce RTX 2080 Ti、Nvidia GeForce RTX 3080 等。試用 Space 演示,它應該可以在 T4 例項 (16GB GPU) 上無縫執行: smangrul/peft-lora-sd-dreambooth

PEFT LoRA Dreambooth Gradio Space

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 包裝基礎 ? Transformer 模型
  model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path)
+ model = get_peft_model(model, peft_config)
+ model.print_trainable_parameters()
# output: trainable params: 2359296 || all params: 1231940608 || trainable%: 0.19151053100118282

就是這樣!訓練迴圈的其餘部分保持不變。有關端到端示例,請參閱示例 peft_lora_seq2seq.ipynb

  1. 當您準備好儲存模型以供推理時,只需執行以下操作。
model.save_pretrained("output_dir") 
# model.push_to_hub("my_awesome_peft_model") also works

這隻會儲存經過訓練的增量 PEFT 權重。例如,您可以在此處的 twitter_complaints raft 資料集上找到使用 LoRA 調整的 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 倉庫 上提出問題 ?。

祝你有一趟快樂的引數高效微調之旅!


英文原文: https://hf.co/blog/peft

作者: Sourab Mangrulkar、Sayak Paul

譯者: Ada Cheng

審校、排版: zhongdongy (阿東)

相關文章