Passer au contenu principal
RM
Retour au blog

BPE, coût par token, pourquoi 'strawberry' bug les LLM, et comment compter ses tokens. Le guide définitif.

Radnoumane Mossabely9 min read
Tokenization expliquée
Token
LLM
Tokenization
BPE
0 vues

TL;DR

  • Un token, c'est un bout de mot. Pas un mot, pas un caractère : un sous-mot découpé par un algorithme (BPE).
  • Le français consomme environ 30% de tokens en plus que l'anglais pour dire la même chose.
  • Le fameux bug "strawberry a 2 r" vient des frontières de tokens. Le modèle ne voit pas les lettres.
  • Le coût d'une API se calcule en tokens : input et output, avec des prix différents.
  • Tu peux compter tes tokens avant d'envoyer une requête. Et tu devrais.

Tout le monde dit "token". Personne ne sait ce que c'est.

Tu lis la doc d'OpenAI : "128K tokens de contexte". Tu regardes les prix : "10$ par million de tokens en input". Tu entends un collègue dire "faut réduire les tokens du prompt". Et à chaque fois, tu hoches la tête en te disant que tu vérifieras plus tard ce que c'est exactement, un token.

Plus tard, c'est maintenant.

Un token, ce n'est pas un mot. Ce n'est pas un caractère. C'est un sous-mot -- un fragment de texte découpé par un algorithme de tokenization. Et comprendre ce découpage change ta façon d'utiliser les LLM, de calculer tes coûts, et même de debugger des réponses incohérentes.

BPE : l'algorithme qui découpe tout

La méthode standard s'appelle BPE -- Byte Pair Encoding. L'idée est simple, l'exécution est élégante.

Le principe en 4 étapes

  1. Tu pars des caractères individuels. Chaque lettre est un token : b, o, n, j, o, u, r.
  2. Tu comptes les paires adjacentes les plus fréquentes dans tout le corpus d'entraînement. Mettons que o + u revient souvent.
  3. Tu fusionne cette paire en un nouveau token : ou. Maintenant "bonjour" se tokenize en b, on, j, ou, r.
  4. Tu répètes jusqu'à atteindre la taille de vocabulaire souhaitée (50 000 à 100 000 tokens pour un LLM moderne).

Le résultat : les mots courants deviennent un seul token ("the", "bonjour", "function"). Les mots rares ou techniques sont découpés en morceaux. Et les caractères vraiment exotiques restent au niveau byte.

Pourquoi BPE et pas juste des mots ?

Trois raisons :

  • Vocabulaire fini : tu ne peux pas mettre tous les mots de toutes les langues dans un dictionnaire. BPE gère n'importe quel texte avec un vocabulaire fixe.
  • Morphologie : "jouer", "jouons", "jouait" partagent le sous-mot "jou". Le modèle capte la racine commune.
  • Gestion de l'inconnu : un mot que le modèle n'a jamais vu se décompose en sous-mots qu'il connaît. Pas de crash, pas de token "inconnu".

Le français paie plus cher que l'anglais

Voilà un truc que peu de gens réalisent : la tokenization n'est pas neutre linguistiquement. Les corpus d'entraînement des tokenizers sont dominés par l'anglais. Résultat : les mots anglais courants sont souvent un seul token, alors que les mots français sont découpés en plusieurs.

Quelques exemples concrets :

TexteTokens (GPT-4)Observation
"Hello world"2Chaque mot = 1 token
"Bonjour le monde"4"Bonjour" = 2 tokens
"authentication"1Mot courant en anglais
"authentification"3La version française coûte plus
"développement"3Les accents fragmentent
"development"1L'anglais gagne

En moyenne, un texte en français consomme 25 à 35% de tokens en plus que son équivalent anglais. Ça veut dire :

  • Ta fenêtre de contexte est effectivement plus petite en français.
  • Tes appels API coûtent plus cher pour dire la même chose.
  • Tes prompts doivent être plus concis si tu travailles en français.

Les accents (é, è, ê, à, ù) sont les principaux coupables. Le tokenizer ne voit pas "développement" comme un seul mot. Il voit "d", "éveloppe", "ment" -- ou quelque chose d'approchant selon le modèle.

Le bug "strawberry" : quand les tokens trahissent le modèle

Tu as peut-être vu passer le mème : demande à GPT combien il y a de "r" dans "strawberry". Il répond 2. La bonne réponse est 3.

Ce n'est pas un problème d'intelligence. C'est un problème de tokenization.

Le modèle ne voit pas les lettres individuelles de "strawberry". Il voit quelque chose comme [ straw | berry ]. Deux tokens. Le modèle raisonne sur des tokens, pas sur des caractères. Il n'a littéralement pas accès à la séquence de lettres s-t-r-a-w-b-e-r-r-y.

C'est pour ça que les LLM sont mauvais pour :

  • Compter des lettres dans un mot
  • Épeler à l'envers
  • Trouver des anagrammes
  • Vérifier la rime entre deux mots

