torchscript.md 10.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<!--Copyright 2024 The HuggingFace Team. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

鈿狅笍 Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be
rendered properly in your Markdown viewer.

-->

# Exportar a TorchScript

<Tip>
Este es el comienzo de nuestros experimentos con TorchScript y todav铆a estamos explorando sus capacidades con modelos de variables de entrada. Es un tema de inter茅s para nosotros y profundizaremos en nuestro an谩lisis en las pr贸ximas versiones, con m谩s ejemplos de c贸digo, una implementaci贸n m谩s flexible y comparativas de rendimiento comparando c贸digos basados en Python con TorchScript compilado.  

</Tip>

De acuerdo con la documentaci贸n de TorchScript: 

> "TorchScript es una manera de crear modelos serializables y optimizables a partir del c贸digo PyTorch."

Hay dos m贸dulos de PyTorch, [JIT y TRACE](https://pytorch.org/docs/stable/jit.html), que permiten a los desarrolladores exportar sus modelos para ser reusados en otros programas, como los programas de C++ orientados a la eficiencia.

Nosotros proveemos una interface que te permite exportar los modelos 馃Transformers a TorchScript para que puedan ser reusados en un entorno diferente al de los programas Python basados en PyTorch. Aqu铆 explicamos como exportar y usar nuestros modelos utilizando TorchScript.

Exportar un modelo requiere de dos cosas:

- La instanciaci贸n del modelo con la bandera TorchScript.
- Un paso hacia adelante con entradas ficticias.

Estas necesidades implican varias cosas de las que los desarrolladores deben tener cuidado, como se detalla a continuaci贸n.

## Bandera TorchScript y pesos atados.

La bandera `torchscript` es necesaria porque la mayor铆a de los modelos de lenguaje de 馃Transformers tienen pesos atados entre su `capa de incrustaci贸n` (`Embedding`) y su `capa de decodificaci贸n` (`Decoding`). TorchScript no te permite exportar modelos que tienen pesos atados, por lo que es necesario desatar y clonar los pesos de antemano.

Los modelos instanciados con la bandera `torchscript` tienen su `capa de incrustaci贸n` (`Embedding`) y su `capa de decodificaci贸n` (`Decoding`) separadas, lo que significa que no deben ser entrenados m谩s adelante. Entrenar desincronizar铆a las dos capas, lo que llevar铆a a resultados inesperados.

Esto no es as铆 para los modelos que no tienen una cabeza de modelo de lenguaje, ya que esos modelos no tienen pesos atados. Estos modelos pueden ser exportados de manera segura sin la bandera `torchscript`.

## Entradas ficticias y longitudes est谩ndar

Las entradas ficticias se utilizan para un paso del modelo 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 *la traza* del modelo.
La traza se crea en relaci贸n con las dimensiones de las entradas. Por lo tanto, est谩 limitada por las dimensiones de la entrada ficticia y no funcionar谩 para ninguna otra longitud de secuencia o tama帽o de lote. Cuando se intenta con un tama帽o diferente, se genera el siguiente error:

```
`El tama帽o expandido del tensor (3) debe coincidir con el tama帽o existente (7) en la dimensi贸n no singleton 2`.
```

Recomendamos trazar el modelo con un tama帽o de entrada ficticio al menos tan grande como la entrada m谩s grande con la que se alimentar谩 al modelo durante la inferencia. El relleno puede ayudar a completar los valores faltantes. Sin embargo, dado que el modelo se traza con un tama帽o de entrada m谩s grande, las dimensiones de la matriz tambi茅n ser谩n grandes, lo que resultar谩 en m谩s c谩lculos.

Ten cuidado con el n煤mero total de operaciones realizadas en cada entrada y sigue de cerca el rendimiento al exportar modelos con longitudes de secuencia variables.

## Usando TorchScript en Python

Esta secci贸n demuestra c贸mo guardar y cargar modelos, as铆 como c贸mo usar la traza para la inferencia.

### Guardando un modelo

Para exportar un `BertModel` con TorchScript, instancia `BertModel` a partir de la clase `BertConfig` y luego gu谩rdalo en disco bajo 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")
```
### Cargando un modelo

Ahora puedes cargar el `BertModel` guardado anteriormente, `traced_bert.pt`, desde el disco y usarlo en la entrada ficticia (`dummy_input`) previamente inicializada:

```python
loaded_model = torch.jit.load("traced_bert.pt")
loaded_model.eval()

all_encoder_layers, pooled_output = loaded_model(*dummy_input)
```

## Usando un modelo trazado para inferencia

Utiliza el modelo trazado para inferencia utilizando su m茅todo `_call_` dunder:

```python
traced_model(tokens_tensor, segments_tensors)
```
## Despliega modelos TorchScript de Hugging Face en AWS con el Neuron SDK

AWS introdujo la familia de instancias [Amazon EC2 Inf1](https://aws.amazon.com/ec2/instance-types/inf1/) para inferencia de aprendizaje autom谩tico de alto rendimiento y bajo costo en la nube. Las instancias Inf1 est谩n alimentadas por 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 SDK para Inferentia que admite el trazado y la optimizaci贸n de modelos de transformers para implementaci贸n en Inf1. El SDK Neuron proporciona:

1. Una API f谩cil de usar con un solo cambio de l铆nea de c贸digo para trazar y optimizar un modelo TorchScript para inferencia en la nube.

2. Optimizaciones de rendimiento listas para usar [para mejorar el rendimiento y el costo](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/benchmark/>).

3. Soporte para modelos de transformers de Hugging Face construidos tanto con [PyTorch](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/src/examples/pytorch/bert_tutorial/tutorial_pretrained_bert.html) como con [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 (Bidirectional Encoder Representations from 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), funcionan mejor en Inf1 para tareas no generativas como la respuesta a preguntas extractivas, la clasificaci贸n de secuencias y la clasificaci贸n de tokens. Sin embargo, las tareas de generaci贸n de texto a煤n pueden adaptarse 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). Se puede encontrar m谩s informaci贸n sobre los modelos que se pueden convertir f谩cilmente para usar en Inferentia en la secci贸n de [Model Architecture Fit](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/models/models-inferentia.html#models-inferentia) de la documentaci贸n de Neuron.

### Dependencias

El uso de AWS Neuron para convertir modelos requiere un [entorno de Neuron SDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/neuron-guide/neuron-frameworks/pytorch-neuron/index.html#installation-guide) que viene preconfigurado en [la AMI de AWS Deep Learning](https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-inferentia-launching.html).

### Convertir un modelo para AWS Neuron

Convierte un modelo para AWS NEURON utilizando el mismo c贸digo de [Uso de TorchScript en Python](torchscript#using-torchscript-in-python) para trazar un `BertModel`. Importa la extensi贸n del framework `torch.neuron` para acceder a los componentes del Neuron SDK a trav茅s de una API de Python:

```python
from transformers import BertModel, BertTokenizer, BertConfig
import torch
import torch.neuron
```
Solo necesitas la linea sigueda:

```diff
- torch.jit.trace(model, [tokens_tensor, segments_tensors])
+ torch.neuron.trace(model, [token_tensor, segments_tensors])
```

Esto permite que el Neuron SDK trace el modelo y lo optimice para las instancias Inf1.

Para obtener m谩s informaci贸n sobre las caracter铆sticas, herramientas, tutoriales de ejemplo y 煤ltimas actualizaciones del AWS Neuron SDK, consulta [la documentaci贸n de AWS NeuronSDK](https://awsdocs-neuron.readthedocs-hosted.com/en/latest/index.html).