Abbiamo già visto in una precedente guida come Hugging Face costituisca un punto centrale di interazione con tutto il mondo dei modelli open source per l’intelligenza artificiale. Ciò che sorprende sin dall’inizio è che con il suo meccanismo di librerie e pipeline, Hugging Face permette di renderci operativi immediatamente su task specifici (generazione di testo, classificazione, computer vision e molte altre applicazioni), offrendoci un modello di default o permettendoci di scegliere quale modello utilizzare.

I modelli sono preaddestrati, il che significa che hanno già vissuto una fase di training sui dati e pertanto vengono rilasciati con tutta una serie di conoscenze acquisite. Il problema è che spesso le loro conoscenze potrebbero essere generiche, imprecise o datate, mentre i nostri servizi  hanno bisogno di una competenza domain-specific ovvero focalizzata su un determinato settore, aggiornata e soprattutto affidabile.

In casi di questo genere, molto comuni a dire il vero, ci sono due strade per potenziare la competenza e l’affidabilità di un modello: si possono utilizzare sistemi per la Retrieval Augmented Generation (RAG), o in alternativa si ricorre al cosiddetto fine-tuning del modello, cioè una messa a punto delle conoscenze di un modello basata su dataset e documenti di cui la nostra azienda dispone.

In questo articolo, esploriamo proprio il procedimento del fine-tuning individuando per sommi capi quali sono gli aspetti fondamentali che ne possono determinare un’implementazione di successo.

Le fasi del fine-tuning di un modello IA

Possiamo in generale vedere il fine-tuning organizzato in questo modo:

  • scelta del modello di cui fare fine-tuning;
  • preparazione del dataset;
  • pre-processing e tokenizzazione del dataset;
  • predisposizione di metriche e strumenti di valutazione dei risultati;
  • training;
  • salvataggio del modello ottimizzato con fine-tuning o sua condivisione tramite Hugging Face.

Scelta del modello da affinare

Per quanto riguarda la scelta del modello, è importante partire da un modello le cui caratteristiche si avvicinino agli scopi che ci siamo prefissati e che quindi sarà parzialmente pronto a soddisfare le nostre necessità. Inoltre, considerando un modello di riferimento da cui partire, potremo confrontare le risposte che darà il modello base rispetto a quello fine-tuned che avremo ottenuto.

Preparazione del dataset

La parte più delicata in assoluto consiste nella determinazione del dataset. Questo conterrà tutti i documenti che il modello deve studiare per poter elaborare risposte più mirate. Hugging Face offre un’apposita libreria per la gestione dei dataset e ciò permette di integrare direttamente i nostri dati nel procedimento. Sarà fondamentale costruire il dataset nel modo più adatto integrando più dati possibile, stando attenti a completarli con tutto ciò di cui il modello avrà bisogno, evitando errori, informazioni parziali o che rischierebbero di deviare il nuovo modello messo a punto.

Inoltre, per poter avere un apprendimento supervisionato, il dataset dovrà essere suddiviso in due porzioni, una effettivamente usata nella fase di training e una di test, da usare come confronto per verificare che le previsioni del modello addestrato corrispondano alle informazioni reali presenti nel secondo dataset. Se scegliamo dataset forniti da Hugging Face saranno già organizzati in questo modo. Se invece vogliamo usare un dataset proprietario (qui informazioni su come caricare un proprio dataset su Hugging Face), potremo procedere noi a separare le due porzioni con la funzione train_test_split da invocare sul dataset.

Come ambiente di lavoro immaginiamo un contesto Python integrato con Hugging Face (se utilizzare Google Colab o un ambiente locale dipenderà solo dai nostri interessi, dotazioni ed eventuali finalità).

Per prima cosa abbiamo bisogno delle librerie necessarie:

pip install accelerate transformers datasets evaluate

La libreria centrale sarà transformers come sempre, mentre evaluate fornirà il necessario per caricare strumenti di valutazione come l’accuracy che durante il fine-tuning verificherà quante previsioni il modello sta realizzando correttamente.

La libreria datasets ci servirà invece soprattutto per elaborare il nostro database o sceglierne uno già disponibile in Hugging Face.

Pre-processing e tokenizzazione del dataset

Una volta predisposto il dataset con i dati di nostro interesse (supponiamo il relativo oggetto Python si chiami dataset)  passeremo alla sua tokenizzazione:

  • richiedendo un tokenizer come nel codice sottostante dove tra doppi apici passeremo il nome del modello di partenza che abbiamo scelto;
  • definiremo una funzione di preprocessing per il trattamento del dataset che in questo caso, come spesso accade, si limita ad adattare la lunghezza dei testi (qui abbiamo dato per scontato che ogni item del dataset includa un campo text, abbastanza tipico per gli esperimenti di classificazione, ma si ricordi di adattare la funzione ai propri scopi).
from transformers import AutoTokenizer

# inseriremo qui il nome del modello di partenza
tokenizer = AutoTokenizer.from_pretrained("....")

def preprocess_function(data):
    return tokenizer(data["text"], truncation=True)

tokenized_dataset = dataset.map(preprocess_function, batched=True)

A questo punto abbiamo il dataset pronto per cui predisponiamo il tutto per il training.

Training e fine tuning di un modello IA

Con Hugging Face si può procedere in maniera più diretta passando per le librerie PyTorch e Tensorflow direttamente o seguire un approccio di più alto livello con la classe Trainer.

Per poter entrare in azione, quest’ultima necessita almeno di:

  • un riferimento al modello di base di cui fare il fine-tuning;
  • i cosiddetti training arguments ovvero una serie di parametri passati in un oggetto di classe TrainingArguments che definisce le modalità pratiche con cui il training si svolgerà. Si potrà scegliere quelli che si preferisce ma almeno il parametro output_dir per indicare la cartella dove l’output sarà salvato andrà esplicitata;
  • un riferimento ad un dataset di training ed uno a quello di valutazione (parametri train_dataset e eval_dataset) che, secondo quanto detto prima, faranno spesso parte dello stesso oggetto di classe Dataset;
  • una funzione da fornire al parametro compute_metrics che la userà per valutare l’andamento del training strada facendo.

Supponiamo di voler stilare un codice essenziale e generico per affrontare il training di un modello di classificazione, potremmo vederlo così:

from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer

# nome del modello di partenza
model_name= "...."

# istanza del modello (supponiamo di avere solo due label nella classificazione)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

# definiamo una funzione per le metriche
def compute_metrics(pred):
    ...
    ...
    return ...

# impostiamo gli argomenti di training
training_args = TrainingArguments(output_dir="trainer_dir")

# predisponiamo  il Trainer con tutto quanto finora preparato
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    compute_metrics=compute_metrics,
)

Una volta tutto pronto, potrà partire il training:

trainer.train()

e alla fine il modello fine-tuned potrà essere caricato sull’hub o salvato in locale con:


trainer.save_model("my_finetuned_model")

dove my_finetuned_model indica la cartella che lo ospiterà.

Salvataggio del modello ottimizzato

A questo punto saremo pronti ad utilizzarlo in locale o dall’hub, con pipeline o senza, proprio come siamo abituati a fare con i modelli di Hugging Face ma avendo a disposizione un modello che è stato riaddestrato per capire al meglio le necessità dei nostri servizi.