Servizio clienti potenziato con l’apprendimento automatico
'Customer service enhanced with machine learning'
In questo post del blog, simuleremo un caso d’uso di servizio clienti del mondo reale e utilizzeremo gli strumenti di machine learning dell’ecosistema Hugging Face per affrontarlo.
Raccomandiamo vivamente di utilizzare questo notebook come modello/esempio per risolvere il vostro caso d’uso del mondo reale.
Definizione di Task, Dataset e Modello
Prima di passare alla parte di codifica effettiva, è importante avere una chiara definizione del caso d’uso che si desidera automatizzare o parzialmente automatizzare. Una chiara definizione del caso d’uso aiuta a identificare il task più adatto, il dataset da utilizzare e il modello da applicare per il vostro caso d’uso.
- Presentazione di Hugging Face per l’Educazione 🤗
- Iniziare con i Transformers su Habana Gaudi
- Direttore delle intuizioni di Apprendimento Automatico
Definizione del vostro task di NLP
Bene, immergiamoci in un problema ipotetico che desideriamo risolvere utilizzando modelli di elaborazione del linguaggio naturale. Supponiamo di vendere un prodotto e che il nostro team di supporto clienti riceva migliaia di messaggi inclusi feedback, reclami e domande che idealmente dovrebbero essere tutti risposti.
Subito diventa evidente che il supporto clienti non è in grado di rispondere a ogni messaggio. Pertanto, decidiamo di rispondere solo ai clienti più insoddisfatti e puntiamo a rispondere al 100% di quei messaggi, in quanto questi sono probabilmente i più urgenti rispetto agli altri messaggi neutrali e positivi.
Supponendo che a) i messaggi dei clienti molto insoddisfatti rappresentino solo una frazione di tutti i messaggi e b) che possiamo filtrare i messaggi insoddisfatti in modo automatizzato, il supporto clienti dovrebbe essere in grado di raggiungere questo obiettivo.
Per filtrare in modo automatizzato i messaggi insoddisfatti, pianifichiamo di applicare tecnologie di elaborazione del linguaggio naturale.
Il primo passo è mappare il nostro caso d’uso – filtrare i messaggi insoddisfatti – in un task di machine learning.
La pagina dei task nell’Hugging Face Hub è un ottimo punto di partenza per vedere quale task si adatta meglio a uno scenario specifico. Ogni task ha una descrizione dettagliata e potenziali casi d’uso.
Il task di trovare i messaggi dei clienti più insoddisfatti può essere modellato come un task di classificazione del testo: Classificare un messaggio in una delle seguenti 5 categorie: molto insoddisfatto, insoddisfatto, neutrale, soddisfatto, o molto soddisfatto.
Ricerca di dataset adatti
Dopo aver deciso il task, dovremmo trovare i dati su cui il modello sarà addestrato. Questo è generalmente più importante per le prestazioni del vostro caso d’uso rispetto alla scelta dell’architettura del modello giusta. Tenete presente che un modello è tanto buono quanto i dati su cui è stato addestrato. Pertanto, dovremmo fare molta attenzione nella cura e/o selezione del dataset.
Dato che consideriamo il caso d’uso ipotetico di filtrare i messaggi insoddisfatti, analizziamo quali dataset sono disponibili.
Per il vostro caso d’uso del mondo reale, è molto probabile che abbiate dati interni che rappresentano al meglio i dati effettivi che il vostro sistema di NLP deve gestire. Pertanto, dovreste utilizzare tali dati interni per addestrare il vostro sistema di NLP. Tuttavia, può essere utile includere anche dati disponibili pubblicamente per migliorare la generalizzabilità del vostro modello.
Diamo un’occhiata a tutti i dataset disponibili nell’Hugging Face Hub. Sul lato sinistro, è possibile filtrare i dataset in base alle categorie di task e alle attività più specifiche. Il nostro caso d’uso corrisponde a Classificazione del testo -> Analisi del sentiment, quindi selezioniamo questi filtri. Al momento della stesura di questo notebook, ci sono circa 80 dataset rimanenti. Due aspetti dovrebbero essere valutati nella scelta di un dataset:
- Qualità: il dataset è di alta qualità? In particolare: i dati corrispondono ai dati con cui ci si aspetta di confrontarsi nel caso d’uso? I dati sono diversi, imparziali, …?
- Dimensione: quanto è grande il dataset? In genere, si può affermare in modo sicuro che più grande è il dataset, meglio è.
È piuttosto complicato valutare in modo efficiente se un dataset è di alta qualità, ed è ancora più difficile sapere se e in che modo il dataset è soggetto a un certo tipo di distorsione. Un’euristica efficiente e ragionevole per valutare la qualità è guardare le statistiche di download. Più download, più utilizzo, maggiori probabilità che il dataset sia di alta qualità. La dimensione è facile da valutare in quanto di solito può essere letta rapidamente. Diamo un’occhiata ai dataset più scaricati:
- Glue
- Amazon polarity
- Tweet eval
- Yelp review full
- Amazon reviews multi
Adesso possiamo esaminare questi dataset in maggior dettaglio leggendo la scheda del dataset, che idealmente dovrebbe fornire tutte le informazioni rilevanti e importanti. Inoltre, il visualizzatore del dataset è uno strumento incredibilmente potente per verificare se i dati si adattano al tuo caso d’uso.
Passiamo velocemente alle schede dei dataset dei modelli sopra elencati:
- GLUE è una collezione di piccoli dataset che servono principalmente a confrontare nuove architetture di modelli per i ricercatori. I dataset sono troppo piccoli e non corrispondono abbastanza al nostro caso d’uso.
- Amazon polarity è un dataset enorme e adatto per il feedback dei clienti in quanto i dati riguardano le recensioni dei clienti. Tuttavia, ha solo etichette binarie (positive/negative), mentre noi cerchiamo una classificazione dei sentimenti più dettagliata.
- Tweet eval utilizza diversi emoji come etichette che non possono essere facilmente mappati in una scala che va da insoddisfatto a soddisfatto.
- Amazon reviews multi sembra essere il dataset più adatto qui. Abbiamo etichette dei sentimenti che vanno da 1 a 5 corrispondenti a 1-5 stelle su Amazon. Queste etichette possono essere mappate come molto insoddisfatto, neutrale, soddisfatto, molto soddisfatto. Abbiamo esaminato alcuni esempi nel visualizzatore del dataset per verificare che le recensioni assomiglino molto alle recensioni effettive dei feedback dei clienti, quindi sembra essere un dataset molto buono. Inoltre, ogni recensione ha un’etichetta
product_category
, quindi potremmo anche limitarci a utilizzare solo le recensioni di una categoria di prodotto corrispondente a quella in cui stiamo lavorando. Il dataset è multilingue, ma per ora siamo interessati solo alla versione inglese. - Yelp review full sembra essere un dataset molto adatto. È grande e contiene recensioni di prodotti e etichette di sentimenti da 1 a 5. Purtroppo, il visualizzatore del dataset non funziona qui e la scheda del dataset è anche relativamente scarsa, richiedendo più tempo per esaminare il dataset. A questo punto, dovremmo leggere l’articolo, ma dato il vincolo di tempo di questo post sul blog, sceglieremo di optare per Amazon reviews multi. In conclusione, concentriamoci sul dataset di Amazon reviews multi considerando tutti gli esempi di addestramento.
Come nota finale, consigliamo di utilizzare la funzionalità del dataset di Hub anche quando si lavora con dataset privati. L’Hugging Face Hub, Transformers e Datasets sono perfettamente integrati, il che rende facile utilizzarli in combinazione durante l’addestramento dei modelli.
Inoltre, l’Hugging Face Hub offre:
- Un visualizzatore del dataset per ogni dataset
- Facile dimostrazione di ogni modello utilizzando widget
- Modelli privati e pubblici
- Controllo della versione Git per i repository
- Migliori meccanismi di sicurezza
Trovare un modello adatto
Dopo aver deciso il compito e il dataset che descrive meglio il nostro caso d’uso, possiamo ora cercare un modello da utilizzare.
Probabilmente dovrai ottimizzare un modello preaddestrato per il tuo caso d’uso, ma vale la pena verificare se l’hub ha già modelli preaddestrati adatti. In tal caso, potresti ottenere una migliore performance continuando semplicemente ad ottimizzare ulteriormente un modello del genere sul tuo dataset.
Diamo un’occhiata a tutti i modelli che sono stati ottimizzati su Amazon Reviews Multi. Puoi trovare l’elenco dei modelli nell’angolo in basso a destra – cliccando su Esplora i modelli addestrati su questo dataset puoi vedere un elenco di tutti i modelli ottimizzati sul dataset che sono pubblicamente disponibili. Nota che siamo interessati solo alla versione inglese del dataset perché i feedback dei nostri clienti saranno solo in inglese. La maggior parte dei modelli più scaricati sono addestrati sulla versione multilingue del dataset e quelli che non sembrano essere multilingue hanno poche informazioni o prestazioni scarse. A questo punto, potrebbe essere più sensato ottimizzare un modello puramente preaddestrato invece di utilizzare uno dei modelli già ottimizzati mostrati nel link sopra.
Bene, il prossimo passo adesso è trovare un modello preaddestrato adatto da utilizzare per l’ottimizzazione. Questo è effettivamente più difficile di quanto sembri data la grande quantità di modelli preaddestrati e ottimizzati che ci sono nell’Hugging Face Hub. Di solito la migliore opzione è semplicemente provare una varietà di modelli diversi per vedere quale offre le migliori prestazioni. Non abbiamo ancora trovato il modo perfetto per confrontare tra loro diversi checkpoint dei modelli su Hugging Face, ma forniamo alcune risorse che vale la pena esaminare:
- Il riepilogo del modello fornisce una breve panoramica delle diverse architetture dei modelli.
- Una ricerca specifica per compito sull’Hugging Face Hub, ad esempio una ricerca su modelli di classificazione del testo, mostra i checkpoint più scaricati, che è anche un’indicazione di quanto bene si comportano quei checkpoint.
Tuttavia, entrambe le risorse sopra menzionate attualmente non sono ottimali. Il riepilogo del modello non viene sempre mantenuto aggiornato dagli autori. La velocità con cui vengono rilasciate nuove architetture di modelli e le vecchie architetture diventano obsolete rende estremamente difficile avere un riepilogo aggiornato di tutte le architetture dei modelli. Allo stesso modo, non significa necessariamente che il checkpoint del modello più scaricato sia il migliore. Ad esempio, bert-base-cased
è tra i checkpoint del modello più scaricati ma non è più il checkpoint con le migliori prestazioni.
Il miglior approccio è provare diverse architetture di modelli, rimanere aggiornati sulle nuove architetture di modelli seguendo gli esperti del settore e controllare le classifiche ben note.
Per la classificazione del testo, i benchmark importanti da considerare sono GLUE e SuperGLUE. Entrambi i benchmark valutano i modelli preaddestrati su una varietà di compiti di classificazione del testo, come la correttezza grammaticale, l’inferenza del linguaggio naturale, la risposta alle domande di tipo Sì/No, ecc…, che sono abbastanza simili al nostro compito di analisi del sentiment. Pertanto, è ragionevole scegliere uno dei modelli leader di questi benchmark per il nostro compito.
Al momento della stesura di questo post del blog, i modelli più performanti sono modelli molto grandi che contengono più di 10 miliardi di parametri, la maggior parte dei quali non sono open source, ad esempio ST-MoE-32B, Turing NLR v5 o ERNIE 3.0. Uno dei modelli più classificati che è facilmente accessibile è DeBERTa. Pertanto, proviamo la nuova versione di base di DeBERTa, cioè microsoft/deberta-v3-base
.
Allenamento / Fine-tuning di un modello con 🤗 Transformers e 🤗 Datasets
In questa sezione, passeremo ai dettagli tecnici su come eseguire il fine-tuning di un modello end-to-end per filtrare automaticamente i messaggi di feedback dei clienti molto insoddisfatti.
Perfetto! Iniziamo installando tutti i pacchetti necessari con pip e configurando il nostro ambiente di codice, quindi vediamo come preelaborare il dataset e infine iniziamo ad addestrare il modello.
Il notebook seguente può essere eseguito online in un google colab pro con l’ambiente di runtime GPU abilitato.
Installare tutti i pacchetti necessari
Per iniziare, installiamo git-lfs
in modo da poter caricare automaticamente i nostri checkpoint addestrati nell’Hub durante l’addestramento.
apt install git-lfs
Inoltre, installiamo le librerie 🤗 Transformers e 🤗 Datasets per eseguire questo notebook. Poiché utilizzeremo DeBERTa in questo post del blog, è necessario installare anche la libreria sentencepiece
per il suo tokenizer.
pip install datasets transformers[sentencepiece]
Successivamente, effettuiamo il login nel nostro account Hugging Face in modo che i modelli vengano caricati correttamente con il tuo nome tag.
from huggingface_hub import notebook_login
notebook_login()
Output:
Login riuscito
Il token è stato salvato in /root/.huggingface/token
Autenticato tramite git-credential store, ma questo non è l'helper definito sulla tua macchina.
Potresti dover effettuare nuovamente l'autenticazione durante il push verso l'Hugging Face Hub. Esegui il comando seguente nel terminale nel caso in cui desideri impostare questo helper delle credenziali come predefinito
git config --global credential.helper store
Preelaborare il dataset
Prima di poter iniziare l’addestramento del modello, è necessario portare il dataset in un formato comprensibile dal modello.
Fortunatamente, la libreria 🤗 Datasets rende questo estremamente facile, come vedrete nelle celle seguenti.
La funzione load_dataset
carica il dataset, lo organizza in modo chiaro in attributi predefiniti, come review_body
e stars
, e infine salva i dati appena organizzati utilizzando il formato arrow su disco. Il formato arrow consente la lettura e la scrittura dei dati veloci ed efficienti in termini di memoria.
Carichiamo e prepariamo la versione in inglese del dataset amazon_reviews_multi
.
from datasets import load_dataset
amazon_review = load_dataset("amazon_reviews_multi", "en")
Output:
Scaricamento e preparazione del dataset amazon_reviews_multi/en (download: 82.11 MiB, generati: 58.69 MiB, post-processati: dimensione sconosciuta, totale: 140.79 MiB) in corso verso /root/.cache/huggingface/datasets/amazon_reviews_multi/en/1.0.0/724e94f4b0c6c405ce7e476a6c5ef4f87db30799ad49f765094cf9770e0f7609...
Dataset amazon_reviews_multi scaricato e preparato in /root/.cache/huggingface/datasets/amazon_reviews_multi/en/1.0.0/724e94f4b0c6c405ce7e476a6c5ef4f87db30799ad49f765094cf9770e0f7609. Chiamate successive utilizzeranno questi dati.
Grande, è stato veloce 🔥. Diamo un’occhiata alla struttura del dataset.
print(amazon_review)
Output:
{.output .execute_result execution_count="5"}
DatasetDict({
train: Dataset({
features: ['review_id', 'product_id', 'reviewer_id', 'stars', 'review_body', 'review_title', 'language', 'product_category'],
num_rows: 200000
})
validation: Dataset({
features: ['review_id', 'product_id', 'reviewer_id', 'stars', 'review_body', 'review_title', 'language', 'product_category'],
num_rows: 5000
})
test: Dataset({
features: ['review_id', 'product_id', 'reviewer_id', 'stars', 'review_body', 'review_title', 'language', 'product_category'],
num_rows: 5000
})
})
Abbiamo 200.000 esempi di addestramento, così come 5000 esempi di convalida e test. Questo sembra ragionevole per l’addestramento! Siamo interessati principalmente alla colonna di input "review_body"
e alla colonna target "starts"
.
Diamo un’occhiata a un esempio casuale.
random_id = 34
print("Stars:", amazon_review["train"][random_id]["stars"])
print("Review:", amazon_review["train"][random_id]["review_body"])
Output:
Stars: 1
Review: Questo prodotto ha causato una grave bruciatura della mia pelle. Ho usato altre marche senza problemi
Il dataset è in un formato leggibile dall’uomo, ma ora dobbiamo trasformarlo in un formato “leggibile dalla macchina”. Definiamo il repository del modello che include tutti gli strumenti necessari per la preelaborazione e l’ottimizzazione del checkpoint che abbiamo scelto.
model_repository = "microsoft/deberta-v3-base"
Successivamente, carichiamo il tokenizer del repository del modello, che è un Tokenizer di DeBERTa.
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model_repository)
Come accennato in precedenza, useremo "review_body"
come input del modello e "stars"
come target del modello. Successivamente, utilizziamo il tokenizer per trasformare l’input in una sequenza di ID di token che possono essere compresi dal modello. Il tokenizer fa esattamente questo e può anche aiutarti a limitare i tuoi dati di input a una determinata lunghezza per evitare problemi di memoria. Qui, limitiamo la lunghezza massima a 128 token che nel caso di DeBERTa corrisponde a circa 100 parole che a loro volta corrispondono a ca. 5-7 frasi. Guardando di nuovo il visualizzatore del dataset, possiamo vedere che questo copre praticamente tutti gli esempi di addestramento. Importante: questo non significa che il nostro modello non possa gestire sequenze di input più lunghe, significa solo che utilizziamo una lunghezza massima di 128 per l’addestramento poiché copre il 99% del nostro addestramento e non vogliamo sprecare memoria. I modelli di trasformatori hanno dimostrato di essere molto bravi a generalizzare a sequenze più lunghe dopo l’addestramento.
Se vuoi saperne di più sulla tokenizzazione in generale, dai un’occhiata alla documentazione dei Tokenizers.
Le etichette sono facili da trasformare poiché corrispondono già a numeri nella loro forma grezza, cioè nell’intervallo da 1 a 5. Qui spostiamo semplicemente le etichette nell’intervallo da 0 a 4 poiché gli indici di solito iniziano da 0.
Grande, riversiamo i nostri pensieri in un po’ di codice. Definiremo una preprocess_function
che applicheremo ad ogni campione di dati.
def preprocess_function(example):
output_dict = tokenizer(example["review_body"], max_length=128, truncation=True)
output_dict["labels"] = [e - 1 for e in example["stars"]]
return output_dict
Per applicare questa funzione a tutti i campioni di dati nel nostro dataset, utilizziamo il metodo map
dell’oggetto amazon_review
che abbiamo creato in precedenza. Questo applicherà la funzione su tutti gli elementi di tutte le divisioni in amazon_review
, quindi i nostri dati di addestramento, convalida e test saranno preelaborati in un singolo comando. Eseguiamo la funzione di mappatura in modalità batched=True
per velocizzare il processo e rimuovere anche tutte le colonne poiché non ne abbiamo più bisogno per l’addestramento.
tokenized_datasets = amazon_review.map(preprocess_function, batched=True, remove_columns=amazon_review["train"].column_names)
Diamo un’occhiata alla nuova struttura.
tokenized_datasets
Output:
DatasetDict({
train: Dataset({
features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
num_rows: 200000
})
validation: Dataset({
features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
num_rows: 5000
})
test: Dataset({
features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
num_rows: 5000
})
})
Possiamo vedere che il livello esterno della struttura è rimasto lo stesso, ma i nomi delle colonne sono cambiati. Diamo un’occhiata allo stesso esempio casuale che abbiamo guardato in precedenza, ma stavolta è stato preelaborato.
print("Input IDS:", tokenized_datasets["train"][random_id]["input_ids"])
print("Labels:", tokenized_datasets["train"][random_id]["labels"])
Output:
Input IDS: [1, 329, 714, 2044, 3567, 5127, 265, 312, 1158, 260, 273, 286, 427, 340, 3006, 275, 363, 947, 2]
Labels: 0
Ottimo, il testo di input è trasformato in una sequenza di interi che possono essere convertiti in word embeddings dal modello, e l’indice dell’etichetta è semplicemente spostato di -1.
Affinare il modello
Dopo aver preelaborato il dataset, possiamo procedere con l’affinamento del modello. Utilizzeremo il popolare Hugging Face Trainer, che ci consente di iniziare l’addestramento con poche righe di codice. Il Trainer
può essere utilizzato per quasi tutte le attività in PyTorch ed è estremamente comodo perché si occupa di molte parti di codice di base necessarie per l’addestramento.
Iniziamo caricando il checkpoint del modello utilizzando il comodo AutoModelForSequenceClassification
. Poiché il checkpoint del repository del modello è solo un checkpoint preaddestrato, dovremmo definire la dimensione della testa di classificazione specificando num_labels=5
(poiché abbiamo 5 classi di sentimenti).
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(model_repository, num_labels=5)
Alcuni pesi del checkpoint del modello microsoft/deberta-v3-base non sono stati utilizzati durante l'inizializzazione di DebertaV2ForSequenceClassification: ['mask_predictions.classifier.bias', 'mask_predictions.LayerNorm.bias', 'mask_predictions.dense.weight', 'mask_predictions.dense.bias', 'mask_predictions.LayerNorm.weight', 'lm_predictions.lm_head.dense.bias', 'lm_predictions.lm_head.bias', 'lm_predictions.lm_head.LayerNorm.weight', 'lm_predictions.lm_head.dense.weight', 'lm_predictions.lm_head.LayerNorm.bias', 'mask_predictions.classifier.weight']
- Questo È previsto se stai inizializzando DebertaV2ForSequenceClassification dal checkpoint di un modello addestrato su un'altra attività o con un'altra architettura (ad es. inizializzando un modello BertForSequenceClassification da un modello BertForPreTraining).
- Questo NON È previsto se stai inizializzando DebertaV2ForSequenceClassification dal checkpoint di un modello che ti aspetti essere esattamente identico (inizializzando un modello BertForSequenceClassification da un modello BertForSequenceClassification).
Alcuni pesi di DebertaV2ForSequenceClassification non sono stati inizializzati dal checkpoint del modello microsoft/deberta-v3-base e sono stati appena inizializzati: ['pooler.dense.bias', 'classifier.weight', 'classifier.bias', 'pooler.dense.weight']
Probabilmente dovresti ADDESTRARE questo modello su un compito secondario per poterlo utilizzare per le previsioni e l'inferenza.
Successivamente, carichiamo un data collator. Un data collator si occupa di assicurarsi che ogni batch venga correttamente riempito durante l’addestramento, il che dovrebbe avvenire in modo dinamico poiché i campioni di addestramento vengono riordinati prima di ogni epoca.
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
Durante l’addestramento, è importante monitorare le prestazioni del modello su un set di validazione separato. Per farlo, dovremmo passare una funzione compute_metrics
al Trainer
che viene quindi chiamata ad ogni passo di validazione durante l’addestramento.
La metrica più semplice per il compito di classificazione del testo è l’accuratezza, che indica semplicemente la percentuale di campioni di addestramento classificati correttamente. L’utilizzo della metrica di accuratezza potrebbe essere problematico se i dati di convalida o di test sono molto sbilanciati. Verifichiamo rapidamente che questo non sia il caso contando le occorrenze di ciascuna etichetta.
from collections import Counter
print("Validazione:", Counter(tokenized_datasets["validation"]["labels"]))
print("Test:", Counter(tokenized_datasets["test"]["labels"]))
Output:
Validazione: Counter({0: 1000, 1: 1000, 2: 1000, 3: 1000, 4: 1000})
Test: Counter({0: 1000, 1: 1000, 2: 1000, 3: 1000, 4: 1000})
I set di dati di convalida e di test sono bilanciati al massimo, quindi possiamo tranquillamente utilizzare l’accuratezza qui!
Carichiamo la metrica di accuratezza tramite la libreria datasets.
from datasets import load_metric
accuracy = load_metric("accuracy")
Successivamente, definiamo la funzione compute_metrics
che verrà applicata alle previsioni del modello, che è di tipo EvalPrediction
e quindi espone le previsioni del modello e le etichette corrette. Calcoliamo la classe di etichetta prevista prendendo l’argomento massimo delle previsioni del modello prima di passarlo insieme alle etichette corrette alla metrica di accuratezza.
import numpy as np
def compute_metrics(pred):
pred_logits = pred.predictions
pred_classes = np.argmax(pred_logits, axis=-1)
labels = np.asarray(pred.label_ids)
acc = accuracy.compute(predictions=pred_classes, references=labels)
return {"accuratezza": acc["accuracy"]}
Ottimo, ora tutti i componenti necessari per l’addestramento sono pronti e non resta che definire gli iperparametri del Trainer
. Dobbiamo assicurarci che i checkpoint del modello vengano caricati su Hugging Face Hub durante l’addestramento. Impostando push_to_hub=True
, questo viene fatto automaticamente ad ogni save_steps
tramite il comodo metodo push_to_hub
.
Inoltre, definiamo alcuni iperparametri standard come il tasso di apprendimento, i passaggi di riscaldamento e gli epoch di addestramento. Verrà registrata la perdita ogni 500 passaggi e verrà eseguita la valutazione ogni 5000 passaggi.
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="deberta_amazon_reviews_v1",
num_train_epochs=2,
learning_rate=2e-5,
warmup_steps=200,
logging_steps=500,
save_steps=5000,
eval_steps=5000,
push_to_hub=True,
evaluation_strategy="steps",
)
Mettendo tutto insieme, possiamo finalmente istanziare il Trainer passando tutti i componenti richiesti. Useremo la suddivisione "validation"
come dataset separato durante l’addestramento.
from transformers import Trainer
trainer = Trainer(
args=training_args,
compute_metrics=compute_metrics,
model=model,
tokenizer=tokenizer,
data_collator=data_collator,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"]
)
Il trainer è pronto per partire 🚀 Puoi iniziare l’addestramento chiamando trainer.train()
.
train_metrics = trainer.train().metrics
trainer.save_metrics("train", train_metrics)
Output:
***** Avvio addestramento *****
Num esempi = 200000
Num epoch = 2
Dimensione batch istantanea per dispositivo = 8
Dimensione batch totale di addestramento (con parallelo, distribuito e accumulazione) = 8
Passaggi di accumulazione del gradiente = 1
Passaggi di ottimizzazione totali = 50000
Output:
Output:
***** Valutazione in corso *****
Num esempi = 5000
Dimensione batch = 8
Salvataggio del checkpoint del modello in deberta_amazon_reviews_v1/checkpoint-50000
Configurazione salvata in deberta_amazon_reviews_v1/checkpoint-50000/config.json
Pesi del modello salvati in deberta_amazon_reviews_v1/checkpoint-50000/pytorch_model.bin
File di configurazione del tokenizzatore salvati in deberta_amazon_reviews_v1/checkpoint-50000/tokenizer_config.json
File di token speciali salvati in deberta_amazon_reviews_v1/checkpoint-50000/special_tokens_map.json
File di token aggiuntivi salvati in deberta_amazon_reviews_v1/checkpoint-50000/added_tokens.json
Addestramento completato. Non dimenticare di condividere il tuo modello su huggingface.co/models =)
Bene, vediamo che il modello sembra imparare qualcosa! La perdita durante l’addestramento e la perdita durante la convalida diminuiscono e l’accuratezza alla fine risulta essere molto superiore alla possibilità casuale (20%). Interessante, vediamo un’accuratezza di circa 58,6% dopo soli 5000 passaggi, che non migliora molto successivamente. Scegliere un modello più grande o addestrare per un periodo più lungo avrebbe probabilmente dato risultati migliori qui, ma è sufficiente per il nostro caso d’uso ipotetico!
Ora, finalmente, carichiamo il checkpoint del modello nell’Hub.
trainer.push_to_hub()
Output:
Salvataggio del checkpoint del modello in deberta_amazon_reviews_v1
Configurazione salvata in deberta_amazon_reviews_v1/config.json
Pesi del modello salvati in deberta_amazon_reviews_v1/pytorch_model.bin
File di configurazione del tokenizer salvato in deberta_amazon_reviews_v1/tokenizer_config.json
File di mapping dei token speciali salvato in deberta_amazon_reviews_v1/special_tokens_map.json
File dei token aggiunti salvato in deberta_amazon_reviews_v1/added_tokens.json
Verranno inviati in upstream più commit (2).
Le barre di avanzamento potrebbero non essere affidabili.
Valutare / Analizzare il modello
Ora che abbiamo ottimizzato il modello, dobbiamo fare molta attenzione nell’analizzarne le prestazioni. Nota che le metriche canoniche, come l’accuratezza, sono utili per avere un’idea generale sulle prestazioni del modello, ma potrebbero non essere sufficienti per valutare quanto bene il modello si comporta nel caso d’uso effettivo. L’approccio migliore è trovare una metrica che descriva al meglio il caso d’uso effettivo del modello e misurare esattamente questa metrica durante e dopo l’addestramento.
Andiamo a valutare il modello 🤿.
Dopo l’addestramento, il modello è stato caricato nell’Hub con il nome deberta_v3_amazon_reviews
, quindi come primo passo, scarichiamolo di nuovo da lì.
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("patrickvonplaten/deberta_v3_amazon_reviews")
Il Trainer non è solo una classe eccellente per addestrare un modello, ma anche per valutare un modello su un dataset. Creiamo un’istanza del trainer con le stesse istanze e funzioni di prima, ma questa volta non c’è bisogno di passare un dataset di addestramento.
trainer = Trainer(
args=training_args,
compute_metrics=compute_metrics,
model=model,
tokenizer=tokenizer,
data_collator=data_collator,
)
Usiamo la funzione predict
del Trainer per valutare il modello sul dataset di test utilizzando la stessa metrica.
prediction_metrics = trainer.predict(tokenized_datasets["test"]).metrics
prediction_metrics
Output:
***** Esecuzione della previsione *****
Numero di esempi = 5000
Dimensione batch = 8
Output:
{'test_accuracy': 0.608,
'test_loss': 0.9637690186500549,
'test_runtime': 21.9574,
'test_samples_per_second': 227.714,
'test_steps_per_second': 28.464}
I risultati sono molto simili alle prestazioni sul dataset di convalida, il che di solito è un buon segno poiché indica che il modello non ha sovraadattato il dataset di test.
Tuttavia, un’accuratezza del 60% è lontana dall’essere perfetta per un problema di classificazione a 5 classi, ma abbiamo bisogno di un’accuratezza molto alta per tutte le classi?
Dato che siamo principalmente interessati ai feedback dei clienti molto negativi, concentriamoci su quanto bene il modello si comporta nella classificazione delle recensioni dei clienti più insoddisfatti. Decidiamo anche di aiutare un po’ il modello: tutti i feedback classificati come molto insoddisfatti o insoddisfatti saranno gestiti da noi, in modo da catturare quasi il 99% dei messaggi molto insoddisfatti. Allo stesso tempo, misuriamo anche quanti messaggi insoddisfatti possiamo gestire in questo modo e quanto lavoro inutile facciamo rispondendo a messaggi di clienti neutrali, soddisfatti e molto soddisfatti.
Perfetto, creiamo una nuova funzione compute_metrics
.
import numpy as np
def compute_metrics(pred):
pred_logits = pred.predictions
pred_classes = np.argmax(pred_logits, axis=-1)
labels = np.asarray(pred.label_ids)
# Cominciamo calcolando la percentuale di messaggi molto insoddisfatti che possiamo catturare
very_unsatisfied_label_idx = (labels == 0)
very_unsatisfied_pred = pred_classes[very_unsatisfied_label_idx]
# Ora sia le etichette 0 che 1 sono etichette 0 e il resto è > 0
very_unsatisfied_pred = very_unsatisfied_pred * (very_unsatisfied_pred - 1)
# Contiamo quante etichette sono 0 -> questa è l'accuratezza di "molto insoddisfatto"
true_positives = sum(very_unsatisfied_pred == 0) / len(very_unsatisfied_pred)
# In secondo luogo, calcoliamo quanti messaggi soddisfatti rispondiamo inutilmente
satisfied_label_idx = (labels > 1)
satisfied_pred = pred_classes[satisfied_label_idx]
# Quante previsioni sono classificate come insoddisfatte tra tutti i messaggi soddisfatti?
false_positives = sum(satisfied_pred <= 1) / len(satisfied_pred)
return {"%_risposte_insoddisfatte": round(true_positives, 2), "%_soddisfatti_etichettati_incorrettamente": round(false_positives, 2)}
Ripetiamo l’istanza del Trainer
per eseguire facilmente la valutazione.
trainer = Trainer(
args=training_args,
compute_metrics=compute_metrics,
model=model,
tokenizer=tokenizer,
data_collator=data_collator,
)
Eseguiamo di nuovo la valutazione con il nostro nuovo calcolo delle metriche, che è più adatto al nostro caso d’uso.
prediction_metrics = trainer.predict(tokenized_datasets["test"]).metrics
prediction_metrics
Output:
***** Esecuzione Predizione *****
Numero di esempi = 5000
Dimensione batch = 8
Output:
{'test_%_etichette_soddisfatte_incorrettamente': 0.11733333333333333,
'test_%_risposte_non_soddisfatte': 0.949,
'test_perdita': 0.9637690186500549,
'test_tempo_di_esecuzione': 22.8964,
'test_esempi_al_secondo': 218.375,
'test_passi_al_secondo': 27.297}
Fantastico! Questo già fornisce un’immagine piuttosto interessante. Riusciamo a individuare automaticamente circa il 95% dei clienti molto insoddisfatti a costo di sprecare i nostri sforzi sul 10% dei messaggi soddisfatti.
Facciamo qualche calcolo veloce. Riceviamo quotidianamente circa 10.000 messaggi, di cui ci aspettiamo che circa 500 siano molto negativi. Invece di dover rispondere a tutti i 10.000 messaggi, utilizzando questo filtraggio automatico, dovremmo solo esaminare 500 + 0,12 * 10.000 = 1700 messaggi e rispondere solo a 475 messaggi, perdendo erroneamente il 5% dei messaggi. Molto bello – una riduzione dell’83% dello sforzo umano perdendo solo il 5% dei clienti molto insoddisfatti!
Ovviamente, i numeri non rappresentano il valore ottenuto di un caso d’uso effettivo, ma potremmo avvicinarci ad esso con un numero sufficiente di dati di addestramento di alta qualità del tuo esempio reale!
Salviamo i risultati
trainer.save_metrics("prediction", prediction_metrics)
e carichiamo nuovamente tutto su Hub.
trainer.push_to_hub()
Output:
Salvando il checkpoint del modello in deberta_amazon_reviews_v1
Configurazione salvata in deberta_amazon_reviews_v1/config.json
Pesi del modello salvati in deberta_amazon_reviews_v1/pytorch_model.bin
File di configurazione del tokenizer salvato in deberta_amazon_reviews_v1/tokenizer_config.json
File di token speciali salvato in deberta_amazon_reviews_v1/special_tokens_map.json
File di token aggiuntivi salvato in deberta_amazon_reviews_v1/added_tokens.json
Verso https://huggingface.co/patrickvonplaten/deberta_amazon_reviews_v1
599b891..ad77e6d main -> main
Eliminazione dei seguenti risultati poiché non hanno tutti i campi necessari:
{'task': {'name': 'Classificazione del testo', 'type': 'text-classification'}}
Verso https://huggingface.co/patrickvonplaten/deberta_amazon_reviews_v1
ad77e6d..13e5ddd main -> main
I dati sono ora salvati qui .
Questo è tutto per oggi 😎. Come passo finale, avrebbe senso provare il modello su dati reali del mondo reale. Questo può essere fatto direttamente sul widget di inferenza sulla scheda del modello:
Sembra generalizzarsi molto bene ai dati del mondo reale 🔥
Ottimizzazione
Non appena ritieni che le prestazioni del modello siano sufficientemente buone per la produzione, si tratta di rendere il modello il più efficiente possibile in termini di memoria e velocità.
Ci sono alcune soluzioni ovvie a questo, come scegliere l’hardware accelerato più adatto, ad esempio GPU migliori, assicurarsi che durante il passaggio in avanti non vengano calcolati gradienti o ridurre la precisione, ad esempio a float16.
Metodi di ottimizzazione più avanzati includono l’utilizzo di librerie open-source per acceleratori come ONNX Runtime, quantizzazione e server di inferenza come Triton.
Presso Hugging Face, abbiamo lavorato molto per facilitare l’ottimizzazione dei modelli, soprattutto con la nostra libreria open-source Optimum. Optimum rende estremamente semplice ottimizzare la maggior parte dei modelli 🤗 Transformers.
Se stai cercando soluzioni altamente ottimizzate che non richiedono alcuna conoscenza tecnica, potresti essere interessato a Inference API, una soluzione plug & play per servire in produzione una vasta gamma di attività di apprendimento automatico, inclusa l’analisi dei sentimenti.
Inoltre, se stai cercando supporto per i tuoi casi d’uso personalizzati, il team di esperti di Hugging Face può aiutarti ad accelerare i tuoi progetti di apprendimento automatico! Il nostro team risponde alle domande e trova soluzioni secondo le tue esigenze nel percorso di apprendimento automatico, dalla ricerca alla produzione. Visita hf.co/support per saperne di più e richiedere un preventivo.