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. | |
| --> | |
| # Exportar modelos 🤗 Transformers | |
| Si necesitas implementar modelos 🤗 Transformers en entornos de producción, te | |
| recomendamos exportarlos a un formato serializado que se pueda cargar y ejecutar | |
| en tiempos de ejecución y hardware especializados. En esta guía, te mostraremos cómo | |
| exportar modelos 🤗 Transformers en dos formatos ampliamente utilizados: ONNX y TorchScript. | |
| Una vez exportado, un modelo puede optimizarse para la inferencia a través de técnicas | |
| como la cuantización y _pruning_. Si estás interesado en optimizar tus modelos para | |
| que funcionen con la máxima eficiencia, consulta la | |
| [biblioteca de 🤗 Optimum](https://github.com/huggingface/optimum). | |
| ## ONNX | |
| El proyecto [ONNX (Open Neural Network eXchange)](http://onnx.ai) es un | |
| estándar abierto que define un conjunto común de operadores y un formato | |
| de archivo común para representar modelos de aprendizaje profundo en una | |
| amplia variedad de _frameworks_, incluidos PyTorch y TensorFlow. Cuando un modelo | |
| se exporta al formato ONNX, estos operadores se usan para construir un | |
| grafo computacional (a menudo llamado _representación intermedia_) que | |
| representa el flujo de datos a través de la red neuronal. | |
| Al exponer un grafo con operadores y tipos de datos estandarizados, ONNX facilita | |
| el cambio entre frameworks. Por ejemplo, un modelo entrenado en PyTorch se puede | |
| exportar a formato ONNX y luego importar en TensorFlow (y viceversa). | |
| 🤗 Transformers proporciona un paquete llamado `transformers.onnx`, el cual permite convertir | |
| los checkpoints de un modelo en un grafo ONNX aprovechando los objetos de configuración. | |
| Estos objetos de configuración están hechos a la medida de diferentes arquitecturas de modelos | |
| y están diseñados para ser fácilmente extensibles a otras arquitecturas. | |
| Las configuraciones a la medida incluyen las siguientes arquitecturas: | |
| <!--This table is automatically generated by `make fix-copies`, do not fill manually!--> | |
| - ALBERT | |
| - BART | |
| - BEiT | |
| - BERT | |
| - BigBird | |
| - BigBird-Pegasus | |
| - Blenderbot | |
| - BlenderbotSmall | |
| - BLOOM | |
| - CamemBERT | |
| - CLIP | |
| - CodeGen | |
| - ConvBERT | |
| - ConvNeXT | |
| - ConvNeXTV2 | |
| - Data2VecText | |
| - Data2VecVision | |
| - DeBERTa | |
| - DeBERTa-v2 | |
| - DeiT | |
| - DETR | |
| - DistilBERT | |
| - ELECTRA | |
| - FlauBERT | |
| - GPT Neo | |
| - GPT-J | |
| - I-BERT | |
| - LayoutLM | |
| - LayoutLMv3 | |
| - LeViT | |
| - LongT5 | |
| - M2M100 | |
| - Marian | |
| - mBART | |
| - MobileBERT | |
| - MobileViT | |
| - MT5 | |
| - OpenAI GPT-2 | |
| - Perceiver | |
| - PLBart | |
| - ResNet | |
| - RoBERTa | |
| - RoFormer | |
| - SqueezeBERT | |
| - T5 | |
| - ViT | |
| - XLM | |
| - XLM-RoBERTa | |
| - XLM-RoBERTa-XL | |
| - YOLOS | |
| En las próximas dos secciones, te mostraremos cómo: | |
| * Exportar un modelo compatible utilizando el paquete `transformers.onnx`. | |
| * Exportar un modelo personalizado para una arquitectura no compatible. | |
| ### Exportar un model a ONNX | |
| Para exportar un modelo 🤗 Transformers a ONNX, tienes que instalar primero algunas | |
| dependencias extra: | |
| ```bash | |
| pip install transformers[onnx] | |
| ``` | |
| El paquete `transformers.onnx` puede ser usado luego como un módulo de 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 tolerence when validating the model. | |
| ``` | |
| Exportar un checkpoint usando una configuración a la medida se puede hacer de la siguiente manera: | |
| ```bash | |
| python -m transformers.onnx --model=distilbert-base-uncased onnx/ | |
| ``` | |
| que debería mostrar los siguientes registros: | |
| ```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 | |
| ``` | |
| Esto exporta un grafo ONNX del checkpoint definido por el argumento `--model`. | |
| En este ejemplo, es un modelo `distilbert-base-uncased`, pero puede ser cualquier | |
| checkpoint en Hugging Face Hub o que esté almacenado localmente. | |
| El archivo `model.onnx` resultante se puede ejecutar en uno de los | |
| [muchos aceleradores](https://onnx.ai/supported-tools.html#deployModel) | |
| que admiten el estándar ONNX. Por ejemplo, podemos cargar y ejecutar el | |
| modelo con [ONNX Runtime](https://onnxruntime.ai/) de la siguiente manera: | |
| ```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)) | |
| ``` | |
| Los nombres necesarios de salida (es decir, `["last_hidden_state"]`) se pueden obtener | |
| echando un vistazo a la configuración ONNX de cada modelo. Por ejemplo, para DistilBERT tenemos: | |
| ```python | |
| >>> from transformers.models.distilbert import DistilBertConfig, DistilBertOnnxConfig | |
| >>> config = DistilBertConfig() | |
| >>> onnx_config = DistilBertOnnxConfig(config) | |
| >>> print(list(onnx_config.outputs.keys())) | |
| ["last_hidden_state"]s | |
| ``` | |
| El proceso es idéntico para los checkpoints de TensorFlow en Hub. | |
| Por ejemplo, podemos exportar un checkpoint puro de TensorFlow desde | |
| [Keras](https://huggingface.co/keras-io) de la siguiente manera: | |
| ```bash | |
| python -m transformers.onnx --model=keras-io/transformers-qa onnx/ | |
| ``` | |
| Para exportar un modelo que está almacenado localmente, deberás tener los pesos | |
| y tokenizadores del modelo almacenados en un directorio. Por ejemplo, podemos cargar | |
| y guardar un checkpoint de la siguiente manera: | |
| <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 vez que se guarda el checkpoint, podemos exportarlo a ONNX usando el argumento `--model` | |
| del paquete `transformers.onnx` al directorio deseado: | |
| ```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") | |
| ``` | |
| Una vez que se guarda el checkpoint, podemos exportarlo a ONNX usando el argumento `--model` | |
| del paquete `transformers.onnx` al directorio deseado: | |
| ```bash | |
| python -m transformers.onnx --model=local-tf-checkpoint onnx/ | |
| ``` | |
| </tf> | |
| </frameworkcontent> | |
| ### Seleccionar características para diferentes topologías de un modelo | |
| Cada configuración a la medida viene con un conjunto de _características_ que te permiten exportar | |
| modelos para diferentes tipos de topologías o tareas. Como se muestra en la siguiente tabla, cada | |
| función está asociada con una auto-clase de automóvil diferente: | |
| | Feature | 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` | | |
| Para cada configuración, puedes encontrar la lista de funciones admitidas a través de `FeaturesManager`. | |
| Por ejemplo, para DistilBERT tenemos: | |
| ```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"] | |
| ``` | |
| Le puedes pasar una de estas características al argumento `--feature` en el paquete `transformers.onnx`. | |
| Por ejemplo, para exportar un modelo de clasificación de texto, podemos elegir un modelo ya ajustado del Hub y ejecutar: | |
| ```bash | |
| python -m transformers.onnx --model=distilbert-base-uncased-finetuned-sst-2-english \ | |
| --feature=sequence-classification onnx/ | |
| ``` | |
| que mostrará los siguientes registros: | |
| ```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 | |
| ``` | |
| Ten en cuenta que, en este caso, los nombres de salida del modelo ajustado son `logits` en lugar de `last_hidden_state` | |
| que vimos anteriormente con el checkpoint `distilbert-base-uncased`. Esto es de esperarse ya que el modelo ajustado | |
| tiene un cabezal de clasificación secuencial. | |
| <Tip> | |
| Las características que tienen un sufijo 'with-past' (por ejemplo, 'causal-lm-with-past') corresponden a topologías | |
| de modelo con estados ocultos precalculados (clave y valores en los bloques de atención) que se pueden usar para una | |
| decodificación autorregresiva más rápida. | |
| </Tip> | |
| ### Exportar un modelo para una arquitectura no compatible | |
| Si deseas exportar un modelo cuya arquitectura no es compatible de forma nativa | |
| con la biblioteca, debes seguir tres pasos principales: | |
| 1. Implementa una configuración personalizada en ONNX. | |
| 2. Exporta el modelo a ONNX. | |
| 3. Valide los resultados de PyTorch y los modelos exportados. | |
| En esta sección, veremos cómo se implementó la serialización de DistilBERT | |
| para mostrar lo que implica cada paso. | |
| #### Implementar una configuración personalizada en ONNX | |
| Comencemos con el objeto de configuración de ONNX. Proporcionamos tres clases abstractas | |
| de las que debe heredar, según el tipo de arquitectura del modelo que quieras exportar: | |
| * Modelos basados en el _Encoder_ inherente de [`~onnx.config.OnnxConfig`] | |
| * Modelos basados en el _Decoder_ inherente de [`~onnx.config.OnnxConfigWithPast`] | |
| * Modelos _Encoder-decoder_ inherente de [`~onnx.config.OnnxSeq2SeqConfigWithPast`] | |
| <Tip> | |
| Una buena manera de implementar una configuración personalizada en ONNX es observar la implementación | |
| existente en el archivo `configuration_<model_name>.py` de una arquitectura similar. | |
| </Tip> | |
| Dado que DistilBERT es un modelo de tipo _encoder_, su configuración se hereda de `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"}), | |
| ... ] | |
| ... ) | |
| ``` | |
| Cada objeto de configuración debe implementar la propiedad `inputs` y devolver un mapeo, | |
| donde cada llave corresponde a una entrada esperada y cada valor indica el eje de esa entrada. | |
| Para DistilBERT, podemos ver que se requieren dos entradas: `input_ids` y `attention_mask`. | |
| Estas entradas tienen la misma forma de `(batch_size, sequence_length)`, es por lo que vemos | |
| los mismos ejes utilizados en la configuración. | |
| <Tip> | |
| Observa que la propiedad `inputs` para `DistilBertOnnxConfig` devuelve un `OrderedDict`. | |
| Esto nos asegura que las entradas coincidan con su posición relativa dentro del método | |
| `PreTrainedModel.forward()` al rastrear el grafo. Recomendamos usar un `OrderedDict` | |
| para las propiedades `inputs` y `outputs` al implementar configuraciones ONNX personalizadas. | |
| </Tip> | |
| Una vez que hayas implementado una configuración ONNX, puedes crear una | |
| instancia proporcionando la configuración del modelo base de la siguiente manera: | |
| ```python | |
| >>> from transformers import AutoConfig | |
| >>> config = AutoConfig.from_pretrained("distilbert-base-uncased") | |
| >>> onnx_config = DistilBertOnnxConfig(config) | |
| ``` | |
| El objeto resultante tiene varias propiedades útiles. Por ejemplo, puedes ver el conjunto de operadores ONNX que se | |
| utilizará durante la exportación: | |
| ```python | |
| >>> print(onnx_config.default_onnx_opset) | |
| 11 | |
| ``` | |
| También puedes ver los resultados asociados con el modelo de la siguiente manera: | |
| ```python | |
| >>> print(onnx_config.outputs) | |
| OrderedDict([("last_hidden_state", {0: "batch", 1: "sequence"})]) | |
| ``` | |
| Observa que la propiedad de salidas sigue la misma estructura que las entradas; | |
| devuelve un objecto `OrderedDict` de salidas nombradas y sus formas. La estructura | |
| de salida está vinculada a la elección de la función con la que se inicializa la configuración. | |
| Por defecto, la configuración de ONNX se inicializa con la función `default` que | |
| corresponde a exportar un modelo cargado con la clase `AutoModel`. Si quieres exportar | |
| una topología de modelo diferente, simplemente proporciona una característica diferente | |
| al argumento `task` cuando inicialices la configuración de ONNX. Por ejemplo, si quisiéramos | |
| exportar DistilBERT con un cabezal de clasificación de secuencias, podríamos usar: | |
| ```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> | |
| Todas las propiedades base y métodos asociados con [`~onnx.config.OnnxConfig`] y las | |
| otras clases de configuración se pueden sobreescribir si es necesario. | |
| Consulte [`BartOnnxConfig`] para ver un ejemplo avanzado. | |
| </Tip> | |
| #### Exportar el modelo | |
| Una vez que hayas implementado la configuración de ONNX, el siguiente paso es exportar el modelo. | |
| Aquí podemos usar la función `export()` proporcionada por el paquete `transformers.onnx`. | |
| Esta función espera la configuración de ONNX, junto con el modelo base y el tokenizador, | |
| y la ruta para guardar el archivo exportado: | |
| ```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) | |
| ``` | |
| Los objetos `onnx_inputs` y `onnx_outputs` devueltos por la función `export()` | |
| son listas de llaves definidas en las propiedades `inputs` y `outputs` de la configuración. | |
| Una vez exportado el modelo, puedes probar que el modelo está bien formado de la siguiente manera: | |
| ```python | |
| >>> import onnx | |
| >>> onnx_model = onnx.load("model.onnx") | |
| >>> onnx.checker.check_model(onnx_model) | |
| ``` | |
| <Tip> | |
| Si tu modelo tiene más de 2GB, verás que se crean muchos archivos adicionales durante la exportación. | |
| Esto es _esperado_ porque ONNX usa [Búferes de protocolo](https://developers.google.com/protocol-buffers/) | |
| para almacenar el modelo y éstos tienen un límite de tamaño de 2 GB. Consulta la | |
| [documentación de ONNX](https://github.com/onnx/onnx/blob/master/docs/ExternalData.md) para obtener | |
| instrucciones sobre cómo cargar modelos con datos externos. | |
| </Tip> | |
| #### Validar los resultados del modelo | |
| El paso final es validar que los resultados del modelo base y exportado coincidan dentro | |
| de cierta tolerancia absoluta. Aquí podemos usar la función `validate_model_outputs()` | |
| proporcionada por el paquete `transformers.onnx` de la siguiente manera: | |
| ```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 | |
| ... ) | |
| ``` | |
| Esta función usa el método `OnnxConfig.generate_dummy_inputs()` para generar entradas para el modelo base | |
| y exportado, y la tolerancia absoluta se puede definir en la configuración. En general, encontramos una | |
| concordancia numérica en el rango de 1e-6 a 1e-4, aunque es probable que cualquier valor menor que 1e-3 esté bien. | |
| ### Contribuir con una nueva configuración a 🤗 Transformers | |
| ¡Estamos buscando expandir el conjunto de configuraciones a la medida para usar y agradecemos las contribuciones de la comunidad! | |
| Si deseas contribuir con su colaboración a la biblioteca, deberás: | |
| * Implementa la configuración de ONNX en el archivo `configuration_<model_name>.py` correspondiente | |
| * Incluye la arquitectura del modelo y las características correspondientes en [`~onnx.features.FeatureManager`] | |
| * Agrega tu arquitectura de modelo a las pruebas en `test_onnx_v2.py` | |
| Revisa cómo fue la contribución para la [configuración de IBERT](https://github.com/huggingface/transformers/pull/14868/files) | |
| y así tener una idea de lo que necesito. | |
| ## TorchScript | |
| <Tip> | |
| Este es el comienzo de nuestros experimentos con TorchScript y todavía estamos explorando sus capacidades con modelos de | |
| tamaño de entrada variable. Es un tema de interés y profundizaremos nuestro análisis en las próximas | |
| versiones, con más ejemplos de código, una implementación más flexible y puntos de referencia que comparen códigos | |
| basados en Python con TorchScript compilado. | |
| </Tip> | |
| Según la documentación de PyTorch: "TorchScript es una forma de crear modelos serializables y optimizables a partir del | |
| código de PyTorch". Los dos módulos de Pytorch [JIT y TRACE](https://pytorch.org/docs/stable/jit.html) permiten al | |
| desarrollador exportar su modelo para reutilizarlo en otros programas, como los programas C++ orientados a la eficiencia. | |
| Hemos proporcionado una interfaz que permite exportar modelos de 🤗 Transformers a TorchScript para que puedan reutilizarse | |
| en un entorno diferente al de un programa Python basado en PyTorch. Aquí explicamos cómo exportar y usar nuestros modelos | |
| usando TorchScript. | |
| Exportar un modelo requiere de dos cosas: | |
| - un pase hacia adelante con entradas ficticias. | |
| - instanciación del modelo con la indicador `torchscript`. | |
| Estas necesidades implican varias cosas con las que los desarrolladores deben tener cuidado. Éstas se detallan a continuación. | |
| ### Indicador de TorchScript y pesos atados | |
| Este indicador es necesario porque la mayoría de los modelos de lenguaje en este repositorio tienen pesos vinculados entre su capa | |
| de `Embedding` y su capa de `Decoding`. TorchScript no permite la exportación de modelos que tengan pesos atados, por lo que es | |
| necesario desvincular y clonar los pesos previamente. | |
| Esto implica que los modelos instanciados con el indicador `torchscript` tienen su capa `Embedding` y `Decoding` separadas, | |
| lo que significa que no deben entrenarse más adelante. El entrenamiento desincronizaría las dos capas, lo que generaría | |
| resultados inesperados. | |
| Este no es el caso de los modelos que no tienen un cabezal de modelo de lenguaje, ya que no tienen pesos atados. | |
| Estos modelos se pueden exportar de forma segura sin el indicador `torchscript`. | |
| ### Entradas ficticias y longitudes estándar | |
| Las entradas ficticias se utilizan para crear un modelo de pase hacia adelante. Mientras los valores de las entradas se | |
| propagan a través de las capas, PyTorch realiza un seguimiento de las diferentes operaciones ejecutadas en cada tensor. | |
| Estas operaciones registradas se utilizan luego para crear el "rastro" del modelo. | |
| El rastro se crea en relación con las dimensiones de las entradas. Por lo tanto, está limitado por las dimensiones de la | |
| entrada ficticia y no funcionará para ninguna otra longitud de secuencia o tamaño de lote. Al intentar con un tamaño diferente, | |
| un error como: | |
| `The expanded size of the tensor (3) must match the existing size (7) at non-singleton dimension 2` | |
| aparecerá. Por lo tanto, se recomienda rastrear el modelo con un tamaño de entrada ficticia al menos tan grande como la | |
| entrada más grande que se alimentará al modelo durante la inferencia. El _padding_ se puede realizar para completar los | |
| valores que faltan. Sin embargo, como el modelo se habrá rastreado con un tamaño de entrada grande, las dimensiones de | |
| las diferentes matrices también serán grandes, lo que dará como resultado más cálculos. | |
| Se recomienda tener cuidado con el número total de operaciones realizadas en cada entrada y seguir de cerca el rendimiento | |
| al exportar modelos de longitud de secuencia variable. | |
| ### Usar TorchScript en Python | |
| A continuación se muestra un ejemplo que muestra cómo guardar, cargar modelos y cómo usar el rastreo para la inferencia. | |
| #### Guardando un modelo | |
| Este fragmento muestra cómo usar TorchScript para exportar un `BertModel`. Aquí, el `BertModel` se instancia de acuerdo | |
| con la clase `BertConfig` y luego se guarda en el disco con el nombre de archivo `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") | |
| ``` | |
| #### Cargar un modelo | |
| Este fragmento muestra cómo cargar el `BertModel` que se guardó previamente en el disco con el nombre `traced_bert.pt`. | |
| Estamos reutilizando el `dummy_input` previamente inicializado. | |
| ```python | |
| loaded_model = torch.jit.load("traced_bert.pt") | |
| loaded_model.eval() | |
| all_encoder_layers, pooled_output = loaded_model(*dummy_input) | |
| ``` | |
| #### Usar un modelo rastreado para la inferencia | |
| Usar el modelo rastreado para la inferencia es tan simple como usar su método `__call__`: | |
| ```python | |
| traced_model(tokens_tensor, segments_tensors) | |
| ``` | |
| ### Implementar los modelos HuggingFace TorchScript en AWS mediante Neuron SDK | |
| AWS presentó la familia de instancias [Amazon EC2 Inf1](https://aws.amazon.com/ec2/instance-types/inf1/) para la inferencia | |
| de aprendizaje automático de bajo costo y alto rendimiento en la nube. Las instancias Inf1 funcionan con el chip AWS | |
| Inferentia, un acelerador de hardware personalizado, que se especializa en cargas de trabajo de inferencia de aprendizaje | |
| profundo. [AWS Neuron](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/#) es el kit de desarrollo para Inferentia | |
| que admite el rastreo y la optimización de modelos de transformers para su implementación en Inf1. El SDK de Neuron proporciona: | |
| 1. API fácil de usar con una línea de cambio de código para rastrear y optimizar un modelo de TorchScript para la inferencia en la nube. | |
| 2. Optimizaciones de rendimiento listas para usar con un [costo-rendimiento mejorado](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/benchmark/>) | |
| 3. Soporte para modelos HuggingFace Transformers construidos 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). | |
| #### Implicaciones | |
| Los modelos Transformers basados en la arquitectura | |
| [BERT (Representaciones de _Enconder_ bidireccional de Transformers)](https://huggingface.co/docs/transformers/main/model_doc/bert), | |
| o sus variantes, como [distilBERT](https://huggingface.co/docs/transformers/main/model_doc/distilbert) y | |
| [roBERTa](https://huggingface.co/docs/transformers/main/model_doc/roberta), se ejecutarán mejor en Inf1 para tareas no | |
| generativas, como la respuesta extractiva de preguntas, la clasificación de secuencias y la clasificación de tokens. | |
| Como alternativa, las tareas de generación de texto se pueden adaptar para ejecutarse en Inf1, según este | |
| [tutorial de AWS Neuron MarianMT](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/src/examples/pytorch/transformers-marianmt.html). | |
| Puedes encontrar más información sobre los modelos que están listos para usarse en Inferentia en la | |
| [sección _Model Architecture Fit_ de la documentación de Neuron](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/models/models-inferentia.html#models-inferentia). | |
| #### Dependencias | |
| Usar AWS Neuron para convertir modelos requiere las siguientes dependencias y entornos: | |
| * Un [entorno Neuron SDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/pytorch-neuron/index.html#installation-guide), | |
| que viene preconfigurado en [AWS Deep Learning AMI](https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-inferentia-launching.html). | |
| #### Convertir un modelo a AWS Neuron | |
| Con el mismo script usado en [Uso de TorchScript en Python](https://huggingface.co/docs/transformers/main/es/serialization#using-torchscript-in-python) | |
| para rastrear un "BertModel", puedes importar la extensión del _framework_ `torch.neuron` para acceder a los componentes | |
| del SDK de Neuron a través de una API de Python. | |
| ```python | |
| from transformers import BertModel, BertTokenizer, BertConfig | |
| import torch | |
| import torch.neuron | |
| ``` | |
| Y modificando la línea de código de rastreo de: | |
| ```python | |
| torch.jit.trace(model, [tokens_tensor, segments_tensors]) | |
| ``` | |
| con lo siguiente: | |
| ```python | |
| torch.neuron.trace(model, [token_tensor, segments_tensors]) | |
| ``` | |
| Este cambio permite a Neuron SDK rastrear el modelo y optimizarlo para ejecutarse en instancias Inf1. | |
| Para obtener más información sobre las funciones, las herramientas, los tutoriales de ejemplo y las últimas actualizaciones | |
| de AWS Neuron SDK, consulte la [documentación de AWS NeuronSDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/index.html). | |