NLP 課程文件

使用Trainer API微調模型

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強文件體驗

開始使用

使用Trainer API微調模型

Ask a Question Open In Colab Open In Studio Lab

🤗 Transformers 提供了一個 Trainer 類,可以幫助您在您的資料集上微調它提供的任何預訓練模型。完成上一節中的所有資料預處理工作後,您只需執行幾個步驟即可定義 Trainer。最困難的部分可能是準備執行 Trainer.train() 的環境,因為它在 CPU 上執行速度會非常慢。如果您沒有設定 GPU,則可以在 Google Colab 上訪問免費的 GPU 或 TPU。

下面的程式碼示例假設您已經執行了上一節中的示例。這是一個簡短的摘要,回顧您需要的內容

from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding

raw_datasets = load_dataset("glue", "mrpc")
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)


def tokenize_function(example):
    return tokenizer(example["sentence1"], example["sentence2"], truncation=True)


tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

訓練

在定義 Trainer 之前,第一步是定義一個 TrainingArguments 類,其中將包含 Trainer 用於訓練和評估的所有超引數。您必須提供的唯一引數是訓練好的模型將儲存到的目錄,以及儲存過程中的檢查點。對於所有其他引數,您可以保留預設值,這對於基本微調應該可以很好地工作。

from transformers import TrainingArguments

training_args = TrainingArguments("test-trainer")

💡 如果您希望在訓練期間自動將模型上傳到 Hub,請在 TrainingArguments 中傳遞 push_to_hub=True。我們將在 第 4 章 中瞭解更多關於此內容。

第二步是定義我們的模型。與 上一章 一樣,我們將使用 AutoModelForSequenceClassification 類,有兩個標籤。

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

您會注意到,與 第 2 章 不同,在例項化此預訓練模型後,您會收到一個警告。這是因為 BERT 沒有在對句子對進行分類上進行預訓練,因此預訓練模型的頭已被丟棄,並且已添加了一個適合序列分類的新頭。警告表明一些權重未被使用(對應於已丟棄的預訓練頭的權重),而另一些權重則被隨機初始化(新頭的權重)。最後,它鼓勵您訓練模型,這正是我們現在要做的。

擁有模型後,我們可以透過將所有構造好的物件傳遞給它來定義 Trainer——modeltraining_args、訓練和驗證資料集、我們的 data_collator 和我們的 tokenizer

from transformers import Trainer

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
)

請注意,當您像這裡這樣傳遞 tokenizer 時,Trainer 使用的預設 data_collator 將是之前定義的 DataCollatorWithPadding,因此您可以在此呼叫中跳過 data_collator=data_collator 這行。在第 2 節中向您展示處理的這一部分仍然很重要!

要對我們的資料集微調模型,我們只需要呼叫 Trainertrain() 方法。

trainer.train()

這將開始微調(在 GPU 上應該需要幾分鐘)並在每 500 步報告訓練損失。但是,它不會告訴您模型的效能如何(或有多差)。這是因為

  1. 我們沒有告訴 Trainer 在訓練期間進行評估,方法是將 evaluation_strategy 設定為 "steps"(每 eval_steps 步評估一次)或 "epoch"(在每個 epoch 結束時評估)。
  2. 我們沒有為 Trainer 提供 compute_metrics() 函式來在上述評估期間計算指標(否則評估只會列印損失,這並不是一個非常直觀的數字)。

評估

讓我們看看如何構建一個有用的 compute_metrics() 函式並在下次訓練時使用它。該函式必須接收一個 EvalPrediction 物件(它是一個名為元組,具有 predictions 欄位和 label_ids 欄位),並將返回一個字典,將字串對映到浮點數(字串是返回的指標的名稱,浮點數是其值)。要從模型中獲取一些預測,我們可以使用 Trainer.predict() 命令。

predictions = trainer.predict(tokenized_datasets["validation"])
print(predictions.predictions.shape, predictions.label_ids.shape)
(408, 2) (408,)

predict() 方法的輸出是另一個名為元組,具有三個欄位:predictionslabel_idsmetricsmetrics 欄位將只包含傳遞給資料集的損失,以及一些時間指標(預測花費的時間,總時間和平均時間)。一旦我們完成了 compute_metrics() 函式並將其傳遞給 Trainer,該欄位還將包含 compute_metrics() 返回的指標。

如您所見,predictions 是一個二維陣列,形狀為 408 x 2(408 是我們使用的資料集中元素的數量)。這些是我們傳遞給 predict() 的資料集每個元素的 logits(正如您在 上一章 中看到的,所有 Transformer 模型都返回 logits)。要將它們轉換為可以與我們的標籤進行比較的預測,我們需要獲取第二軸上具有最大值的索引。

import numpy as np

preds = np.argmax(predictions.predictions, axis=-1)

現在我們可以將這些 preds 與標籤進行比較。要構建我們的 compute_metric() 函式,我們將依賴於 🤗 Evaluate 庫中的指標。我們可以像載入資料集一樣輕鬆地載入與 MRPC 資料集關聯的指標,這次使用 evaluate.load() 函式。返回的物件有一個 compute() 方法,我們可以用它來進行指標計算。

import evaluate

metric = evaluate.load("glue", "mrpc")
metric.compute(predictions=preds, references=predictions.label_ids)
{'accuracy': 0.8578431372549019, 'f1': 0.8996539792387542}

您獲得的確切結果可能會有所不同,因為模型頭的隨機初始化可能會改變它達到的指標。在這裡,我們可以看到我們的模型在驗證集上的準確率為 85.78%,F1 分數為 89.97。這是用於評估 GLUE 基準測試中 MRPC 資料集結果的兩個指標。 BERT 論文 中的表格報告了基本模型的 F1 分數為 88.9。那是 uncased 模型,而我們目前正在使用 cased 模型,這解釋了更好的結果。

將所有內容整合在一起,我們得到了我們的 compute_metrics() 函式。

def compute_metrics(eval_preds):
    metric = evaluate.load("glue", "mrpc")
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

為了看到它在每個 epoch 結束時報告指標的實際應用,以下是如何使用此 compute_metrics() 函式定義一個新的 Trainer

training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics,
)

請注意,我們建立了一個新的 TrainingArguments,其 evaluation_strategy 設定為 "epoch",並建立了一個新的模型——否則,我們將只是繼續訓練我們已經訓練過的模型。要啟動新的訓練執行,我們執行

trainer.train()

這次,除了訓練損失之外,它還會在每個 epoch 結束時報告驗證損失和指標。同樣,由於模型的隨機頭部初始化,您達到的準確率/F1 分數可能與我們發現的略有不同,但應該在同一個範圍內。

Trainer 將在多個 GPU 或 TPU 上開箱即用,並提供許多選項,例如混合精度訓練(在訓練引數中使用 fp16 = True)。我們將在第 10 章中介紹它支援的所有內容。

這結束了使用 Trainer API 進行微調的介紹。在第 7 章中將提供針對大多數常見 NLP 任務的示例,但現在讓我們看看如何在純 PyTorch 中執行相同的操作。

✏️ 動手試試! 使用你在第 2 節中完成的資料處理,在 GLUE SST-2 資料集上微調模型。

© . This site is unofficial and not affiliated with Hugging Face, Inc.