<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mathématiques on kenji.blog</title><link>http://kenji.blog/fr/categories/math%C3%A9matiques/</link><description>Recent content in Mathématiques on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>fr</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 22:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/fr/categories/math%C3%A9matiques/index.xml" rel="self" type="application/rss+xml"/><item><title>【Pour les débutants】Décrypter la structure mathématique du modèle Transformer</title><link>http://kenji.blog/fr/p/transformer-mathematical-structure/</link><pubDate>Fri, 11 Sep 2026 22:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/transformer-mathematical-structure/</guid><description>&lt;img src="http://kenji.blog/p/transformer-mathematical-structure/img/eyecatch.jpg" alt="Featured image of post 【Pour les débutants】Décrypter la structure mathématique du modèle Transformer" />&lt;h1 id="introduction--pourquoi-apprendre-les-mathématiques-du-transformer-">Introduction : Pourquoi apprendre les mathématiques du Transformer ?
&lt;/h1>&lt;p>Il n&amp;rsquo;est pas exagéré de dire que le &amp;ldquo;Transformer&amp;rdquo; est l&amp;rsquo;architecture qui a réécrit l&amp;rsquo;histoire du traitement du langage naturel (NLP) moderne et de l&amp;rsquo;IA dans son ensemble. Ce modèle, proposé pour la première fois dans l&amp;rsquo;article &amp;ldquo;Attention Is All You Need&amp;rdquo; publié par des chercheurs de Google en 2017, sert de cœur aux grands modèles de langage (LLM) qui dominent actuellement le monde, tels que la série GPT d&amp;rsquo;OpenAI (la technologie sous-jacente de ChatGPT), BERT de Google et Claude d&amp;rsquo;Anthropic.&lt;/p>
&lt;p>Cependant, bien que l&amp;rsquo;on trouve souvent des explications qualitatives sur le fonctionnement du Transformer telles que &amp;ldquo;comprendre le contexte en utilisant l&amp;rsquo;Attention (mécanisme d&amp;rsquo;attention)&amp;rdquo;, il existe actuellement très peu d&amp;rsquo;explications approfondies destinées aux débutants sur la &lt;strong>structure mathématique&lt;/strong> qui se cache derrière. Pour vraiment comprendre comment l&amp;rsquo;IA traite les &amp;ldquo;mots&amp;rdquo; comme des &amp;ldquo;formules mathématiques&amp;rdquo; et génère des textes étonnamment naturels, il est essentiel de décrypter son mécanisme mathématique.&lt;/p>
&lt;p>Dans cet article, destiné à ceux qui ont des connaissances de base en mathématiques et en programmation (ceux qui comprennent les concepts de matrices et de dérivées au niveau du lycée), nous allons décrypter de manière exhaustive et compréhensible les structures mathématiques qui constituent le cœur du Transformer, telles que le &amp;ldquo;mécanisme de Self-Attention&amp;rdquo;, le modèle &amp;ldquo;Requête-Clé-Valeur (Q/K/V)&amp;rdquo;, la &amp;ldquo;normalisation par la fonction Softmax&amp;rdquo; et le &amp;ldquo;Positional Encoding&amp;rdquo;.&lt;/p>
&lt;p>Vous pourriez être submergé par la liste des formules, mais chaque calcul a une &amp;ldquo;signification&amp;rdquo; claire. À la fin de cet article, vous devriez comprendre que le Transformer n&amp;rsquo;est pas simplement une boîte noire magique, mais l&amp;rsquo;aboutissement de mathématiques et de statistiques conçues avec précision.&lt;/p>
&lt;hr>
&lt;h1 id="1-les-limites-des-méthodes-traditionnelles-et-linnovation-du-transformer">1. Les limites des méthodes traditionnelles et l&amp;rsquo;innovation du Transformer
&lt;/h1>&lt;p>Avant l&amp;rsquo;apparition du Transformer, le courant principal du traitement du langage naturel était les réseaux de neurones récurrents (RNN) et leurs dérivés, les LSTM (Long Short-Term Memory). Les RNN ont été conçus pour traiter des données chronologiques et lisent les phrases mot par mot, dans l&amp;rsquo;ordre, depuis le début.&lt;/p>
&lt;p>Cependant, les RNN présentaient deux faiblesses fatales.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Difficulté d&amp;rsquo;apprentissage des dépendances à long terme&lt;/strong> : Lorsque les phrases deviennent longues, les informations des mots saisis au début s&amp;rsquo;estompent avant d&amp;rsquo;atteindre la fin (problème de la disparition du gradient).&lt;/li>
&lt;li>&lt;strong>Impossibilité de calcul parallèle&lt;/strong> : Comme les mots doivent être traités séquentiellement, il est difficile d&amp;rsquo;effectuer des calculs parallèles à grande échelle à l&amp;rsquo;aide de GPU, ce qui nécessite un temps énorme pour l&amp;rsquo;apprentissage.&lt;/li>
&lt;/ol>
&lt;p>Le Transformer a complètement abandonné la structure des RNN et a provoqué un changement de paradigme consistant à capturer le contexte en utilisant uniquement l&amp;rsquo;&amp;ldquo;Attention&amp;rdquo;. Grâce à cela, quelle que soit la longueur de la séquence, il n&amp;rsquo;y a aucune perte d&amp;rsquo;information, et il est devenu possible de paralléliser les calculs pour maximiser les performances du GPU.&lt;/p>
&lt;hr>
&lt;h1 id="2-larchitecture-globale-du-transformer">2. L&amp;rsquo;architecture globale du Transformer
&lt;/h1>&lt;p>Commençons par examiner l&amp;rsquo;architecture globale du Transformer. Le Transformer est composé principalement de deux blocs : l&amp;rsquo;&amp;ldquo;Encoder&amp;rdquo; (encodeur) et le &amp;ldquo;Decoder&amp;rdquo; (décodeur). Si l&amp;rsquo;on prend l&amp;rsquo;exemple d&amp;rsquo;une tâche de traduction, l&amp;rsquo;Encoder convertit la langue source (ex : anglais) en une représentation vectorielle mathématique, et le Decoder génère la langue cible (ex : japonais) à partir de cette représentation vectorielle.&lt;/p>
&lt;p>Le diagramme ci-dessous est une simplification de la structure interne du bloc Encoder.&lt;/p>
&lt;div class="mermaid">graph TD
A["Jetons d'entrée"] --> B["Intégration d'entrée"]
B --> C["Encodage positionnel"]
C --> D["Multi-Head Self-Attention"]
D --> E["Ajout et normalisation de couche"]
E --> F["Réseau Feed Forward"]
F --> G["Ajout et normalisation de couche"]
G --> H["Sortie vers la couche suivante"]
C -.->|"Connexion résiduelle"| E
E -.->|"Connexion résiduelle"| G&lt;/div>
&lt;p>À partir d&amp;rsquo;ici, examinons étape par étape les opérations mathématiques effectuées dans chaque composant.&lt;/p>
&lt;hr>
&lt;h1 id="3-vectorisation-des-mots-et-encodage-positionnel-positional-encoding">3. Vectorisation des mots et encodage positionnel (Positional Encoding)
&lt;/h1>&lt;p>Un ordinateur ne peut pas comprendre le texte tel quel. Le texte d&amp;rsquo;entrée est d&amp;rsquo;abord divisé en unités appelées &amp;ldquo;jetons&amp;rdquo; (Tokens), et chacun est converti en un vecteur de longueur fixe. C&amp;rsquo;est ce qu&amp;rsquo;on appelle l&amp;rsquo;&lt;strong>Input Embedding&lt;/strong> (Intégration d&amp;rsquo;entrée).&lt;/p>
&lt;h2 id="31-les-mathématiques-de-linput-embedding">3.1 Les mathématiques de l&amp;rsquo;Input Embedding
&lt;/h2>&lt;p>Soit $V$ la taille du vocabulaire et $d_{model}$ la dimension des vecteurs d&amp;rsquo;intégration (dans l&amp;rsquo;article original, $d_{model} = 512$). Chaque mot $w_i$ est converti en un vecteur $x_i \in \mathbb{R}^{d_{model}}$ à l&amp;rsquo;aide de la matrice d&amp;rsquo;intégration $W_E \in \mathbb{R}^{V \times d_{model}}$.&lt;/p>
$$ x_i = W_E \cdot \text{one\_hot}(w_i) $$
&lt;p>Ainsi, la phrase entière est représentée comme une matrice $X \in \mathbb{R}^{N \times d_{model}}$ ($N$ étant la longueur de la phrase).&lt;/p>
&lt;h2 id="32-la-nécessité-et-les-formules-du-positional-encoding-encodage-positionnel">3.2 La nécessité et les formules du Positional Encoding (Encodage positionnel)
&lt;/h2>&lt;p>Le Transformer ne traite pas les mots séquentiellement comme les RNN, mais traite tous les mots simultanément et en parallèle. Bien que cela soit un grand avantage du point de vue de la vitesse de calcul, cela pose le problème que &lt;strong>l&amp;rsquo;information importante de &amp;ldquo;l&amp;rsquo;ordre des mots&amp;rdquo; est perdue&lt;/strong>. Par exemple, &amp;ldquo;Un chien mord un homme&amp;rdquo; et &amp;ldquo;Un homme mord un chien&amp;rdquo; ont le même ensemble de mots en entrée, mais des significations complètement différentes.&lt;/p>
&lt;p>Le &lt;strong>Positional Encoding&lt;/strong> a été conçu pour fournir cette information d&amp;rsquo;ordre des mots au modèle.
Le Positional Encoding $PE$ pour la dimension $i$ du mot situé à la position $pos$ est calculé à l&amp;rsquo;aide des fonctions trigonométriques suivantes.&lt;/p>
$$ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$
$$ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$
&lt;p>Où $pos$ est la position du mot ($0, 1, 2, \dots, N-1$), et $i$ est l&amp;rsquo;indice de la dimension du vecteur ($0, 1, \dots, d_{model}/2 - 1$).&lt;/p>
&lt;h3 id="pourquoi-utiliser-le-sinus-et-le-cosinus-">Pourquoi utiliser le sinus et le cosinus ?
&lt;/h3>&lt;p>À première vue, cela ressemble à une formule très complexe et étrange, mais il y a une raison mathématique profonde à cela. En utilisant des fonctions trigonométriques, le modèle peut facilement apprendre non seulement les &lt;strong>&amp;ldquo;positions absolues&amp;rdquo; mais aussi les différences de &amp;ldquo;positions relatives&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;p>Rappelez-vous les formules d&amp;rsquo;addition trigonométriques apprises au lycée.
&lt;/p>
$$ \sin(\alpha + \beta) = \sin\alpha \cos\beta + \cos\alpha \sin\beta $$
$$ \cos(\alpha + \beta) = \cos\alpha \cos\beta - \sin\alpha \sin\beta $$
&lt;p>Le Positional Encoding d&amp;rsquo;une position $pos + k$ décalée d&amp;rsquo;un offset $k$ par rapport à une position $pos$ peut être exprimé comme une combinaison linéaire du Positional Encoding de la position $pos$. C&amp;rsquo;est-à-dire, en utilisant une matrice $M_k$, cela peut s&amp;rsquo;écrire ainsi :&lt;/p>
$$ PE_{pos+k} = M_k \cdot PE_{pos} $$
&lt;p>Ainsi, le mécanisme d&amp;rsquo;Attention peut facilement reconnaître la distance relative &amp;ldquo;à quelle distance&amp;rdquo; se trouvent les mots les uns par rapport aux autres grâce au calcul du produit scalaire. De plus, en combinant plusieurs ondes de sinus et cosinus de longueurs d&amp;rsquo;onde différentes, il y a l&amp;rsquo;avantage de pouvoir générer un vecteur de position unique, quelle que soit la longueur de la phrase.&lt;/p>
&lt;p>La matrice d&amp;rsquo;entrée finale $X_{input}$ est la somme des vecteurs d&amp;rsquo;intégration des mots et de cet encodage positionnel.&lt;/p>
$$ X_{input} = X + PE $$
&lt;hr>
&lt;h1 id="4-les-mathématiques-profondes-de-la-self-attention-mécanisme-dauto-attention">4. Les mathématiques profondes de la Self-Attention (Mécanisme d&amp;rsquo;auto-attention)
&lt;/h1>&lt;p>Nous entrons enfin dans le composant le plus important du Transformer, la &lt;strong>Self-Attention&lt;/strong> (mécanisme d&amp;rsquo;auto-attention). L&amp;rsquo;objectif de la Self-Attention est de &amp;ldquo;calculer le degré de pertinence entre tous les mots de la phrase et de mettre à jour le vecteur de chaque mot vers une représentation plus riche qui prend en compte le contexte&amp;rdquo;.&lt;/p>
&lt;p>Ici, nous utilisons l&amp;rsquo;analogie d&amp;rsquo;un &amp;ldquo;système de recherche&amp;rdquo;.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Query (Q)&lt;/strong> : Requête (terme de recherche). &amp;ldquo;Quelle est l&amp;rsquo;information que je cherche maintenant ?&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>Key (K)&lt;/strong> : Clé (en-tête). &amp;ldquo;Quelle est l&amp;rsquo;information que je possède ?&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>Value (V)&lt;/strong> : Valeur (entité). &amp;ldquo;Quelle est l&amp;rsquo;information que je fournis réellement ?&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;h2 id="41-génération-des-matrices-q-k-v">4.1 Génération des matrices $Q, K, V$
&lt;/h2>&lt;p>Pour la matrice d&amp;rsquo;entrée $X \in \mathbb{R}^{N \times d_{model}}$ (pour simplifier, nous ignorons la taille du batch ici), nous calculons la requête $Q$, la clé $K$ et la valeur $V$ en multipliant par les matrices de poids apprenables $W^Q, W^K, W^V \in \mathbb{R}^{d_{model} \times d_k}$. (Généralement $d_k = d_v = d_{model} / h$)&lt;/p>
$$ Q = X W^Q $$
$$ K = X W^K $$
$$ V = X W^V $$
&lt;p>Ici, $Q, K, V$ sont toutes des matrices de $\mathbb{R}^{N \times d_k}$.&lt;/p>
&lt;h2 id="42-calcul-de-lattention-score-produit-scalaire">4.2 Calcul de l&amp;rsquo;Attention Score (Produit scalaire)
&lt;/h2>&lt;p>Pour mesurer à quel point la Query de chaque mot est liée aux Key de tous les autres mots, nous calculons le &lt;strong>produit scalaire&lt;/strong> des vecteurs. Écrit en opérations matricielles, cela donne :&lt;/p>
$$ \text{Scores} = Q K^T $$
&lt;p>Chaque élément $s_{ij}$ de la matrice $\text{Scores} \in \mathbb{R}^{N \times N}$ obtenue par ce calcul représente le produit scalaire entre la Query du $i$-ème mot et la Key du $j$-ème mot, c&amp;rsquo;est-à-dire &amp;ldquo;l&amp;rsquo;intensité de la pertinence&amp;rdquo;.&lt;/p>
&lt;h2 id="43-mise-à-léchelle-scale">4.3 Mise à l&amp;rsquo;échelle (Scale)
&lt;/h2>&lt;p>Il y a un problème avec le calcul du score par produit scalaire. Lorsque la dimension des vecteurs $d_k$ augmente, la valeur du produit scalaire devient extrêmement grande ou petite.&lt;/p>
&lt;p>Prouvons-le mathématiquement.
Supposons que chaque élément de la requête $q \sim \mathcal{N}(0, 1)$ et chaque élément de la clé $k \sim \mathcal{N}(0, 1)$ suivent des distributions normales centrées réduites indépendantes.
Nous cherchons la moyenne et la variance du produit scalaire $q \cdot k = \sum_{i=1}^{d_k} q_i k_i$.
Moyenne : Comme $\mathbb{E}[q_i k_i] = \mathbb{E}[q_i] \mathbb{E}[k_i] = 0 \times 0 = 0$, la moyenne de la somme est aussi $0$.
Variance : La variance de $q_i k_i$ est, par indépendance, $\text{Var}(q_i k_i) = \mathbb{E}[(q_i k_i)^2] - (\mathbb{E}[q_i k_i])^2 = 1 \times 1 - 0 = 1$.
Par conséquent, la variance totale du produit scalaire est égale à la dimension $d_k$.&lt;/p>
$$ \text{Var}(q \cdot k) = d_k $$
&lt;p>Si la variance devient grande, la fonction Softmax appliquée par la suite entraînera une &amp;ldquo;disparition du gradient&amp;rdquo; où les gradients des valeurs autres que le maximum deviendront extrêmement petits, ce qui empêchera l&amp;rsquo;apprentissage de progresser.
Pour éviter cela, nous divisons (mettons à l&amp;rsquo;échelle) les scores par $\sqrt{d_k}$ afin de maintenir la variance toujours à $1$.&lt;/p>
$$ \text{Scaled Scores} = \frac{Q K^T}{\sqrt{d_k}} $$
&lt;h2 id="44-probabilisation-par-la-fonction-softmax">4.4 Probabilisation par la fonction Softmax
&lt;/h2>&lt;p>Afin de convertir les scores obtenus en une distribution de probabilité (poids) dont la somme est de $1$, nous appliquons la &lt;strong>fonction Softmax&lt;/strong> ligne par ligne.&lt;/p>
$$ a_{ij} = \text{softmax}(s_i)_j = \frac{\exp(s_{ij} / \sqrt{d_k})}{\sum_{m=1}^N \exp(s_{im} / \sqrt{d_k})} $$
&lt;p>La matrice $A \in \mathbb{R}^{N \times N}$ est appelée matrice de poids d&amp;rsquo;attention (Attention Weight). Si l&amp;rsquo;on regarde chaque ligne $i$ de cette matrice, &amp;ldquo;dans quelle mesure faut-il prêter attention au mot $j$ pour comprendre le mot $i$&amp;rdquo; est exprimé par une valeur allant de 0 à 1.&lt;/p>
&lt;h2 id="45-somme-pondérée-des-value">4.5 Somme pondérée des Value
&lt;/h2>&lt;p>Enfin, en utilisant la matrice Attention Weight $A$ obtenue, nous calculons la somme pondérée de la matrice Value $V$.&lt;/p>
$$ \text{Output} = A V = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V $$
&lt;p>La matrice $Z \in \mathbb{R}^{N \times d_v}$ produite par cette opération est un ensemble de &amp;ldquo;représentations vectorielles de mots mises à jour en tenant compte du contexte&amp;rdquo;.
C&amp;rsquo;est la vue d&amp;rsquo;ensemble du &lt;strong>Scaled Dot-Product Attention&lt;/strong> défini dans l&amp;rsquo;article.&lt;/p>
&lt;hr>
&lt;h1 id="5-multi-head-attention-attention-multi-têtes">5. Multi-Head Attention (Attention multi-têtes)
&lt;/h1>&lt;p>Avec un seul calcul d&amp;rsquo;Attention (tête unique), il est possible de ne capturer le contexte que d&amp;rsquo;un seul point de vue (par exemple, &amp;ldquo;la relation grammaticale&amp;rdquo;). Par conséquent, pour capturer simultanément les diverses relations sémantiques et syntaxiques du langage (comme &amp;ldquo;sujet et prédicat&amp;rdquo;, &amp;ldquo;pronom et son référent&amp;rdquo;, etc.), la &lt;strong>Multi-Head Attention&lt;/strong> a été introduite.&lt;/p>
&lt;p>La génération de $Q, K, V$ et le calcul de l&amp;rsquo;Attention précédents sont effectués en parallèle $h$ fois (nombre de têtes. Dans l&amp;rsquo;article original $h=8$).&lt;/p>
$$ \text{head}_i = \text{Attention}(X W_i^Q, X W_i^K, X W_i^V) $$
&lt;p>Ici, $W_i^Q, W_i^K, W_i^V \in \mathbb{R}^{d_{model} \times d_k}$ sont des matrices de poids apprenables dédiées à la $i$-ème tête.&lt;/p>
&lt;p>Les résultats $\text{head}_i \in \mathbb{R}^{N \times d_v}$ de chaque tête sont concaténés horizontalement.&lt;/p>
$$ \text{Concat}(\text{head}_1, \dots, \text{head}_h) \in \mathbb{R}^{N \times (h \cdot d_v)} $$
&lt;p>Habituellement, on paramètre de telle sorte que $h \cdot d_v = d_{model}$, donc la dimension après concaténation revient à $d_{model}$, identique à l&amp;rsquo;entrée. Enfin, cette matrice est multipliée par une matrice de poids $W^O \in \mathbb{R}^{d_{model} \times d_{model}}$ pour obtenir la sortie finale.&lt;/p>
$$ \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h) W^O $$
&lt;div class="mermaid">graph TD
X["Entrée X"] --> Q1["Q1"]
X --> K1["K1"]
X --> V1["V1"]
Q1 &amp; K1 &amp; V1 --> H1["Tête 1"]
X --> Q2["Q2"]
X --> K2["K2"]
X --> V2["V2"]
Q2 &amp; K2 &amp; V2 --> H2["Tête 2"]
X --> QN["..."]
X --> KN["..."]
X --> VN["..."]
QN &amp; KN &amp; VN --> HN["Tête h"]
H1 &amp; H2 &amp; HN --> C["Concaténer"]
C --> WO["Multiplier par WO"]
WO --> OUT["Sortie Multi-Head"]&lt;/div>
&lt;hr>
&lt;h1 id="6-réseau-de-neurones-feed-forward-ffn">6. Réseau de neurones Feed-Forward (FFN)
&lt;/h1>&lt;p>La sortie de la Multi-Head Attention est ensuite introduite dans un &lt;strong>Position-wise Feed-Forward Network (FFN)&lt;/strong>.
Il s&amp;rsquo;agit d&amp;rsquo;un réseau de neurones entièrement connecté à deux couches appliqué &amp;ldquo;indépendamment à chaque position (mot)&amp;rdquo; de la séquence.&lt;/p>
&lt;p>Exprimé par des formules, cela donne :&lt;/p>
$$ \text{FFN}(x) = \max(0, x W_1 + b_1) W_2 + b_2 $$
&lt;p>Ici, $\max(0, z)$ représente la fonction d&amp;rsquo;activation ReLU (Rectified Linear Unit) (dans les modèles récents, GELU ou SwiGLU sont souvent utilisés).&lt;/p>
&lt;p>Le rôle de ce réseau est très important. Le mécanisme d&amp;rsquo;Attention apprend les &amp;ldquo;relations entre les mots (relations spatiales et séquentielles)&amp;rdquo;, tandis que le FFN se charge de la &amp;ldquo;transformation de caractéristiques non linéaires du vecteur de chaque mot lui-même&amp;rdquo;.
Habituellement, la dimension est temporairement considérablement augmentée par le poids $W_1$ de la première couche (par exemple, augmentée 4 fois, de $d_{model}=512$ à $d_{ff}=2048$), et après avoir effectué des calculs complexes dans l&amp;rsquo;espace des caractéristiques, elle est ramenée à sa dimension d&amp;rsquo;origine par le poids $W_2$ de la deuxième couche. Cette &amp;ldquo;expansion et réduction de dimension&amp;rdquo; augmente considérablement la puissance expressive du modèle.&lt;/p>
&lt;hr>
&lt;h1 id="7-connexions-résiduelles-residual-connection-et-layer-normalization">7. Connexions résiduelles (Residual Connection) et Layer Normalization
&lt;/h1>&lt;p>En apprentissage profond, lorsque les couches du réseau sont approfondies, il y a un problème de disparition ou d&amp;rsquo;explosion des gradients pendant l&amp;rsquo;apprentissage, ce qui empêche un apprentissage correct. Pour éviter cela, des &lt;strong>connexions résiduelles (Residual Connection)&lt;/strong> et une &lt;strong>Layer Normalization (normalisation de couche)&lt;/strong> sont placées autour de chaque sous-couche (Attention et FFN) du Transformer.&lt;/p>
&lt;p>Écrit mathématiquement, la sortie de la sous-couche est traitée comme suit :&lt;/p>
$$ \text{Output} = \text{LayerNorm}(x + \text{Sublayer}(x)) $$
&lt;h2 id="71-connexion-résiduelle-x--textsublayerx">7.1 Connexion résiduelle ($x + \text{Sublayer}(x)$)
&lt;/h2>&lt;p>L&amp;rsquo;entrée $x$ est directement ajoutée à la sortie de la sous-couche. Ainsi, lors de la rétropropagation, le gradient est transmis directement aux couches peu profondes via ce raccourci, ce qui stabilise l&amp;rsquo;apprentissage même si les couches sont profondes.&lt;/p>
&lt;h2 id="72-les-mathématiques-de-la-layer-normalization">7.2 Les mathématiques de la Layer Normalization
&lt;/h2>&lt;p>La Layer Normalization est une technique de normalisation des données en calculant la moyenne et la variance le long de la dimension des caractéristiques. Pour une entrée de taille de batch $B$, de longueur de séquence $N$ et de dimension $d_{model}$, la normalisation est effectuée sur un seul vecteur de mot $x \in \mathbb{R}^{d_{model}}$.&lt;/p>
&lt;p>On calcule la moyenne $\mu$ et la variance $\sigma^2$.
&lt;/p>
$$ \mu = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} x_i $$
$$ \sigma^2 = \frac{1}{d_{model}} \sum_{i=1}^{d_{model}} (x_i - \mu)^2 $$
&lt;p>Et nous obtenons la sortie normalisée $\hat{x}$.
&lt;/p>
$$ \text{LN}(x) = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} \odot \gamma + \beta $$
&lt;p>
($\epsilon$ est une petite constante pour éviter la division par zéro. $\gamma, \beta$ sont des paramètres apprenables de mise à l&amp;rsquo;échelle et de décalage)&lt;/p>
&lt;p>La raison d&amp;rsquo;adopter la normalisation de couche (Layer Normalization) plutôt que la normalisation de batch (Batch Normalization) est que lors du traitement de données séquentielles de longueur variable comme des phrases, les statistiques entre les batchs ont tendance à devenir instables. Grâce à la Layer Normalization, le Transformer peut effectuer un apprentissage stable indépendamment de la taille du batch.&lt;/p>
&lt;hr>
&lt;h1 id="8-structures-spécifiques-au-décodeur--masked-attention-et-cross-attention">8. Structures spécifiques au décodeur : Masked Attention et Cross-Attention
&lt;/h1>&lt;p>La structure expliquée jusqu&amp;rsquo;à présent est celle de l&amp;rsquo;encodeur. Dans le bloc décodeur qui génère les phrases, la structure est légèrement différente.&lt;/p>
&lt;h2 id="81-masked-multi-head-attention">8.1 Masked Multi-Head Attention
&lt;/h2>&lt;p>Le rôle du décodeur est de &amp;ldquo;prédire le mot suivant à partir des mots passés&amp;rdquo;. Par conséquent, regarder les &amp;ldquo;mots futurs&amp;rdquo; pendant l&amp;rsquo;entraînement s&amp;rsquo;apparenterait à tricher. L&amp;rsquo;opération mathématique pour éviter cela est le &lt;strong>Masking (masquage)&lt;/strong>.&lt;/p>
&lt;p>À la matrice de scores $Q K^T$, on ajoute une matrice de masque $M$ qui définit des valeurs très petites proches de $-\infty$ dans la partie triangulaire supérieure (correspondant aux informations futures).&lt;/p>
$$ M_{ij} = \begin{cases} 0 &amp; (i \le j) \\ -\infty &amp; (i > j) \end{cases} $$
$$ \text{Masked Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T + M}{\sqrt{d_k}}\right) V $$
&lt;p>Lors du calcul de la fonction Softmax, puisque $\exp(-\infty) = 0$, l&amp;rsquo;Attention Weight pour les mots futurs devient complètement $0$. Cela permet une génération autorégressive en préservant la causalité (Causality).&lt;/p>
&lt;h2 id="82-encoder-decoder-cross-attention">8.2 Encoder-Decoder Cross-Attention
&lt;/h2>&lt;p>La deuxième sous-couche du décodeur est la &lt;strong>Cross-Attention&lt;/strong> qui se réfère à la sortie de l&amp;rsquo;encodeur.
Ici, $Q$ est généré à partir de la couche de décodage précédente, mais $K$ et $V$ sont générés à partir de la sortie de la dernière couche de l&amp;rsquo;encodeur.&lt;/p>
$$ Q_{decoder} = X_{dec} W^Q $$
$$ K_{encoder} = X_{enc} W^K $$
$$ V_{encoder} = X_{enc} W^V $$
&lt;p>Grâce à ce calcul, le modèle peut apprendre, par exemple dans une tâche de traduction, &amp;ldquo;à quelle partie de la phrase en langue étrangère d&amp;rsquo;origine le mot actuellement traduit est-il fortement lié&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h1 id="9-complexité-de-calcul-et-mathématiques-de-loptimisation-moderne">9. Complexité de calcul et mathématiques de l&amp;rsquo;optimisation moderne
&lt;/h1>&lt;p>Le Transformer est un modèle formidable, mais il a aussi des &amp;ldquo;faiblesses&amp;rdquo; dues à sa structure mathématique.
Faites attention à la complexité de calcul de la Self-Attention. Le calcul de la matrice de scores $Q K^T$ nécessite de multiplier une matrice de $(N \times d_k)$ par une matrice de $(d_k \times N)$, sa complexité de calcul est donc de &lt;strong>$O(N^2 \cdot d_{model})$&lt;/strong>.&lt;/p>
&lt;p>En d&amp;rsquo;autres termes, &lt;strong>la quantité de calculs et l&amp;rsquo;utilisation de la mémoire augmentent de manière quadratique par rapport à la longueur de la séquence $N$&lt;/strong>.
Cela ne pose pas de problème si la phrase est courte, mais si vous essayez de saisir un long contexte tel qu&amp;rsquo;un livre entier dans un LLM, $N$ atteint des dizaines à des centaines de milliers, et la mémoire du GPU s&amp;rsquo;épuise immédiatement avec le calcul classique de l&amp;rsquo;Attention.&lt;/p>
&lt;p>Pour briser cette malédiction de $O(N^2)$, diverses optimisations basées sur des approches mathématiques et matérielles ont été proposées ces dernières années.
Un exemple typique est &lt;strong>FlashAttention&lt;/strong>. FlashAttention est un algorithme qui divise le calcul de l&amp;rsquo;Attention en tuiles (Tiling) afin de minimiser le transfert de données (accès mémoire) entre la hiérarchie de la mémoire GPU (SRAM et HBM). Bien que mathématiquement il produise exactement le même résultat que l&amp;rsquo;Attention standard (Exact Attention), les optimisations au niveau matériel permettent de réaliser une accélération spectaculaire et une réduction de la mémoire, rendant possible des modèles à long contexte comme GPT-4.&lt;/p>
&lt;p>De plus, des recherches sur Sparse Attention et Linear Attention, qui estiment la complexité de calcul à $O(N \log N)$ ou $O(N)$, sont également activement menées.&lt;/p>
&lt;hr>
&lt;h1 id="10-image-dimplémentation-pseudo-code-de-type-pytorch">10. Image d&amp;rsquo;implémentation (Pseudo-code de type PyTorch)
&lt;/h1>&lt;p>Si l&amp;rsquo;on transpose la structure mathématique vue jusqu&amp;rsquo;ici dans un code de programmation réel (Python / PyTorch), on s&amp;rsquo;aperçoit qu&amp;rsquo;elle peut être décrite de manière étonnamment simple. Voici le pseudo-code de la partie centrale de la Self-Attention.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">torch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">torch.nn.functional&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">F&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">scaled_dot_product_attention&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">v&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">mask&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">None&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># formes de q, k, v : [batch_size, num_heads, seq_length, d_k]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">d_k&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">q&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 1. Calcul du score par produit scalaire : Q * K^T&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Transposer les deux dernières dimensions et calculer le produit matriciel&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">scores&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">matmul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">k&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">transpose&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 2. Mise à l&amp;#39;échelle&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">scores&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">scores&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">d_k&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 3. Masking (dans le cas de la Masked Attention)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">mask&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">scores&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">scores&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">masked_fill&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">mask&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mf">1e9&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 4. Probabilisation par Softmax&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">attention_weights&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">F&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">softmax&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">scores&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dim&lt;/span>&lt;span class="o">=-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 5. Multiplication de la matrice Value&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">torch&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">matmul&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">attention_weights&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">v&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">output&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">attention_weights&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Vous pouvez voir que la formule mathématique $Q K^T / \sqrt{d_k}$ est implémentée de manière intuitive comme &lt;code>torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(d_k)&lt;/code>. C&amp;rsquo;est un aspect très intéressant de l&amp;rsquo;apprentissage profond de voir que les théories mathématiques peuvent être réalisées en quelques lignes de code avec l&amp;rsquo;aide de bibliothèques d&amp;rsquo;optimisation avancées.&lt;/p>
&lt;hr>
&lt;h1 id="conclusion--la-forme-de-lintelligence-vue-à-travers-les-mathématiques">Conclusion : La forme de l&amp;rsquo;&amp;ldquo;intelligence&amp;rdquo; vue à travers les mathématiques
&lt;/h1>&lt;p>Dans cet article, nous avons décrypté la structure mathématique profonde du modèle Transformer.&lt;/p>
&lt;p>L&amp;rsquo;Embedding qui mappe les mots dans un espace vectoriel multidimensionnel, le Positional Encoding qui exprime les informations de position par la synthèse d&amp;rsquo;ondes triangulaires, et le mécanisme de Self-Attention qui est un calcul de produit scalaire matriciel né de l&amp;rsquo;analogie de la recherche d&amp;rsquo;informations. Chacun de ces composants n&amp;rsquo;est qu&amp;rsquo;une accumulation de mathématiques fondamentales telles que l&amp;rsquo;algèbre linéaire, le calcul différentiel et intégral, et les probabilités et statistiques.&lt;/p>
&lt;p>Cependant, lorsque ces simples opérations matricielles se superposent sur de nombreuses couches et apprennent des modèles à partir d&amp;rsquo;énormes ensembles de données via des milliards et des centaines de milliards de paramètres, une &amp;ldquo;forme d&amp;rsquo;intelligence&amp;rdquo; émerge, semblant comprendre nos &amp;ldquo;mots&amp;rdquo;, effectuer des raisonnements logiques et parfois générer des idées créatives.&lt;/p>
&lt;p>Comme l&amp;rsquo;indique le titre provocateur &amp;ldquo;Attention Is All You Need&amp;rdquo;, la beauté de cette architecture, qui a abandonné les traitements récurrents et convolutifs complexes pour se spécialiser uniquement dans le calcul de &amp;ldquo;l&amp;rsquo;attention (degré de pertinence)&amp;rdquo;, réside véritablement dans sa simplicité mathématique.&lt;/p>
&lt;p>À l&amp;rsquo;avenir, il est possible que de nouvelles architectures dépassant le Transformer (telles que Mamba, qui est un State Space Model) apparaissent, mais le cadre mathématique de &amp;ldquo;compréhension du contexte par Attention&amp;rdquo; construit par le Transformer restera à jamais gravé dans l&amp;rsquo;histoire de l&amp;rsquo;IA.&lt;/p>
&lt;p>Si vous avez l&amp;rsquo;occasion d&amp;rsquo;utiliser des LLM comme ChatGPT ou Claude à l&amp;rsquo;avenir, essayez d&amp;rsquo;imaginer les billions de produits matriciels $Q K^T$ calculés chaque seconde en arrière-plan, et la fonction Softmax crachant des probabilités. Votre résolution de compréhension de la technologie augmentera, et vous trouverez probablement le monde de l&amp;rsquo;IA encore plus fascinant.&lt;/p>
&lt;h3 id="références">Références
&lt;/h3>&lt;ul>
&lt;li>Vaswani, A., et al. (2017). &amp;ldquo;Attention Is All You Need.&amp;rdquo; &lt;em>Advances in Neural Information Processing Systems&lt;/em>.&lt;/li>
&lt;li>Alammar, J. (2018). &amp;ldquo;The Illustrated Transformer.&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;hr>
&lt;p>&lt;em>Cet article a été rédigé comme un guide pour ceux qui apprennent les bases mathématiques du traitement du langage naturel et de l&amp;rsquo;IA. Si vous avez des questions ou des discussions, n&amp;rsquo;hésitez pas à nous le faire savoir dans la section des commentaires !&lt;/em>&lt;/p></description></item><item><title>Existe-t-il un algorithme surpassant GNFS (Crible général du corps de nombres) ?</title><link>http://kenji.blog/fr/p/beyond-gnfs-integer-factorization-algorithms/</link><pubDate>Fri, 11 Sep 2026 09:00:00 +0900</pubDate><guid>http://kenji.blog/fr/p/beyond-gnfs-integer-factorization-algorithms/</guid><description>&lt;img src="http://kenji.blog/p/beyond-gnfs-integer-factorization-algorithms/img/eyecatch.jpg" alt="Featured image of post Existe-t-il un algorithme surpassant GNFS (Crible général du corps de nombres) ?" />&lt;h2 id="1-introduction--la-factorisation-dentiers-et-le-fondement-de-la-cryptographie-moderne">1. Introduction : La factorisation d&amp;rsquo;entiers et le fondement de la cryptographie moderne
&lt;/h2>&lt;p>La sécurité des communications sur Internet dans la société moderne dépend fortement de la sécurité de la cryptographie à clé publique RSA. La sécurité de RSA repose sur l&amp;rsquo;hypothèse mathématique de la « difficulté de factoriser d&amp;rsquo;énormes nombres composés ». Si un algorithme de factorisation extrêmement efficace était découvert, l&amp;rsquo;infrastructure de communication mondiale s&amp;rsquo;effondrerait depuis ses fondations.&lt;/p>
&lt;p>Actuellement, dans la factorisation d&amp;rsquo;entiers gigantesques à l&amp;rsquo;aide d&amp;rsquo;ordinateurs classiques, l&amp;rsquo;algorithme qui règne en tant que plus rapide et plus puissant est le &lt;strong>Crible général du corps de nombres (GNFS : General Number Field Sieve)&lt;/strong>. GNFS est né en tant qu&amp;rsquo;extension du crible spécial du corps de nombres (SNFS) proposé à la fin des années 1980, et jusqu&amp;rsquo;à aujourd&amp;rsquo;hui, il a établi des records de factorisation pour des nombres composés énormes tels que RSA-768 et RSA-250.&lt;/p>
&lt;p>Cependant, les cryptographes et les mathématiciens se posent constamment les questions suivantes : « Existe-t-il un algorithme classique surpassant GNFS ? », « Où se situent les limites des ordinateurs classiques ? » et « Comment les ordinateurs quantiques vont-ils surmonter cette situation ? »&lt;/p>
&lt;p>Cet article dissèque de manière approfondie la structure mathématique profonde derrière GNFS, et fournit une analyse technique détaillée de la sélection de polynômes, du processus de criblage et de l&amp;rsquo;étape d&amp;rsquo;algèbre linéaire via la méthode par blocs de Wiedemann. En outre, il examine les méthodes d&amp;rsquo;extension de GNFS, comme l&amp;rsquo;amélioration de Coppersmith, et compare et explique les différences cruciales entre les algorithmes classiques en temps sous-exponentiel (Sub-exponential time) et les algorithmes quantiques en temps polynomial d&amp;rsquo;un point de vue mathématique.&lt;/p>
&lt;hr>
&lt;h2 id="2-complexité-asymptotique-et-notation-l-l-notation">2. Complexité asymptotique et notation L (L-notation)
&lt;/h2>&lt;p>Lors de l&amp;rsquo;évaluation de la complexité des algorithmes de factorisation, au lieu de la notation standard en temps polynomial (comme $O(n^k)$), on utilise la &lt;strong>notation L (L-notation)&lt;/strong> pour exprimer le temps sous-exponentiel par rapport au nombre de chiffres de l&amp;rsquo;entrée $n$. La notation L est définie comme suit :&lt;/p>
$$
L_n[\alpha, c] = \exp \left( (c + o(1)) (\ln n)^\alpha (\ln \ln n)^{1-\alpha} \right)
$$
&lt;p>Où $n$ est l&amp;rsquo;entier à factoriser, et $\ln n$ est le logarithme népérien, qui est proportionnel à la longueur en bits de $n$.&lt;/p>
&lt;ul>
&lt;li>Lorsque $\alpha = 0$ : $L_n[0, c] = \exp(c \ln \ln n) = (\ln n)^c$, ce qui représente un &lt;strong>temps polynomial (Polynomial time)&lt;/strong> par rapport à la longueur en bits.&lt;/li>
&lt;li>Lorsque $\alpha = 1$ : $L_n[1, c] = \exp(c \ln n) = n^c$, ce qui représente un &lt;strong>temps exponentiel (Exponential time)&lt;/strong> par rapport à la longueur en bits.&lt;/li>
&lt;li>Lorsque $0 &lt; \alpha &lt; 1$ : Cela devient un &lt;strong>temps sous-exponentiel (Sub-exponential time)&lt;/strong>, situé entre le temps polynomial et le temps exponentiel.&lt;/li>
&lt;/ul>
&lt;p>L&amp;rsquo;histoire de l&amp;rsquo;évolution des algorithmes de factorisation du passé a également été l&amp;rsquo;histoire de la réduction progressive de la valeur de cet $\alpha$.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Méthode des fractions continues (CFRAC) et crible quadratique à polynômes multiples (MPQS)&lt;/strong> : Appartiennent à la classe $\alpha = 1/2$, avec une complexité d&amp;rsquo;environ $L_n[1/2, 1]$.&lt;/li>
&lt;li>&lt;strong>Crible général du corps de nombres (GNFS)&lt;/strong> : Atteint $\alpha = 1/3$, et s&amp;rsquo;enorgueillit de la complexité la plus rapide parmi les algorithmes classiques connus à ce jour, qui est de $L_n[1/3, (64/9)^{1/3}]$.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="3-lalgorithme-complet-et-la-structure-mathématique-de-gnfs">3. L&amp;rsquo;algorithme complet et la structure mathématique de GNFS
&lt;/h2>&lt;p>GNFS possède des fondations mathématiques extrêmement complexes et avancées. L&amp;rsquo;idée de base s&amp;rsquo;inscrit dans la continuité du petit théorème de Fermat et du crible quadratique (QS), qui consiste à trouver des paires non triviales $(X, Y)$ satisfaisant la congruence $X^2 \equiv Y^2 \pmod n$ et $X \not\equiv \pm Y \pmod n$, pour en déduire un facteur de $n$, $\gcd(X-Y, n)$.&lt;/p>
&lt;p>Cependant, l&amp;rsquo;essence de GNFS réside dans le fait qu&amp;rsquo;il n&amp;rsquo;effectue pas cela uniquement dans le corps des nombres rationnels $\mathbb{Q}$, mais qu&amp;rsquo;il recherche simultanément des « nombres friables (Smooth numbers) » à la fois dans un corps d&amp;rsquo;extension $\mathbb{Q}(\alpha)$ appelé corps de nombres algébriques (Algebraic Number Field) et dans le corps des rationnels, et construit des relations de congruence par le biais d&amp;rsquo;homomorphismes.&lt;/p>
&lt;p>Le processus de GNFS est divisé en 5 phases principales.&lt;/p>
&lt;div class="mermaid">graph TD
A["Problème de factorisation d'entiers (entrée n)"] --> B["1. Sélection de polynômes (Polynomial Selection)"]
B --> C["2. Processus de criblage (Sieving Phase)"]
C --> D["3. Filtrage (Filtering Phase)"]
D --> E["4. Algèbre linéaire (Linear Algebra Phase)"]
E --> F["5. Racine carrée (Square Root Phase)"]
F --> G["Sortie des facteurs premiers p, q"]&lt;/div>
&lt;h3 id="31-phase-1--sélection-de-polynômes-polynomial-selection">3.1 Phase 1 : Sélection de polynômes (Polynomial Selection)
&lt;/h3>&lt;p>Le succès de GNFS dépend fortement de la sélection de polynômes appropriés. L&amp;rsquo;objectif est de trouver deux polynômes irréductibles ayant une racine commune $m$ : $f_1(x)$ (côté rationnel) et $f_2(x)$ (côté algébrique). C&amp;rsquo;est-à-dire qu&amp;rsquo;ils satisfont :
$f_1(m) \equiv f_2(m) \equiv 0 \pmod n$&lt;/p>
&lt;p>Généralement, on choisit un polynôme de degré 1, $f_1(x) = x - m$, pour le côté rationnel, et un polynôme unitaire de degré $d$ (typiquement 5 ou 6) pour le polynôme côté algébrique $f_2(x)$. L&amp;rsquo;approche la plus classique est la &lt;strong>méthode de la Base-$m$&lt;/strong>.
On choisit un entier $m = \lfloor n^{1/(d+1)} \rfloor$ proche de la puissance $1/(d+1)$ de $n$, et on développe $n$ en base $m$.
$n = c_d m^d + c_{d-1} m^{d-1} + \dots + c_1 m + c_0$
On obtient ainsi le polynôme $f_2(x) = c_d x^d + c_{d-1} x^{d-1} + \dots + c_0$. Évidemment, on a $f_2(m) = n \equiv 0 \pmod n$.&lt;/p>
&lt;p>Cependant, dans les implémentations modernes, on utilise l&amp;rsquo;&lt;strong>algorithme de Kleinjung&lt;/strong>. Celui-ci évite que les coefficients des polynômes ne deviennent trop grands (optimisation du Skewness) tout en optimisant les propriétés algébriques (valeur $E$ de Murphy et valeur $\alpha$), cherchant ainsi des polynômes susceptibles de générer facilement des nombres friables lors de la phase de criblage. Rien que pour cette étape, d&amp;rsquo;importantes ressources de calcul sont mobilisées.&lt;/p>
&lt;h3 id="32-phase-2--processus-de-criblage-sieving-phase">3.2 Phase 2 : Processus de criblage (Sieving Phase)
&lt;/h3>&lt;p>Une fois les polynômes déterminés, l&amp;rsquo;algorithme entre dans la phase de « criblage (Sieving) », qui est la plus gourmande en calculs. Ici, on recherche des paires $(a, b)$. Ces paires doivent être premières entre elles, et il est requis que les deux valeurs suivantes soient simultanément « friables (Smooth) » :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Norme du côté rationnel&lt;/strong> : $F_1(a, b) = b \cdot f_1(a/b) = a - bm$&lt;/li>
&lt;li>&lt;strong>Norme du côté algébrique&lt;/strong> : $F_2(a, b) = b^d \cdot f_2(a/b)$&lt;/li>
&lt;/ol>
&lt;p>« Friable » signifie qu&amp;rsquo;elles ne peuvent être factorisées qu&amp;rsquo;avec des nombres premiers inférieurs ou égaux à une limite spécifiée (Sieve bound). On prépare une base de facteurs (Factor base) pour le côté rationnel et une autre pour le côté algébrique, et on trouve efficacement les nombres friables sur un vaste espace de recherche à la manière du crible d&amp;rsquo;Ératosthène.
Aujourd&amp;rsquo;hui, une méthode appelée &lt;strong>crible par réseaux (Lattice Sieving)&lt;/strong> est dominante. En fixant un certain nombre premier $q$, et en ne criblant que les paires $(a, b)$ sur un sous-réseau où les côtés rationnel et algébrique sont tous deux des multiples de $q$, on atteint une efficacité extrêmement élevée.&lt;/p>
&lt;h3 id="33-phase-3--filtrage-filtering-phase">3.3 Phase 3 : Filtrage (Filtering Phase)
&lt;/h3>&lt;p>Le nombre de relations (relations) friables trouvées lors du processus de criblage s&amp;rsquo;élève à des centaines de millions, voire des milliards. Cependant, celles-ci contiennent également beaucoup d&amp;rsquo;informations inutiles.
Le but du filtrage est de construire une énorme matrice creuse (Sparse Matrix) tout en réduisant ses dimensions autant que possible.&lt;/p>
&lt;p>Plus précisément, les opérations suivantes sont effectuées :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Suppression des singletons (Singleton removal)&lt;/strong> : Suppression des relations contenant un facteur premier qui n&amp;rsquo;apparaît qu&amp;rsquo;une seule fois.&lt;/li>
&lt;li>&lt;strong>Suppression/Fusion de cliques (Clique removal / Merging)&lt;/strong> : Multiplication entre elles de relations ayant des facteurs premiers apparaissant deux fois ou plus, afin d&amp;rsquo;éliminer des variables et de réduire à un système d&amp;rsquo;équations plus dense, mais de dimension plus petite.&lt;/li>
&lt;/ul>
&lt;p>Grâce à cela, une matrice de milliards de lignes est compressée en une énorme matrice creuse $\mathbf{A}$ de dizaines de millions de lignes (dont les éléments sont des 0 et des 1 sur le corps $\mathbb{F}_2$).&lt;/p>
&lt;h3 id="34-phase-4--algèbre-linéaire-linear-algebra-phase">3.4 Phase 4 : Algèbre linéaire (Linear Algebra Phase)
&lt;/h3>&lt;p>Ici, on trouve un vecteur solution non trivial $\mathbf{x}$ de l&amp;rsquo;équation $\mathbf{A} \mathbf{x} \equiv \mathbf{0} \pmod 2$. Autrement dit, c&amp;rsquo;est le problème de trouver l&amp;rsquo;espace nul à gauche (Left Nullspace) d&amp;rsquo;une énorme matrice creuse.&lt;/p>
&lt;p>Étant donné que la taille de la matrice est extrêmement grande, il est absolument impossible de la calculer avec l&amp;rsquo;élimination de Gauss habituelle ($O(N^3)$). Par conséquent, des méthodes itératives, qui sont un type de méthode de sous-espace de Krylov, sont utilisées. Historiquement, la &lt;strong>méthode par blocs de Lanczos (Block Lanczos)&lt;/strong> était utilisée, mais dans les environnements informatiques distribués actuels, la &lt;strong>méthode par blocs de Wiedemann (Block Wiedemann Algorithm)&lt;/strong>, qui permet de réduire considérablement la surcharge de communication, prédomine.&lt;/p>
&lt;p>La méthode par blocs de Wiedemann calcule un polynôme minimal à partir de la matrice $\mathbf{A}$ et d&amp;rsquo;une séquence de vecteurs, et utilise l&amp;rsquo;algorithme de Berlekamp-Massey pour construire une base de l&amp;rsquo;espace nul. Cette étape est très difficile à paralléliser et constitue l&amp;rsquo;un des plus plus grands goulots d&amp;rsquo;étranglement de GNFS, exigeant des superordinateurs ou des réseaux de communication étroitement couplés de grands clusters.&lt;/p>
&lt;h3 id="35-phase-5--racine-carrée-square-root-phase">3.5 Phase 5 : Racine carrée (Square Root Phase)
&lt;/h3>&lt;p>À partir des solutions de l&amp;rsquo;algèbre linéaire, on construit des produits qui sont des « carrés parfaits » pour chacun des côtés rationnel et algébrique.
Du côté rationnel, $\prod (a-bm)$ devient le carré $X^2$ d&amp;rsquo;un certain entier $X$, et du côté algébrique, le produit des idéaux correspondants devient un carré parfait $\gamma^2$ sur le corps de nombres algébriques.
En calculant ce $\gamma$ sur le corps de nombres algébriques et en appliquant l&amp;rsquo;homomorphisme $\phi: \alpha \mapsto m \pmod n$ vers l&amp;rsquo;anneau des entiers rationnels, on obtient la congruence :
$X^2 \equiv \phi(\gamma)^2 \equiv Y^2 \pmod n$&lt;/p>
&lt;p>Pour calculer la racine carrée sur le corps de nombres algébriques, des algorithmes complexes tels que la &lt;strong>méthode de Montgomery (Montgomery&amp;rsquo;s Method)&lt;/strong> sont utilisés, ce qui nécessite des connaissances approfondies en théorie algébrique des nombres. Enfin, en calculant $\gcd(X-Y, n)$, et si un facteur non trivial est obtenu, la factorisation est terminée.&lt;/p>
&lt;hr>
&lt;h2 id="4-existe-t-il-un-algorithme-classique-surpassant-gnfs-">4. Existe-t-il un algorithme classique surpassant GNFS ?
&lt;/h2>&lt;p>À ce jour, aucun algorithme classique avec une complexité asymptotique inférieure à $L_n[1/3, c]$ pour la factorisation d&amp;rsquo;entiers généraux n&amp;rsquo;a été découvert. Cependant, il existe plusieurs tentatives et algorithmes dérivés pour franchir les limites théoriques et pratiques.&lt;/p>
&lt;h3 id="41-crible-multiple-du-corps-de-nombres-mnfs-multiple-number-field-sieve">4.1 Crible multiple du corps de nombres (MNFS: Multiple Number Field Sieve)
&lt;/h3>&lt;p>Comme approche étendant GNFS, on trouve le &lt;strong>crible multiple du corps de nombres (MNFS)&lt;/strong> par D. Coppersmith. Alors que GNFS utilise deux polynômes (côté rationnel et côté algébrique), MNFS utilise simultanément plusieurs polynômes différents du côté algébrique pour un seul polynôme du côté rationnel.&lt;/p>
$$ f_1(x), f_{2,1}(x), f_{2,2}(x), \dots, f_{2,V}(x) $$
&lt;p>En utilisant plusieurs corps algébriques, la probabilité de devenir « friable dans l&amp;rsquo;un des corps algébriques » à chaque étape de criblage peut être considérablement augmentée. Avec cette approche, Coppersmith a réussi à réduire légèrement la constante $c$ de la complexité $L_n[1/3, c]$.
Concrètement, alors que la constante de GNFS est $c = (64/9)^{1/3} \approx 1.923$, il a été théoriquement démontré qu&amp;rsquo;en optimisant MNFS, la complexité pouvait être réduite à environ $c \approx 1.902$.
Cependant, dans la pratique, la surcharge due à la gestion de corps multiples est importante, et cela n&amp;rsquo;a pas conduit à une percée décisive pour les modules RSA à l&amp;rsquo;échelle pratique.&lt;/p>
&lt;h3 id="42-des-algorithmes-de-la-classe-l_n14-sont-ils-possibles-">4.2 Des algorithmes de la classe $L_n[1/4]$ sont-ils possibles ?
&lt;/h3>&lt;p>Concernant les limites des algorithmes classiques de factorisation d&amp;rsquo;entiers, un thème longuement débattu parmi les mathématiciens est la question : « Existe-t-il un algorithme d&amp;rsquo;exposant $\alpha = 1/4$ ? ».
Le GNFS actuel et ses dérivés sont fortement liés au cadre de « recherche de friabilité » par le criblage, et il est largement admis qu&amp;rsquo;au sein de ce paradigme, $\alpha = 1/3$ est la limite. D&amp;rsquo;après l&amp;rsquo;analyse de la probabilité de distribution des entiers friables à l&amp;rsquo;aide de la fonction de Dickman, on pense qu&amp;rsquo;il est impossible de franchir le mur de $O(L_n[1/3])$, quelle que soit l&amp;rsquo;optimisation, avec la combinaison actuelle de construction de corps algébriques et de criblage.&lt;/p>
&lt;p>S&amp;rsquo;il existait un algorithme en $L_n[1/4]$, ou même un algorithme classique en temps polynomial, il devrait dépendre d&amp;rsquo;une nouvelle structure mathématique totalement différente des approches basées sur la « friabilité » comme GNFS, et actuellement impensable pour l&amp;rsquo;humanité (par exemple, une approche de géométrie algébrique plus avancée comme l&amp;rsquo;algorithme de Schoof pour la cryptographie sur les courbes elliptiques). Cependant, il n&amp;rsquo;y a pour le moment aucun signe de cela.&lt;/p>
&lt;hr>
&lt;h2 id="5-la-percée-par-les-ordinateurs-quantiques--lalgorithme-de-shor">5. La percée par les ordinateurs quantiques : l&amp;rsquo;algorithme de Shor
&lt;/h2>&lt;p>Alors que les ordinateurs classiques font face au mur du $L_n[1/3]$, c&amp;rsquo;est l&amp;rsquo;&lt;strong>algorithme de Shor (Shor&amp;rsquo;s Algorithm)&lt;/strong>, publié en 1994 par Peter Shor, qui a brisé ce mur en changeant fondamentalement le modèle de calcul lui-même.&lt;/p>
&lt;h3 id="51-le-choc-du-temps-quantique-polynomial">5.1 Le choc du temps quantique polynomial
&lt;/h3>&lt;p>L&amp;rsquo;algorithme de Shor réduit le problème de la factorisation d&amp;rsquo;entiers au « problème de la recherche de l&amp;rsquo;ordre (Order Finding Problem) ». Pour un entier donné $a$, il s&amp;rsquo;agit de trouver la période (ordre) $r$ de la fonction $f(x) = a^x \pmod n$.
Bien qu&amp;rsquo;un ordinateur classique nécessite un temps exponentiel pour trouver cette période, en utilisant l&amp;rsquo;&lt;strong>estimation de phase quantique (QPE : Quantum Phase Estimation)&lt;/strong> et la &lt;strong>transformée de Fourier quantique (QFT : Quantum Fourier Transform)&lt;/strong> sur un ordinateur quantique, il est possible d&amp;rsquo;évaluer en parallèle une superposition de tous les états (Superposition) et d&amp;rsquo;extraire la période $r$ avec une forte probabilité.&lt;/p>
&lt;p>En termes de complexité, le temps d&amp;rsquo;exécution de l&amp;rsquo;algorithme de Shor est un &lt;strong>temps quantique polynomial&lt;/strong>, plus précisément comme suit :
&lt;/p>
$$ O((\log n)^3) $$
&lt;p>
Compte tenu des implémentations de circuits optimisées récentes, on considère que cela peut être réduit à $O((\log n)^2 \log \log n)$.&lt;/p>
&lt;div class="mermaid">graph LR
A["Algorithme classique (GNFS)"] -->|Limite| B["Temps sous-exponentiel L_n[1/3]"]
C["Algorithme quantique (Shor)"] -->|Percée| D["Temps polynomial O((log n)^3)"]
B --> E["Utilisation continue de RSA (augmentation de la longueur des clés)"]
D --> F["Effondrement total de la cryptographie RSA"]&lt;/div>
&lt;h3 id="52-temps-sous-exponentiel-classique-vs-temps-polynomial-quantique">5.2 Temps sous-exponentiel classique vs Temps polynomial quantique
&lt;/h3>&lt;p>La différence entre ces deux classes de complexité a une signification décisive pour la sécurité cryptographique dans le monde réel.&lt;/p>
&lt;p>Prenons l&amp;rsquo;exemple de la factorisation de RSA-2048 (un nombre composé de 2048 bits).&lt;/p>
&lt;ul>
&lt;li>&lt;strong>GNFS (Classique)&lt;/strong> : En substituant $n \approx 2^{2048}$ dans $L_n[1/3, 1.923]$, il faut environ $2^{112}$ opérations. Il s&amp;rsquo;agit d&amp;rsquo;une quantité astronomique de calculs qui prendrait plus de temps que l&amp;rsquo;âge de l&amp;rsquo;univers, même en rassemblant toutes les ressources informatiques actuelles sur Terre.&lt;/li>
&lt;li>&lt;strong>Algorithme de Shor (Quantique)&lt;/strong> : Avec un algorithme en $O((\log n)^3)$, il suffit d&amp;rsquo;environ $2048^3 \approx 8.5 \times 10^9$ opérations de portes logiques. Cela signifie que si le matériel approprié (un ordinateur quantique universel avec des millions de qubits physiques et des capacités de correction d&amp;rsquo;erreurs) existait, le calcul serait terminé en quelques heures à quelques jours seulement.&lt;/li>
&lt;/ul>
&lt;p>Le changement de paradigme passant d&amp;rsquo;une fonction sous-exponentielle avec un « exposant $\alpha=1/3$ » à un « temps polynomial » neutralise la stratégie traditionnelle de la cryptographie qui consiste à garantir la sécurité en augmentant la longueur de la clé.&lt;/p>
&lt;hr>
&lt;h2 id="6-conclusion--perspectives-pour-la-prochaine-génération">6. Conclusion : Perspectives pour la prochaine génération
&lt;/h2>&lt;p>Le consensus actuel de la communauté scientifique concernant la question « Existe-t-il un algorithme classique surpassant GNFS ? » est le suivant :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Les améliorations pratiques se poursuivront, mais il n&amp;rsquo;y a pas de saut asymptotique&lt;/strong> : Les tentatives pour améliorer le terme constant $c$ de GNFS, telles que le MNFS, l&amp;rsquo;optimisation de la sélection de polynômes, ou la parallélisation de la méthode par blocs de Wiedemann, se poursuivent. Cependant, la probabilité de découvrir un algorithme classique descendant en dessous de $\alpha = 1/3$ est considérée comme extrêmement faible.&lt;/li>
&lt;li>&lt;strong>La sécurité de RSA sur les ordinateurs classiques reste forte&lt;/strong> : La complexité de GNFS reste énorme, et RSA-2048 ainsi que RSA-4096 continueront de maintenir leur sécurité contre les attaques par des ordinateurs classiques pour les décennies à venir.&lt;/li>
&lt;li>&lt;strong>La véritable menace vient des algorithmes quantiques&lt;/strong> : C&amp;rsquo;est l&amp;rsquo;algorithme de Shor, basé sur les principes de la mécanique quantique, qui a franchi le mur de la complexité computationnelle. De ce fait, le monde est contraint de faire la transition vers la cryptographie post-quantique (PQC : Post-Quantum Cryptography). La transition vers de nouveaux problèmes mathématiques considérés comme difficiles à résoudre (impossibles à résoudre en temps polynomial) même pour les ordinateurs quantiques, tels que la cryptographie sur les réseaux euclidiens ou la cryptographie basée sur les hachages, constitue la frontière actuelle de la cryptographie.&lt;/li>
&lt;/ol>
&lt;p>Le crible général du corps de nombres (GNFS) est l&amp;rsquo;un des « points culminants » atteints par l&amp;rsquo;humanité après avoir défié les limites des mathématiques classiques et de la conception d&amp;rsquo;algorithmes. Comprendre la structure mathématique profonde de GNFS n&amp;rsquo;est pas seulement apprendre l&amp;rsquo;histoire de la cryptanalyse, mais c&amp;rsquo;est aussi un voyage d&amp;rsquo;exploration intellectuelle touchant à la beauté de la théorie de la complexité algorithmique et de la théorie algébrique des nombres. Jusqu&amp;rsquo;au jour où les ordinateurs quantiques seront mis en pratique, GNFS continuera très probablement de défendre son trône de plus puissant algorithme de factorisation d&amp;rsquo;entiers.&lt;/p></description></item><item><title>Comment intégrer KaTeX dans Hugo et afficher de belles formules mathématiques de style LaTeX</title><link>http://kenji.blog/fr/p/hugo%E3%81%A7katexlatex%E9%A2%A8%E6%95%B0%E5%BC%8F%E8%A1%A8%E7%A4%BA%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/</link><pubDate>Fri, 31 Mar 2023 23:11:26 +0900</pubDate><guid>http://kenji.blog/fr/p/hugo%E3%81%A7katexlatex%E9%A2%A8%E6%95%B0%E5%BC%8F%E8%A1%A8%E7%A4%BA%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/</guid><description>&lt;img src="http://kenji.blog/p/hugo%E3%81%A7katexlatex%E9%A2%A8%E6%95%B0%E5%BC%8F%E8%A1%A8%E7%A4%BA%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/img.webp" alt="Featured image of post Comment intégrer KaTeX dans Hugo et afficher de belles formules mathématiques de style LaTeX" />&lt;h1 id="quest-ce-que-katex">Qu&amp;rsquo;est-ce que KaTeX
&lt;/h1>&lt;p>KaTeX est une bibliothèque javascript permettant d&amp;rsquo;afficher des formules mathématiques de style LaTeX en HTML.&lt;/p>
&lt;p>Plus précisément, vous pouvez afficher des formules comme ci-dessous.&lt;/p>
$$f(x) = x^2 + x + 41$$
&lt;p>Il semble y avoir d&amp;rsquo;autres bibliothèques d&amp;rsquo;affichage de formules de style LaTeX, mais KaTeX est réputé pour être simple et rapide.&lt;/p>
&lt;h1 id="comment-lintégrer-à-hugo">Comment l&amp;rsquo;intégrer à hugo
&lt;/h1>&lt;ol>
&lt;li>Créez un nouveau &lt;code>layouts/partials/math.html&lt;/code> dans la hiérarchie des dossiers de hugo.&lt;/li>
&lt;/ol>
&lt;p>Le contenu doit être le suivant.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">&amp;lt;link rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css&amp;#34; integrity=&amp;#34;sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0&amp;#34; crossorigin=&amp;#34;anonymous&amp;#34;&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;script defer src=&amp;#34;https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js&amp;#34; integrity=&amp;#34;sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4&amp;#34; crossorigin=&amp;#34;anonymous&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;script defer src=&amp;#34;https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js&amp;#34; integrity=&amp;#34;sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05&amp;#34; crossorigin=&amp;#34;anonymous&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;script&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">document.addEventListener(&amp;#34;DOMContentLoaded&amp;#34;, function() {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> renderMathInElement(
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> document.body,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> delimiters: [
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {left: &amp;#34;$$&amp;#34;, right: &amp;#34;$$&amp;#34;, display: true},
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {left: &amp;#34;\\[&amp;#34;, right: &amp;#34;\\]&amp;#34;, display: true},
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {left: &amp;#34;$&amp;#34;, right: &amp;#34;$&amp;#34;, display: false},
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {left: &amp;#34;\\(&amp;#34;, right: &amp;#34;\\)&amp;#34;, display: false}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> });
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> });
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;/script&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ol start="2">
&lt;li>Ensuite, ajoutez le code ci-dessous au fichier existant &lt;code>layouts/partials/extend_head.html&lt;/code>.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">{{ if or .Params.math .Site.Params.math }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ partial &amp;#34;math.html&amp;#34; . }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ol start="3">
&lt;li>Vous êtes maintenant prêt à utiliser KaTeX.&lt;/li>
&lt;/ol>
&lt;p>Vous pouvez activer KaTeX en ajoutant &lt;code>math: true&lt;/code> au front matter de la page.&lt;/p>
&lt;ol start="4">
&lt;li>Il ne vous reste plus qu&amp;rsquo;à écrire la formule dans le style LaTeX dans le corps de l&amp;rsquo;article de la page.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">$$ e^{i \pi} = -1 $$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>En l&amp;rsquo;écrivant comme ci-dessus, il s&amp;rsquo;affichera comme ci-dessous.&lt;/p>
$$ e^{i \pi} = -1 $$
&lt;h1 id="référence">Référence
&lt;/h1>&lt;ul>
&lt;li>&lt;a class="link" href="https://reorx.github.io/hugo-PaperModX/docs/math-typesetting/" target="_blank" rel="noopener"
>Math Typesetting | PaperModX&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://katex.org/docs/autorender.html" target="_blank" rel="noopener"
>KaTex Auto-render Extension&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://www.storange.jp/2017/02/katex.html" target="_blank" rel="noopener"
>Introduction à KaTeX | The Strange Storage&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>