Pytorch
TensorFlow

#
Colocando tudo junto

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)