分享方式:


微調單一 GPU 的 Hugging Face 模型

本文說明如何在單一 GPU 上使用 Hugging Face transformers 程式庫微調 Hugging Face 模型。 它也包含 Databricks 特定的建議,以從 Lakehouse 載入資料,並將模型記錄至 MLflow,這可讓您在 Azure Databricks 上使用及控管模型。

Hugging Face transformers 程式庫提供訓練器公用程式和自動模型類別,以啟用載入和微調轉換器模型。

這些工具只需簡單的修改,便可用於下列工作:

  • 載入要微調的模型。
  • 建構 Hugging Face Transformers 訓練器公用程式的組態。
  • 在單一 GPU 上執行訓練。

請參閱什麼是 Hugging Face Transformers?

需求

標記化 Hugging Face 資料集

Hugging Face Transformers 模型需要權杖化輸入,而不是所下載資料中的文字。 若要確保與基本模型相容,請使用從基本模型載入的 AutoTokenizer。 Hugging Face datasets 可讓您將權杖化工具一致地套用至訓練和測試資料。

例如:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained(base_model)
def tokenize_function(examples):
    return tokenizer(examples["text"], padding=False, truncation=True)

train_test_tokenized = train_test_dataset.map(tokenize_function, batched=True)

設定訓練組態

Hugging Face 訓練組態工具可用來設定訓練器。 訓練器類別需要使用者提供:

  • 計量
  • 基本模型
  • 訓練組態

除了 Trainer 計算的預設 loss 計量之外,您還可以設定評估計量。 以下範例示範如何新增 accuracy 作為計量:

import numpy as np
import evaluate
metric = evaluate.load("accuracy")
def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

使用 NLP 的自動模型類別,為您的工作載入適當的模型。

針對文字分類,使用 AutoModelForSequenceClassification 來載入文字分類基本模型。 建立模型時,提供在資料集準備期間建立的類別數目和標籤對應。

from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(
        base_model,
        num_labels=len(label2id),
        label2id=label2id,
        id2label=id2label
        )

接下來,建立訓練組態。 TrainingArguments 類別可讓您指定輸出目錄、評估策略、學習速率和其他參數。

from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(output_dir=training_output_dir, evaluation_strategy="epoch")

在訓練和評估資料集中使用資料定序器批次輸入。 DataCollatorWithPadding 可針對文字分類提供良好的基準效能。

from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer)

建構所有這些參數後,您現在可以建立一個 Trainer

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_test_dataset["train"],
    eval_dataset=train_test_dataset["test"],
    compute_metrics=compute_metrics,
    data_collator=data_collator,
)

訓練並記錄至 MLflow

Hugging Face 與 MLflow 介面良好,並在模型訓練期間使用 MLflowCallback 自動記錄計量。 不過,您必須自行記錄訓練的模型。

在 MLflow 執行中裝合訓練。 這會從權杖化工具和訓練的模型建構轉換器管線,並將它寫入本機磁碟。 最後,使用 mlflow.transformers.log_model 將模型記錄至 MLflow。

from transformers import pipeline

with mlflow.start_run() as run:
  trainer.train()
  trainer.save_model(model_output_dir)
  pipe = pipeline("text-classification", model=AutoModelForSequenceClassification.from_pretrained(model_output_dir), batch_size=1, tokenizer=tokenizer)
  model_info = mlflow.transformers.log_model(
        transformers_model=pipe,
        artifact_path="classification",
        input_example="Hi there!",
    )

如果您不需要建立管線,您可以將用於訓練的元件提交至字典中:

model_info = mlflow.transformers.log_model(
  transformers_model={"model": trainer.model, "tokenizer": tokenizer},
  task="text-classification",
  artifact_path="text_classifier",
  input_example=["MLflow is great!", "MLflow on Databricks is awesome!"],
)

載入模型以進行推斷

當您的模型已記錄並準備就緒時,載入模型進行推斷的程序與載入 MLflow 裝合的預先訓練的 MLflow 相同。

logged_model = "runs:/{run_id}/{model_artifact_path}".format(run_id=run.info.run_id, model_artifact_path=model_artifact_path)

# Load model as a Spark UDF. Override result_type if the model does not return double values.
loaded_model_udf = mlflow.pyfunc.spark_udf(spark, model_uri=logged_model, result_type='string')

test = test.select(test.text, test.label, loaded_model_udf(test.text).alias("prediction"))
display(test)

如需詳細資訊,請參閱使用 Azure Databricks 的模型服務

常見 CUDA 錯誤疑難排解

本節說明常見的 CUDA 錯誤,並指導如何解決這些錯誤。

OutOfMemoryError:CUDA 記憶體不足

訓練大型模型時,您可能會遇到的一個常見錯誤是 CUDA 記憶體不足錯誤。

範例:

OutOfMemoryError: CUDA out of memory. Tried to allocate 20.00 MiB (GPU 0; 14.76 GiB total capacity; 666.34 MiB already allocated; 17.75 MiB free; 720.00 MiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF.

若要解決此錯誤,請遵循下列建議:

  • 減小用於訓練的批次大小。 您可以減小 TrainingArguments 中的 per_device_train_batch_size 值。

  • 使用較低精確度的訓練。 您可以在 TrainingArguments 中設定 fp16=True

  • TrainingArguments 中使用 gradient_accumulation_steps,以有效增加整體批次大小。

  • 使用 8 位 Adam 最佳化工具

  • 在訓練之前清理 GPU 記憶體。 有時候,GPU 記憶體可能會被一些未使用的程式碼佔用。

    from numba import cuda
    device = cuda.get_current_device()
    device.reset()
    

CUDA 核心程序錯誤

執行訓練時,您可能會收到 CUDA 核心程序錯誤。

範例:

CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect.

For debugging, consider passing CUDA_LAUNCH_BLOCKING=1.

若要進行疑難排解:

  • 嘗試在 CPU 上執行程式碼,以查看錯誤是否可重現。

  • 另一個選項是藉由設定 CUDA_LAUNCH_BLOCKING=1 來取得更好的追蹤:

    import os
    os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
    

筆記本:微調單一 GPU 上的文字分類

為了快速開始使用範例程式碼,此範例筆記本會提供一個微調文字分類模型的端對端範例。 本文後續各節會深入探討在 Azure Databricks 上使用 Hugging Face 進行微調的更多詳細資訊。

微調 Hugging Face 文字分類模型筆記本

取得筆記本

其他資源

深入了解 Azure Databricks 上的 Hugging Face。