Pytorch
TensorFlow

#
Condividere modelli pre-addestrati

Nei passi seguenti illustreremo i modi più semplici e veloci per condividere modelli pre-addestrati sull’🤗 Hub. Vedremo degli strumenti e delle utility che rendono semplice condividere e aggiornare modelli direttamente sull’🤗 Hub.

Incoraggiamo tutti gli utenti che addestrano un modello a contribuire alla comunità condividendolo — anche se i vostri modelli sono addestrati su dati molto specifici, possono comunque aiutare gli altri a risparmiare tempo e risorse computazionali. A vostra volta, potrete beneficiare del lavoro che gli altri hanno fatto!

Ci sono tre modi per creare un nuovo repository di un modello:

- Usando la funzione `push_to_hub` dell’API
- Usando la libreria Python `huggingface_hub`
- Usando l’interfaccia web

Una volta che avrete creato un repository, potrete caricarvi i file attraverso git e git-lfs. Nelle sezioni seguenti vedremo in dettaglio come creare un repository e aggiungervi i file.

##
Utilizzando la funzione push_to_hub dell’API

Il modo più semplice di caricare file sull’Hub è attraverso la funzione `push_to_hub` dell’API.

Prima di continuare sarà necessario generare un token di autenticazione così che l’API `huggingface_hub` sappia chi siete e a quali namespace avete accesso in scrittura. Assicuratevi di essere in un ambiente in cui la libreria `transformers` è installata (vedi Installazione). Se state utilizzando un notebook, potete usare la seguente funzione per effettuare il login:

    from huggingface_hub import notebook_login

    notebook_login()

In una finestra del terminale, potete eseguire:

    huggingface-cli login

In entrambi i casi, vi verrà chiesto di inserire il vostro nome utente e la password, che sono gli stessi che utilizzate per accedere all’Hub. Se non avete ancora un profilo sull’Hub, potete crearne uno qui.

Perfetto! Ora il token di autenticazione è salvato nella cartella di cache, e possiamo creare dei nuovi repository!

Se avete usato la API `Trainer` per addestrare un modello, il modo più semplice per caricarlo sull’Hub è impostare il parametro `push_to_hub=True` quando definite i `TrainingArguments` (parametri di addestramento):

    from transformers import TrainingArguments

    training_args = TrainingArguments(
        "bert-finetuned-mrpc", save_strategy="epoch", push_to_hub=True
    )

Invocando la funzione `trainer.train()`, l’oggetto `Trainer` caricherà il modello sull’Hub ad ogni salvataggio (nell’esempio dopo ogni epoca) all’interno di un repository nel vostro namespace. Il repository avrà come nome la stessa stringa che avete scelto come nome per la cartella di output (qui `bert-finetuned-mrpc`), ma è possibile scegliere un nome diverso impostando il parametro `hub_model_id = "un_nome_diverso"`.

Volendo caricare il modello nello spazio di una organizzazione di cui si è membri, sarà sufficiente impstare il parametro `hub_model_id = "nome_organizzazione/nome_repository"`.

Alla fine dell’addestramento, sarà necessario invocare per l’ultima volta la funzione `trainer.push_to_hub()` per caricare la versione definitiva del modello. Questa azione genererà automaticamente anche un cartellino del modello, con tutti i metadati rilevanti, riportando anche gli iper-parametri utilizzati e i risultati della valutazione finale. Questo è un esempio del contenuto di uno di questi cartellini:

In ogni caso, quando si lavora con modelli, tokenizers, e oggetti di configurazione, è comunque possibile accedere all’Hub dei modelli direttamente ulizzando il rispettivo methodo `push_to_hub()`. Questo metodo si occupa di creare il repository e caricarvi i file del modello e tokenizer. Non è necessario gestire manualmente questa operazione, a differenza dell’API che vedremo più avanti.

Per farvi una idea di come funziona questo processo, inizializzate un modello e un tokenizer:

    from transformers import AutoModelForMaskedLM, AutoTokenizer

    checkpoint = "camembert-base"

    model = AutoModelForMaskedLM.from_pretrained(checkpoint)
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)

