Sbocciare il Tokenizer ChatGPT

Tokenizzazione ChatGPT

Mani in pasta! Come gestisce ChatGPT i token?

Gif autoprodotto.

Vi siete mai chiesti quali sono i componenti chiave dietro ChatGPT?

A tutti ci hanno detto la stessa cosa: ChatGPT predice la prossima parola. Ma in realtà, c’è un po’ di bugia in questa affermazione. Non predice la prossima parola, ChatGPT predice il prossimo token.

Token? Sì, un token è l’unità di testo per i Large Language Models (LLM).

Infatti, uno dei primi passaggi che ChatGPT compie quando elabora qualsiasi input dell’utente è suddividere l’input in token. E questo è compito del cosiddetto tokenizer.

In questo articolo, scopriremo come funziona il tokenizer di ChatGPT con una pratica hands-on utilizzando la libreria originale utilizzata da OpenAI, la libreria tiktoken.

TikTok-en… Abbastanza divertente 🙂

Andiamo in profondità e comprendiamo i passaggi effettuati dal tokenizer e come il suo comportamento influisce realmente sulla qualità dell’output di ChatGPT.

Come funziona il Tokenizer

Nell’articolo Mastering ChatGPT: Effective Summarization with LLMs abbiamo già visto alcuni dei misteri dietro il tokenizer di ChatGPT, ma partiamo da zero.

Il tokenizer appare al primo passo nel processo di generazione del testo. È responsabile di scomporre il pezzo di testo che inseriamo in ChatGPT in elementi individuali, i token, che vengono poi elaborati dal modello di linguaggio per generare nuovo testo.

Quando il tokenizer scompone un pezzo di testo in token, lo fa basandosi su un insieme di regole che sono progettate per identificare le unità significative della lingua di destinazione.

Ad esempio, quando le parole che compaiono in una determinata frase sono parole abbastanza comuni, è probabile che ogni token corrisponda a una parola. Ma se utilizziamo un prompt con parole meno frequentemente utilizzate, come nella frase “Prompting as powerful developer tool”, potremmo non ottenere una corrispondenza uno a uno. In questo caso, la parola “prompting” non è ancora così comune nella lingua inglese, quindi viene effettivamente scomposta in tre token: “‘prom”, “pt” e “ing” perché queste tre sequenze di lettere si verificano comunemente.

Vediamo un altro esempio!

Considera la seguente frase: “Voglio mangiare un panino al burro di arachidi”. Se il tokenizer è configurato per suddividere i token in base agli spazi e alla punteggiatura, potrebbe scomporre questa frase nei seguenti token con un conteggio totale di parole di 8, uguale al conteggio dei token.

Immagine autoprodotta.

Tuttavia, se il tokenizer considera “burro di arachidi” come una parola composta a causa del fatto che i componenti compaiono spesso insieme, potrebbe scomporre la frase nei seguenti token, con un conteggio totale di parole di 8, ma un conteggio dei token di 7.

Immagine autoprodotta.

Nel contesto di ChatGPT e la gestione dei token, i termini encoding e decoding si riferiscono ai processi di conversione del testo in token che il modello può comprendere (encoding) e la conversione del completamento del modello in un testo leggibile dall’uomo (decoding).

Libreria Tiktoken

Conoscere la teoria dietro il tokenizer di ChatGPT è necessario, ma in questo articolo mi piacerebbe concentrarmi anche su alcune rivelazioni pratiche.

L’implementazione di ChatGPT utilizza la libreria tiktoken per la gestione dei token. Possiamo installarla come qualsiasi altra libreria Python:

pip install --upgrade tiktoken

Una volta installato, è molto semplice ottenere lo stesso modello di codifica che ChatGPT utilizza, poiché esiste un metodo encoding_for_model(). Come suggerisce il nome, questo metodo carica automaticamente la codifica corretta per un determinato nome del modello.

La prima volta che viene eseguito per un determinato modello, richiede una connessione internet per scaricare il modello di codifica. Le esecuzioni successive non avranno bisogno di internet poiché la codifica è già memorizzata nella cache.

Per il modello ampiamente utilizzato gpt-3.5-turbo, possiamo semplicemente eseguire:

