NLP Course documentation

Colocando tudo junto

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Colocando tudo junto

Ask a Question Open In Colab Open In Studio Lab

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:

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:

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:

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:

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

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:

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:

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

print(tokenizer.decode(model_inputs["input_ids"]))
print(tokenizer.decode(ids))
"[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:

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)