微調 LLaMA 2:定制大型語言模型的分步指南
深入了解如何運用新技術在 Google Colab 平臺上對 Llama-2 進行微調操作,從而有效克服內存與計算方面的限制,讓開源大型語言模型變得更加易于獲取和使用。自從 Meta 發布了 LLaMA 的首個版本后,一場旨在構建更為強大、能夠與 GPT-3.5(ChatGPT)等模型相抗衡的大型語言模型(LLM)的競賽便正式開啟。開源社區迅速行動起來,不斷發布性能愈發強大的模型。對于人工智能領域的愛好者而言,這段時間就如同圣誕節一般充滿驚喜,新的技術進展接連不斷地涌現。
然而,這些顯著的進步也帶來了一些不可忽視的弊端。一方面,大多數開源模型的使用許可存在諸多限制,這就意味著它們僅僅能夠被應用于研究領域。另一方面,只有那些資金充裕的大型企業或專業的研究機構,才具備足夠的實力對模型進行微調或訓練操作。此外,部署和維護最前沿的大型模型所需的成本相當高昂。全新版本的 LLaMA 模型正是為了解決上述這些問題而誕生的。它提供了商業許可證,使得更多的組織都有機會使用該模型。而且,現在出現了一些新的方法,能夠讓用戶在內存有限的消費級 GPU 上實現對模型的微調。
人工智能的民主化對于其實現廣泛應用來說至關重要。通過打破進入的壁壘,即便是規模較小的公司,也能夠依據自身的實際需求和預算,構建出符合自身特點的定制化模型。在本教程當中,我們將會深入探索 Llama-2 模型,并實際演示如何借助 Google Colab 平臺,在新的數據集上對其進行微調。此外,我們還會介紹一些有助于降低內存占用量,并加快訓練速度的新方法和微調技巧。
了解 Llama 2 和模型微調
Llama 2 是 Meta 公司推出的第二代開源大型語言模型(LLM)集合,并且附帶了商業使用許可證。該模型旨在處理各類自然語言處理任務,其模型規模有所不同,參數數量從 70 億到 700 億不等。如果您想深入了解更多關于 LLaMA 模型的詳細信息,歡迎閱讀我們的文章《Meta AI LLaMA 簡介:賦能 AI 創新》。Llama-2-Chat 模型針對對話場景進行了專門優化,其性能目前已經能夠與 ChatGPT、PaLM 等備受關注的閉源模型相媲美。實際上,我們還可以通過在高質量的對話數據集上對該模型進行微調操作,進一步提升其性能表現。
機器學習領域中,微調指的是根據新的數據對預訓練模型的權重和參數進行調整,以此來提高模型在特定任務上的表現的過程。這一過程需要在與當前任務相關的新數據集上對模型進行訓練,同時更新模型的權重,使其更好地適應新的數據特征。若您希望了解更多關于微調的相關信息,歡迎閱讀我們的《GPT 3.5 微調指南》。以往,由于顯存(VRAM)和計算能力的限制,在消費級硬件設備上無法實現對大型語言模型(LLM)的微調操作。不過,在本教程里,我們將著力克服這些在內存和計算方面所面臨的挑戰,并使用免費版本的 Google Colab Notebook 來完成對我們模型的訓練工作。
如何微調 Llama 2:分步指南
在本部分內容中,我們將一同學習在配備 T4 GPU 的環境下,對擁有 70 億個參數的 Llama 2 模型進行微調操作所需要的全部步驟。您可以自由選擇使用 Google Colab 或者 Kaggle 平臺上提供的免費 GPU 資源。需要注意的是,相應的代碼在這兩個平臺上均能夠正常運行。
Google Colab 所配備的 T4 GPU 的顯存(VRAM)存在一定限制,僅有 16GB。這一容量僅僅勉強能夠存儲 Llama 2-7b 模型的權重數據,這也就表明我們無法對其進行完整的微調操作,因此,我們必須采用諸如 LoRA 或者 QLoRA 這類參數高效的微調技術。
在接下來的操作中,我們將運用 QLoRA 技術,以 4 位精度對模型展開微調工作,并且對顯存(VRAM)的使用進行優化。為了達成這一目標,我們會使用 Hugging Face 生態系統中的大型語言模型(LLM)庫,具體包括:transformers、accelerate、peft、trl 以及 bitsandbytes。
入門
我們將從安裝所需的庫開始
%%capture
%pip install accelerate peft bitsandbytes transformers trl
之后,我們將從這些庫中加載必要的模塊。
import os
import torch
from datasets import load_dataset
from transformers import (AutoModelForCausalLM,AutoTokenizer,BitsAndBytesConfig,TrainingArguments,pipeline,logging,
)
from peft import LoraConfig
from trl import SFTTrainer
模型配置
Meta 公司官方的 Llama-2 模型可以從 Hugging Face 平臺獲取,不過需要進行申請,并且在申請后通常得等待幾天時間才能收到確認回復。為了避免這種等待的時間成本,將選擇使用 NousResearch 的 Llama-2-7b-chat-hf 模型作為基礎模型。該模型與原始的 Llama-2 模型在性能等方面是一致的,而且相對來說更容易獲取到。
將使用名為mlabonne/guanaco-llama2-1k的較小數據集對的基礎模型進行微調,并為微調后的模型寫下名稱。
# Model from Hugging Face hub
base_model = "NousResearch/Llama-2-7b-chat-hf"# New instruction dataset
guanaco_dataset = "mlabonne/guanaco-llama2-1k"# Fine-tuned model
new_model = "llama-2-7b-chat-guanaco"
加載數據集、模型和標記器
將從 Hugging Face 中心加載“guanaco-llama2-1k”數據集。該數據集包含 1000 個樣本,已處理為符合 Llama 2 提示格式,并且是優秀的timdettmers/openassistant-guanaco數據集的子集。
dataset = load_dataset(guanaco_dataset, split="train")
dataset = load_dataset(guanaco_dataset, split="train")
位量化配置
QLoRA 實現的 4 位量化,能在消費級硬件上高效微調大型 LLM 模型,還能維持高性能。這極大提升了實際應用的可及性與可用性。
QLoRA 把預訓練的語言模型量化為 4 位并凍結參數,接著往模型中添加少量可訓練的低秩適配器層。
微調時,梯度會經凍結的 4 位量化模型反向傳播至低秩適配器層。所以,整個預訓練模型的梯度固定為 4 位,僅適配器層會更新。而且,4 位量化不會對模型性能造成影響。
可以閱讀該論文以更好地理解它。在例子中,使用 BitsAndBytes 創建具有 NF4 類型配置的 4 位量化。
compute_dtype = getattr(torch, "float16")quant_config = BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_quant_type="nf4",bnb_4bit_compute_dtype=compute_dtype,bnb_4bit_use_double_quant=False,
)
加載Llama 2模型
接下來,我們將從 Hugginface 加載標記器并設置padding_side為“正確”以修復 fp16 的問題
model = AutoModelForCausalLM.from_pretrained(base_model,quantization_config=quant_config,device_map={"": 0}
)
model.config.use_cache = False
model.config.pretraining_tp = 1
加載標記器
接下來,將從Hugginface加載標記器,并設置padding_side為“正確”,以修復fp16的問題。
tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"
PEFT參數
預訓練語言模型 (PLM) 的傳統微調需要更新模型的所有參數,這在計算方面成本高昂,并且需要大量的數據。
參數高效微調 (PEFT) 的運作方式是僅更新模型中影響力最大的一小部分參數,借此顯著提升模型的效率。可以閱讀 PEFT 官方文檔來了解相關參數。
peft_params = LoraConfig(lora_alpha=16,lora_dropout=0.1,r=64,bias="none",task_type="CAUSAL_LM",
)
訓練參數
以下是可用于優化訓練過程的超參數列表:
- output_dir:輸出目錄是存儲模型預測和檢查點的地方。
- num_train_epochs:一個訓練時期。
- fp16/bf16:禁用 fp16/bf16 訓練。
- per_device_train_batch_size:每個 GPU 的訓練批次大小。
- per_device_eval_batch_size:用于評估的每個 GPU 的批次大小。
- Gradient_accumulation_steps:這指的是更新過程中累積梯度所需的步數。
- Gradient_checkpointing:啟用梯度檢查點。
- max_grad_norm:梯度剪裁。
- learning_rate:初始學習率。
- weight_decay:權重衰減適用于除偏差/LayerNorm權重之外的所有層。
- Optim:模型優化器(AdamW 優化器)。
- lr_scheduler_type:學習率計劃。
- max_steps:訓練步數。
- warmup_ratio:線性預熱的步驟比率。
- group_by_length:這可以顯著提高性能并加速訓練過程。
- save_steps:每 25 個更新步驟保存檢查點。
- logging_steps:每 25 個更新步驟記錄一次。
training_params = TrainingArguments(output_dir="./results",num_train_epochs=1,per_device_train_batch_size=4,gradient_accumulation_steps=1,optim="paged_adamw_32bit",save_steps=25,logging_steps=25,learning_rate=2e-4,weight_decay=0.001,fp16=False,bf16=False,max_grad_norm=0.3,max_steps=-1,warmup_ratio=0.03,group_by_length=True,lr_scheduler_type="constant",report_to="tensorboard"
)
模型微調
監督微調 (SFT) 是強化學習(基于人類反饋)的關鍵步驟。HuggingFace 的 TRL 庫提供了一個使用便捷的 API,僅需幾行代碼就能創建 SFT 模型,并在數據集上開展訓練。它附帶了一些工具,可用來通過強化學習訓練語言模型,流程是先從監督微調起步,接著進行獎勵建模,最后實施近端策略優化 (PPO)。
將為 SFT Trainer 提供模型、數據集、Lora 配置、標記器以及訓練參數。
trainer = SFTTrainer(model=model,train_dataset=dataset,peft_config=peft_params,dataset_text_field="text",max_seq_length=None,tokenizer=tokenizer,args=training_params,packing=False,
)
將使用.train()新的數據集對 Llama 2 模型進行微調。該模型完成 1 個 epoch 需要一個半小時。
模型訓練完成后,將保存模型采用器和分詞器,也可以使用類似的 API 將模型上傳到 Hugging Face。
trainer.model.save_pretrained(new_model)
trainer.tokenizer.save_pretrained(new_model)
評估
現在可以在 Tensorboard 的交互式會話中查看訓練結果。
from tensorboard import notebook
log_dir = "results/runs"
notebook.start("--logdir {} --port 4000".format(log_dir))
為了測試我們微調的模型,將使用transformers文本生成管道并提出一些簡單的問題,例如“列奧納多達芬奇是誰?”。
logging.set_verbosity(logging.CRITICAL)prompt = "Who is Leonardo Da Vinci?"
pipe = pipeline(task="text-generation", model=model, tokenizer=tokenizer, max_length=200)
result = pipe(f"<s>[INST] {prompt} [/INST]")
print(result[0]['generated_text'])
輸出:
正如我們所見,得到了驚人的結果。
<s>[INST] Who is Leonardo Da Vinci? [/INST] Leonardo da Vinci (1452-1519) was an Italian polymath, artist, inventor, and engineer.Da Vinci is widely considered one of the greatest painters of all time, and his works include the famous Mona Lisa. He was also an accomplished engineer, inventor, and anatomist, and his designs for machines and flight were centuries ahead of his time.Da Vinci was born in the town of Vinci, Italy, and he was the illegitimate son of a local notary. Despite his humble origins, he was able to study art and engineering in Florence, and he became a renowned artist and inventor.Da Vinci's work had a profound impact on the Renaissance, and his legacy continues to inspire artists, engineers, and inventors to this day. He
再問一個問題
prompt = "What is Datacamp Career track?"
result = pipe(f"<s>[INST] {prompt} [/INST]")
print(result[0]['generated_text'])
輸出:
Guanaco 是一個高質量的數據集,過去曾用于微調最先進的 LLM。Hugging Face 上提供了完整的 Guanaco 數據集,它有潛力在各種自然語言任務上取得更優異的表現。
<s>[INST] What is Datacamp Career track? [/INST] DataCamp Career Track is a program that offers a comprehensive learning experience to help you build your skills and prepare for a career in data science.The program includes a range of courses, projects, and assessments that are designed to help you build your skills in data science. You will learn how to work with data, create visualizations, and build predictive models.In addition to the technical skills, you will also learn how to communicate your findings to stakeholders and how to work with a team to solve complex problems.The program is designed to be flexible, so you can learn at your own pace and on your own schedule. You will also have access to a community of learners and mentors who can provide support and guidance throughout the program.Overall, DataCamp Career Track is a great way to build your skills and prepare for a career in
這是Colab Notebook,其中包含代碼和輸出,可幫助您完成編碼之旅。
結論
本教程提供了全面的指南,指導您如何使用 QLoRA、PEFT 和 SFT 等技術對 LLaMA 2 模型進行微調,以克服內存和計算能力的限制。通過利用 Hugging Face 庫(例如transformers、accelerate、peft、trl和bitsandbytes),我們能夠在消費級 GPU 上成功微調 7B 參數的 LLaMA 2 模型。
總的來說,本教程舉例說明了最近的進展如何實現大型語言模型的民主化和可訪問性,甚至允許業余愛好者利用有限的資源構建最先進的人工智能。