import tiktokenencoding = tiktoken.encoding_for_model("gpt-3.5-turbo")

L’output encoding è un oggetto tokenizer che possiamo utilizzare per visualizzare come ChatGPT vede effettivamente il nostro prompt.

In modo più specifico, la funzione tiktoken.encoding_for_model inizializza una pipeline di tokenizzazione specificamente per il modello gpt-3.5-turbo. Questa pipeline gestisce la tokenizzazione e la codifica del testo, preparandolo per il consumo del modello.

Un aspetto importante da considerare è che i token sono rappresentazioni numeriche. Nel nostro esempio “Prompting as powerful developer tool”, i token associati alla parola “prompting” erano “’prom”, “pt” e “ing”, ma ciò che il modello riceve effettivamente è la rappresentazione numerica di quelle sequenze.

Niente paura! Vedremo come appare questo nella sezione pratica.

Tipi di codifica

La libreria tiktoken supporta diversi tipi di codifica. Infatti, diversi modelli gpt utilizzano diverse codifiche. Ecco una tabella con le più comuni:

Codifica – Pratica!

Andiamo avanti e proviamo a codificare il nostro primo prompt. Dato il prompt “tiktoken è fantastico!” e la codifica già caricata, possiamo utilizzare il metodo encoding.encode per suddividere il prompt in token e visualizzarne la rappresentazione numerica:

prompt = "tiktoken è fantastico!"encoded_prompt = encoding.encode(prompt)print(encoded_prompt)# Output: [83, 1609, 5963, 374, 2294, 0]

Sì, è vero. L’output [83, 1609, 5963, 374, 2294, 0] non sembra molto significativo. Ma in realtà, c’è qualcosa che si può intuire a prima vista.

Ci sei?

La lunghezza! Possiamo vedere rapidamente che il nostro prompt “tiktoken è fantastico!” è diviso in 6 token. In questo caso, ChatGPT non sta suddividendo questo prompt di esempio in base agli spazi vuoti, ma alle sequenze di lettere più frequenti.

Nel nostro esempio, ogni coordinata nella lista di output corrisponde a un token specifico nella sequenza di tokenizzati, i cosiddetti ID del token. Gli ID del token sono interi che identificano univocamente ogni token in base al vocabolario utilizzato dal modello. Gli ID sono tipicamente mappati su parole o unità di sottostringa nel vocabolario.

Decodifichiamo semplicemente la lista di coordinate per verificare che corrisponda al nostro prompt originale:

encoding.decode(encoded_prompt)# Output: 'tiktoken è fantastico!'

Il metodo .decode() converte una lista di interi di token in una stringa. Anche se il metodo .decode() può essere applicato a singoli token, ricorda che può comportare una perdita di informazioni per i token che non si trovano sui confini dell’ utf-8 .

E ora potresti chiederti, c’è un modo per vedere i token individuali?

Andiamo a cercarli!

Per i singoli token, il metodo .decode_single_token_bytes() converte in modo sicuro un singolo token intero nei byte che rappresenta. Per il nostro prompt di esempio:

[encoding.decode_single_token_bytes(token) for token in encoded_prompt]# Output: [b't', b'ik', b'token', b' è', b' fantastico', b'!']

Nota che il b davanti alle stringhe indica che le stringhe sono stringhe di byte. Per la lingua inglese, un token corrisponde approssimativamente a circa quattro caratteri o a circa tre quarti di una parola.

Conoscere come il testo viene suddiviso in token è utile perché i modelli GPT vedono il testo sotto forma di token. Sapere quanti token ci sono in una stringa di testo può fornire informazioni utili come ad esempio se la stringa è troppo lunga per essere elaborata da un modello di testo, o quanto costerà una chiamata API di OpenAI in termini di token, tra gli altri.

Confronto tra modelli di codifica

Gif autoprodotto.

Come abbiamo visto, i diversi modelli utilizzano tipi di codifica diversi. A volte, può esserci una grande differenza nella gestione dei token tra i modelli.

Le diverse codifiche variano nel modo in cui suddividono le parole, raggruppano gli spazi e gestiscono i caratteri non inglesi. Utilizzando i metodi sopra descritti, possiamo confrontare diverse codifiche per i diversi modelli gpt disponibili su alcune stringhe di esempio.