A questo punto, siete liberi di fare quello che volete con questi oggetti - aggiungere token diversi al tokenizer, addestrare il modello, affinarlo. Quando siete soddisfatti con il modello, i pesi e il tokenizer ottenuti, potrete usare il methodo `push_to_hub()` direttamente disponibile sul oggetto `model`:

    model.push_to_hub("dummy-model")

Questo genererà un nuovo repository `dummy-model` nel vostro profilo, e lo popolerà con i file del modello. Ripetete la stessa operazione con il tokenizer, così tutti i file saranno disponibili nel repository:

    tokenizer.push_to_hub("dummy-model")

Se siete affiliati con una organizzazione, basterà specificare il parametro `organization` per caricare i file nel namespace dell’organizzazione:

    tokenizer.push_to_hub("dummy-model", organization="huggingface")

Se desiderate utilizzare uno specifico token di autenticazione di Hugging Face, è possibile specificarlo durante l’invocazione del metodo `push_to_hub()`:

    tokenizer.push_to_hub("dummy-model", organization="huggingface", use_auth_token="<TOKEN>")

Ora potete dirigervi alla pagina del Model Hub per trovare il vostro nuovo modello appena caricato: https://huggingface.co/user-or-organization/dummy-model.

Cliccando sulla scheda “Files and versions” dovreste vedere la lista dei file caricati, come nell’immagine sottostante:

✏️ Prova tu! Prendi il modello e il tokenizer associati con il cehckpoint `bert-base-cased` e caricali in un repository nel tuo namespace usando il metodo `push_to_hub()`. Verifica che il repository appaia correttamente sulla tua pagina prima di cancellarlo.

Come avete visto, il metodo `push_to_hub()` accetta numerosi parametri, rendendo possible caricare i file su uno specifico repository o in un namespace di una organizzazione, o utilizzare un qualunque API token. Consigliamo di leggere la documentazione disponibile alla pagina 🤗 Transformers documentation per farsi una idea di tutte le possibilità offerte dal metodo.

`push_to_hub()` è supportato dal package `huggingface_hub` di Python, che offre una API diretta per interagire con l’Hub di Hugging Face. È integrato in 🤗 Transformers e in numerosi altre librirerie di machine learning, come `allenlp`. In questo capitolo ci siamo soffermati sull’integrazione con 🤗 Transformers, ma integrarlo nel proprio codice o libreria è semplice.

Saltate all’ultima sezione per vedere come caricare i file nel repository appena creato!

##
Utilizzando la libreria Python huggingface_hub

La libreria Python `huggingface_hub` offre una varietà di strumenti per interfacciarsi con gli hub di modelli e dataset. Fornisce delle classi e dei metodi semplici per operazioni comuni come ottenere informazioni e gestire repository sull’hub. Fornisce anche delle semplici API che sfruttano git per gestire i contenuti dei repository e integrare l’Hub nei propri prgetti e librerie.

Come per la funzione `push_to_hub`, anche questo approccio richiede di avere un API token salvato nella propria cartella di cache. Per ottenerlo, sarà necessario usare il comando `login` dalla interfaccia da riga di comando (CLI), come indicato nella sezione precedente (assicuratevi di inserire il carattere `!` prima di questi comandi se li state eseguendo in Google Colab):

    huggingface-cli login

La libreria `huggingface_hub` offre molte classi e metodi utili al nostro scopo. In primo luogo, ci sono alcuni metodi per gestire operazioni quali creazione e cancellazione di repository:

    from huggingface_hub import (
        # User management
        login,
        logout,
        whoami,

        # Repository creation and management
        create_repo,
        delete_repo,
        update_repo_visibility,

        # And some methods to retrieve/change information about the content
        list_models,
        list_datasets,
        list_metrics,
        list_repo_files,
        upload_file,
        delete_file,
    )

È inoltre offerta una classe `Repository` molto completa per gestire un repository locale. Nelle seguenti sezioni li esploreremo e capiremo come utilizzarli.

Il metodo `create_repo` può essere utilizzato per creare un nuovo repository sull’hub:

    from huggingface_hub import create_repo

    create_repo("dummy-model")

Questo genererà un nuovo repository `dummy-model` nel vostro namespace. Potete anche specificare un’organizzazione a cui il repository dovrebbe appartenere utilizzando il parametro `organization`:

    from huggingface_hub import create_repo

    create_repo("dummy-model", organization="huggingface")

Che genererà il repository `dummy_model` all’interno del namespace `huggingface`, assumendo che apperteniate a questa organizzazione. Altri parametri che possono tornare utili sono:

- `private`, che permette di specificare se il repository dovrebbe essere visibile da altri oppure no.
- `token`, che permette di specificare un token di autenticazione diverso da quello salvato nella propria cartella di cache.
- `repo_type`, che permette di creare un `dataset` o un `space` (spazio) invece di un modello. I valori accettati sono `"dataset"` e `"space"`.

Una volta creato il repository, dovremo aggiungere file al suo interno! Saltate alla sezione successiva per vedere tre modi per farlo.

##
Usando l’interfaccia web

L’interfaccia we offre strumenti per gestire i repository direttamente sull’Hub. Usando questa interfaccia potrete facilmente creare repository, aggiungere file (anche grandi!), esplorare modelli, visualizzare differenze tra file, e molto altro.

Per creare un nuovo repository visitate la pagina huggingface.co/new:

Per prima cosa sarà necessario specificare chi sia il proprietario del repository: questi potete essere voi, o qualunque delle organizzazioni a cui siete affiliati. Se scegliete un’organizzazione, il modello sarà presente sulla pagina dell’organizzazione e tutti i membri dell’organizzazione avranno la possibilità di contribuire al repository.

Ora potete inserire il nome del vostro modello. Questo sarà anche il nome del repository. Infine, potete specificare se volete che il vostro modello sia pubblico o privato. I modelli privati sono nascosti al pubblico.

Dopo aver creato il repository del vostro modello, dovreste vedere una pagina come questa:

Qui è dove il vostro modello sarà reso disponibile. Per iniziare a popolarlo, potete aggiungere un file README direttamente dalla interfaccia web.

Il file README è in formato Markdown — sentitevi liberi di sbizzarrirvi col README! La terza parte di questo capitolo è dedicata alla generazione del cartellino del modello. Questi cartellini sono estremamente importanti nel valorizzare il vostro modello, poiché è qui che potrete comunicare agli altri le potenzialità del vostro modello.

Nella scheda “Files and versions” (File e versioni), vedrete che non ci sono ancora molti file — solo il README.md che avete appena creato e il file .gitattributes che tiene traccia dei file grandi.

Vedremo ora come aggiungere nuovi file.

##
Caricare i file del modello

Il sistema di gestione dei file sull’Hub di Hugging Face è basato su git per file normali, e su git-lfs (Git Large File Storage) per file più grandi.

Nella sezione seguente, illustreremo tre diversi modi per caricare file sull’Hub: attraverso `huggingface_hub` e attraverso comandi git.

###
Usando upload_file

Caricare file utilizzando `upload_file` non richiede di avere git e git-lfs installati sul proprio sistema. Infatti questo metodo trasferisce i file sul 🤗 Hub attraverso richieste HTTP POST. Una limitazione di questo approccio è che non può gestire file di dimensioni più grandi di 5GB. Se i vostri file sono più grandi di 5GB, seguite gli altri due metodi dettagliati sotto.

La API può essere usata in questo modo:

    from huggingface_hub import upload_file

    upload_file(
        "<path_to_file>/config.json",
        path_in_repo="config.json",
        repo_id="<namespace>/dummy-model",
    )

Questo caricherà il file `config.json`, locato in `<path_to_file>`, nella cartella di base (root) del repository come `config.json`, nel repository `dummy-model`. Altri parametri che possono essere utili sono:

- `token`, che permette di utilizzare un token di autenticazione specifico invece di quello salvato nella vostra cartella di cache.
- `repo_type`, che permette di caricare un file in un `dataset` o uno `space` invece di un modello. Valori accettati sono `"dataset"` e `"space"`.

###
La classe Repository

La classe `Repository` gestisce un repository locale in un modo simile a git. Elimina la maggior parte della complessità che un utente potrebbe incontrare con git, per fornire tutte le funzionalità di cui abbiamo bisogno.

