Spaces:
Paused
Paused
| <!--Copyright 2020 The HuggingFace Team. All rights reserved. | |
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | |
| the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | |
| an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
| specific language governing permissions and limitations under the License. | |
| ⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be | |
| rendered properly in your Markdown viewer. | |
| --> | |
| # Esporta modelli 🤗 Transformers | |
| Se devi implementare 🤗 modelli Transformers in ambienti di produzione, noi | |
| consigliamo di esportarli in un formato serializzato che può essere caricato ed eseguito | |
| su runtime e hardware specializzati. In questa guida ti mostreremo come farlo | |
| esporta 🤗 Modelli Transformers in due formati ampiamente utilizzati: ONNX e TorchScript. | |
| Una volta esportato, un modello può essere ottimizato per l'inferenza tramite tecniche come | |
| la quantizzazione e soppressione. Se sei interessato a ottimizzare i tuoi modelli per l'esecuzione | |
| con la massima efficienza, dai un'occhiata a [🤗 Optimum | |
| library](https://github.com/huggingface/optimum). | |
| ## ONNX | |
| Il progetto [ONNX (Open Neural Network eXchange)](http://onnx.ai) Il progetto onnx è un open | |
| standard che definisce un insieme comune di operatori e un formato di file comune a | |
| rappresentano modelli di deep learning in un'ampia varietà di framework, tra cui | |
| PyTorch e TensorFlow. Quando un modello viene esportato nel formato ONNX, questi | |
| operatori sono usati per costruire un grafico computazionale (often called an | |
| _intermediate representation_) che rappresenta il flusso di dati attraverso la | |
| rete neurale. | |
| Esponendo un grafico con operatori e tipi di dati standardizzati, ONNX rende | |
| più facile passare da un framework all'altro. Ad esempio, un modello allenato in PyTorch può | |
| essere esportato in formato ONNX e quindi importato in TensorFlow (e viceversa). | |
| 🤗 Transformers fornisce un pacchetto `transformers.onnx` che ti consente di | |
| convertire i checkpoint del modello in un grafico ONNX sfruttando gli oggetti di configurazione. | |
| Questi oggetti di configurazione sono già pronti per una serie di architetture di modelli, | |
| e sono progettati per essere facilmente estensibili ad altre architetture. | |
| Le configurazioni pronte includono le seguenti architetture: | |
| <!--This table is automatically generated by `make fix-copies`, do not fill manually!--> | |
| - ALBERT | |
| - BART | |
| - BEiT | |
| - BERT | |
| - BigBird | |
| - BigBird-Pegasus | |
| - Blenderbot | |
| - BlenderbotSmall | |
| - CamemBERT | |
| - ConvBERT | |
| - Data2VecText | |
| - Data2VecVision | |
| - DeiT | |
| - DistilBERT | |
| - ELECTRA | |
| - FlauBERT | |
| - GPT Neo | |
| - GPT-J | |
| - I-BERT | |
| - LayoutLM | |
| - M2M100 | |
| - Marian | |
| - mBART | |
| - MobileBERT | |
| - OpenAI GPT-2 | |
| - Perceiver | |
| - PLBart | |
| - RoBERTa | |
| - RoFormer | |
| - SqueezeBERT | |
| - T5 | |
| - ViT | |
| - XLM | |
| - XLM-RoBERTa | |
| - XLM-RoBERTa-XL | |
| Nelle prossime due sezioni, ti mostreremo come: | |
| * Esporta un modello supportato usando il pacchetto `transformers.onnx`. | |
| * Esporta un modello personalizzato per un'architettura non supportata. | |
| ### Esportazione di un modello in ONNX | |
| Per esportare un modello 🤗 Transformers in ONNX, dovrai prima installarne alcune | |
| dipendenze extra: | |
| ```bash | |
| pip install transformers[onnx] | |
| ``` | |
| Il pacchetto `transformers.onnx` può essere usato come modulo Python: | |
| ```bash | |
| python -m transformers.onnx --help | |
| usage: Hugging Face Transformers ONNX exporter [-h] -m MODEL [--feature {causal-lm, ...}] [--opset OPSET] [--atol ATOL] output | |
| positional arguments: | |
| output Path indicating where to store generated ONNX model. | |
| optional arguments: | |
| -h, --help show this help message and exit | |
| -m MODEL, --model MODEL | |
| Model ID on huggingface.co or path on disk to load model from. | |
| --feature {causal-lm, ...} | |
| The type of features to export the model with. | |
| --opset OPSET ONNX opset version to export the model with. | |
| --atol ATOL Absolute difference tolerance when validating the model. | |
| ``` | |
| L'esportazione di un checkpoint utilizzando una configurazione già pronta può essere eseguita come segue: | |
| ```bash | |
| python -m transformers.onnx --model=distilbert-base-uncased onnx/ | |
| ``` | |
| che dovrebbe mostrare i seguenti log: | |
| ```bash | |
| Validating ONNX model... | |
| -[✓] ONNX model output names match reference model ({'last_hidden_state'}) | |
| - Validating ONNX Model output "last_hidden_state": | |
| -[✓] (2, 8, 768) matches (2, 8, 768) | |
| -[✓] all values close (atol: 1e-05) | |
| All good, model saved at: onnx/model.onnx | |
| ``` | |
| Questo esporta un grafico ONNX del checkpoint definito dall'argomento `--model`. | |
| In questo esempio è `distilbert-base-uncased`, ma può essere qualsiasi checkpoint | |
| Hugging Face Hub o uno memorizzato localmente. | |
| Il file risultante `model.onnx` può quindi essere eseguito su uno dei [tanti | |
| acceleratori](https://onnx.ai/supported-tools.html#deployModel) che supportano il | |
| lo standard ONNX. Ad esempio, possiamo caricare ed eseguire il modello con [ONNX | |
| Runtime](https://onnxruntime.ai/) come segue: | |
| ```python | |
| >>> from transformers import AutoTokenizer | |
| >>> from onnxruntime import InferenceSession | |
| >>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased") | |
| >>> session = InferenceSession("onnx/model.onnx") | |
| >>> # ONNX Runtime expects NumPy arrays as input | |
| >>> inputs = tokenizer("Using DistilBERT with ONNX Runtime!", return_tensors="np") | |
| >>> outputs = session.run(output_names=["last_hidden_state"], input_feed=dict(inputs)) | |
| ``` | |
| I nomi di output richiesti (cioè `["last_hidden_state"]`) possono essere ottenuti | |
| dando un'occhiata alla configurazione ONNX di ogni modello. Ad esempio, per | |
| DistilBERT abbiamo: | |
| ```python | |
| >>> from transformers.models.distilbert import DistilBertConfig, DistilBertOnnxConfig | |
| >>> config = DistilBertConfig() | |
| >>> onnx_config = DistilBertOnnxConfig(config) | |
| >>> print(list(onnx_config.outputs.keys())) | |
| ["last_hidden_state"] | |
| ``` | |
| Il processo è identico per i checkpoint TensorFlow sull'hub. Ad esempio, noi | |
| possiamo esportare un checkpoint TensorFlow puro da [Keras | |
| organizzazione](https://huggingface.co/keras-io) come segue: | |
| ```bash | |
| python -m transformers.onnx --model=keras-io/transformers-qa onnx/ | |
| ``` | |
| Per esportare un modello memorizzato localmente, devi disporre dei pesi del modello | |
| e file tokenizer memorizzati in una directory. Ad esempio, possiamo caricare e salvare un | |
| checkpoint come segue: | |
| <frameworkcontent> | |
| <pt> | |
| ```python | |
| >>> from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
| >>> # Load tokenizer and PyTorch weights form the Hub | |
| >>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased") | |
| >>> pt_model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased") | |
| >>> # Save to disk | |
| >>> tokenizer.save_pretrained("local-pt-checkpoint") | |
| >>> pt_model.save_pretrained("local-pt-checkpoint") | |
| ``` | |
| Una volta salvato il checkpoint, possiamo esportarlo su ONNX puntando l'argomento `--model` | |
| del pacchetto `transformers.onnx` nella directory desiderata: | |
| ```bash | |
| python -m transformers.onnx --model=local-pt-checkpoint onnx/ | |
| ``` | |
| </pt> | |
| <tf> | |
| ```python | |
| >>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification | |
| >>> # Load tokenizer and TensorFlow weights from the Hub | |
| >>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased") | |
| >>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased") | |
| >>> # Save to disk | |
| >>> tokenizer.save_pretrained("local-tf-checkpoint") | |
| >>> tf_model.save_pretrained("local-tf-checkpoint") | |
| ``` | |
| Once the checkpoint is saved, we can export it to ONNX by pointing the `--model` | |
| argument of the `transformers.onnx` package to the desired directory: | |
| ```bash | |
| python -m transformers.onnx --model=local-tf-checkpoint onnx/ | |
| ``` | |
| </tf> | |
| </frameworkcontent> | |
| ### Selezione delle caratteristiche per diverse topologie di modello | |
| Ogni configurazione già pronta viene fornita con una serie di _caratteristiche_ che ti consentono di | |
| esportare modelli per diversi tipi di topologie o attività. Come mostrato nella tabella | |
| di seguito, ogni caratteristica è associata a una diversa Auto Class: | |
| | Caratteristica | Auto Class | | |
| | ------------------------------------ | ------------------------------------ | | |
| | `causal-lm`, `causal-lm-with-past` | `AutoModelForCausalLM` | | |
| | `default`, `default-with-past` | `AutoModel` | | |
| | `masked-lm` | `AutoModelForMaskedLM` | | |
| | `question-answering` | `AutoModelForQuestionAnswering` | | |
| | `seq2seq-lm`, `seq2seq-lm-with-past` | `AutoModelForSeq2SeqLM` | | |
| | `sequence-classification` | `AutoModelForSequenceClassification` | | |
| | `token-classification` | `AutoModelForTokenClassification` | | |
| Per ciascuna configurazione, puoi trovare l'elenco delle funzionalità supportate tramite il | |
| `FeaturesManager`. Ad esempio, per DistilBERT abbiamo: | |
| ```python | |
| >>> from transformers.onnx.features import FeaturesManager | |
| >>> distilbert_features = list(FeaturesManager.get_supported_features_for_model_type("distilbert").keys()) | |
| >>> print(distilbert_features) | |
| ["default", "masked-lm", "causal-lm", "sequence-classification", "token-classification", "question-answering"] | |
| ``` | |
| Puoi quindi passare una di queste funzionalità all'argomento `--feature` nel | |
| pacchetto `transformers.onnx`. Ad esempio, per esportare un modello di classificazione del testo | |
| possiamo scegliere un modello ottimizzato dall'Hub ed eseguire: | |
| ```bash | |
| python -m transformers.onnx --model=distilbert-base-uncased-finetuned-sst-2-english \ | |
| --feature=sequence-classification onnx/ | |
| ``` | |
| che visualizzerà i seguenti registri: | |
| ```bash | |
| Validating ONNX model... | |
| -[✓] ONNX model output names match reference model ({'logits'}) | |
| - Validating ONNX Model output "logits": | |
| -[✓] (2, 2) matches (2, 2) | |
| -[✓] all values close (atol: 1e-05) | |
| All good, model saved at: onnx/model.onnx | |
| ``` | |
| Puoi notare che in questo caso, i nomi di output del modello ottimizzato sono | |
| `logits` invece di `last_hidden_state` che abbiamo visto con il | |
| checkpoint `distilbert-base-uncased` precedente. Questo è previsto dal | |
| modello ottimizato visto che ha una testa di e. | |
| <Tip> | |
| Le caratteristiche che hanno un suffisso `wtih-past` (ad es. `causal-lm-with-past`) | |
| corrispondono a topologie di modello con stati nascosti precalcolati (chiave e valori | |
| nei blocchi di attenzione) che possono essere utilizzati per la decodifica autoregressiva veloce. | |
| </Tip> | |
| ### Esportazione di un modello per un'architettura non supportata | |
| Se desideri esportare un modello la cui architettura non è nativamente supportata dalla | |
| libreria, ci sono tre passaggi principali da seguire: | |
| 1. Implementare una configurazione ONNX personalizzata. | |
| 2. Esportare il modello in ONNX. | |
| 3. Convalidare gli output di PyTorch e dei modelli esportati. | |
| In questa sezione, vedremo come DistilBERT è stato implementato per mostrare cosa è | |
| coinvolto in ogni passaggio. | |
| #### Implementazione di una configurazione ONNX personalizzata | |
| Iniziamo con l'oggetto di configurazione ONNX. Forniamo tre classi | |
| astratte da cui ereditare, a seconda del tipo di archittettura | |
| del modello che desideri esportare: | |
| * I modelli basati su encoder ereditano da [`~onnx.config.OnnxConfig`] | |
| * I modelli basati su decoder ereditano da [`~onnx.config.OnnxConfigWithPast`] | |
| * I modelli encoder-decoder ereditano da[`~onnx.config.OnnxSeq2SeqConfigWithPast`] | |
| <Tip> | |
| Un buon modo per implementare una configurazione ONNX personalizzata è guardare l'implementazione | |
| esistente nel file `configuration_<model_name>.py` di un'architettura simile. | |
| </Tip> | |
| Poiché DistilBERT è un modello basato su encoder, la sua configurazione eredita da | |
| `OnnxConfig`: | |
| ```python | |
| >>> from typing import Mapping, OrderedDict | |
| >>> from transformers.onnx import OnnxConfig | |
| >>> class DistilBertOnnxConfig(OnnxConfig): | |
| ... @property | |
| ... def inputs(self) -> Mapping[str, Mapping[int, str]]: | |
| ... return OrderedDict( | |
| ... [ | |
| ... ("input_ids", {0: "batch", 1: "sequence"}), | |
| ... ("attention_mask", {0: "batch", 1: "sequence"}), | |
| ... ] | |
| ... ) | |
| ``` | |
| Ogni oggetto di configurazione deve implementare la proprietà `inputs` e restituire una | |
| mappatura, dove ogni chiave corrisponde a un input previsto e ogni valore | |
| indica l'asse di quell'input. Per DistilBERT, possiamo vedere che sono richiesti | |
| due input: `input_ids` e `attention_mask`. Questi inputs hanno la stessa forma di | |
| `(batch_size, sequence_length)` per questo motivo vediamo gli stessi assi usati nella | |
| configurazione. | |
| <Tip> | |
| Puoi notare che la proprietà `inputs` per `DistilBertOnnxConfig` restituisce un | |
| `OrdinatoDict`. Ciò garantisce che gli input corrispondano alla loro posizione | |
| relativa all'interno del metodo `PreTrainedModel.forward()` durante il tracciamento del grafico. | |
| Raccomandiamo di usare un `OrderedDict` per le proprietà `inputs` e `outputs` | |
| quando si implementano configurazioni ONNX personalizzate. | |
| </Tip> | |
| Dopo aver implementato una configurazione ONNX, è possibile istanziarla | |
| fornendo alla configurazione del modello base come segue: | |
| ```python | |
| >>> from transformers import AutoConfig | |
| >>> config = AutoConfig.from_pretrained("distilbert-base-uncased") | |
| >>> onnx_config = DistilBertOnnxConfig(config) | |
| ``` | |
| L'oggetto risultante ha diverse proprietà utili. Ad esempio è possibile visualizzare il | |
| Set operatore ONNX che verrà utilizzato durante l'esportazione: | |
| ```python | |
| >>> print(onnx_config.default_onnx_opset) | |
| 11 | |
| ``` | |
| È inoltre possibile visualizzare gli output associati al modello come segue: | |
| ```python | |
| >>> print(onnx_config.outputs) | |
| OrderedDict([("last_hidden_state", {0: "batch", 1: "sequence"})]) | |
| ``` | |
| Puoi notare che la proprietà degli output segue la stessa struttura degli input; esso | |
| restituisce un `OrderedDict` di output con nome e le loro forme. La struttura di output | |
| è legato alla scelta della funzione con cui viene inizializzata la configurazione. | |
| Per impostazione predefinita, la configurazione ONNX viene inizializzata con la funzione 'predefinita' | |
| che corrisponde all'esportazione di un modello caricato con la classe `AutoModel`. Se tu | |
| desideri esportare una topologia di modello diversa, è sufficiente fornire una funzionalità diversa a | |
| l'argomento `task` quando inizializzi la configurazione ONNX. Ad esempio, se | |
| volevamo esportare DistilBERT con una testa di classificazione per sequenze, potremmo | |
| usare: | |
| ```python | |
| >>> from transformers import AutoConfig | |
| >>> config = AutoConfig.from_pretrained("distilbert-base-uncased") | |
| >>> onnx_config_for_seq_clf = DistilBertOnnxConfig(config, task="sequence-classification") | |
| >>> print(onnx_config_for_seq_clf.outputs) | |
| OrderedDict([('logits', {0: 'batch'})]) | |
| ``` | |
| <Tip> | |
| Tutte le proprietà e i metodi di base associati a [`~onnx.config.OnnxConfig`] e le | |
| altre classi di configurazione possono essere sovrascritte se necessario. Guarda | |
| [`BartOnnxConfig`] per un esempio avanzato. | |
| </Tip> | |
| #### Esportazione del modello | |
| Una volta implementata la configurazione ONNX, il passaggio successivo consiste nell'esportare il | |
| modello. Qui possiamo usare la funzione `export()` fornita dal | |
| pacchetto `transformers.onnx`. Questa funzione prevede la configurazione ONNX, insieme | |
| con il modello base e il tokenizer e il percorso per salvare il file esportato: | |
| ```python | |
| >>> from pathlib import Path | |
| >>> from transformers.onnx import export | |
| >>> from transformers import AutoTokenizer, AutoModel | |
| >>> onnx_path = Path("model.onnx") | |
| >>> model_ckpt = "distilbert-base-uncased" | |
| >>> base_model = AutoModel.from_pretrained(model_ckpt) | |
| >>> tokenizer = AutoTokenizer.from_pretrained(model_ckpt) | |
| >>> onnx_inputs, onnx_outputs = export(tokenizer, base_model, onnx_config, onnx_config.default_onnx_opset, onnx_path) | |
| ``` | |
| Gli `onnx_inputs` e `onnx_outputs` restituiti dalla funzione `export()` sono | |
| liste di chiavi definite nelle proprietà di `input` e `output` della | |
| configurazione. Una volta esportato il modello, puoi verificare che il modello sia ben | |
| formato come segue: | |
| ```python | |
| >>> import onnx | |
| >>> onnx_model = onnx.load("model.onnx") | |
| >>> onnx.checker.check_model(onnx_model) | |
| ``` | |
| <Tip> | |
| Se il tuo modello è più largo di 2 GB, vedrai che molti file aggiuntivi sono | |
| creati durante l'esportazione. Questo è _previsto_ perché ONNX utilizza [Protocol | |
| Buffer](https://developers.google.com/protocol-buffers/) per memorizzare il modello e | |
| questi hanno un limite di dimensione 2 GB. Vedi la [Documentazione | |
| ONNX](https://github.com/onnx/onnx/blob/master/docs/ExternalData.md) | |
| per istruzioni su come caricare modelli con dati esterni. | |
| </Tip> | |
| #### Convalida degli output del modello | |
| Il passaggio finale consiste nel convalidare gli output dal modello di base e quello esportato | |
| corrispondere entro una soglia di tolleranza assoluta. Qui possiamo usare la | |
| Funzione `validate_model_outputs()` fornita dal pacchetto `transformers.onnx` | |
| come segue: | |
| ```python | |
| >>> from transformers.onnx import validate_model_outputs | |
| >>> validate_model_outputs( | |
| ... onnx_config, tokenizer, base_model, onnx_path, onnx_outputs, onnx_config.atol_for_validation | |
| ... ) | |
| ``` | |
| Questa funzione usa il metodo `OnnxConfig.generate_dummy_inputs()` per generare | |
| input per il modello di base e quello esportato e la tolleranza assoluta può essere | |
| definita nella configurazione. Generalmente troviamo una corrispondenza numerica nell'intervallo da 1e-6 | |
| a 1e-4, anche se è probabile che qualsiasi cosa inferiore a 1e-3 vada bene. | |
| ### Contribuire con una nuova configurazione a 🤗 Transformers | |
| Stiamo cercando di espandere l'insieme di configurazioni già pronte e di accettare | |
| contributi della community! Se vuoi contribuire con la tua aggiunta | |
| nella libreria, dovrai: | |
| * Implementare la configurazione ONNX nella corrispondente `configuration file | |
| _<model_name>.py` | |
| * Includere l'architettura del modello e le funzioni corrispondenti in [`~onnx.features.FeatureManager`] | |
| * Aggiungere la tua architettura del modello ai test in `test_onnx_v2.py` | |
| Scopri come stato contribuito la configurazione per [IBERT] | |
| (https://github.com/huggingface/transformers/pull/14868/files) per | |
| avere un'idea di cosa è coinvolto. | |
| ## TorchScript | |
| <Tip> | |
| Questo è l'inizio dei nostri esperimenti con TorchScript e stiamo ancora esplorando le sue capacità con | |
| modelli con variable-input-size. È una nostra priorità e approfondiremo le nostre analisi nelle prossime versioni, | |
| con più esempi di codici, un'implementazione più flessibile e benchmark che confrontano i codici basati su Python con quelli compilati con | |
| TorchScript. | |
| </Tip> | |
| Secondo la documentazione di Pytorch: "TorchScript è un modo per creare modelli serializzabili e ottimizzabili da codice | |
| Pytorch". I due moduli di Pytorch [JIT e TRACE](https://pytorch.org/docs/stable/jit.html) consentono allo sviluppatore di esportare | |
| il loro modello da riutilizzare in altri programmi, come i programmi C++ orientati all'efficienza. | |
| Abbiamo fornito un'interfaccia che consente l'esportazione di modelli 🤗 Transformers in TorchScript in modo che possano essere riutilizzati | |
| in un ambiente diverso rispetto a un programma Python basato su Pytorch. Qui spieghiamo come esportare e utilizzare i nostri modelli utilizzando | |
| TorchScript. | |
| Esportare un modello richiede due cose: | |
| - Un passaggio in avanti con input fittizzi. | |
| - Istanziazione del modello con flag `torchscript`. | |
| Queste necessità implicano diverse cose a cui gli sviluppatori dovrebbero prestare attenzione. Questi dettagli mostrati sotto. | |
| ### Flag TorchScript e pesi legati | |
| Questo flag è necessario perché la maggior parte dei modelli linguistici in questo repository hanno pesi legati tra il loro | |
| strato "Embedding" e lo strato "Decoding". TorchScript non consente l'esportazione di modelli che hanno pesi | |
| legati, quindi è necessario prima slegare e clonare i pesi. | |
| Ciò implica che i modelli istanziati con il flag `torchscript` hanno il loro strato `Embedding` e strato `Decoding` | |
| separato, il che significa che non dovrebbero essere addestrati in futuro. L'allenamento de-sincronizza i due | |
| strati, portando a risultati inaspettati. | |
| Questo non è il caso per i modelli che non hanno una testa del modello linguistico, poiché quelli non hanno pesi legati. Questi modelli | |
| può essere esportato in sicurezza senza il flag `torchscript`. | |
| ### Input fittizi e standard lengths | |
| Gli input fittizzi sono usati per fare un modello passaggio in avanti . Mentre i valori degli input si propagano attraverso i strati, | |
| Pytorch tiene traccia delle diverse operazioni eseguite su ciascun tensore. Queste operazioni registrate vengono quindi utilizzate per | |
| creare la "traccia" del modello. | |
| La traccia viene creata relativamente alle dimensioni degli input. È quindi vincolato dalle dimensioni dell'input | |
| fittizio e non funzionerà per altre lunghezze di sequenza o dimensioni batch. Quando si proverà con una dimensione diversa, ci sarà errore | |
| come: | |
| `La dimensione espansa del tensore (3) deve corrispondere alla dimensione esistente (7) nella dimensione non singleton 2` | |
| will be raised. Si consiglia pertanto di tracciare il modello con una dimensione di input fittizia grande almeno quanto il più grande | |
| input che verrà fornito al modello durante l'inferenza. È possibile eseguire il padding per riempire i valori mancanti. Il modello | |
| sarà tracciato con una grande dimensione di input, tuttavia, anche le dimensioni della diverse matrici saranno grandi, | |
| risultando in più calcoli. | |
| Si raccomanda di prestare attenzione al numero totale di operazioni eseguite su ciascun input e di seguire da vicino le prestazioni | |
| durante l'esportazione di modelli di sequenza-lunghezza variabili. | |
| ### Usare TorchSscript in Python | |
| Di seguito è riportato un esempio, che mostra come salvare, caricare modelli e come utilizzare la traccia per l'inferenza. | |
| #### Salvare un modello | |
| Questo frammento di codice mostra come usare TorchScript per esportare un `BertModel`. Qui il `BertModel` è istanziato secondo | |
| una classe `BertConfig` e quindi salvato su disco con il nome del file `traced_bert.pt` | |
| ```python | |
| from transformers import BertModel, BertTokenizer, BertConfig | |
| import torch | |
| enc = BertTokenizer.from_pretrained("bert-base-uncased") | |
| # Tokenizing input text | |
| text = "[CLS] Who was Jim Henson ? [SEP] Jim Henson was a puppeteer [SEP]" | |
| tokenized_text = enc.tokenize(text) | |
| # Masking one of the input tokens | |
| masked_index = 8 | |
| tokenized_text[masked_index] = "[MASK]" | |
| indexed_tokens = enc.convert_tokens_to_ids(tokenized_text) | |
| segments_ids = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1] | |
| # Creating a dummy input | |
| tokens_tensor = torch.tensor([indexed_tokens]) | |
| segments_tensors = torch.tensor([segments_ids]) | |
| dummy_input = [tokens_tensor, segments_tensors] | |
| # Initializing the model with the torchscript flag | |
| # Flag set to True even though it is not necessary as this model does not have an LM Head. | |
| config = BertConfig( | |
| vocab_size_or_config_json_file=32000, | |
| hidden_size=768, | |
| num_hidden_layers=12, | |
| num_attention_heads=12, | |
| intermediate_size=3072, | |
| torchscript=True, | |
| ) | |
| # Instantiating the model | |
| model = BertModel(config) | |
| # The model needs to be in evaluation mode | |
| model.eval() | |
| # If you are instantiating the model with *from_pretrained* you can also easily set the TorchScript flag | |
| model = BertModel.from_pretrained("bert-base-uncased", torchscript=True) | |
| # Creating the trace | |
| traced_model = torch.jit.trace(model, [tokens_tensor, segments_tensors]) | |
| torch.jit.save(traced_model, "traced_bert.pt") | |
| ``` | |
| #### Caricare un modello | |
| Questo frammento di codice mostra come caricare il `BertModel` che era stato precedentemente salvato su disco con il nome `traced_bert.pt`. | |
| Stiamo riutilizzando il `dummy_input` precedentemente inizializzato. | |
| ```python | |
| loaded_model = torch.jit.load("traced_bert.pt") | |
| loaded_model.eval() | |
| all_encoder_layers, pooled_output = loaded_model(*dummy_input) | |
| ``` | |
| #### Utilizzare un modello tracciato per l'inferenza | |
| Usare il modello tracciato per l'inferenza è semplice come usare il suo metodo dunder `__call__`: | |
| ```python | |
| traced_model(tokens_tensor, segments_tensors) | |
| ``` | |
| ###Implementare modelli HuggingFace TorchScript su AWS utilizzando Neuron SDK | |
| AWS ha introdotto [Amazon EC2 Inf1](https://aws.amazon.com/ec2/instance-types/inf1/) | |
| famiglia di istanze per l'inferenza di machine learning a basso costo e ad alte prestazioni nel cloud. | |
| Le istanze Inf1 sono alimentate dal chip AWS Inferentia, un acceleratore hardware personalizzato, | |
| specializzato in carichi di lavoro di inferenza di deep learning. | |
| [AWS Neuron](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/#) | |
| è l'SDK per Inferentia che supporta il tracciamento e l'ottimizzazione dei modelli transformers per | |
| distribuzione su Inf1. L'SDK Neuron fornisce: | |
| 1. API di facile utilizzo con una riga di modifica del codice per tracciare e ottimizzare un modello TorchScript per l'inferenza nel cloud. | |
| 2. Ottimizzazioni delle prestazioni pronte all'uso per [miglioramento dei costi-prestazioni](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/benchmark/>) | |
| 3. Supporto per i modelli di trasformatori HuggingFace costruiti con [PyTorch](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/src/examples/pytorch/bert_tutorial/tutorial_pretrained_bert.html) | |
| o [TensorFlow](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/src/examples/tensorflow/huggingface_bert/huggingface_bert.html). | |
| #### Implicazioni | |
| Modelli Transformers basati su architettura [BERT (Bidirectional Encoder Representations from Transformers)](https://huggingface.co/docs/transformers/main/model_doc/bert), | |
| o sue varianti come [distilBERT](https://huggingface.co/docs/transformers/main/model_doc/distilbert) | |
| e [roBERTa](https://huggingface.co/docs/transformers/main/model_doc/roberta) | |
| funzioneranno meglio su Inf1 per attività non generative come la question answering estrattive, | |
| Classificazione della sequenza, Classificazione dei token. In alternativa, generazione di testo | |
| le attività possono essere adattate per essere eseguite su Inf1, secondo questo [tutorial AWS Neuron MarianMT](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/src/examples/pytorch/transformers-marianmt.html). | |
| Ulteriori informazioni sui modelli che possono essere convertiti fuori dagli schemi su Inferentia possono essere | |
| trovati nella [sezione Model Architecture Fit della documentazione Neuron](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/models/models-inferentia.html#models-inferentia). | |
| #### Dipendenze | |
| L'utilizzo di AWS Neuron per convertire i modelli richiede le seguenti dipendenze e l'ambiente: | |
| * A [Neuron SDK environment](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/pytorch-neuron/index.html#installation-guide), | |
| which comes pre-configured on [AWS Deep Learning AMI](https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-inferentia-launching.html). | |
| #### Convertire un modello per AWS Neuron | |
| Usando lo stesso script come in [Usando TorchScipt in Python](https://huggingface.co/docs/transformers/main/en/serialization#using-torchscript-in-python) | |
| per tracciare un "BertModel", importi l'estensione del framework `torch.neuron` per accedere | |
| i componenti di Neuron SDK tramite un'API Python. | |
| ```python | |
| from transformers import BertModel, BertTokenizer, BertConfig | |
| import torch | |
| import torch.neuron | |
| ``` | |
| E modificare solo la riga di codice di traccia | |
| Da: | |
| ```python | |
| torch.jit.trace(model, [tokens_tensor, segments_tensors]) | |
| ``` | |
| A: | |
| ```python | |
| torch.neuron.trace(model, [token_tensor, segments_tensors]) | |
| ``` | |
| Questa modifica consente a Neuron SDK di tracciare il modello e ottimizzarlo per l'esecuzione nelle istanze Inf1. | |
| Per ulteriori informazioni sulle funzionalità, gli strumenti, i tutorial di esempi e gli ultimi aggiornamenti di AWS Neuron SDK, | |
| consultare la [documentazione AWS NeuronSDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/index.html). |