Un modello dal Hugging Face Hub può essere eseguito localmente con Transformers: configurare l'ambiente Python, selezionare un modello e richiamarlo con pipeline(). La documentazione della Pipeline di Hugging Face descrive come il compito scelto collega il modello e la preelaborazione; con device="cpu" l' esempio viene eseguito esplicitamente sulla CPU.
Per la prima chiamata è adatto un modello per la classificazione di testo inglese. Il suo identificatore viene impostato nel comando in modo che la Pipeline non selezioni un modello predefinito per il compito. Al primo avvio, Transformers scarica i file necessari dal Hub; in seguito, il runtime locale elabora la frase inserita.
Un ambiente virtuale mantiene le dipendenze Python di un progetto insieme. La guida all'installazione per Transformers descrive anche l'installazione con PyTorch, la cache locale e la modalità offline. Su Linux o macOS, nel directory del progetto, sono sufficienti questi comandi iniziali:
Su Windows, l'ambiente viene attivato tramite la cartella Scripts; in seguito, lo stesso comando di installazione è valido. Per la chiamata CPU mostrata, non è necessaria alcuna configurazione GPU. Se in futuro si vuole che una GPU esegua i calcoli, la versione di PyTorch installata deve essere compatibile con l'hardware.
I file dei modelli scaricati finiscono normalmente nella cache Hub dell'account utente. Chi vuole specificarne la posizione può, ad esempio, impostare export HFHUBCACHE="$PWD/.hf-cache" prima di avviare Python su Linux o macOS. La cache è un'area di download gestita da Hugging Face: per una propria directory di modelli trasportabile, il modello e il Tokenizer dovrebbero essere salvati in modo mirato, invece di assemblare a mano i file dalla struttura della cache.
Selezione del Modello
Per esempio, si utilizza distilbert/distilbert-base-uncased-finetuned-sst-2-english. La scheda del checkpoint DistilBERT indica la classificazione di testo inglese come compito e Apache-2.0 come licenza. La frase cinematografica inglese nel seguente comando corrisponde a questo scopo di utilizzo; dall'esempio non si può dedurre l'idoneità per testi tedeschi.
La chiamata completa si adatta a una riga nel terminale:
python -c "from transformers import pipeline; pipe = pipeline('text-classification', model='distilbert/distilbert-base-uncased-finetuned-sst-2-english', device='cpu'); print(pipe('This film is excellent.'))"
L'output è una lista con un'etichetta di classificazione e uno score. Questo score appartiene alla previsione per l'input specifico; non misura la qualità generale del modello. L'identificatore del modello rende la chiamata più univoca rispetto a una Pipeline a cui viene passato solo il compito. Tuttavia, non stabilisce ancora una revisione del repository immutabile, nel caso in cui i file nel ramo scelto vengano aggiornati in seguito.
Funzionamento della Pipeline
text-classification sceglie il tipo di Pipeline. L'identificatore del checkpoint indica il checkpoint la cui configurazione descrive l'architettura e la corrispondenza delle classi di output. Per l'elaborazione del testo, la Pipeline ha bisogno anche di un Tokenizer: esso suddivide l'input e lo converte nelle ID token con cui il modello calcola. Dopo l'esecuzione del modello, la Pipeline formatta l'output in un'etichetta leggibile con score.
Pertanto, da soli i file dei pesi non sono sufficienti per questa chiamata. Senza una preelaborazione appropriata, il modello non riceve l'input nella forma prevista; senza la classe di modello specifica per il compito corretto, non è possibile richiamare in modo significativo la classificazione desiderata. Anche durante la sostituzione dell'identificatore del modello, compito e checkpoint devono corrispondere. Un modello per la generazione di testo non può essere trasformato in un classificatore sostituendo solo il nome del repository nel comando esistente.
Metodi di Caricamento
Il modo automatico è comodo perché la Pipeline assembla questi componenti per un checkpoint supportato. Nasconde, tuttavia, quali oggetti vengono creati nel programma Python. Non appena gli input devono essere preparati autonomamente o i componenti riutilizzati separatamente, il caricamento esplicito è più chiaro.
Per il checkpoint mostrato, AutoTokenizer e AutoModelForSequenceClassification si adattano al compito. Entrambi vengono caricati con lo stesso identificatore di repository e poi passati come oggetti alla Pipeline:
python -c "from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline; name='distilbert/distilbert-base-uncased-finetuned-sst-2-english'; tokenizer=AutoTokenizer.frompretrained(name); model=AutoModelForSequenceClassification.frompretrained(name); pipe=pipeline('text-classification', model=model, tokenizer=tokenizer, device='cpu'); print(pipe('This film is excellent.'))"
Così è visibile quale Tokenizer appartiene all'input e quale classe carica i pesi di classificazione. Questo è utile se un programma deve utilizzare il Tokenizer indipendentemente dalla Pipeline o se si vuole controllare esplicitamente la scelta del modello. Per l'inferenza semplice, la chiamata più breve riunisce gli stessi componenti di base; il caricamento esplicito di per sé non riduce il requisito di memoria.
Gestione della Cache e Modalità Offline
La cache occupa spazio sul disco, il modello caricato richiede RAM. Durante l'inferenza, si aggiungono input e valori intermedi. Un download di successo non significa quindi che sia disponibile sufficiente RAM per l'avvio. In un'esecuzione con GPU, conta inoltre la memoria grafica disponibile; il limite di memoria durante l'avvio locale del modello riguarda sia il modo di caricamento automatico che quello esplicito.
Per un avvio senza accesso alla rete, la configurazione, il Tokenizer e i pesi devono essere già disponibili localmente. Con HFHUBOFFLINE=1, il client Hub utilizza file locali invece di eseguire query sul Hub. Se manca un file necessario, la chiamata offline non può scaricarlo. Una propria cartella di modelli è un'alternativa alla cache per questo scopo: Tokenizer e modello possono essere salvati con savepretrained() nello stesso percorso e successivamente caricati con frompretrained() da questo percorso.
Considerazioni Finali
Prima di passare a un altro checkpoint, vale la pena dare un'occhiata alla sua scheda del modello: lingua, compito e licenza appartengono al repository specifico. Le condizioni di utilizzo dell'esempio DistilBERT non si applicano automaticamente a un altro modello. Chi deve mantenere riproducibile la chiamata a lungo termine dovrebbe inoltre scegliere una revisione fissa del repository, in modo che le modifiche successive al ramo standard mobile non scambino i file caricati inosservatamente.