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
- Un cluster a nodo singolo con una GPU nel driver.
- Versione GPU di Databricks Runtime 13.0 ML e versioni successive.
- Questo esempio per l'ottimizzazione richiede i pacchetti Transformers 🤗, Datasets 🤗 e Evaluate 🤗 inclusi in Databricks Runtime 13.0 ML e versioni successive.
- MLflow 2.3.
- Dati preparati e caricati per ottimizzare un modello con trasformatori.
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
Risorse aggiuntive
Altre informazioni su Hugging Face in Azure Databricks.
- Che cosa sono gli Hugging Face Transformers?
- È possibile usare i modelli Hugging Face Transformers in Spark per aumentare il numero di istanze delle applicazioni batch NLP, vedere Inferenza del modello con Hugging Face Transformers per NLP.