Séance 1 · Fondations des LLM

Du texte aux représentations numériques et aux premiers modèles séquentiels

Cette séance construit le socle conceptuel des LLM. On suit une progression continue : texte brut vers tokens, tokens vers vecteurs, vecteurs vers transformations matricielles, puis modèles séquentiels (RNN et LSTM) et leurs limites. Cette trajectoire prépare la séance suivante consacrée au Transformer et à la self-attention.

Ce que construit cette séance

Le cours avance par couches. Il part du langage comme signal textuel, passe par la tokenisation, transforme les tokens en vecteurs, puis montre pourquoi les RNN et les LSTM ont constitué une étape clé avant l’attention et le Transformer.

La logique reste cumulative. Chaque bloc répond à une question précise de modélisation et prépare la suivante, sans rupture artificielle entre mathématiques, intuition et lecture critique.

Résumé exécutif et hypothèses

Résumé exécutif

Cette séance construit le socle conceptuel des LLM. On suit une progression continue : texte brut vers tokens, tokens vers vecteurs, vecteurs vers transformations matricielles, puis modèles séquentiels (RNN et LSTM) et leurs limites. Cette trajectoire prépare la séance suivante consacrée au Transformer et à la self-attention.

Le fil pédagogique est volontairement cumulatif : chaque brique répond à une question précise de modélisation du langage et éclaire la suivante.

Objectifs pédagogiques et prérequis

À la fin de cette séance, vous devez pouvoir
  1. Expliquer ce qu'est le NLP et situer les LLM dans une trajectoire réaliste, sans récit linéaire simplifié.
  2. Définir token et tokenisation, et justifier clairement pourquoi token ne signifie pas mot.
  3. Distinguer embedding d'un token, table d'embedding du vocabulaire et matrice d'embeddings d'une séquence.
  4. Interpréter une transformation matricielle apprise et relier cette opération au calcul neuronal.
  5. Comprendre la malédiction de la dimension et expliquer le rôle des embeddings dans la généralisation.
  6. Décrire le fonctionnement d'une RNN et d'une LSTM, leurs apports et leurs limites structurelles.
  7. Distinguer attention, logits, softmax et décodage pour éviter les confusions classiques sur la prédiction du token suivant.

Du NLP aux tokens : tokenisation, sous-mots et représentation discrète

Qu'est-ce que traiter automatiquement une langue ?

Commençons par une question volontairement simple : que signifie "traiter automatiquement une langue" ? Le NLP (Natural Language Processing) vise à faire exécuter par des machines des tâches impliquant du langage : analyser, traduire, résumer, extraire des informations, répondre à des questions, etc. Dans les manuels de référence, le NLP est présenté comme un champ à l'intersection de la linguistique, de l'informatique et de l'apprentissage automatique, avec une grande diversité de modèles selon les époques et les tâches (Jurafsky & Martin, 2024).

Historiquement, il n'y a pas eu une marche triomphale "n-gram → Transformer → LLM" comme si tout était écrit d'avance. Il y a eu des périodes où certaines approches dominaient parce qu'elles étaient calculables et performantes (par exemple les modèles n-gram en modélisation du langage), d'autres idées existaient mais étaient limitées par le calcul, l'accès aux données ou la maturité des algorithmes d'apprentissage, puis des ruptures ont émergé quand une combinaison "architecture + données + calcul" s'est alignée.

Une façon fiable de raconter cette histoire est de suivre un fil conducteur : comment représenter le texte pour qu'un algorithme apprenne ? C'est là que naissent nos trois briques fondamentales : tokenisation, embeddings, et modèles séquentiels / contextuels.

Qu'est-ce qu'un token ?

Principe fondamental

Un ordinateur ne "mange" pas des phrases : il ingère des symboles discrets. La tokenisation transforme une chaîne de caractères (texte brut) en une suite d'unités appelées tokens. Dans les systèmes modernes, les tokens sont très souvent des sous-mots (subwords), pour gérer la diversité des langues, les mots rares et les néologismes (Sennrich et al., 2016).

Définition simple

Un token est une brique de texte utilisée par le modèle : un morceau de mot, un mot entier, de la ponctuation, etc.

Explication rigoureuse

La plupart des LLM utilisent une segmentation en sous-unités (famille BPE/unigram). L'idée, popularisée en traduction neuronale puis en tokenisation moderne, est de représenter des mots rares comme des séquences de sous-unités fréquentes, ce qui réduit les problèmes de vocabulaire fixe (Sennrich et al., 2016 ; Kudo & Richardson, 2018).

Analogie

Imaginez un jeu de LEGO : si vous n'avez que des pièces de mots entiers, un mot rare devient introuvable. Avec des pièces de sous-mots, vous reconstruisez plus facilement des mots nouveaux.

Exemple simple de tokenisation
Texte d'entrée

J'aime l'IA.

Segmentation possible A
J ' aime l ' IA .
Segmentation possible B
J ' aime l' IA .

Point clé : les tokens ne correspondent pas toujours à des mots. La segmentation dépend d'un vocabulaire appris, de type BPE ou unigram, et des conventions d'espaces et de ponctuation.

Encadré de clarification

Deux tokenizers différents peuvent tokeniser différemment la même phrase. La longueur "en tokens" n'est pas la longueur "en mots". Pour des raisons d'ingénierie (coûts, latence, fenêtre de contexte), on compte très souvent en tokens (Kudo & Richardson, 2018).

Bloc Python obligatoire : tokenisation
Python - texte vers IDsCliquez pour l'explication
# Objectif : rendre concret texte -> tokens -> IDs
import tiktoken

texte = "Bonjour, monde ! Une tokenisation n'est pas une découpe en mots."
enc = tiktoken.get_encoding("o200k_base")

ids = enc.encode(texte)
texte_reconstruit = enc.decode(ids)

print("Texte original :", texte)
print("IDs :", ids)
print("Nombre de tokens :", len(ids))
print("Texte reconstruit :", texte_reconstruit)

Lecture vulgarisée Tokenisation

Le modèle ne voit pas des mots, il voit des IDs. Le comptage en tokens sert ensuite aux coûts, à la latence et à la fenêtre de contexte.

Embeddings, matrices, multiplications matricielles et malédiction de la dimension

Point clé : tokenisation et embedding

La tokenisation transforme le texte en IDs discrets. L'embedding transforme ensuite ces IDs en vecteurs continus. Le contexte n'est pas fabriqué par la tokenisation, il émerge des transformations du réseau.

Des identifiants aux vecteurs

Une suite de tokens, ce sont des identifiants (0, 1, 2, …). Mais un réseau neuronal apprend mieux quand les objets sont dans un espace continu où la similarité a un sens. C'est l'idée des représentations distribuées : un mot (ou token) est associé à un vecteur réel (Bengio et al., 2003).

Définition simple

Un embedding est une liste de nombres (un vecteur) qui représente un token (ou une phrase) de manière exploitable par le modèle.

Explication rigoureuse

Les réseaux de langage neuronaux ont mis en avant l'idée d'apprendre simultanément : (i) des vecteurs pour les mots/tokens, (ii) une fonction de probabilité sur les séquences, afin de mieux généraliser malgré la malédiction de la dimension des distributions discrètes (Bengio et al., 2003).

Quand la dimension augmente, les exemples deviennent statistiquement plus dispersés. Les distances utiles deviennent moins discriminantes, et il faut davantage de données pour estimer correctement les régularités. Les embeddings aident justement à compresser de l'information utile dans un espace continu appris, plus exploitable qu'une représentation purement discrète.

Repère méthodologique

La dimension élevée n'est pas un défaut en soi. Le problème apparaît quand le nombre d'exemples et la qualité de l'espace appris ne suffisent pas pour structurer correctement cette grande dimension.

Analogie

Si les tokens étaient des noms de villes et les embeddings des coordonnées sur une carte, deux mots proches en sens se retrouveraient proches dans cette carte. Le modèle peut alors généraliser plus facilement.

Exemple d'embedding en 3 dimensions (simplifié)
Python - vecteurs d'exempleCliquez pour l'explication
embedding("chat")   = [ 0.2,  0.8, -0.1]
embedding("chien")  = [ 0.1,  0.7, -0.2]
embedding("banane") = [-0.6,  0.0,  0.9]

Lecture vulgarisée Espace vectoriel

Chaque token est représenté par un point dans un espace à haute dimension. La distance entre deux points reflète leur similarité sémantique.

  1. "chat" et "chien" partagent des contextes similaires (animaux domestiques) → leurs vecteurs sont proches.
  2. "banane" apparaît dans des contextes très différents → son vecteur est éloigné.
  3. En pratique, on utilise des centaines ou milliers de dimensions, pas 3.
  4. La sémantique est distribuée sur toutes les dimensions : aucune dimension ne correspond à un trait linguistique précis.
  5. C'est un encodage émergent appris par l'optimisation, pas une table de traits écrite à la main.
Visualisation intuitive (2D)
axe1 axe2 chat chien banane

Intuition : chat et chien sont proches ; banane est ailleurs. En pratique, les embeddings sont en centaines ou milliers de dimensions.

Représentation vectorielle
Python - lecture d'un vecteurCliquez pour l'explication
Vecteur = [dimension1, dimension2, dimension3, ...]
         [  0.12    ,  -0.03   ,   0.77    , ...]

Lecture vulgarisée Représentation distribuée

Contrairement à une table de traits (ex. [+animé, +domestique, …]), un embedding ne possède pas de dimensions interprétables directement. La signification émerge de la structure globale de l'espace.

  1. Chaque dimension est un nombre réel appris par rétropropagation.
  2. Aucune dimension isolée ne correspond à un trait linguistique précis.
  3. C'est la combinaison de toutes les dimensions qui encode le sens.
  4. Cela permet une généralisation bien meilleure que les représentations one-hot.
Projection PCA 2D PC1 PC2

Vue compacte pour repérer des groupes proches sur deux axes principaux.

Projection PCA 3D PC1 PC2 PC3 point visible en 3D

Vue plus fidèle quand la séparation nécessite une troisième composante principale. Un point supplémentaire apparaît ici et n'était pas distinguable en projection 2D.

Embeddings statiques vs représentations contextualisées

À ce stade, un piège classique apparaît : croire qu'un mot a "un sens" fixe. Les embeddings statiques (type Word2Vec, GloVe) associent en gros un vecteur par mot (ou par token), ce qui marche bien pour une sémantique moyenne.

Mais la langue est pleine de polysémie. Exemple : "banc" (banc de poissons vs banc pour s'asseoir). Un embedding statique doit "moyenner" ces usages en un seul point.

Les représentations contextualisées (ELMo, BERT, Transformers) produisent une représentation du token conditionnée par le contexte : le vecteur pour "banc" n'est pas le même dans "banc de poissons" et "banc en bois".

Encadré de clarification - les trois sens d'"embedding"

Le terme "embedding" peut désigner trois choses distinctes selon le contexte technique : (1) un vecteur appris en entrée (statique, type Word2Vec) ; (2) une représentation interne d'un token à une couche donnée (contextualisée) ; (3) un embedding de phrase (agrégation) utilisé pour la recherche ou la similarité. Le sens du mot "embedding" dépend donc du contexte.

Tableau comparatif
Élément Idée centrale Avantage Limite typique Source pivot
Embeddings statiques
Word2Vec / GloVe
Un vecteur par mot/token Simple, efficace, capture des régularités Polysémie mal gérée (un seul vecteur) Bengio et al., 2003
RNN / LSTM Lire séquentiellement, état caché Naturel pour séquences, historique Longues dépendances + faible parallélisme Elman, 1990
Représentations contextualisées
ELMo / Transformers
Vecteur dépend du contexte Polysémie mieux capturée, transfert Complexité, besoin de données/calcul Jurafsky & Martin, 2024
Trois niveaux, embedding lookup et multiplication matricielle

Cette partie regroupe les trois notions qui créent le plus de confusion. Le but est simple : savoir exactement quel objet on manipule à chaque étape.

1) Embedding d'un token, table du vocabulaire, matrice de séquence

\[ e_i \in \mathbb{R}^{d} \]

C'est la fiche d'identité numérique d'un seul token. On peut l'imaginer comme une ligne de nombres qui décrit ce token pour le modèle.

\[ E \in \mathbb{R}^{|V| \times d} \]

C'est le grand classeur de toutes les fiches d'identité possibles. Une ligne par token du vocabulaire, toujours la même largeur \(d\).

\[ X \in \mathbb{R}^{n \times d}, \qquad X = \begin{bmatrix}E[i_1] \\ E[i_2] \\ \vdots \\ E[i_n]\end{bmatrix} \]

Pour une phrase de longueur \(n\), on empile \(n\) fiches du classeur. La phrase devient une matrice.

2) Formule de lookup

\[ e_i = E_{i,:} \]

Le modèle va dans le classeur \(E\), prend la ligne numéro \(i\), et c'est tout. Le lookup est un accès direct à la bonne ligne.

\[ e_i = o_i^{\top} E \]

Cette écriture dit la même chose autrement. Le vecteur one-hot \(o_i\) agit comme un curseur qui sélectionne exactement une ligne.

3) Transformation matricielle et généralisation

\[ y = xW \]

Le réseau prend une représentation \(x\), la transforme avec \(W\), et produit une nouvelle vue \(y\). C'est la brique de base de presque tous les calculs internes.

\[ N_{\text{séquences}}(n)=|V|^n \]

Le nombre de phrases possibles explose très vite. Les embeddings et les transformations matricielles aident le modèle à généraliser sans avoir vu toutes les phrases exactes.

Bloc Python obligatoire : lookup d'embedding et matrices
Python - table E et matrice XCliquez pour l'explication
import numpy as np

vocab = {"chat": 0, "chien": 1, "banane": 2, ".": 3}
V = len(vocab)
d = 4

np.random.seed(0)
E = np.random.randn(V, d)

sequence = ["chat", "chien", ".", "banane"]
ids = [vocab[t] for t in sequence]
X = E[ids, :]

print("E shape:", E.shape)
print("X shape:", X.shape)
print("embedding('chat'):", X[0])
Exemples appliqués - polysémie "banc"

Phrase A : "Il s'assoit sur le banc."

Phrase B : "Un banc de poissons traverse la baie."

Un embedding statique pour "banc" est unique : il représente une moyenne de ses usages. Une représentation contextualisée, elle, tient compte du contexte "s'assoit" ou "poissons" et se positionne différemment dans l'espace interne.

Pour réfléchir : d'autres mots comme « avocat » (fruit vs métier) ou « charge » (électrique vs responsabilité) posent le même problème. Un embedding statique doit moyenner ces significations, tandis qu'une représentation contextualisée peut distinguer les sens selon la phrase.

RNN et LSTM : architecture, équations, forces, limites, et lien vers l attention

Point clé : dépendance séquentielle

Un RNN ne traite pas les mots indépendamment. À chaque pas, il combine le token courant \(x_t\) avec l'état caché précédent \(h_{t-1}\). Le contexte est donc intégré pendant le calcul.

Principe des réseaux récurrents

Avant les Transformers, les réseaux récurrents (RNN) ont structuré une grande partie du NLP neuronal, notamment parce qu'ils modélisent naturellement des séquences : à chaque pas, l'état caché accumule l'information du passé (Elman, 1990).

Définition simple

Une RNN lit une phrase mot par mot et conserve un état interne.

Explication rigoureuse

Les modèles de langage récurrents (RNNLM) ont montré qu'on pouvait améliorer des métriques de modélisation du langage (perplexité) en exploitant un historique potentiellement long via la récurrence (Elman, 1990).

Analogie

Imaginez un lecteur qui avance ligne par ligne et garde un carnet. Il ne relit pas tout le livre à chaque ligne, il s'appuie sur ce carnet.

Réseau neuronal 1-3-4-3-1
Entrée 1 Cachée 3 Cachée 4 Cachée 3 Sortie 1

Chaque neurone est connecté à tous les neurones de la couche suivante. Le réseau est donc pleinement connecté entre couches adjacentes.

Dans un réseau de neurones dense, chaque couche reçoit les activations de la couche précédente. Elle effectue d'abord une transformation affine, puis applique une fonction d'activation non linéaire.

\[ z^{(\ell)} = W^{(\ell)} a^{(\ell-1)} + b^{(\ell)}, \qquad a^{(\ell)} = \phi\!\left(z^{(\ell)}\right) \]

Ces équations ne décrivent pas une probabilité de passer d'une couche à l'autre. Elles décrivent le calcul réalisé par la couche \(\ell\) à partir des activations de la couche précédente.

Dans le cas particulier d'une classification binaire, la dernière couche contient un seul neurone de sortie. On applique alors une sigmoïde pour obtenir une valeur comprise entre 0 et 1.

\[ \hat{p} = \sigma\!\left(W^{(L)} a^{(L-1)} + b^{(L)}\right) \]
\[ P(y=1 \mid x)=\hat{p}, \qquad P(y=0 \mid x)=1-\hat{p} \]

Les couches internes ne calculent pas des probabilités de transition. Elles transforment progressivement l'information. La dimension probabiliste apparaît à la fin, au niveau de la sortie. En binaire, si la sortie vaut 0,82, le modèle attribue une probabilité estimée de 0,82 à la classe positive.

Signification des symboles : \(a^{(\ell-1)}\) représente les activations de la couche précédente. \(W^{(\ell)}\) et \(b^{(\ell)}\) sont les paramètres appris. \(z^{(\ell)}\) est le signal avant activation. \(\phi\) est la fonction d'activation non linéaire. \(\hat{p}\) est la probabilité estimée de la classe positive.

Limites majeures des RNN

1. Dépendances longues et gradients

Apprendre à conserver une information très ancienne est difficile : les gradients qui se propagent dans le temps ont tendance à s'évanouir ou à exploser. Les LSTM (Long Short-Term Memory) ont été proposées pour mieux gérer ces dépendances via des mécanismes de "gates" (Hochreiter & Schmidhuber, 1997).

2. Parallélisation

Une RNN traite intrinsèquement la séquence pas-à-pas. Même si on optimise l'implémentation, il existe une dépendance séquentielle difficile à éliminer : le calcul de ht requiert ht-1, ce qui empêche le traitement en parallèle de tous les tokens simultanément.

3. Goulot d'étranglement de compression

Dans certaines architectures encodeur-décodeur, tout le sens devait passer par un vecteur fixe (le "vecteur de contexte"), ce qui a motivé l'apparition du mécanisme d'attention dans la traduction neuronale.

Cellule LSTM
Cellule LSTM ct-1 ht-1 xt ct ht σ porte oubli ft σ porte entree it g candidate c~t σ porte sortie ot h Legende connexion principale connexion peephole ⊙ : produit terme a terme ⊕ : somme des flux σ : porte sigmoide g : candidat memoire (tanh) h : activation de sortie (tanh) ct : etat de memoire ht : etat cache de sortie

Cette cellule sépare la mémoire longue \(c_t\) et la sortie instantanée \(h_t\). Les portes contrôlent ce qui est oublié, ajouté et transmis. C'est précisément ce mécanisme qui stabilise l'apprentissage sur des dépendances longues.

\[ \begin{aligned} f_t &= \sigma(W_f[x_t,h_{t-1}] + b_f) \\ i_t &= \sigma(W_i[x_t,h_{t-1}] + b_i) \\ \tilde{c}_t &= \tanh(W_c[x_t,h_{t-1}] + b_c) \\ c_t &= f_t \odot c_{t-1} + i_t \odot \tilde{c}_t \\ o_t &= \sigma(W_o[x_t,h_{t-1}] + b_o) \\ h_t &= o_t \odot \tanh(c_t) \end{aligned} \]
Schéma de la RNN simplifiée
Architecture RNNCliquez pour l'explication
x1 -> [RNN] -> h1 -> y1
x2 -> [RNN] -> h2 -> y2
x3 -> [RNN] -> h3 -> y3
...

Relation récurrente :

• xt = embedding du token t
• ht = état caché (résume le passé)
• yt = sortie (ex. probas du prochain token)

Lecture vulgarisée Architecture RNN

La RNN traite la séquence pas-à-pas. À chaque étape t, elle combine l'embedding du token courant xt avec l'état caché précédent ht-1 pour produire le nouvel état ht et une sortie yt.

  1. xt : le token t est converti en vecteur (embedding).
  2. ht-1 : l'état caché du pas précédent résume tout le passé.
  3. La fonction récurrente combine l'entrée courante et l'état précédent.
  4. yt : la sortie (ex. distribution de probabilité sur le prochain token).
  5. La dépendance séquentielle ht -> ht+1 rend la parallélisation difficile.
\[ h_t = \tanh\!\left(W_x x_t + W_h h_{t-1} + b_h\right) \]

Version canonique : la non-linéarité \(\tanh\) transforme le mélange du présent et du passé.

Bloc Python obligatoire : un pas RNN et un pas LSTM
Python - équations manipulablesCliquez pour l'explication
import numpy as np

def tanh(x):
    return np.tanh(x)

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def rnn_step(x_t, h_prev, Wx=0.8, Wh=0.4, b=0.0):
    preact = Wx * x_t + Wh * h_prev + b
    h_t = tanh(preact)
    return h_t

def lstm_step(c_prev, i_preact=1.0, f_preact=-1.0, o_preact=0.5, g_preact=0.2):
    i_t, f_t, o_t = sigmoid(i_preact), sigmoid(f_preact), sigmoid(o_preact)
    g_t = tanh(g_preact)
    c_t = f_t * c_prev + i_t * g_t
    h_t = o_t * tanh(c_t)
    return h_t, c_t

print("rnn h_t =", rnn_step(1.0, 0.5))
print("lstm (h_t, c_t) =", lstm_step(0.1))

Aperçu du Transformer : attention, Q/K/V, softmax, logits et token suivant

Intuition du mécanisme d attention

Le mécanisme d'attention est au cœur de l'architecture Transformer. Pour chaque token, trois vecteurs sont calculés à partir de son embedding : la requête (Query, q), la clé (Key, k) et la valeur (Value, v). Le diagramme ci-dessous illustre ce mécanisme sur la phrase "A cute teddy bear is reading."

A cute teddy bear is reading. a cute teddy bear is reading . va vcute vteddy bear vis vreading v. a cute teddy bear is reading . kTa kTcute kTteddy bear kTis kTreading kT. qteddy bear a cute teddy bear is reading . LÉGENDE vx = Value du token x kTx = Key transposée de x qx = Query du token x = score k·q Token focus : teddy bear (token "requêteur") v_a : Value du token "a". k^T_a : Key transposée du token "a". Ces vecteurs sont calculés par multiplication de l'embedding par des matrices de poids W_V et W_K. v_cute : Value du token "cute". k^T_cute : Key transposée du token "cute". v_teddy bear : Value du token "teddy bear". k^T_teddy bear : Key transposée. q_teddy bear : Query - ce token est le token "requêteur" dans cet exemple. Sa Query est comparée aux Keys de tous les autres tokens. v_is : Value du token "is". k^T_is : Key transposée du token "is". v_reading : Value du token "reading". k^T_reading : Key transposée du token "reading". v_. : Value du token ".". k^T_. : Key transposée du token ".".
Explication du diagramme

Le diagramme illustre le mécanisme d'attention pour le token "teddy bear" dans la phrase "A cute teddy bear is reading." La rangée supérieure montre les tokens de la phrase tels qu'ils arrivent en entrée. La rangée centrale montre les mêmes tokens avec leurs vecteurs Value (v, en vert, au-dessus) et leurs vecteurs Key transposés (kT, en bleu, en dessous). Les lignes convergent toutes vers la Query qteddy bear (en rouge), qui représente "ce que le token teddy bear cherche" dans le contexte. La rangée inférieure montre les tokens de sortie, avec "teddy bear" mis en évidence comme token dont la représentation contextualisée est calculée.

Formellement, le score d'attention entre le token requêteur \(i\) et le token clé \(j\) est un produit scalaire entre \(q_i\) et \(k_j\), suivi d'une normalisation.

\[ \mathrm{Attention}(Q,K,V)=\mathrm{softmax}\!\left(\frac{QK^{T}}{\sqrt{d_k}}\right)V \]
Formules clés pour l'aperçu Transformer

Produit scalaire

\[ q \cdot k = \sum_{m=1}^{d} q_m k_m \]

Scaled dot-product attention

\[ \mathrm{Attention}(Q,K,V)=\mathrm{softmax}\!\left(\frac{QK^{T}}{\sqrt{d_k}}\right)V \]

Softmax

\[ \mathrm{softmax}(z)_i = \frac{e^{z_i}}{\sum_j e^{z_j}} \]

Même fonction mathématique, deux usages différents : distribution d'attention sur le contexte, puis distribution de sortie sur le vocabulaire.

Logits et probabilité du token suivant

Point clé : l'attention construit une représentation contextualisée. La sélection du token suivant se fait ensuite via les logits et le décodage.

\[ z_t = W_o h_t + b_o \]
\[ P(x_{t+1}=j \mid x_{\le t}) = \mathrm{softmax}(z_t)_j \]

Le modèle calcule des scores \(z_t\), puis les convertit en probabilités avant le choix du token suivant.

Tableau comparatif : RNN/LSTM vs Transformer
Critère RNN / LSTM Transformer (aperçu)
Parallélisation Limitée par la dépendance séquentielle Plus forte grâce aux opérations matricielles sur la séquence
Dépendances longues Difficiles malgré les portes LSTM Mieux gérées via les interactions attentionnelles directes
Coût en longueur Séquentiel, peu parallélisable Attention quadratique en version standard, mais parallélisable
Mécanisme de mémoire Etat caché et cellule mémoire Représentation distribuée par attention

Atelier Python : température, top-k, top-p et impact en décodage

Bloc Python obligatoire : sampling sur distribution jouet
Python - logits, softmax, top-k, top-pCliquez pour l'explication
import math
import random

def softmax(logits):
    m = max(logits)
    exps = [math.exp(x - m) for x in logits]
    s = sum(exps)
    return [e / s for e in exps]

def apply_temperature(logits, T):
    return [x / T for x in logits]

def top_k_filter(tokens, probs, k):
    pairs = sorted(zip(tokens, probs), key=lambda x: x[1], reverse=True)
    kept = pairs[:k]
    total = sum(p for _, p in kept)
    return [(t, p/total) for t, p in kept]

def top_p_filter(tokens, probs, p):
    pairs = sorted(zip(tokens, probs), key=lambda x: x[1], reverse=True)
    kept, cum = [], 0.0
    for t, pr in pairs:
        kept.append((t, pr))
        cum += pr
        if cum >= p:
            break
    total = sum(pr for _, pr in kept)
    return [(t, pr/total) for t, pr in kept]

tokens = ["lait", "eau", "moteur", "chaise"]
logits = [2.0, 1.0, 0.1, -0.5]
probs = softmax(logits)

print("T=1:", list(zip(tokens, probs)))
print("top-k=2:", top_k_filter(tokens, probs, k=2))
print("top-p=0.8:", top_p_filter(tokens, probs, p=0.8))

Fenêtre glissante, erreurs fréquentes et bibliographie

Fenêtre glissante et apprentissage auto-régressif

La fenêtre glissante est une bonne intuition pédagogique pour comprendre le décalage des cibles. Le principe reste toujours le même : à partir d'un préfixe de tokens, le modèle apprend à prédire le token suivant.

Dans une implémentation explicite, on décale la fenêtre d'un seul token à chaque nouvel exemple. Dans les LLM modernes, on traite plutôt une séquence complète de longueur de contexte, puis on apprend en une passe plusieurs prédictions décalées. Le cadre reste auto-régressif et correspond à la next-token prediction.

Intuition minimaleCliquez pour l'explication
fenêtre 1 -> [t1, t2, t3] pour prédire t4
fenêtre 2 -> [t2, t3, t4] pour prédire t5
fenêtre 3 -> [t3, t4, t5] pour prédire t6
Erreurs fréquentes à éviter
Erreur fréquente Pourquoi c'est incorrect
Confondre token et mot Un token est souvent un sous-mot ou un signe de ponctuation selon le tokenizer.
Confondre tokenisation et embedding La tokenisation produit des IDs discrets, l'embedding produit des vecteurs continus.
Confondre table d'embedding et matrice de séquence \(E\) couvre tout le vocabulaire, \(X\) ne contient que les lignes sélectionnées pour la séquence.
Dire attention = choix du prochain token L'attention contextualise ; logits, softmax et décodage réalisent le choix de sortie.
Dire top-p ou température modifient l'apprentissage Ces réglages interviennent à l'inférence, pas dans les poids appris.
Bibliographie commentée de la séance

Speech and Language Processing - Jurafsky, D., Martin, J. H. Manuel de référence pour NLP et LLM.

A Neural Probabilistic Language Model - Bengio et al., 2003. Représentations distribuées et généralisation.

Efficient Estimation of Word Representations in Vector Space - Mikolov et al., 2013.

Subword Units for Rare Words - Sennrich et al., 2016.

SentencePiece - Kudo, Richardson, 2018.

Finding Structure in Time - Elman, 1990.

Learning Long-Term Dependencies with Gradient Descent is Difficult - Bengio et al., 1994.

On the difficulty of training RNN - Pascanu et al., 2012.

Long Short-Term Memory - Hochreiter, Schmidhuber, 1997.

Attention Is All You Need - Vaswani et al., 2017.

The Curious Case of Neural Text Degeneration - Holtzman et al., 2019.

Documentation API OpenAI - Paramètres de sampling et manipulation des logits.