Condividi tramite


Ottimizzare i modelli Hugging Face per una singola GPU

Questo articolo descrive come ottimizzare un modello Hugging Face con la libreria Hugging Face transformers in una singola GPU. Include anche raccomandazioni specifiche di Databricks per il caricamento di dati dai modelli lakehouse e di registrazione a MLflow, che consente di usare e gestire i modelli in Azure Databricks.

La libreria Hugging Face transformers fornisce l'utilità Trainer e le classi modello automatico che consentono il caricamento e l'ottimizzazione dei modelli dei trasformatori.

Questi strumenti sono disponibili per le attività seguenti con modifiche semplici:

  • Caricamento di modelli per ottimizzare.
  • Costruzione della configurazione per l'utilità Hugging Face Transformers Trainer.
  • Esecuzione del training su una singola GPU.

Si veda Che cosa sono gli Hugging Face Transformers?

Requisiti

Tokenizzare un set di dati Hugging Face

I modelli Hugging Face Transformers prevedono un input tokenizzato, anziché il testo dei dati scaricati. Per garantire la compatibilità con il modello di base, utilizzare un autoTokenizer caricato dal modello di base. Hugging Face datasets consente di applicare direttamente il tokenizer in modo coerente ai dati di training e di test.

Ad esempio:

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)

Impostare la configurazione del training

Gli strumenti di configurazione del training Hugging Face possono essere utilizzati per configurare un trainer. Le classi Trainer richiedono all'utente di fornire:

  • Metrica
  • Un modello di base
  • Una configurazione del training

È possibile configurare le metriche di valutazione oltre alla metrica predefinita loss che calcola Trainer. L'esempio seguente mostra come aggiungere accuracy come metrica:

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)

Utilizzare le classi del modello automatico per NLP per caricare il modello appropriato per l'attività.

Per la classificazione del testo, usare AutoModelForSequenceClassification per caricare un modello di base per la classificazione del testo. Quando si crea il modello, specificare il numero di classi e i mapping delle etichette creati durante la preparazione del set di dati.

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

Creare quindi la configurazione di training. La classe TrainingArguments consente di specificare la directory di output, la strategia di valutazione, la frequenza di apprendimento e altri parametri.

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

L'uso di un agente di confronto dati inserisce l'input nei set di dati di training e valutazione. DataCollatorWithPadding offre buone prestazioni di base per la classificazione del testo.

from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer)

Con tutti questi parametri costruiti, a questo punto possibile creare un oggetto 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,
)

Eseguire il training e l'accesso a MLflow

Hugging Face si interfaccia bene con MLflow e registra automaticamente le metriche durante l'addestramento del modello utilizzando MLflowCallback. Tuttavia, è necessario registrare manualmente il modello sottoposto a training.

Eseguire il wrapping del training in un'esecuzione MLflow. In questo modo viene creata una pipeline trasformatori dal tokenizer e dal modello sottoposto a training e la scrive nel disco locale. Infine, registrare il modello in MLflow con mlflow.transformers.log_model.

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!",
    )

Se non è necessario creare una pipeline, è possibile inviare i componenti usati nel training in un dizionario:

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!"],
)

Caricare il modello per l'inferenza

Quando il modello viene registrato e pronto, il caricamento del modello per l'inferenza equivale al caricamento del modello sottoposto a wrapping preliminare di 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)

Per altre informazioni, si veda Gestione dei modelli con Azure Databricks.

Risolvere problemi comuni di CUDA

Questa sezione descrive gli errori CUDA comuni e presenta indicazioni su come risolverli.

OutOfMemoryError: memoria insufficiente CUDA

Quando si esegue il training di modelli di grandi dimensioni, è possibile che si verifichi un errore comune di CUDA in memoria insufficiente.

Esempio:

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.

Seguire le seguenti raccomandazioni per risolvere l'errore:

  • Ridurre le dimensioni del batch da usare per il training. È possibile ridurre il valore per_device_train_batch_size in TrainingArguments.

  • Usare il training con precisione inferiore. È possibile impostare fp16=True in TrainingArguments.

  • Usare gradient_accumulation_steps in TrainingArguments per aumentare efficacemente le dimensioni complessive del batch.

  • Usare Adam Optimizer a 8 bit.

  • Pulire la memoria GPU prima del training. In alcuni casi, la memoria GPU può essere occupata da codice inutilizzato.

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

Errori del kernel CUDA

Quando si esegue il training, è possibile che vengano visualizzati errori del kernel CUDA.

Esempio:

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.

Per risolvere il problema:

  • Provare a eseguire il codice sulla CPU per verificare se l'errore è riproducibile.

  • Un'altra opzione consiste nel ottenere un traceback migliore impostando CUDA_LAUNCH_BLOCKING=1:

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

Notebook: Ottimizzare la classificazione del testo in una singola GPU

Per iniziare rapidamente a usare il codice di esempio, questo notebook di esempio fornisce un esempio end-to-end per ottimizzare un modello per la classificazione del testo. Le sezioni successive di questo articolo illustrano in modo più dettagliato l'uso di Hugging Face per l'ottimizzazione in Azure Databricks.

Notebook dei modelli di classificazione del testo hugging viso per l'ottimizzazione

Ottenere il notebook

Risorse aggiuntive

Altre informazioni su Hugging Face in Azure Databricks.