微調大語言模型的七個步驟
譯文譯者 | 布加迪
審校 | 重樓
在最近一年半的時間里,自然語言處理(NLP)領域發生了顯著的變化,這主要得益于OpenAI的GPT系列等大語言模型(LLM)的興起。
這些功能強大的模型已徹底改變了我們處理自然語言任務的方法,在翻譯、情緒分析和文本自動生成等方面提供了前所未有的能力。它們理解和生成類似人類的文本的能力已帶來了曾經被認為無法實現的可能性。
然而,盡管這些模型具有出色的能力,但訓練它們的過程卻充滿了挑戰,比如需要投入大量的時間和資金。這時候,微調LLM就體現出了其重要性。
通過細化這些預訓練的模型以更好地適應特定的應用環境或領域,我們就可以顯著提高它們處理特定任務的性能。這一步不僅提高了它們的質量,還擴大了它們在一系列廣泛領域的用途。
本文旨在將這個過程分解為七個簡單步驟,以便使任何LLM針對特定任務進行微調。
理解預訓練的大語言模型
LLM是機器學習算法的一個特殊類別,旨在根據前一個單詞提供的上下文預測序列中的下一個單詞。這些模型建立在Transformers架構上,這是機器學習技術領域的一大突破,在谷歌的《你需要的就是注意力》文章中作了首次解釋。
GPT(生成式預訓練Transformer)之類的模型就是已經暴露于大量文本數據的預訓練語言模型。這種廣泛的訓練使它們得以掌握語言使用的基本規則,包括如何將單詞組合成連貫的句子。
這些模型的一個關鍵優勢在于,它們不僅能夠理解自然語言,還能夠根據提供的輸入生成酷似人類寫作的文本。
那么其最大的優點是什么呢?那就是這些模型已經通過API向大眾開放。
什么是微調,為什么很重要?
微調是指選擇一個預訓練的模型,并通過使用特定領域的數據集進一步訓練來改進它的過程。
大多數LLM模型有很好的自然語言技能和通用知識性能,但在處理特定的面向任務的問題時差強人意。微調過程提供了一種方法,可以提升模型處理特定問題的性能,同時降低計算費用,無需從頭開始構建模型。
簡而言之,模型經過微調后,針對特定任務擁有更好的性能,使其在實際應用中更有效、更通用。這個過程對于改進現有模型以處理特定的任務或領域至關重要。
微調LLM的逐步指南
不妨通過如下七個步驟微調一個實際模型來舉例說明這個概念。
第一步:明確具體目標
假設我們想要推斷任何文本的情緒,決定試用GPT-2來完成這樣的任務。
我敢肯定,我們很快就會發現它在這方面做得很差,這并不奇怪。然后,一個自然而然的問題浮現在腦海中:我們可以做些什么來改善其性能?
當然,答案是我們可以!
使用含有推文及相應情緒的數據集訓練來自Hugging Face Hub的預訓練GPT-2模型,充分利用微調的效果,以便提高性能。
所以,我們的最終目標是擁有一個善于從文本中推斷情緒的模型。
第二步:選擇預訓練的模型和數據集
第二步是選擇什么模型作為基本模型。在本文例子中,我們已經選擇了模型:GPT-2。所以我們要對它進行一些簡單的微調。
始終記住要選擇適合您任務的模型。
第三步:加載要使用的數據
我們已有了模型和主要任務,現在需要一些數據來處理。
不過別擔心,Hugging Face已經把一切都安排好了!
這時候,它的數據集庫有了用武之地。
在這個例子中,我們將充分利用Hugging Face數據集庫來導入一個數據集,其中的推文被標記為相應的情緒(積極的、中立的或消極的)。
from datasets import load_dataset
dataset = load_dataset("mteb/tweet_sentiment_extraction")
df = pd.DataFrame(dataset['train'])
數據看起來就像這樣:
第四步:分詞器(Tokenizer)
現在我們有了模型和數據集來對其進行微調。因此,接下來的合理步驟是加載分詞器。由于LLM使用token(而不是單詞!!),我們需要分詞器將數據發送到我們的模型。
通過利用map方法對整個數據集進行分詞處理,我們很容易做到這一點。
from transformers import GPT2Tokenizer
# Loading the dataset to train our model
dataset = load_dataset("mteb/tweet_sentiment_extraction")
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
tokenizer.pad_token = tokenizer.eos_token
def tokenize_function(examples):
return tokenizer(examples["text"], padding="max_length", truncatinotallow=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
為了提高我們的處理性能,生成兩個較小的子集:
- 訓練集:用來微調我們的模型。
- 測試集:用來評估模型。
Small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
Small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))
第五步:初始化基本模型
一旦我們有了要使用的數據集,就加載我們的模型,并指定預期標簽的數量。您可以從推文的情緒數據集知道有三種可能的標簽:
- 0或消極的
- 1或中性的
- 2或積極的
from transformers import GPT2ForSequenceClassification
model = GPT2ForSequenceClassification.from_pretrained("gpt2", num_labels=3)
第六步:評估方法
Transformers庫提供了一個名為“Trainer”的類,它可以優化我們模型的訓練和評估。因此,在實際訓練開始之前,我們需要定義一個函數來評估經過微調的模型。
import evaluate
metric = evaluate.load("accuracy")
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return metric.compute(predictinotallow=predictions, references=labels)
第七步:使用Trainer方法進行微調
最后一步是微調模型。為此,我們將一起設置訓練參數與評估策略,并執行Trainer對象。
要執行Trainer對象,我們只需使用train()命令。
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir="test_trainer",
#evaluation_strategy="epoch",
per_device_train_batch_size=1, # Reduce batch size here
per_device_eval_batch_size=1, # Optionally, reduce for evaluation as well
gradient_accumulation_steps=4
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=small_train_dataset,
eval_dataset=small_eval_dataset,
compute_metrics=compute_metrics,
)
trainer.train()
一旦我們的模型經過微調,我們使用測試集來評估其性能。trainer對象已經包含了經過優化的evaluate()方法。
import evaluate
trainer.evaluate()
這就是對任何LLM進行微調的基本過程。
另外請記住,微調LLM的過程對計算資源的要求很高,因此您的本地計算機可能沒有足夠的能力來進行微調。
主要結論
如今,針對特定任務對預訓練的大語言模型(比如GPT)進行微調對于改進LLM在特定領域的性能至關重要。它使我們得以利用LLM的自然語言能力,同時提高它們的效率和定制方面的潛力,使這個過程易于訪問且具有成本效益。
如果遵循這七個簡單的步驟:從選擇正確的模型和數據集到訓練和評估微調模型,我們可以在特定領域實現卓越的模型性能。
如果想要查看完整代碼,可以在我的大語言模型GitHub代碼庫中找到:https://github.com/rfeers/large-language-models/blob/main/7%20Steps%20to%20Fine-Tune%20LLMs.ipynb。
原文標題:7 Steps to Mastering Large Language Model Fine-tuning,作者:Josep Ferrer