Ce ne sont pas des bugs. C'est une conséquence directe de l'architecture. Le modèle opère au niveau token, pas au niveau caractère. Si la frontière entre deux tokens coupe un mot à un endroit inattendu, le modèle perd l'information sur les caractères individuels.

Coût par token : input vs output

Quand tu appelles une API de LLM, tu paies en tokens. Mais pas de la même façon pour l'input et l'output.

Pourquoi l'output coûte plus cher ?

L'inférence en input est parallélisable : le modèle traite tous tes tokens d'entrée en une seule passe. L'output, lui, est séquentiel -- le modèle génère un token à la fois, chacun dépendant du précédent. C'est plus lent, donc plus cher.

Ordre de grandeur (début 2025)

ModèleInput (par 1M tokens)Output (par 1M tokens)
GPT-4o~2.50$~10$
Claude 3.5 Sonnet~3$~15$
GPT-4o mini~0.15$~0.60$
Llama 3 (self-hosted)Coût infraCoût infra

Les implications pratiques :

  • Un prompt système de 2000 tokens envoyé 10 000 fois par jour = 20M tokens d'input par jour. Ça chiffre vite.
  • Les réponses longues coûtent 3 à 5 fois plus que les prompts. Si ton modèle génère des pavés, tu paies cher.
  • Le caching de prompt (quand le provider le supporte) réduit drastiquement le coût des tokens d'input répétés.

La fenêtre de contexte : en tokens, pas en mots

Quand on te dit qu'un modèle a une fenêtre de 128K tokens, ce n'est pas 128 000 mots. En anglais, c'est environ 96 000 mots. En français, c'est plutôt 75 000 mots. La différence vient du ratio token/mot qui varie selon la langue.

Règles de pouce :

  • Anglais : 1 token ≈ 0.75 mot (ou 4 caractères)
  • Français : 1 token ≈ 0.55-0.65 mot
  • Code : très variable, mais les symboles ({, }, =>) sont souvent 1 token chacun
  • JSON : gros consommateur de tokens à cause des guillemets et de la structure

Compter tes tokens avant d'envoyer

Tu ne devrais pas deviner combien de tokens consomme ton prompt. Tu peux le calculer. Voici comment avec Python et la bibliothèque tiktoken (le tokenizer d'OpenAI) :

hljs python
import tiktoken

# Charger l'encodage pour GPT-4
enc = tiktoken.encoding_for_model("gpt-4o")

# Tokenizer un texte
texte = "Bonjour, comment fonctionnent les tokens ?"
tokens = enc.encode(texte)

print(f"Texte : {texte}")
print(f"Nombre de tokens : {len(tokens)}")
print(f"Tokens : {tokens}")
print(f"Décodés : {[enc.decode([t]) for t in tokens]}")

# Résultat :
# Texte : Bonjour, comment fonctionnent les tokens ?
# Nombre de tokens : 10
# Tokens : [61469, 11, 4068, 2267, 36808, 306, 2655, 11766, 949, 128]
# Décodés : ['Bonj', 'our', ',', ' comment', ' fonction', 'nent', ' les', ' tokens', ' ?']

Tu vois le découpage ? "Bonjour" devient deux tokens. "fonctionnent" devient deux tokens. Chaque morceau a un identifiant numérique que le modèle manipule.

Pour une intégration dans un projet TypeScript / Next.js, tu peux utiliser js-tiktoken :

hljs typescript
import { encodingForModel } from "js-tiktoken";

const enc = encodingForModel("gpt-4o");
const tokens = enc.encode("Bonjour, comment fonctionnent les tokens ?");
console.log(`Nombre de tokens : ${tokens.length}`);

Astuce pratique

Avant d'envoyer un prompt à une API, vérifie :

  1. Ton prompt système ne dépasse pas 10-15% de la fenêtre de contexte.
  2. Ton prompt + la réponse attendue tiennent dans la fenêtre. Si ton prompt fait 100K tokens sur un modèle 128K, il reste 28K pour la réponse.
  3. Ton budget mensuel : multiplie le nombre moyen de tokens par requête par le nombre de requêtes par jour. Tu auras des surprises.

Ce qu'il faut retenir

Les tokens sont l'unité fondamentale des LLM. Pas les mots, pas les phrases -- les tokens. Tout en découle : les capacités du modèle, les limites de contexte, les coûts, et même certains bugs apparents.

Quelques réflexes à prendre :

  • Pense en tokens quand tu conçois des prompts. Chaque mot inutile coûte.
  • Teste ta langue : si tu travailles en français, mesure le surcoût par rapport à l'anglais.
  • Ne fais pas confiance au modèle pour les tâches au niveau caractère. Il ne voit pas les lettres.
  • Mesure avant d'envoyer : tiktoken en Python, js-tiktoken en JS. Pas d'excuses.

La tokenization, c'est le fondement invisible de toute l'IA générative. Et maintenant, tu sais ce qui se passe sous le capot.

Ressources

Partager: