# Comment construire votre propre découpeur en jetons pour un modèle de langage?

Date: 2026-04-11 · Author: Robert Scales · https://guidetoartificialintelligence.com/fr/apprendre/construire-decoupeur-jetons-soi-meme/

**Answer:** Entraînez un découpeur à codage par paires d’octets (BPE) : partez des 256 valeurs d’octets possibles, fusionnez sans cesse la paire voisine la plus fréquente en un nouveau jeton et arrêtez à la taille de vocabulaire choisie. Trente lignes de Python montrent l’idée, la bibliothèque tokenizers de Hugging Face le fait à vraie échelle, et le vôtre n’est nécessaire que si vous préentraînez à partir de zéro.

Un modèle de langage ne sait pas lire les lettres. Il lit des nombres, et le **découpeur en jetons** (*tokenizer*) est le petit programme qui convertit le texte en nombres, et l’inverse. Notre [introduction aux jetons](/fr/apprendre/jetons-modeles-de-langage-lisent-texte/) explique pourquoi les modèles lisent des morceaux de mots. Cet article porte sur la fabrication de ce programme, la première chose qu’on entraîne dans tout projet à partir de zéro, avant le modèle.

Contrairement à un modèle, un découpeur n’apprend aucun sens. Il apprend seulement quelles suites d’octets sont courantes dans votre texte. Son entraînement est donc rapide : celui de nanochat indique environ 34 secondes pour 2 milliards de caractères sur un MacBook Pro récent.

## L’algorithme en mots simples

Le **codage par paires d’octets** (*byte pair encoding*, BPE) est la méthode derrière les découpeurs de GPT-2, de GPT-4, de Llama et de bien d’autres. Le texte est d’abord transformé en octets, les 256 valeurs de base que stocke un ordinateur. Ensuite :

1. Comptez chaque paire de jetons voisins.
2. Donnez un nouveau numéro à la paire la plus fréquente.
3. Remplacez cette paire partout, puis recommencez.

Après des milliers de tours, les mots et morceaux de mots courants ont leur propre numéro, et les mots rares restent représentables, au pire octet par octet. Votre vocabulaire final compte les 256 octets, plus un jeton par fusion, plus les jetons spéciaux éventuels.

## En bâtir un en trente lignes

Le projet éducatif [minbpe](https://github.com/karpathy/minbpe) de Karpathy est le meilleur code à lire ensuite. Cette version plus courte n’utilise que Python, sans rien à installer.

```python
def pairs(ids):
    counts = {}
    for a, b in zip(ids, ids[1:]):
        counts[(a, b)] = counts.get((a, b), 0) + 1
    return counts

def merge(ids, pair, new_id):
    out, i = [], 0
    while i < len(ids):
        if i < len(ids) - 1 and (ids[i], ids[i + 1]) == pair:
            out.append(new_id)
            i += 2
        else:
            out.append(ids[i])
            i += 1
    return out

text = "les élèves étudient; les élèves écrivent; les enseignantes étudient"
ids = list(text.encode("utf-8"))     # partir des octets bruts : 256 jetons possibles
print(len(text), "caractères,", len(ids), "octets")

merges = {}
for step in range(8):
    counts = pairs(ids)
    best = max(counts, key=counts.get)
    new_id = 256 + step
    ids = merge(ids, best, new_id)
    merges[best] = new_id

vocab = {i: bytes([i]) for i in range(256)}
for (a, b), new_id in merges.items():
    vocab[new_id] = vocab[a] + vocab[b]

print(len(ids), "jetons après 8 fusions")
print(b"".join(vocab[i] for i in ids).decode("utf-8"))
print([vocab[i].decode("utf-8", "replace") for i in ids])
```

La sortie commence ainsi :

```text
67 caractères, 74 octets
41 jetons après 8 fusions
les élèves étudient; les élèves écrivent; les enseignantes étudient
['les él', '�', '�', 'v', 'es é', 't', 'u', 'd', 'i', 'ent', ...
```

Il y a trois leçons ici. Les 7 octets de plus sont les accents, puisque « é » et « è » prennent chacun 2 octets en UTF-8, l’encodage de texte standard. La ligne reconstituée à partir des jetons correspond exactement à l’original, et c’est le test qu’un découpeur doit toujours réussir. Et les marques « � » montrent les deux octets de « è » dans des jetons séparés. C’est normal : un jeton peut finir au milieu d’un caractère, et le texte ne redevient entier que lorsque les octets sont rejoints. Imprimé seul, un jeton peut sembler brisé.

Remarquez aussi que « les él » est devenu un jeton, parce que ce tout petit texte le répète. Entraîné sur trop peu de texte, un découpeur mémorise des expressions. Utilisez un échantillon vaste et varié.

## À vraie échelle

La version en Python ci-dessus serait beaucoup trop lente sur des milliards de caractères. La bibliothèque `tokenizers` de Hugging Face est écrite en Rust et les traite rapidement. Son guide de démarrage utilise une séparation aux espaces et un vocabulaire basé sur les caractères, ce qui change un émoji en jeton inconnu dans son propre exemple. Pour un modèle de langage, un montage au niveau des octets est plus sûr, puisque tout texte possible peut être représenté. Cette version demande `pip install tokenizers` et un fichier de texte à vous, ici `corpus.txt` :

```python
from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import ByteLevel
from tokenizers.decoders import ByteLevel as ByteLevelDecoder

tok = Tokenizer(BPE())
tok.pre_tokenizer = ByteLevel(add_prefix_space=False)
tok.decoder = ByteLevelDecoder()

trainer = BpeTrainer(
    vocab_size=32768,
    initial_alphabet=ByteLevel.alphabet(),
    special_tokens=["<|endoftext|>", "<|user|>", "<|assistant|>"],
)
tok.train(["corpus.txt"], trainer)
tok.save("tokenizer.json")

sample = "Déjà, l’élève québécois écrit à l’hôpital."
out = tok.encode(sample)
print(out.tokens)
print(tok.decode(out.ids) == sample)
```

Les jetons imprimés semblent illisibles, par exemple `Ã©` là où vous attendez `é`. C’est seulement la façon dont la bibliothèque affiche des octets bruts sous forme de texte. La dernière ligne devrait imprimer `True`.

Les **jetons spéciaux** marquent ce qui n’est pas du texte, comme la fin d’un document ou le début du tour de l’assistant. Ils s’ajoutent aux fusions. La documentation de minbpe met en garde contre le fait de transformer par défaut le texte saisi par l’utilisateur en jetons spéciaux, car quelqu’un pourrait alors simuler le tour de l’assistant. Encodez les entrées non fiables de façon que ces chaînes restent du texte ordinaire.

## Choisir une taille de vocabulaire

| Découpeur | Vocabulaire |
|---|---|
| Notre jouet | 264 |
| nanochat | 32 768 |
| GPT-2 | 50 257 |
| Échelle de GPT-4, selon minbpe | environ 100 000 |

Un vocabulaire plus grand veut dire moins de jetons par phrase, donc plus de texte dans chaque lot d’entraînement. Il veut dire aussi une table plus grande à apprendre pour le modèle, et des jetons rares qu’il voit trop peu. Pour un petit modèle à partir de zéro, 32 768 entraîné sur environ 2 milliards de caractères est un point de départ éprouvé. Pour le français, incluez de vrai texte français : un vocabulaire entraîné sur l’anglais laisse les mots accentués en plusieurs petits morceaux, ce qui gruge votre contexte et votre budget.

> **À essayer :** exécutez le script de trente lignes sur un paragraphe à vous, avec 8 fusions, puis avec 50. Imprimez les jetons chaque fois et repérez le moment où ils cessent de ressembler à des morceaux de mots pour ressembler à des expressions mémorisées.

## Devriez-vous entraîner votre propre découpeur ou en réutiliser un?

Si vous faites un ajustement fin, réutilisez toujours. Les nombres d’un modèle à poids ouverts ont été appris pour son propre découpeur : le jeton 5 000 a pour lui un sens précis. Un autre découpeur brouille ses entrées. Il en va de même pour l’ajout de nombreux nouveaux jetons, qui devraient aussi être entraînés.

Si vous préentraînez à partir de zéro sur de l’anglais courant ou un mélange de langues communes, l’un ou l’autre choix se défend, puisque l’entraînement en prend quelques minutes et la réutilisation, aucune. Vérifiez la licence et testez l’aller-retour.

Entraînez le vôtre lorsque votre texte diffère de ce que les découpeurs existants ont vu : une langue peu présente en ligne, comme bien des langues autochtones, ou un domaine spécialisé comme le code ou la chimie. Comparez les candidats à l’aide d’un seul chiffre : le nombre de jetons que chacun exige pour un même échantillon de votre texte. Le script `tok_eval` de nanochat indique ce genre de taux de compression. Moins de jetons pour le même texte, c’est un entraînement moins cher et plus de place dans la fenêtre de contexte. Figez-le ensuite, car toutes les étapes suivantes dépendent de ce fichier précis.

## Sources

- minbpe README: https://github.com/karpathy/minbpe
- Tokenization algorithms: https://huggingface.co/docs/transformers/tokenizer_summary
- Tokenizers quicktour: https://huggingface.co/docs/tokenizers/en/quicktour

---

Tiré du Guide de l’intelligence artificielle, par Robert Scales, publié par Holistic Hybrid inc. Partage et adaptation permis selon la licence CC BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/) : citez le guide, mettez un lien vers https://guidetoartificialintelligence.com/fr/apprendre/construire-decoupeur-jetons-soi-meme/, pas d’usage commercial sans permission, et gardez la même licence.
