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 della formazione
Gli strumenti di configurazione del training Hugging Face possono essere utilizzati per configurare un trainer. Le classi Trainer richiedono all'utente di fornire:
- Metriche
- Un modello di base
- Una configurazione della formazione
È 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 collatore di dati raggruppa 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, è ora possibile creare un 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 registrare su 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 addestrato.
Eseguire il wrapping del training in un'esecuzione MLflow. Viene creata una pipeline di Transformers utilizzando il tokenizer e il modello addestrato, e successivamente viene salvata sul 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 è lo stesso di quello di un modello pre-addestrato avvolto da 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, vedere Distribuire modelli con Mosaic AI Model Serving.
Risolvere problemi comuni di CUDA
Questa sezione descrive gli errori CUDA comuni e presenta indicazioni su come risolverli.
OutOfMemoryError: CUDA memoria esaurita
Quando si addestrano modelli grandi, un errore comune che potrebbe verificarsi è il "CUDA out of memory error".
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 un addestramento con precisione più bassa. È possibile impostare
fp16=True
in TrainingArguments.Usare gradient_accumulation_steps in TrainingArguments per aumentare efficacemente la dimensione complessiva del batch.
Usare ottimizzatore Adam 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 di modelli di classificazione del testo di Hugging Face per il fine-tuning
Risorse aggiuntive
Altre informazioni su Hugging Face in Azure Databricks.
- Che cosa sono gli Hugging Face Transformers?
- È possibile utilizzare i modelli Hugging Face Transformers su Spark per scalare le applicazioni batch di NLP, consulta Inferenza del modello con Hugging Face Transformers per NLP.