Addestramento Distribuito Addestra BART/T5 per la Sintesi utilizzando 🤗 Transformers e Amazon SageMaker
'Addestramento Distribuito di BART/T5 per la Sintesi con 🤗 Transformers e Amazon SageMaker'
In caso te lo fossi perso: il 25 marzo abbiamo annunciato una collaborazione con Amazon SageMaker per rendere più facile creare modelli di Machine Learning all’avanguardia e spedire funzionalità NLP all’ultimo grido più velocemente.
Insieme al team di SageMaker, abbiamo costruito 🤗 Containers di Deep Learning ottimizzati per i Transformers per accelerare l’addestramento dei modelli basati su Transformers. Grazie amici di AWS!🤗 🚀
Con il nuovo estimatore HuggingFace nel SDK Python di SageMaker, puoi iniziare l’addestramento con una sola riga di codice.
- Presentando 🤗 Accelerate
- Scaling-up BERT Inference su CPU (Parte 1)
- Utilizzo e combinazione di modelli Hugging Face con Gradio 2.0
Il post del blog di annunci fornisce tutte le informazioni che devi conoscere sull’integrazione, incluso un esempio di “Come iniziare” e link alla documentazione, agli esempi e alle funzionalità .
elencate nuovamente qui:
- 🤗 Documentazione Transformers: Amazon SageMaker
- Notebook di esempio
- Documentazione Amazon SageMaker per Hugging Face
- Documentazione SDK Python SageMaker per Hugging Face
- Container di Deep Learning
Se non sei familiare con Amazon SageMaker: “Amazon SageMaker è un servizio completamente gestito che fornisce a ogni sviluppatore e scienziato dei dati la capacità di creare, addestrare e distribuire modelli di machine learning (ML) rapidamente. SageMaker rimuove il lavoro pesante da ogni passaggio del processo di machine learning per rendere più facile sviluppare modelli di alta qualità .” [REF]
Useremo i nuovi DLC di Hugging Face e l’estensione di Amazon SageMaker per addestrare un modello Seq2Seq-transformer distribuito sul compito di summarization
utilizzando le librerie transformers
e datasets
, quindi caricheremo il modello su huggingface.co e lo testeremo.
Come strategia di addestramento distribuito utilizzeremo il Data Parallelism di SageMaker, che è stato integrato nell’API del Trainer. Per utilizzare il data-parallelism dobbiamo solo definire il parametro distribution
nel nostro estimatore HuggingFace
.
# configurazione per l'esecuzione dell'addestramento su smdistributed Data Parallel
distribution = {'smdistributed':{'dataparallel':{ 'enabled': True }}}
In questo tutorial, utilizzeremo un’istanza del notebook di Amazon SageMaker per eseguire il nostro lavoro di addestramento. Puoi imparare qui come configurare un’istanza del notebook.
Cosa faremo:
- Configurare un ambiente di sviluppo e installare sagemaker
- Scegliere lo script 🤗 Transformers
examples/
- Configurare l’addestramento distribuito e gli iperparametri
- Creare un estimatore
HuggingFace
e avviare l’addestramento - Caricare il modello fine-tuned su huggingface.co
- Testare l’inferenza
Modello e Dataset
Stiamo per effettuare il fine-tuning di facebook/bart-large-cnn sul dataset samsum. “BART è un modello sequenza-a-sequenza addestrato con denoising come obiettivo di pretraining.” [REF]
Il dataset samsum
contiene circa 16k conversazioni simili a messaggi con riassunti.
{"id": "13818513",
"summary": "Amanda ha fatto dei biscotti e li porterà a Jerry domani.",
"dialogue": "Amanda: Ho fatto dei biscotti. Ne vuoi qualcuno?\r\nJerry: Certo!\r\nAmanda: Te li porterò domani :-)"}
Configurare un ambiente di sviluppo e installare sagemaker
Dopo che la nostra istanza del notebook di SageMaker è in esecuzione, possiamo selezionare Jupyter Notebook o JupyterLab e creare un nuovo notebook con il kernel conda_pytorch_p36
.
Nota: L’uso di Jupyter è opzionale: potremmo anche avviare lavori di addestramento di SageMaker da qualsiasi punto in cui abbiamo installato un SDK, connettività al cloud e autorizzazioni appropriate, come un laptop, un altro IDE o un pianificatore di attività come Airflow o AWS Step Functions.
Dopo di che possiamo installare le dipendenze richieste
!pip install transformers "datasets[s3]" sagemaker --upgrade
installa git-lfs
per il caricamento del modello.
!curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash
!sudo yum install git-lfs -y
!git lfs install
Per eseguire l’addestramento su SageMaker è necessario creare una sessione sagemaker e fornire un ruolo IAM con i permessi corretti. Questo ruolo IAM verrà successivamente allegato al TrainingJob
consentendogli di scaricare i dati, ad esempio da Amazon S3.
import sagemaker
sess = sagemaker.Session()
role = sagemaker.get_execution_role()
print(f"ARN del ruolo IAM utilizzato per eseguire l'addestramento: {role}")
print(f"Bucket S3 utilizzato per archiviare gli artefatti: {sess.default_bucket()}")
La repository 🤗 Transformers contiene diversi script examples/
per il fine-tuning dei modelli su compiti che vanno dal language-modeling
alla token-classification
. Nel nostro caso, stiamo utilizzando run_summarization.py
dagli esempi in seq2seq/
.
Nota: è possibile utilizzare questo tutorial così com’è per addestrare il proprio modello su uno script di esempi diverso.
Dato che HuggingFace Estimator ha il supporto git integrato, possiamo specificare uno script di addestramento archiviato in un repository GitHub come entry_point
e source_dir
.
Utilizzeremo il DLC transformers 4.4.2
, il che significa che dobbiamo configurare v4.4.2
come il ramo da cui scaricare gli script di esempio compatibili.
#git_config = {'repo': 'https://github.com/huggingface/transformers.git','branch': 'v4.4.2'} # v4.4.2 si riferisce alla `transformers_version` utilizzata nell'estimatore.
# utilizzato a causa di un pacchetto mancante in v4.4.2
git_config = {'repo': 'https://github.com/philschmid/transformers.git','branch': 'master'} # v4.4.2 si riferisce alla `transformers_version` utilizzata nell'estimatore.
Configurare l’addestramento distribuito e gli iperparametri
Successivamente, definiremo i nostri iperparametri
e configureremo la nostra strategia di addestramento distribuito. Come iperparametro, possiamo definire qualsiasi Seq2SeqTrainingArguments e quelli definiti in run_summarization.py.
# iperparametri, che vengono passati al job di addestramento
iperparametri={
'per_device_train_batch_size': 4,
'per_device_eval_batch_size': 4,
'model_name_or_path':'facebook/bart-large-cnn',
'dataset_name':'samsum',
'do_train':True,
'do_predict': True,
'predict_with_generate': True,
'output_dir':'/opt/ml/model',
'num_train_epochs': 3,
'learning_rate': 5e-5,
'seed': 7,
'fp16': True,
}
# configurazione per l'esecuzione dell'addestramento su smdistributed Data Parallel
distribuzione = {'smdistributed':{'dataparallel':{ 'enabled': True }}}
Dato che stiamo utilizzando la parallelizzazione dei dati di SageMaker, il nostro total_batch_size
sarà per_device_train_batch_size
* n_gpus
.
Creare un estimatore HuggingFace
e avviare l’addestramento
Ultimo passo prima dell’addestramento è creare un estimatore HuggingFace
. L’Estimator gestisce l’addestramento end-to-end di Amazon SageMaker. Definiamo quale script di fine-tuning dovrebbe essere utilizzato come entry_point
, quale instance_type
dovrebbe essere utilizzato e quali iperparametri
vengono passati.
from sagemaker.huggingface import HuggingFace
# creare l'estimatore
huggingface_estimator = HuggingFace(
entry_point='run_summarization.py', # script
source_dir='./examples/seq2seq', # percorso relativo all'esempio
git_config=git_config,
instance_type='ml.p3dn.24xlarge',
instance_count=2,
transformers_version='4.4.2',
pytorch_version='1.6.0',
py_version='py36',
role=role,
hyperparameters = iperparametri,
distribution = distribuzione
)
Come instance_type
stiamo utilizzando ml.p3dn.24xlarge
, che contiene 8x NVIDIA A100 con un instance_count
di 2. Ciò significa che eseguiremo l’addestramento su 16 GPU e un total_batch_size
di 16*4=64. Addestreremo un modello con 400 milioni di parametri con un total_batch_size
di 64, il che è incredibile. Per avviare l’addestramento chiamiamo il metodo .fit()
.
# avvio del lavoro di addestramento
huggingface_estimator.fit()
2021-04-01 13:00:35 Avvio - Avvio del lavoro di addestramento...
2021-04-01 13:01:03 Avvio - Avvio delle istanze di ML richiesteProfilerReport-1617282031: In corso
2021-04-01 13:02:23 Avvio - Preparazione delle istanze per l'addestramento......
2021-04-01 13:03:25 Download - Download dei dati di input...
2021-04-01 13:04:04 Addestramento - Download dell'immagine di addestramento...............
2021-04-01 13:06:33 Addestramento - Download dell'immagine di addestramento completato. Addestramento in corso
....
....
2021-04-01 13:16:47 Caricamento - Caricamento del modello di addestramento generato
2021-04-01 13:27:49 Completato - Lavoro di addestramento completato
Secondi di addestramento: 2882
Secondi fatturabili: 2882
I secondi di addestramento sono 2882 perché sono moltiplicati per il numero di istanze. Se calcoliamo 2882/2=1441, otteniamo la durata dal “Download dell’immagine di addestramento” al “Lavoro di addestramento completato”. Convertito in denaro reale, il nostro addestramento su 16 NVIDIA Tesla V100-GPU per un modello di sintesi di stato dell’arte ammonta a circa 28$.
Carica il modello sintonizzato su huggingface.co
Dato che il nostro modello ha ottenuto un punteggio abbastanza buono, lo caricheremo su huggingface.co, creeremo una model_card
e lo testeremo con il widget Hosted Inference. Per caricare un modello, è necessario creare un account qui .
Possiamo scaricare il nostro modello da Amazon S3 e decomprimerlo utilizzando il seguente frammento di codice.
import os
import tarfile
from sagemaker.s3 import S3Downloader
local_path = 'my_bart_model'
os.makedirs(local_path, exist_ok = True)
# scarica il modello da S3
S3Downloader.download(
s3_uri=huggingface_estimator.model_data, # s3 uri in cui si trova il modello addestrato
local_path=local_path, # percorso locale in cui verrà salvato il file *.tar.gz
sagemaker_session=sess # sessione sagemaker utilizzata per addestrare il modello
)
# decomprimi il modello
tar = tarfile.open(f"{local_path}/model.tar.gz", "r:gz")
tar.extractall(path=local_path)
tar.close()
os.remove(f"{local_path}/model.tar.gz")
Prima di caricare il nostro modello su huggingface.co, dobbiamo creare una model_card
. La model_card
descrive il modello e include iperparametri, risultati e specifica quale dataset è stato utilizzato per l’addestramento. Per creare una model_card
creiamo un file README.md
nella nostra local_path
# leggi i risultati di valutazione e test
with open(f"{local_path}/eval_results.json") as f:
eval_results_raw = json.load(f)
eval_results={}
eval_results["eval_rouge1"] = eval_results_raw["eval_rouge1"]
eval_results["eval_rouge2"] = eval_results_raw["eval_rouge2"]
eval_results["eval_rougeL"] = eval_results_raw["eval_rougeL"]
eval_results["eval_rougeLsum"] = eval_results_raw["eval_rougeLsum"]
with open(f"{local_path}/test_results.json") as f:
test_results_raw = json.load(f)
test_results={}
test_results["test_rouge1"] = test_results_raw["test_rouge1"]
test_results["test_rouge2"] = test_results_raw["test_rouge2"]
test_results["test_rougeL"] = test_results_raw["test_rougeL"]
test_results["test_rougeLsum"] = test_results_raw["test_rougeLsum"]
Dopo aver estratto tutte le metriche che vogliamo includere, creiamo il nostro README.md
. Oltre alla generazione automatica della tabella dei risultati, aggiungiamo manualmente le metriche al metadata
della nostra model card sotto model-index
import json
MODEL_CARD_TEMPLATE = """
---
language: it
tags:
- sagemaker
- bart
- sintesi
license: apache-2.0
datasets:
- samsum
model-index:
- name: {model_name}
results:
- task:
name: Sintesi di testo astratto
type: sintesi-di-testo-astratto
dataset:
name: "SAMSum Corpus: un dataset di dialoghi annotati dall'uomo per la sintesi astratta"
type: samsum
metrics:
- name: ROGUE-1 di validazione
type: rogue-1
value: 42.621
- name: ROGUE-2 di validazione
type: rogue-2
value: 21.9825
- name: ROGUE-L di validazione
type: rogue-l
value: 33.034
- name: ROGUE-1 di test
type: rogue-1
value: 41.3174
- name: ROGUE-2 di test
type: rogue-2
value: 20.8716
- name: ROGUE-L di test
type: rogue-l
value: 32.1337
widget:
- text: |
Jeff: Posso addestrare un modello 🤗 Transformers su Amazon SageMaker?
Philipp: Certamente puoi utilizzare il nuovo Hugging Face Deep Learning Container.
Jeff: ok.
Jeff: e come posso iniziare?
Jeff: dove posso trovare la documentazione?
Philipp: ok, ok puoi trovare tutto qui. https://huggingface.co/blog/the-partnership-amazon-sagemaker-and-hugging-face
---
## `{model_name}`
Questo modello è stato addestrato utilizzando Amazon SageMaker e il nuovo Hugging Face Deep Learning container.
Per ulteriori informazioni, consulta:
- [🤗 Documentazione di Transformers: Amazon SageMaker](https://huggingface.co/transformers/sagemaker.html)
- [Esempi di notebook](https://github.com/huggingface/notebooks/tree/master/sagemaker)
- [Documentazione di Amazon SageMaker per Hugging Face](https://docs.aws.amazon.com/sagemaker/latest/dg/hugging-face.html)
- [Documentazione Python SDK SageMaker per Hugging Face](https://sagemaker.readthedocs.io/en/stable/frameworks/huggingface/index.html)
- [Deep Learning Container](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#huggingface-training-containers)
## Iperparametri
{hyperparameters}
## Utilizzo
from transformers import pipeline
summarizer = pipeline("summarization", model="philschmid/{model_name}")
conversation = '''Jeff: Posso addestrare un modello 🤗 Transformers su Amazon SageMaker?
Philipp: Certamente puoi utilizzare il nuovo Hugging Face Deep Learning Container.
Jeff: ok.
Jeff: e come posso iniziare?
Jeff: dove posso trovare la documentazione?
Philipp: ok, ok puoi trovare tutto qui. https://huggingface.co/blog/the-partnership-amazon-sagemaker-and-hugging-face
'''
nlp(conversation)
## Risultati
| chiave | valore |
| ------ | ------ |
{eval_table}
{test_table}
"""
# Genera la model card (todo: aggiungi più dati da Trainer)
model_card = MODEL_CARD_TEMPLATE.format(
model_name=f"{hyperparameters['model_name_or_path'].split('/')[1]}-{hyperparameters['dataset_name']}",
hyperparameters=json.dumps(hyperparameters, indent=4, sort_keys=True),
eval_table="\n".join(f"| {k} | {v} |" for k, v in eval_results.items()),
test_table="\n".join(f"| {k} | {v} |" for k, v in test_results.items()),
)
with open(f"{local_path}/README.md", "w") as f:
f.write(model_card)
Dopo aver ottenuto il nostro modello decompresso e la scheda del modello posizionati in my_bart_model
, possiamo utilizzare l’SDK huggingface_hub
per creare un repository e caricarlo su huggingface.co – oppure semplicemente andare su https://huggingface.co/new e creare un nuovo repository e caricarlo.
from getpass import getpass
from huggingface_hub import HfApi, Repository
hf_username = "philschmid" # il tuo nome utente su huggingface.co
hf_email = "[email protected]" # email utilizzata per il commit
repository_name = f"{hyperparameters['model_name_or_path'].split('/')[1]}-{hyperparameters['dataset_name']}" # nome del repository su huggingface.co
password = getpass("Inserisci la tua password:") # crea un prompt per l'inserimento della password
# ottieni il token hf
token = HfApi().login(username=hf_username, password=password)
# crea il repository
repo_url = HfApi().create_repo(token=token, name=repository_name, exist_ok=True)
# crea un'istanza di Repository
model_repo = Repository(use_auth_token=token,
clone_from=repo_url,
local_dir=local_path,
git_user=hf_username,
git_email=hf_email)
# carica il modello nell'hub
model_repo.push_to_hub()
Test di inferenza
Dopo aver caricato il nostro modello, possiamo accedervi su https://huggingface.co/{hf_username}/{repository_name}
print(f"https://huggingface.co/{hf_username}/{repository_name}")
E utilizzare il widget “Hosted Inference API” per testarlo.
https://huggingface.co/philschmid/bart-large-cnn-samsum