# Colocando tudo junto

{#if fw === 'pt'}

{:else}

{/if}

Nas últimas seções, temos feito o nosso melhor para fazer a maior parte do trabalho à mão. Exploramos como funcionam os tokenizers e analisamos a tokenização, conversão para IDs de entrada, padding, truncagem e máscaras de atenção.

Entretanto, como vimos na seção 2, a API dos 🤗 Transformers pode tratar de tudo isso para nós com uma função de alto nível, na qual mergulharemos aqui. Quando você chama seu `tokenizer` diretamente na frase, você recebe de volta entradas que estão prontas para passar pelo seu modelo:

```py
from transformers import AutoTokenizer

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)
```

Aqui, a variável `model_inputs` contém tudo o que é necessário para que um modelo funcione bem. Para DistilBERT, isso inclui os IDs de entrada, bem como a máscara de atenção. Outros modelos que aceitam entradas adicionais também terão essas saídas pelo objeto `tokenizer`.

Como veremos em alguns exemplos abaixo, este método é muito poderoso. Primeiro, ele pode simbolizar uma única sequência:

```py
sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)
```

Também lida com várias sequências de cada vez, sem nenhuma mudança na API:

```py
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

model_inputs = tokenizer(sequences)
```

Ela pode ser aplicada de acordo com vários objetivos:

```py
# Irá preencher as sequências até o comprimento máximo da sequência
model_inputs = tokenizer(sequences, padding="longest")

# Irá preencher as sequências até o comprimento máximo do modelo
# (512 para o modelo BERT ou DistilBERT)
model_inputs = tokenizer(sequences, padding="max_length")

# Irá preencher as sequências até o comprimento máximo especificado
model_inputs = tokenizer(sequences, padding="max_length", max_length=8)
```

Também pode truncar sequências:

```py
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

# Irá preencher as sequências até o comprimento máximo do modelo
# (512 para o modelo BERT ou DistilBERT)
model_inputs = tokenizer(sequences, truncation=True)

# Truncará as sequências que são mais longas do que o comprimento máximo especificado
model_inputs = tokenizer(sequences, max_length=8, truncation=True)
```

O objeto `tokenizer` pode lidar com a conversão para tensores de estrutura específicos, que podem então ser enviados diretamente para o modelo. Por exemplo, na seguinte amostra de código, estamos solicitando que o tokenizer retorne tensores de diferentes estruturas - `"pt"` retorna tensores PyTorch, `"tf"` retorna tensores TensorFlow, e `"np"` retorna arrays NumPy:

```py
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

# Retorna tensores PyTorch
model_inputs = tokenizer(sequences, padding=True, return_tensors="pt")

# Retorna tensores TensorFlow
model_inputs = tokenizer(sequences, padding=True, return_tensors="tf")

# Retorna NumPy arrays
model_inputs = tokenizer(sequences, padding=True, return_tensors="np")
```

## Tokens especiais

Se dermos uma olhada nos IDs de entrada devolvidos pelo tokenizer, veremos que eles são um pouco diferentes do que tínhamos anteriormente:

```py
sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)
print(model_inputs["input_ids"])

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)
```

```python out
[101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102]
[1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012]
```

Um token ID foi adicionada no início e uma no final. Vamos decodificar as duas sequências de IDs acima para ver do que se trata:

```py
print(tokenizer.decode(model_inputs["input_ids"]))
print(tokenizer.decode(ids))
```

```python out
"[CLS] i've been waiting for a huggingface course my whole life. [SEP]"
"i've been waiting for a huggingface course my whole life."
```

O tokenizer acrescentou a palavra especial `[CLS]` no início e a palavra especial `[SEP]` no final. Isto porque o modelo foi pré-treinado com esses, então para obter os mesmos resultados para inferência, precisamos adicioná-los também. Note que alguns modelos não acrescentam palavras especiais, ou acrescentam palavras diferentes; os modelos também podem acrescentar estas palavras especiais apenas no início, ou apenas no final. Em qualquer caso, o tokenizer sabe quais são as palavras que são esperadas e tratará disso para você.

## Do tokenizer ao modelo

Agora que já vimos todos os passos individuais que o objeto `tokenizer` utiliza quando aplicado em textos, vamos ver uma última vez como ele pode lidar com múltiplas sequências (padding!), sequências muito longas (truncagem!), e múltiplos tipos de tensores com seu API principal:

{#if fw === 'pt'}
```py
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt")
output = model(**tokens)
```
{:else}
```py
import tensorflow as tf
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = TFAutoModelForSequenceClassification.from_pretrained(checkpoint)
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="tf")
output = model(**tokens)
```
{/if}