Confrontiamo le codifiche della tabella sopra ( gpt2 , p50k_base e cl100k_base ). Per farlo, possiamo utilizzare la seguente funzione che contiene tutte le parti che abbiamo visto finora:

La funzione compare_encodings prende in input una example_string e confronta le codifiche di quella stringa utilizzando tre diversi schemi di codifica: gpt2 , p50k_base e cl100k_base . Infine, stampa varie informazioni sulle codifiche, incluse il numero di token, gli interi dei token e i byte dei token.

Proviamo alcuni esempi!

In questo primo esempio, sebbene i modelli gpt2 e p50k_base siano d’accordo sulla codifica unendo i simboli matematici agli spazi vuoti, la codifica di cl100k_base li considera entità separate.

In questo esempio, il modo di tokenizzare la parola “Prompting” dipende anche dalla codifica selezionata.

Limitazioni del tokenizer

Gif autoprodotto.

Questo modo di tokenizzare gli input può essere la causa di alcuni errori di completamento di ChatGPT. Ad esempio, se chiediamo a ChatGPT di scrivere la parola “lollipop” in ordine inverso, lo fa in modo errato!

Screenshot autoprodotto.

Cosa succede qui è che il tokenizer suddivide effettivamente la parola data in tre token: “l”, “oll” e “ipop”. Pertanto, ChatGPT non vede le singole lettere, ma vede questi tre token rendendo più difficile stampare correttamente le singole lettere in ordine inverso.

Essere consapevoli delle limitazioni può permetterti di trovare soluzioni alternative per evitarle. In questo caso, se aggiungiamo dei trattini tra le lettere individuali della parola, possiamo forzare il tokenizer a suddividere il testo in base a quei simboli. Modificando leggermente la frase di input, ottiene un risultato molto migliore:

Screenshot autoprodotto.

Utilizzando i trattini, è più facile per il modello vedere le singole lettere e stamparle in ordine inverso. Quindi, tenetelo a mente: se volete usare ChatGPT per giocare a un gioco di parole, come Word o Scrabble, o costruire un’applicazione basata su questi principi, questo astuto trucco aiuta a vedere meglio le singole lettere delle parole.

Questo è solo un esempio semplice in cui il tokenizer di ChatGPT fa fallire il modello in un compito molto semplice. Avete incontrato altri casi simili?

Sommario

In questo articolo abbiamo esplorato come ChatGPT vede i comandi dell’utente e li elabora per generare un output di completamento basato su modelli statistici appresi da grandi quantità di dati linguistici durante il suo addestramento.

Utilizzando la libreria tiktoken, ora siamo in grado di valutare qualsiasi comando prima di alimentarlo in ChatGPT. Questo ci può aiutare a debuggare gli errori di ChatGPT poiché può capitare che modificando leggermente il nostro comando, ChatGPT riesca a completare meglio il compito.

C’è anche un messaggio aggiuntivo da portare a casa: alcune decisioni di design possono trasformarsi in debiti tecnici in futuro. Come abbiamo visto nell’esempio del lecca-lecca semplice, mentre il modello riesce in compiti straordinari, non riesce a completare esercizi semplici. E la ragione di ciò non sta nelle capacità del modello, ma nella prima fase di tokenizzazione!

Ecco tutto! Grazie mille per la lettura!

Spero che questo articolo vi sia utile nella creazione di applicazioni ChatGPT!

Potete anche iscrivervi alla mia Newsletter per rimanere aggiornati su nuovi contenuti. In particolare, se siete interessati a articoli su ChatGPT:

Mastering ChatGPT: Sommarizzazione efficace con LLM

Come guidare ChatGPT per ottenere sommarizzazioni di alta qualità

towardsdatascience.com

Corso di ingegneria dei comandi di OpenAI – Inferire, Trasformare ed Espandere con ChatGPT

Massimizzare il potenziale di ChatGPT nella tua applicazione personalizzata

VoAGI.com

Sbloccare una nuova dimensione di ChatGPT: Integrazione Text-to-Speech

Migliorare l’esperienza dell’utente nelle interazioni con ChatGPT

towardsdatascience.com

Sentitevi liberi di inoltrare qualsiasi domanda che possiate avere a [email protected] 🙂