Transformers documentation

Esporta modelli 🤗 Transformers

You are viewing v4.26.0 version. A newer version v4.47.1 is available.
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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.

ONNX

Il progetto ONNX (Open Neural Network eXchange) 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:

  • 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:

pip install transformers[onnx]

Il pacchetto transformers.onnx può essere usato come modulo Python:

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:

python -m transformers.onnx --model=distilbert-base-uncased onnx/

che dovrebbe mostrare i seguenti log:

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 che supportano il lo standard ONNX. Ad esempio, possiamo caricare ed eseguire il modello con ONNX Runtime come segue:

>>> 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:

>>> 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 come segue:

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:

Pytorch
Hide Pytorch content
>>> 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:

python -m transformers.onnx --model=local-pt-checkpoint onnx/
TensorFlow
Hide TensorFlow content
>>> 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:

python -m transformers.onnx --model=local-tf-checkpoint onnx/

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:

>>> 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:

python -m transformers.onnx --model=distilbert-base-uncased-finetuned-sst-2-english \
                            --feature=sequence-classification onnx/

che visualizzerà i seguenti registri:

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.

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.

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 OnnxConfig
  • I modelli basati su decoder ereditano da OnnxConfigWithPast
  • I modelli encoder-decoder ereditano daOnnxSeq2SeqConfigWithPast

Un buon modo per implementare una configurazione ONNX personalizzata è guardare l’implementazione esistente nel file configuration_<model_name>.py di un’architettura simile.

Poiché DistilBERT è un modello basato su encoder, la sua configurazione eredita da OnnxConfig:

>>> 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.

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.

Dopo aver implementato una configurazione ONNX, è possibile istanziarla fornendo alla configurazione del modello base come segue:

>>> 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:

>>> print(onnx_config.default_onnx_opset)
11

È inoltre possibile visualizzare gli output associati al modello come segue:

>>> 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:

>>> 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'})])

Tutte le proprietà e i metodi di base associati a OnnxConfig e le altre classi di configurazione possono essere sovrascritte se necessario. Guarda BartOnnxConfig per un esempio avanzato.

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:

>>> 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:

>>> import onnx

>>> onnx_model = onnx.load("model.onnx")
>>> onnx.checker.check_model(onnx_model)

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 per memorizzare il modello e questi hanno un limite di dimensione 2 GB. Vedi la Documentazione ONNX per istruzioni su come caricare modelli con dati esterni.

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:

>>> 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

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.

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 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

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.

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__:

traced_model(tokens_tensor, segments_tensors)

###Implementare modelli HuggingFace TorchScript su AWS utilizzando Neuron SDK

AWS ha introdotto Amazon EC2 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 è 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
  3. Supporto per i modelli di trasformatori HuggingFace costruiti con PyTorch o TensorFlow.

Implicazioni

Modelli Transformers basati su architettura BERT (Bidirectional Encoder Representations from Transformers), o sue varianti come distilBERT e 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. Ulteriori informazioni sui modelli che possono essere convertiti fuori dagli schemi su Inferentia possono essere trovati nella sezione Model Architecture Fit della documentazione Neuron.

Dipendenze

L’utilizzo di AWS Neuron per convertire i modelli richiede le seguenti dipendenze e l’ambiente:

Convertire un modello per AWS Neuron

Usando lo stesso script come in Usando TorchScipt in Python per tracciare un “BertModel”, importi l’estensione del framework torch.neuron per accedere i componenti di Neuron SDK tramite un’API Python.

from transformers import BertModel, BertTokenizer, BertConfig
import torch
import torch.neuron

E modificare solo la riga di codice di traccia

Da:

torch.jit.trace(model, [tokens_tensor, segments_tensors])

A:

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.