NLP Course documentation

Mettiamo insieme i pezzi

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Mettiamo insieme i pezzi

Ask a Question Open In Colab Open In Studio Lab

Nelle ultime sezioni abbiamo fatto del nostro meglio per fare la maggior parte del lavoro a mano. Abbiamo esplorato il funzionamento dei tokenizer e abbiamo esaminato la tokenizzazione, la conversione in ID di input, il padding, il troncamento e le maschere di attenzione.

Tuttavia, come abbiamo visto nella sezione 2, l’API 🤗 Transformers può gestire tutto questo con una funzione di alto livello che approfondiremo qui. Quando si chiama il tokenizer direttamente sulla frase, si ottengono input pronti per passare attraverso il modello:

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)

Qui, la variabile model_inputs contiene tutto ciò che è necessario per il buon funzionamento del modello. Per DistilBERT, questo include gli ID degli ingressi e la maschera di attenzione. Altri modelli che accettano input aggiuntivi avranno anche questi output dall’oggetto tokenizer.

Come vedremo in alcuni esempi, questo metodo è molto potente. Innanzitutto, può tokenizzare una singola sequenza:

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

model_inputs = tokenizer(sequence)

Gestisce anche più sequenze alla volta, senza alcuna modifica dell’API:

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

model_inputs = tokenizer(sequences)

Possiamo implementare il padding in diversi modi

# Effettua il padding della sequenza fino allla massima lunghezza della sequenza
model_inputs = tokenizer(sequences, padding="longest")

# Effettua il padding fino alla lunghezza massima del modello
# (512 per BERT o DistilBERT)
model_inputs = tokenizer(sequences, padding="max_length")

# Effettua il padding fino alla lunghezza massima specificata
model_inputs = tokenizer(sequences, padding="max_length", max_length=8)

Può anche troncare le sequenze:

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

# Tronca le sequenze più lunghe della lunghezza massima del modello.
# (512 per BERT o DistilBERT)
model_inputs = tokenizer(sequences, truncation=True)

# Tronca le sequenze più lunghe della lunghezza massima specificata.
model_inputs = tokenizer(sequences, max_length=8, truncation=True)

L’oggetto tokenizer può gestire la conversione in tensori di framework specifici, che possono successivamente essere inviati direttamente al modello. Per esempio, nel seguente esempio di codice si chiede al tokenizer di restituire i tensori dei diversi framework: "pt" restituisce i tensori di PyTorch, "tf" restituisce i tensori di TensorFlow e "np" restituisce gli array di NumPy:

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

# Ritorna tensori PyTorch
model_inputs = tokenizer(sequences, padding=True, return_tensors="pt")

# Ritorna tensori TensorFlow
model_inputs = tokenizer(sequences, padding=True, return_tensors="tf")

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

Token speciali

Se diamo un’occhiata agli ID di input restituiti dal tokenizer, noteremo che sono leggermente diversi da quelli che avevamo prima:

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]

Un ID token è stato aggiunto all’inizio e uno alla fine. Decodifichiamo le due sequenze di ID qui sopra per capire di cosa si tratta:

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."

Il tokenizer ha aggiunto la parola speciale [CLS] all’inizio e la parola speciale [SEP] alla fine. Questo perché il modello è stato preaddestrato con queste parole, quindi per ottenere gli stessi risultati per l’inferenza dobbiamo aggiungerle anche noi. Si noti che alcuni modelli non aggiungono parole speciali, o ne aggiungono di diverse; i modelli possono anche aggiungere queste parole speciali solo all’inizio o solo alla fine. In ogni caso, il tokenizer sa quali sono previste e se ne occuperà per voi.

Conclusione: Dal tokenizer al modello

Ora che abbiamo visto tutti i singoli passaggi che l’oggetto tokenizer utilizza quando viene applicato ai testi, vediamo un’ultima volta come può gestire sequenze multiple (padding!), sequenze molto lunghe (troncamento!) e diversi tipi di tensori con la sua API principale:

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)