Spaces:
Runtime error
Runtime error
<!--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. | |
--> | |
# 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). |