Questa classe necessità di git e git-lfs, quindi assicuratevi di averli installati (vedere qui per le istruzioni di installazione) e di averli configurati prima di iniziare.

In order to start playing around with the repository we have just created, we can start by initialising it into a local folder by cloning the remote repository: Per iniziare a sperimentare con il repository appena creato, possiamo iniziallizzare il repository in una cartella locale clonando il repository remoto:

    from huggingface_hub import Repository

    repo = Repository("<path_to_dummy_folder>", clone_from="<namespace>/dummy-model")

Questa azione crea la cartella `<path_to_dummy_folder>` nella cartella di lavoro corrente (working directory). Questa cartella contiene solo il file `.gitattributes` poichè quello è l’unico file che viene creato quando si istanzia un repository attraverso il metodo `create_repo`.

Da questo punto possiamo usare molti dei metodi classici di git.

    repo.git_pull()
    repo.git_add()
    repo.git_commit()
    repo.git_push()
    repo.git_tag()

E molti altri! Consigliamo di leggere la documentazione della classe `Repository` disponibile qui per una panoramica dei metodi disponibili.

In questo momento abbiamo un modello e un tokenizer che vorremmo caricare sull’hub. Avendo correttamente clonato il repository, possiamo salvare i file al suo interno.

Assicuriamoci prima che il nostro clone locale sia aggiornato scaricando (pulling) gli ultimi cambiamenti:

    repo.git_pull()

Fatto questo, salviamo i file del modello e del tokenizer:

    model.save_pretrained("<path_to_dummy_folder>")
    tokenizer.save_pretrained("<path_to_dummy_folder>")

La cartella `<path_to_dummy_folder>` ora conteine tutti i file del modello e del tokenizer. Possiamo seguire la sequenza di operazioni (workflow) standard di git, aggiungendo file alla staging area, utilizzando git commit e git push per caricarli sull’hub:

    repo.git_add()
    repo.git_commit("Add model and tokenizer files")
    repo.git_push()

Congratulazioni! Avete appena caricato i vostri primi file sull’hub.

###
L’approccio basato su git

Questo è un approccio molto minimalista al caricamento dei file: utilizzeremo git e git-lfs direttamente. Gli approcci precedenti rimuovevano la maggior parte della complessità utilizzando astrazioni. Siccome ci sono alcune limitazioni con questo metodo, mostreremo un caso di utilizzo più complesso.

Questo metodo richeide git e git-lfs, quindi assicuratevi di averli installati (vedere qui per le istruzioni di installazione) e di averli configurati prima di iniziare.

Per prima cosa inizializziamo git-lfs:

    git lfs install

    Updated git hooks.
    Git LFS initialized.

Fatto questo, il primo passo è clonare il repository del proprio modello:

    git clone https://huggingface.co/<namespace>/<your-model-id>

Il mio nome utente è `lysandre` e ho usato il nome `dummy` per il modello, quindi per me il comando da eseguire diventa:

    git clone https://huggingface.co/lysandre/dummy

Adesso ho una cartella chiamata dummy nella mia cartella di lavoro corrente (working directory). Posso spostarmi nella cartella usando `cd` ed esaminare i contenuti:

    cd dummy && ls

    README.md

Se avete appena creato la repository usando il metodo `create_repo` di Hugging Face Hub, questa cartella dovrebbe contenere solo un file nascosto `.gitattributes`. Se avete seguito le istruzioni nella sezione precedente per creare una repository usando l’interfaccia web, la cartella dovrebbe contenere un singolo file README.md assieme al file nascosto `.gitattributes`, come mostrato qui.

Per aggiungere un file di taglia regolare, come un file di configurazione, un file vocabolario, o in genere qualsiasi file di taglia inferiore a qualche megabyte, si procede nello stesso modo di un qualunque systema basato su git. Tuttavia, i file più grandi devono essere registrati con git-lfs per poter essere caricati su huggingface.co.

