mirror of
https://github.com/huggingface/transformers.git
synced 2025-07-31 02:02:21 +06:00
Add Spanish translation of serialization.mdx (#20245)
* Update _toctree and clone original content * Translate first three sections * Add more translated chapters. Only 3 more left. * Finish translation * Run style from doc-builder * Address recommended changes from reviewer
This commit is contained in:
parent
05d80d856c
commit
d28448c5cd
@ -47,6 +47,8 @@
|
||||
title: Modelos multilingües para inferencia
|
||||
- local: converting_tensorflow_models
|
||||
title: Convertir checkpoints de TensorFlow
|
||||
- local: serialization
|
||||
title: Serialización
|
||||
title: Guías prácticas
|
||||
- sections:
|
||||
- local: philosophy
|
||||
|
669
docs/source/es/serialization.mdx
Normal file
669
docs/source/es/serialization.mdx
Normal file
@ -0,0 +1,669 @@
|
||||
<!--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
|
||||
- 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).
|
Loading…
Reference in New Issue
Block a user