Ouvrir le Capot
À l'époque, je voyais l'IA comme une boîte noire magique. J'ai demandé à mon interlocuteur numérique de m'expliquer, vraiment, comment ça marche. Pas d'analogies foireuses. Je voulais voir les fichiers. Je voulais voir la théorie brute.
Il m'a généré un guide technique que j'ai conservé précieusement. Le voici, tel quel :
Archive: comprendre_llm.md
1. Comment ça fonctionne ? (La théorie)
Imaginez le correcteur automatique de votre téléphone, mais sous stéroïdes. Le cœur du fonctionnement repose sur trois piliers :
- A. La Tokenisation : L'ordinateur ne comprend pas les mots. Il ne voit que des nombres. "Le chat mange" devient
[1204, 4588, 992]. - B. L'Embedding : Chaque token est transformé en un vecteur. Le mot "Roi" aura des nombres mathématiquement proches de "Reine". C'est ainsi que le modèle comprend le sens.
- C. Le Transformer : Son innovation majeure est le mécanisme d'Attention. Il permet au modèle de "regarder" tous les mots précédents en même temps pour comprendre le contexte (savoir que "il" désigne l'animal et pas la rue).
2. À quoi ressemblent ses fichiers ?
Si vous téléchargiez un LLM sur votre disque dur, voici ce que vous verriez :
config.json: La carte d'identité (nombre de couches, etc.).tokenizer.json: Le dictionnaire de traduction Mots -> Nombres.- Les Poids (model.safetensors) : Le "cerveau". Un fichier de plusieurs Go qui ne contient aucun texte, juste des milliards de nombres à virgule flottante (les paramètres figés après l'entraînement).
Mais le plus frappant fut le code. Il a réduit l'intelligence artificielle à quelques classes Python. C'est de l'algèbre linéaire pure.
import torch
import torch.nn as nn
import torch.nn.functional as F
# L'essence de l'attention (Self-Attention Head)
class Head(nn.Module):
def __init__(self, head_size, n_embd, block_size):
super().__init__()
self.key = nn.Linear(n_embd, head_size, bias=False)
self.query = nn.Linear(n_embd, head_size, bias=False)
self.value = nn.Linear(n_embd, head_size, bias=False)
# Masque pour ne pas tricher en regardant le futur
self.register_buffer('tril', torch.tril(torch.ones(block_size, block_size)))
def forward(self, x):
B, T, C = x.shape
k = self.key(x)
q = self.query(x)
# Calcul des scores d'attention ("qui regarde qui ?")
wei = q @ k.transpose(-2, -1) * C**-0.5
wei = wei.masked_fill(self.tril[:T, :T] == 0, float('-inf'))
wei = F.softmax(wei, dim=-1)
v = self.value(x)
out = wei @ v
return out
# Le bloc Transformer standard
class Block(nn.Module):
def __init__(self, n_embd, n_head, block_size, dropout):
super().__init__()
head_size = n_embd // n_head
self.sa = MultiHeadAttention(n_head, head_size, n_embd, block_size, dropout)
self.ffwd = FeedFoward(n_embd, dropout)
self.ln1 = nn.LayerNorm(n_embd)
self.ln2 = nn.LayerNorm(n_embd)
def forward(self, x):
# Communication (Attention) + Réflexion (FeedForward)
x = x + self.sa(self.ln1(x))
x = x + self.ffwd(self.ln2(x))
return x