Tornando a Python per un momento, generiamo un modello e un tokenizer che vorremmo caricare sul nostro repository dummy:

    from transformers import AutoModelForMaskedLM, AutoTokenizer

    checkpoint = "camembert-base"

    model = AutoModelForMaskedLM.from_pretrained(checkpoint)
    tokenizer = AutoTokenizer.from_pretrained(checkpoint)

    # Do whatever with the model, train it, fine-tune it...

    model.save_pretrained("<path_to_dummy_folder>")
    tokenizer.save_pretrained("<path_to_dummy_folder>")

Adesso che abbiamo salvato gli artefatti del modello e del tokenizer, esaminiamo la cartella dummy:

    ls

    config.json  pytorch_model.bin  README.md  sentencepiece.bpe.model  special_tokens_map.json tokenizer_config.json  tokenizer.json

Guardando le dimensioni dei file (ad esempio con `ls -lh`), possiamo vedere che il file contenente lo stato del modello (model state dict file) (pytorch_model.bin) è l’unico file anomalo, occupando più di 400 MB.

✏️ When creating the repository from the web interface, the *.gitattributes* file is automatically set up to consider files with certain extensions, such as *.bin* and *.h5*, as large files, and git-lfs will track them with no necessary setup on your side. ✏️ Creando il reposiotry dall'interfaccia web, il file *.gitattributes* viene automaticamente configurato per considerare file con alcune estensioni, come *.bin* e *.h5*, come file grandi, e git-lfs li traccerà senza necessità di configurazione da parte dell'utente.

Possiamo quindi procedere come faremo per un repository Git tradizionale. Possiamo aggiungere tutti i file all’ambiente di staging di Git con il comando `git add`:

    git add .

Possiamo quindi vedere i file che sono attualmente in staging:

    git status

    On branch main
    Your branch is up to date with 'origin/main'.

    Changes to be committed:
      (use "git restore --staged <file>..." to unstage)
      modified:   .gitattributes
    	new file:   config.json
    	new file:   pytorch_model.bin
    	new file:   sentencepiece.bpe.model
    	new file:   special_tokens_map.json
    	new file:   tokenizer.json
    	new file:   tokenizer_config.json

Allo stesso modo possiamo assucurarci che git-lfs stia tenendo traccia dei file giusti utilizzando il comando `status`:

    git lfs status

    On branch main
    Objects to be pushed to origin/main:

    Objects to be committed:

    	config.json (Git: bc20ff2)
    	pytorch_model.bin (LFS: 35686c2)
    	sentencepiece.bpe.model (LFS: 988bc5a)
    	special_tokens_map.json (Git: cb23931)
    	tokenizer.json (Git: 851ff3e)
    	tokenizer_config.json (Git: f0f7783)

    Objects not staged for commit:

Possiamo notare che tutti i file hanno `Git` come gestore (handler), ad eccezione di pytorch_model.bin e sentencepiece.bpe.model, che invece hanno `LFS`. Perfetto!

Possiamo quindi procedere al passo finale, utilizzando i comandi commit e push per caricare i file sul repository remoto huggingface.co:

    git commit -m "First model version"

    [main b08aab1] First model version
     7 files changed, 29027 insertions(+)
      6 files changed, 36 insertions(+)
     create mode 100644 config.json
     create mode 100644 pytorch_model.bin
     create mode 100644 sentencepiece.bpe.model
     create mode 100644 special_tokens_map.json
     create mode 100644 tokenizer.json
     create mode 100644 tokenizer_config.json

L’operazione di push può richiedere un po’ di tempo, a seconda della velocità della connessione a internet e della dimensione dei file:

    git push

    Uploading LFS objects: 100% (1/1), 433 MB | 1.3 MB/s, done.
    Enumerating objects: 11, done.
    Counting objects: 100% (11/11), done.
    Delta compression using up to 12 threads
    Compressing objects: 100% (9/9), done.
    Writing objects: 100% (9/9), 288.27 KiB | 6.27 MiB/s, done.
    Total 9 (delta 1), reused 0 (delta 0), pack-reused 0
    To https://huggingface.co/lysandre/dummy
       891b41d..b08aab1  main -> main

Alla fine di questa operazione, possiamo controllare il repository e vedere tutti i file aggiunti di recente:

L’interfaccia permette di esplorare i file e le commit, e visualizzare le differenze (file diff) introdotte da ogni commit: