Tokenisation et fondamentaux du NLP : BPE, SentencePiece et WordPiece
La tokenisation est le processus qui consiste à diviser un texte en sous-unités (tokens) pouvant être traitées par un modèle. Ce processus, qui constitue la base des LLM modernes, affecte directement les performances du modèle.
Qu’est-ce que la tokenisation ?
La tokenisation est la première étape pour convertir du texte brut en représentations numériques :
"Hello world!" → ["Hello", "world", "!"] → [1234, 5678, 99]
Niveaux de tokenisation
- Au niveau du caractère : Chaque caractère est un token.
- Au niveau du mot : Chaque mot est un token.
- Au niveau du sous-mot : Les mots sont divisés en sous-unités plus petites (l’approche moderne).
Tokenisation au niveau du mot
Approche simple
1def word_tokenize(text): 2 return text.split() 3 4# Example 5text = "Artificial intelligence is shaping the future" 6tokens = word_tokenize(text) 7# ['Artificial', 'intelligence', 'is', 'shaping', 'the', 'future']
Problèmes
- OOV (Out of Vocabulary) : Rencontre de mots jamais vus durant l’entraînement.
- Vocabulaire volumineux : Gérer des centaines de milliers de mots n’est pas efficace.
- Richesse morphologique : Dans des langues comme le turc, le nombre de variations dues aux suffixes est immense.
- Mots composés : Déterminer si « Artificial intelligence » doit être un seul concept ou deux.
Tokenisation au niveau du caractère
1def char_tokenize(text): 2 return list(text) 3 4# Example 5text = "Hello" 6tokens = char_tokenize(text) 7# ['H', 'e', 'l', 'l', 'o']
Avantages
- Aucun problème d’OOV.
- Taille de vocabulaire réduite (~100 caractères).
Inconvénients
- Les séquences obtenues sont très longues.
- Perte de sens contextuel au niveau du token.
- Coût computationnel plus élevé pour le modèle.
Tokenisation en sous-mots
Le choix des LLM modernes : un équilibre entre niveaux mot et caractère.
"tokenization" → ["token", "ization"] "unhappiness" → ["un", "happiness"] ou ["un", "happy", "ness"]
BPE (Byte Pair Encoding)
L’algorithme de tokenisation en sous-mots le plus largement utilisé.
Algorithme BPE
- Diviser le texte en caractères individuels.
- Trouver la paire de caractères adjacents la plus fréquente.
- Fusionner cette paire en un nouveau token unique.
- Répéter jusqu’à atteindre la taille de vocabulaire souhaitée.
Exemple BPE
1Starting vocabulary: ['l', 'o', 'w', 'e', 'r', 'n', 's', 't', 'i', 'd'] 2Corpus: "low lower newest lowest widest" 3 4Step 1: Most frequent pair 'e' + 's' → 'es' 5Step 2: Most frequent pair 'es' + 't' → 'est' 6Step 3: Most frequent pair 'l' + 'o' → 'lo' 7Step 4: Most frequent pair 'lo' + 'w' → 'low' 8... 9 10Final Result: ['low', 'est', 'er', 'new', 'wid', ...]
Implémentation BPE
1def get_stats(vocab): 2 pairs = {} 3 for word, freq in vocab.items(): 4 symbols = word.split() 5 for i in range(len(symbols) - 1): 6 pair = (symbols[i], symbols[i + 1]) 7 pairs[pair] = pairs.get(pair, 0) + freq 8 return pairs 9 10def merge_vocab(pair, vocab): 11 new_vocab = {} 12 bigram = ' '.join(pair) 13 replacement = ''.join(pair) 14 for word in vocab: 15 new_word = word.replace(bigram, replacement) 16 new_vocab[new_word] = vocab[word] 17 return new_vocab 18 19def train_bpe(corpus, num_merges): 20 vocab = get_initial_vocab(corpus) 21 22 for i in range(num_merges): 23 pairs = get_stats(vocab) 24 if not pairs: 25 break 26 best_pair = max(pairs, key=pairs.get) 27 vocab = merge_vocab(best_pair, vocab) 28 29 return vocab
WordPiece
Un algorithme développé par Google et utilisé dans des modèles comme BERT.
BPE vs WordPiece
| Feature | BPE | WordPiece |
|---|---|---|
| Merge Criterion | Frequency | Likelihood |
| Prefix | None | ## (for mid-word tokens) |
| Used In | GPT, LLaMA | BERT, DistilBERT |
Exemple WordPiece
1"tokenization" → ["token", "##ization"] 2"playing" → ["play", "##ing"] 3## SentencePiece 4 5Un tokenizer indépendant de la langue également développé par Google. 6 7### Features 8 9- **Indépendant de la langue :** Ne suppose pas que l’espace est un séparateur de mots. 10- **Niveau octet :** Fonctionne directement sur le texte brut. 11- **BPE + Unigram :** Prend en charge plusieurs algorithmes. 12- **Réversible :** Une détokenisation parfaite est possible. 13 14### SentencePiece Usage 15 16```python 17import sentencepiece as spm 18 19# Training the model 20spm.SentencePieceTrainer.train( 21 input='corpus.txt', 22 model_prefix='tokenizer', 23 vocab_size=32000, 24 model_type='bpe' # or 'unigram' 25) 26 27# Loading and using the model 28sp = spm.SentencePieceProcessor() 29sp.load('tokenizer.model') 30 31# Encode 32tokens = sp.encode('Hello world', out_type=str) 33# ['▁Hello', '▁world'] 34 35ids = sp.encode('Hello world', out_type=int) 36# [1234, 5678, 9012] 37 38# Decode 39text = sp.decode(ids) 40# 'Hello world'
Symbole ▁ (Underscore)
SentencePiece marque le début des mots avec ▁ :
"Hello world" → ["▁Hello", "▁world"] "New York" → ["▁New", "▁York"]
Tiktoken (OpenAI)
L’implémentation BPE spécialisée utilisée par OpenAI.
1import tiktoken 2 3# Loading the encoder 4enc = tiktoken.encoding_for_model("gpt-4") 5 6# Encode 7tokens = enc.encode("Hello world!") 8# [12345, 67890, 999] 9 10# Decode 11text = enc.decode(tokens) 12# "Hello world!" 13 14# Check token count 15print(len(tokens)) # 3
Model-Encoder Mappings
| Model | Encoder | Vocab Size |
|---|---|---|
| GPT-4 | cl100k_base | 100,277 |
| GPT-3.5 | cl100k_base | 100,277 |
| GPT-3 | p50k_base | 50,281 |
| Codex | p50k_edit | 50,281 |
Hugging Face Tokenizers
1from transformers import AutoTokenizer 2 3# Loading the tokenizer 4tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") 5 6# Encode 7encoded = tokenizer("Hello, world!", return_tensors="pt") 8# { 9# 'input_ids': tensor([[101, 7592, 1010, 2088, 999, 102]]), 10# 'attention_mask': tensor([[1, 1, 1, 1, 1, 1]]) 11# } 12 13# Decode 14text = tokenizer.decode(encoded['input_ids'][0]) 15# "[CLS] hello, world! [SEP]" 16 17# Token List 18tokens = tokenizer.tokenize("Hello, world!") 19# ['hello', ',', 'world', '!']
Fast Tokenizers
1from tokenizers import Tokenizer, models, trainers, pre_tokenizers 2 3# Creating a new tokenizer 4tokenizer = Tokenizer(models.BPE()) 5tokenizer.pre_tokenizer = pre_tokenizers.Whitespace() 6 7trainer = trainers.BpeTrainer( 8 vocab_size=30000, 9 special_tokens=["[PAD]", "[UNK]", "[CLS]", "[SEP]", "[MASK]"] 10) 11 12tokenizer.train(files=["corpus.txt"], trainer=trainer) 13tokenizer.save("my_tokenizer.json")
Special Tokens
Common Special Tokens
| Token | Description | Use Case |
|---|---|---|
| [CLS] | Début de séquence | Tâches de classification BERT |
| [SEP] | Séparateur de segments | Séparation de paires de phrases |
| [PAD] | Padding | Alignement pour le traitement en batch |
| [UNK] | Token inconnu | Gestion des mots hors vocabulaire |
| [MASK] | Masque | Masked Language Modeling (MLM) |
| <|endoftext|> | Fin de séquence | Tâches génératives GPT |
Chat Tokens
1<|system|>You are a helpful assistant<|end|> 2<|user|>Hello!<|end|> 3<|assistant|>Hello! How can I help you today?<|end|>
Tokenization Challenges in Turkish
Morphological Richness
1"gelebileceklermiş" (they were said to be able to come) → Un seul mot mais une structure complexe 2gel (come) + ebil (can) + ecek (will) + ler (they) + miş (reportedly) 3 4Tokenization: 5- Poor: ["gelebileceklermiş"] (Single token, very rare) 6- Good: ["gel", "ebil", "ecek", "ler", "miş"]
Solutions
- Entraînement d’un tokenizer optimisé pour le turc.
- Intégration d’une analyse morphologique.
- Application BPE sensible aux suffixes.
Limites et gestion des tokens
Fenêtre de contexte
| Modèle | Longueur du contexte (Tokens) | ~Équivalent en mots |
|---|---|---|
| GPT-3.5 | 16K | ~12 000 |
| GPT-4 | 128K | ~96 000 |
| Claude 3 | 200K | ~150 000 |
Estimation du nombre de tokens
1def estimate_tokens(text): 2 # Rough estimate: 1 token ≈ 4 characters (English) 3 # For Turkish: 1 token ≈ 3 characters 4 return len(text) // 3 5 6# More accurate calculation 7def count_tokens(text, model="gpt-4"): 8 enc = tiktoken.encoding_for_model(model) 9 return len(enc.encode(text))
Conclusion
La tokenisation est le fondement des systèmes NLP et des LLM. Les méthodes de sous-mots comme BPE, WordPiece et SentencePiece jouent un rôle crucial dans le succès des modèles de langue modernes. Le choix et la configuration du bon tokenizer ont un impact direct sur les performances finales du modèle.
Chez Veni AI, nous proposons des stratégies de tokenisation spécialisées pour les solutions NLP turques.
