# Comment fonctionne réellement la traduction automatique neuronale: Guide d'un développeur

<datetime class="hidden">2025-11-09T14:30</datetime>

<!--category-- Neural Machine Translation, Machine Learning, AI, EasyNMT, Deep Learning, AI-Article -->
## Présentation

Si vous suivez ce blog, vous savez que je suis un peu obsédé par la traduction automatique.[J'ai écrit à propos de](/blog/autotranslatingmarkdownfiles), [utilisant EasyNMT](/blog/backgroundtranslationspt1)construction de services de traduction de l'arrière-plan[, et même](/blog/mostlylucid-nmt-complete-guide)améliorer EasyNMT**Mais j'ai réalisé que je n'avais jamais vraiment expliqué

> Comment

traduction automatique neuronale fonctionne sous le capot.

REMARQUE: Ceci fait partie de mes expériences avec l'IA / un moyen de dépenser 1000 $ Code Calude crédits Web.

- J'ai alimenté ça un BUNCH de papiers, ma compréhension, des questions que j'ai dû générer cet article.
- C'est amusant et il comble un vide que je n'ai pas vu comblé nulle part ailleurs.
- Alors réparons ça !
- Ce post vous amènera de « traduction est magique » à « traduction est maths intelligents » en expliquant les concepts clés derrière la traduction automatique neuronale en anglais simple (avec beaucoup de diagrammes et un certain code C# pour le rendre concret).
- À la fin de ce post, vous comprendrez :

Quels sont les réseaux neuronaux artificiels et comment ils apprennent

[TOC]

## Comment les mots deviennent des nombres (embudings)

Ce que signifie "attention" dans l'IA (spoiler: il ne s'agit pas de prêter attention)

```mermaid
graph LR
    A[Source Sentence] --> B[Convert to Numbers]
    B --> C[Neural Network Processing]
    C --> D[Convert to Words]
    D --> E[Translated Sentence]

```

Comment fonctionne l'architecture de l'encodeur-décodeur

## Pourquoi les transformateurs ont-ils pris le monde en main?

Ne vous inquiétez pas si vous n'êtes pas un mathiste - je vais garder ceci aussi pratique et visuel que possible.

### Plongons dedans !

L'idée de base : la traduction comme calcul de nombre

1. Voici le premier concept d'esprit-bénéfice: la traduction de machine neuronale traite la traduction comme un processus purement mathématique.
2. Vous alimentez une phrase, le système la convertit en nombres, effectue des millions d'opérations mathématiques, et sort une traduction.
3. Mais attendez - comment convertissez-vous les mots en nombres?
4. Et comment les maths "comprendre" le langage ?

Commençons par les blocs de construction.

```mermaid
graph LR
    I1[Input 1] -->|weight: 0.8| N[Neuron]
    I2[Input 2] -->|weight: -0.3| N
    I3[Input 3] -->|weight: 0.5| N
    N --> O[Output]

    style N stroke-width:4px
```

Réseaux neuronaux artificiels : la Fondation

```csharp
public class Neuron
{
    private double[] weights;
    private double bias;

    public double Activate(double[] inputs)
    {
        // Step 1: Multiply each input by its weight and sum them
        double sum = bias;
        for (int i = 0; i < inputs.Length; i++)
        {
            sum += inputs[i] * weights[i];
        }

        // Step 2: Apply activation function (tanh keeps values between -1 and 1)
        return Math.Tanh(sum);
    }
}
```

Avant de pouvoir comprendre la traduction automatique neuronale, nous devons comprendre les réseaux neuronaux artificiels.`Math.Tanh`Malgré leur nom, ils sont plutôt simples à leur cœur.

### Qu'est-ce qu'un neurone artificiel?

Un neurone artificiel est une fonction mathématique qui:

```mermaid
graph LR
    subgraph Input Layer
        I1[Input 1]
        I2[Input 2]
        I3[Input 3]
    end

    subgraph Hidden Layer 1
        H1[Neuron 1]
        H2[Neuron 2]
        H3[Neuron 3]
        H4[Neuron 4]
    end

    subgraph Hidden Layer 2
        H5[Neuron 5]
        H6[Neuron 6]
        H7[Neuron 7]
    end

    subgraph Output Layer
        O1[Output 1]
        O2[Output 2]
    end

    I1 --> H1 & H2 & H3 & H4
    I2 --> H1 & H2 & H3 & H4
    I3 --> H1 & H2 & H3 & H4

    H1 --> H5 & H6 & H7
    H2 --> H5 & H6 & H7
    H3 --> H5 & H6 & H7
    H4 --> H5 & H6 & H7

    H5 --> O1 & O2
    H6 --> O1 & O2
    H7 --> O1 & O2
```

Prend plusieurs entrées

- Multiplie chaque entrée par un poids (quelle est l'importance de cette entrée?)
- Ça les ajoute tous.
- Applique une "fonction d'activation" pour produire une sortie

### Voici une représentation visuelle :

Faisons en sorte que cela soit concret avec un code C# :

```mermaid
graph TD
    A[Start with Random Weights] --> B[Feed in Training Example]
    B --> C[Network Makes Prediction]
    C --> D{Is Prediction Correct?}
    D -->|No| E[Calculate Error]
    E --> F[Adjust Weights Slightly]
    F --> B
    D -->|Yes| G[Try Next Example]
    G --> B

    style E stroke-width:2px
    style F stroke-width:2px
```

La fonction d'activation (dans ce cas**) est ce qui rend les réseaux neuronaux intéressants.**Il introduit la non-linéarité, permettant au réseau d'apprendre des modèles complexes.

Sans ça, peu importe le nombre de neurones que vous avez empilés ensemble, vous auriez juste une fonction linéaire fantaisiste.

```csharp
public class SimpleNeuralNetwork
{
    private double learningRate = 0.01;
    private Neuron[] neurons;

    public void Train(TrainingExample[] examples, int epochs)
    {
        for (int epoch = 0; epoch < epochs; epoch++)
        {
            foreach (var example in examples)
            {
                // Forward pass: make a prediction
                double prediction = Predict(example.Input);

                // Calculate error
                double error = example.ExpectedOutput - prediction;

                // Backward pass: adjust weights
                // (simplified - real networks use backpropagation)
                AdjustWeights(error * learningRate);
            }
        }
    }
}
```

Des neurones aux réseaux**La magie se produit lorsque vous reliez des milliers ou des millions de ces neurones en couches :**Chaque couche "raffine" la représentation de l'entrée, en extrayant des motifs de plus en plus abstraits.

## En traduction:

Les couches précoces peuvent détecter "c'est un verbe" ou "ce mot est tendu"

### Les couches moyennes peuvent détecter "c'est une question" ou "c'est à propos du temps"

Plus tard, les couches les combinent en "translate ceci comme une question polie sur le temps de demain"

```csharp
// Don't do this!
var wordToNumber = new Dictionary<string, int>
{
    {"cat", 1},
    {"dog", 2},
    {"king", 3},
    {"queen", 4},
    {"man", 5},
    {"woman", 6}
};
```

Comment les réseaux apprennent : le processus de formation

### Voici la partie intelligente : nous ne réglons pas manuellement tous ces poids.

Le réseau les apprend à partir d'exemples!**Ce processus s'appelle**descente en pente

```csharp
public class WordEmbedding
{
    // Each word is represented by a vector of floats
    private Dictionary<string, float[]> embeddings;

    public float[] GetEmbedding(string word)
    {
        return embeddings[word]; // e.g., [0.2, -0.5, 0.8, 0.1, ...]
    }

    // Calculate similarity between two words
    public double Similarity(string word1, string word2)
    {
        var vec1 = GetEmbedding(word1);
        var vec2 = GetEmbedding(word2);

        // Cosine similarity: how "aligned" are the vectors?
        return CosineSimilarity(vec1, vec2);
    }

    private double CosineSimilarity(float[] a, float[] b)
    {
        double dot = 0, magA = 0, magB = 0;
        for (int i = 0; i < a.Length; i++)
        {
            dot += a[i] * b[i];
            magA += a[i] * a[i];
            magB += b[i] * b[i];
        }
        return dot / (Math.Sqrt(magA) * Math.Sqrt(magB));
    }
}
```



```mermaid
graph TD
    subgraph "2D Projection of 300D Space"
        King[King<br/>0.8, 0.6]
        Queen[Queen<br/>0.75, 0.55]
        Man[Man<br/>0.3, 0.2]
        Woman[Woman<br/>0.25, 0.15]
        Dog[Dog<br/>-0.6, 0.4]
        Cat[Cat<br/>-0.65, 0.38]
    end

    King -.similar.-> Queen
    Man -.similar.-> Woman
    Dog -.similar.-> Cat
    King -.same vector.-> Man
    Queen -.same vector.-> Woman
```

Pour chaque mauvaise réponse, le réseau calcule « quels poids étaient les plus responsables de cette erreur ? » et les adapte un petit peu.`king - man + woman ≈ queen`

```csharp
public float[] AnalogicalReasoning(string a, string b, string c)
{
    // king - man + woman = ?
    var vecA = GetEmbedding(a); // king
    var vecB = GetEmbedding(b); // man
    var vecC = GetEmbedding(c); // woman

    var result = new float[vecA.Length];
    for (int i = 0; i < vecA.Length; i++)
    {
        result[i] = vecA[i] - vecB[i] + vecC[i];
    }

    // Find the word closest to this vector
    return FindClosestWord(result); // Should return "queen"
}
```

### Après avoir vu des millions d'exemples, les poids s'établissent en valeurs qui fonctionnent bien.

Voici une version simplifiée en C#:

```mermaid
graph LR
    A["The cat sat on the mat"] --> B[Train Neural Network]
    B --> C["cat → [0.1, 0.5, -0.3, ...]"]
    B --> D["sat → [0.2, -0.1, 0.4, ...]"]
    B --> E["mat → [0.15, 0.45, -0.25, ...]"]

```

Les réseaux neuronaux réels utilisent un algorithme plus sophistiqué appelé

## contre-propagation

qui calcule efficacement comment ajuster les poids sur l'ensemble du réseau, mais le principe est le même : apprendre des erreurs.

```mermaid
graph TD
    subgraph English
        E1[The]
        E2[cat]
        E3[sat]
        E4[on]
        E5[the]
        E6[mat]
    end

    subgraph French
        F1[Le]
        F2[chat]
        F3[s'est assis]
        F4[sur]
        F5[le]
        F6[tapis]
    end

    E2 -. focus 90% .-> F2
    E3 -. focus 70% .-> F3
    E4 -. focus 80% .-> F4
    E6 -. focus 85% .-> F6
    E1 -. focus 30% .-> F1
```

**Embeddings de mots: transformer le langage en mathématiques**Maintenant, nous avons relevé notre premier défi majeur : comment nourrir les mots dans un réseau neuronal ?

### Nous devons convertir le texte en nombres.

Le problème de l'encodage à simple hot

```csharp
public class AttentionMechanism
{
    // Calculate attention weights for each source word
    public double[] CalculateAttention(
        float[] currentTargetState,     // Where we are in translation
        float[][] sourceWordStates)     // All source words
    {
        int sourceLength = sourceWordStates.Length;
        double[] scores = new double[sourceLength];

        // Step 1: Calculate relevance scores
        for (int i = 0; i < sourceLength; i++)
        {
            scores[i] = DotProduct(currentTargetState, sourceWordStates[i]);
        }

        // Step 2: Convert to probabilities (softmax)
        return Softmax(scores);
    }

    public float[] ApplyAttention(
        double[] attentionWeights,
        float[][] sourceWordStates)
    {
        // Create weighted average of source words
        int dim = sourceWordStates[0].Length;
        float[] result = new float[dim];

        for (int i = 0; i < sourceWordStates.Length; i++)
        {
            for (int j = 0; j < dim; j++)
            {
                result[j] += (float)(attentionWeights[i] * sourceWordStates[i][j]);
            }
        }

        return result;
    }

    private double[] Softmax(double[] scores)
    {
        double[] result = new double[scores.Length];
        double sum = 0;

        for (int i = 0; i < scores.Length; i++)
        {
            result[i] = Math.Exp(scores[i]);
            sum += result[i];
        }

        for (int i = 0; i < scores.Length; i++)
        {
            result[i] /= sum;
        }

        return result;
    }

    private double DotProduct(float[] a, float[] b)
    {
        double sum = 0;
        for (int i = 0; i < a.Length; i++)
        {
            sum += a[i] * b[i];
        }
        return sum;
    }
}
```

L'approche naïve est l'"encodage à chaud" - assignez à chaque mot un numéro unique:

1. Mais cela pose un énorme problème : les chiffres sont arbitraires.
2. Le réseau ne peut pas dire que "cat" et "dog" sont plus similaires que "cat" et "queen".
3. Les chiffres 1 et 2 ne signifient rien.
4. La solution : l'adhésion des mots

### Au lieu de cela, nous représentons chaque mot comme un

vecteur

```mermaid
graph TD
    subgraph "English (Source)"
        E1[The]
        E2[agreement]
        E3[on]
        E4[the]
        E5[European]
        E6[Economic]
        E7[Area]
    end

    subgraph "German (Target)"
        G1[Das]
        G2[Abkommen]
        G3[über]
        G4[den]
        G5[Europäischen]
    end

    E1 -->|0.8| G1
    E2 -->|0.9| G2
    E3 -->|0.6| G3
    E4 -->|0.3| G3
    E5 -->|0.85| G5
    E6 -->|0.7| G5

```

de nombres, généralement de 300 à 1000 dimensions.

### Des mots similaires obtiennent des vecteurs similaires:

Voici ce qui rend l'intégration magique - ils capturent les relations sémantiques:**L'exemple célèbre:**Comment les inscriptions sont - elles apprises?

```mermaid
graph LR
    subgraph "Self-Attention for 'bank'"
        B[bank]
        R[river]
        W[water]
        F[fish]
    end

    B -.high attention.-> R
    B -.high attention.-> W
    B -.medium attention.-> F

```

Les inscriptions sont apprises par la formation d'un réseau neuronal sur une tâche simple: «prédicer les mots environnants».

## L'idée est que les mots apparaissant dans des contextes similaires devraient avoir des significations similaires.

Après une formation sur des milliards de phrases, les mots qui apparaissent dans des contextes similaires finissent par avoir des emboîtements similaires. "Cat" et "dog" apparaissent tous les deux près de "pet", "feed", "cute", de sorte que leurs emboîtements finissent par se rapprocher.**Attention: le changement de jeu**Voici un aperçu critique: lors de la traduction de "Le chat assis sur le tapis" en français, différents mots sources comptent pour différents mots cibles:

```mermaid
graph LR
    subgraph Encoder
        E1[Word Embeddings] --> E2[Self-Attention Layer 1]
        E2 --> E3[Self-Attention Layer 2]
        E3 --> E4[Self-Attention Layer N]
        E4 --> E5[Contextual Representations]
    end

    subgraph Decoder
        D1[Previous Translations] --> D2[Self-Attention]
        D2 --> D3[Cross-Attention to Encoder]
        D3 --> D4[Feed Forward]
        D4 --> D5[Next Word Prediction]
    end

    E5 -.provides context.-> D3

```

### Garde-à-vous.

est un mécanisme qui permet au réseau de « se concentrer » sur différentes parties de l'entrée lors de la génération de chaque mot de sortie.

```csharp
public class TransformerEncoder
{
    private WordEmbedding wordEmbedding;
    private SelfAttentionLayer[] layers;

    public float[][] Encode(string[] sourceWords)
    {
        // Step 1: Convert words to embeddings
        float[][] embeddings = sourceWords
            .Select(w => wordEmbedding.GetEmbedding(w))
            .ToArray();

        // Step 2: Add positional encoding (so network knows word order)
        float[][] withPositions = AddPositionalEncoding(embeddings);

        // Step 3: Apply multiple self-attention layers
        float[][] representations = withPositions;
        foreach (var layer in layers)
        {
            representations = layer.Forward(representations);
        }

        return representations; // Contextual representations for each word
    }

    private float[][] AddPositionalEncoding(float[][] embeddings)
    {
        // Add position-specific patterns so network knows word order
        // (transformers don't naturally understand sequence order)
        int sequenceLength = embeddings.Length;
        int embeddingDim = embeddings[0].Length;

        for (int pos = 0; pos < sequenceLength; pos++)
        {
            for (int i = 0; i < embeddingDim; i++)
            {
                double angle = pos / Math.Pow(10000, (2.0 * i) / embeddingDim);
                // Use sine for even dimensions, cosine for odd
                embeddings[pos][i] += (float)(i % 2 == 0 ? Math.Sin(angle) : Math.Cos(angle));
            }
        }

        return embeddings;
    }
}
```

Comment fonctionne l'attention

- Pensez à l'attention comme demandant: "Pour traduire ce mot, à quels mots sources devrais-je prêter attention?"
- Le mécanisme d'attention:
- Comparer l'état cible actuel à chaque mot source

### Calcule un « score de pertinence » pour chaque mot source

Convertit les scores en probabilités (ils s'élèvent à 1)

```csharp
public class TransformerDecoder
{
    private WordEmbedding targetEmbedding;
    private SelfAttentionLayer[] selfAttentionLayers;
    private CrossAttentionLayer[] crossAttentionLayers;
    private FeedForwardLayer[] feedForwardLayers;

    public string[] Decode(float[][] encodedSource, int maxLength)
    {
        List<string> translation = new List<string>();
        translation.Add("<START>"); // Special token to begin

        while (translation.Count < maxLength)
        {
            // Get next word
            string nextWord = GenerateNextWord(encodedSource, translation.ToArray());

            if (nextWord == "<END>") break; // Stop token

            translation.Add(nextWord);
        }

        return translation.Skip(1).ToArray(); // Remove <START> token
    }

    private string GenerateNextWord(float[][] encodedSource, string[] partialTranslation)
    {
        // Step 1: Embed the partial translation
        float[][] targetEmbeddings = partialTranslation
            .Select(w => targetEmbedding.GetEmbedding(w))
            .ToArray();

        // Step 2: Self-attention on target words
        float[][] selfAttended = ApplySelfAttention(targetEmbeddings);

        // Step 3: Cross-attention to source (this is where translation happens!)
        float[][] crossAttended = ApplyCrossAttention(selfAttended, encodedSource);

        // Step 4: Feed forward
        float[] finalState = ApplyFeedForward(crossAttended[^1]); // Last position

        // Step 5: Predict next word
        return PredictWord(finalState);
    }

    private string PredictWord(float[] state)
    {
        // Convert state to probability distribution over all possible words
        Dictionary<string, double> wordProbabilities = CalculateWordProbabilities(state);

        // Return most likely word (or sample from distribution)
        return wordProbabilities.OrderByDescending(kv => kv.Value).First().Key;
    }
}
```

Crée une moyenne pondérée des mots sources en fonction de ces probabilités

```mermaid
sequenceDiagram
    participant Input as Source Sentence
    participant Encoder
    participant Decoder
    participant Output as Translation

    Input->>Encoder: "The cat sat"
    Encoder->>Encoder: Build representations
    Encoder->>Decoder: Encoded states

    Decoder->>Decoder: Generate [START]
    Decoder->>Output: Emit START token

    Decoder->>Decoder: Attend to "The" → Generate "Le"
    Decoder->>Output: "Le"

    Decoder->>Decoder: Attend to "cat" → Generate "chat"
    Decoder->>Output: "chat"

    Decoder->>Decoder: Attend to "sat" → Generate "s'est assis"
    Decoder->>Output: "s'est assis"

    Decoder->>Decoder: Generate [END]
    Output->>Output: "Le chat s'est assis"
```

## Visualisation de l'attention

Lors de la traduction de "L'accord sur l'Espace économique européen a été signé en août 1992" en allemand, l'attention se présente comme suit:

1. **Lors de la génération de «Abkommen» (accord), le réseau accorde 90% d'attention à «accord», 5% à «le», et 5% distribué entre autres mots.**L'auto-attention: S'occuper de soi-même
2. **Utilisation des transformateurs modernes**auto-attention
3. **: les mots dans la même phrase s'adressent l'un à l'autre pour construire de meilleures représentations.**Dans « Le poisson nage près de la rive », le mot « rive » s'adresse fortement à « rivière », « poisson » et « eau », aidant le réseau à comprendre qu'il signifie « riverbank » et non « institution financière ».

```csharp
public class TranslationTrainer
{
    private TransformerEncoder encoder;
    private TransformerDecoder decoder;
    private double learningRate = 0.0001;

    public void Train(ParallelCorpus corpus, int epochs)
    {
        foreach (var epoch in Enumerable.Range(0, epochs))
        {
            double totalLoss = 0;
            int batchCount = 0;

            foreach (var batch in corpus.GetBatches(batchSize: 32))
            {
                // Forward pass
                var predictions = new List<string[]>();
                var losses = new List<double>();

                foreach (var pair in batch)
                {
                    // Encode source
                    var encoded = encoder.Encode(pair.Source);

                    // Try to decode target
                    var predicted = decoder.Decode(encoded, pair.Target.Length);

                    // Calculate loss (how different is prediction from target?)
                    double loss = CalculateLoss(predicted, pair.Target);
                    losses.Add(loss);
                }

                // Backward pass: adjust weights
                double avgLoss = losses.Average();
                UpdateWeights(avgLoss);

                totalLoss += avgLoss;
                batchCount++;
            }

            Console.WriteLine($"Epoch {epoch}: Average Loss = {totalLoss / batchCount}");
        }
    }

    private double CalculateLoss(string[] predicted, string[] target)
    {
        // Cross-entropy loss: how far off were our word predictions?
        double loss = 0;

        for (int i = 0; i < Math.Min(predicted.Length, target.Length); i++)
        {
            if (predicted[i] != target[i])
            {
                loss += 1.0; // Simplified - real loss is more nuanced
            }
        }

        return loss / target.Length;
    }

    private void UpdateWeights(double loss)
    {
        // Backpropagation: adjust all weights in encoder and decoder
        // to reduce the loss (simplified here)
        // Real implementation uses automatic differentiation
    }
}
```

L'architecture de l'encodeur-décodeur

```mermaid
graph TD
    A[10M Sentence Pairs] --> B[Initial Random Weights]
    B --> C[Epoch 1: Loss = 5.2]
    C --> D[Epoch 2: Loss = 3.8]
    D --> E[Epoch 3: Loss = 2.1]
    E --> F[Epoch 10: Loss = 0.8]
    F --> G[Epoch 20: Loss = 0.3]
    G --> H[Trained Model!]

    style A stroke-width:2px
    style H stroke-width:4px
```

Maintenant, on peut tout mettre ensemble !

- **Traduction automatique neuronale utilise un**encodeur-décodeur
- **architecture:**L'encodeur: Comprendre la source
- **Le travail de l'encodeur est de lire la phrase source et de construire des représentations riches:**Après l'encodage, chaque mot source a une représentation qui capture :

## Son sens (de l'encastrement)

Sa position dans la phrase (à partir de l'encodage positionnel)

```mermaid
graph TD
    subgraph "1. Encoding"
        A1[The] --> E1[emb: 0.2, -0.1, ...]
        A2[cat] --> E2[emb: 0.5, 0.3, ...]
        A3[sat] --> E3[emb: -0.1, 0.4, ...]
        A4[on] --> E4[emb: 0.1, -0.2, ...]
        A5[the] --> E5[emb: 0.2, -0.1, ...]
        A6[mat] --> E6[emb: 0.4, 0.2, ...]
    end

    subgraph "2. Self-Attention in Encoder"
        E1 & E2 & E3 & E4 & E5 & E6 --> SA[Self-Attention]
        SA --> C1[ctx: 0.3, 0.1, ...]
        SA --> C2[ctx: 0.6, 0.4, ...]
        SA --> C3[ctx: -0.2, 0.5, ...]
    end

    subgraph "3. Decoding"
        D1[START] --> G1[Le]
        C2 -.attend.-> G1

        G1 --> G2[chat]
        C2 -.attend.-> G2

        G2 --> G3[s'est assis]
        C3 -.attend.-> G3
    end


```

### Son rapport à d'autres mots (de l'auto-attention)

**Le Décoder: Générer la Traduction**

```csharp
var theEmbedding = encoder.GetEmbedding("The");
// [0.2, -0.1, 0.3, 0.05, ..., 0.1] (300 dimensions)
```

**Le décodeur génère la traduction un mot à la fois:**

```csharp
var catEmbedding = encoder.GetEmbedding("cat");
// [0.5, 0.3, -0.2, 0.4, ..., 0.15] (300 dimensions)
```

**Le processus de traduction complet:**

```csharp
// "cat" attends to other words
var catAttention = attention.CalculateAttention(catEmbedding, allWordEmbeddings);
// [0.1, 0.3, 0.2, 0.05, 0.1, 0.25]
// High attention to "sat" (0.3) and "mat" (0.25)

var catContextual = attention.ApplyAttention(catAttention, allWordEmbeddings);
// Weighted average incorporating context
```

**Formation d'un modèle de traduction<START>**

```csharp
var decoderState = decoder.InitialState();
```

**La formation d'un modèle de traduction nécessite trois choses :**

```csharp
// Attend to source
var sourceAttention = crossAttention.Calculate(decoderState, encodedSource);
// [0.8, 0.05, 0.05, 0.02, 0.05, 0.03]
// Strong focus on "The" (0.8)

var nextWordProbs = decoder.PredictNextWord(decoderState, sourceAttention);
// {"Le": 0.85, "La": 0.08, "Les": 0.04, ...}

var firstWord = "Le";
```

**corpus parallèle**

```csharp
decoderState = decoder.UpdateState(decoderState, "Le");

var sourceAttention = crossAttention.Calculate(decoderState, encodedSource);
// [0.05, 0.9, 0.02, 0.01, 0.01, 0.01]
// Strong focus on "cat" (0.9)

var nextWordProbs = decoder.PredictNextWord(decoderState, sourceAttention);
// {"chat": 0.92, "chien": 0.03, ...}

var secondWord = "chat";
```

**: Des millions de paires de phrases dans les deux langues<END>**

```
Final translation: "Le chat s'est assis sur le tapis"
```

## Fonction de perte

: Quelle était notre prédiction ?

1. **Optimisation**: Ajuster les poids pour réduire la perte
2. **La formation prend d'énormes quantités de données et de calculs:**Pour un modèle à la fine pointe de la technologie:
3. **Données sur la formation**: 10-100 millions de paires de phrases

```mermaid
graph LR
    subgraph "Old: Recurrent Neural Networks"
        R1[Word 1] --> R2[Word 2]
        R2 --> R3[Word 3]
        R3 --> R4[Word 4]
    end

    subgraph "New: Transformers"
        T1[Word 1] -.attend.-> T2[Word 2]
        T1 -.attend.-> T3[Word 3]
        T1 -.attend.-> T4[Word 4]
        T2 -.attend.-> T3
        T2 -.attend.-> T4
        T3 -.attend.-> T4
    end


```

Temps de formation

## : 1-4 semaines sur les GPU haut de gamme

Taille du modèle

```csharp
public class TranslationService
{
    private readonly HttpClient _httpClient;
    private readonly string _nmtServiceUrl;

    public TranslationService(HttpClient httpClient, IConfiguration config)
    {
        _httpClient = httpClient;
        _nmtServiceUrl = config["NMT:ServiceUrl"];
    }

    public async Task<TranslationResult> TranslateAsync(
        string text,
        string sourceLang,
        string targetLang)
    {
        var request = new TranslationRequest
        {
            Text = new[] { text },
            SourceLang = sourceLang,
            TargetLang = targetLang
        };

        var response = await _httpClient.PostAsJsonAsync(
            $"{_nmtServiceUrl}/translate",
            request);

        response.EnsureSuccessStatusCode();

        var result = await response.Content
            .ReadFromJsonAsync<TranslationResponse>();

        return new TranslationResult
        {
            Original = text,
            Translated = result.Translated[0],
            SourceLanguage = sourceLang,
            TargetLanguage = targetLang,
            TranslationTime = result.TranslationTime
        };
    }
}

public class TranslationRequest
{
    [JsonPropertyName("text")]
    public string[] Text { get; set; }

    [JsonPropertyName("source_lang")]
    public string SourceLang { get; set; }

    [JsonPropertyName("target_lang")]
    public string TargetLang { get; set; }
}

public class TranslationResponse
{
    [JsonPropertyName("translated")]
    public string[] Translated { get; set; }

    [JsonPropertyName("translation_time")]
    public double TranslationTime { get; set; }
}
```

: paramètres de 100M à 1B+ (poids)

```csharp
// In your controller or service
public class BlogPostController : ControllerBase
{
    private readonly TranslationService _translator;

    public async Task<IActionResult> TranslatePost(int postId, string targetLang)
    {
        var post = await _blogService.GetPostAsync(postId);

        var translatedTitle = await _translator.TranslateAsync(
            post.Title,
            "en",
            targetLang);

        var translatedContent = await _translator.TranslateAsync(
            post.Content,
            "en",
            targetLang);

        return Ok(new
        {
            Title = translatedTitle.Translated,
            Content = translatedContent.Translated,
            OriginalLanguage = "en",
            TargetLanguage = targetLang
        });
    }
}
```

## Tout mettre ensemble : un exemple complet

### Traçons en traduisant "Le chat assis sur le tapis" en français :

Processus étape par étape :

```csharp
public async Task<string> TranslateLongText(string longText, string targetLang)
{
    const int maxChunkSize = 500; // characters

    // Split on paragraph boundaries
    var paragraphs = longText.Split(new[] { "\n\n", "\r\n\r\n" },
        StringSplitOptions.RemoveEmptyEntries);

    var translatedParagraphs = new List<string>();

    foreach (var paragraph in paragraphs)
    {
        if (paragraph.Length <= maxChunkSize)
        {
            var result = await _translator.TranslateAsync(paragraph, "en", targetLang);
            translatedParagraphs.Add(result.Translated);
        }
        else
        {
            // Split long paragraph into sentences
            var sentences = SplitIntoSentences(paragraph);
            var translatedSentences = new List<string>();

            foreach (var sentence in sentences)
            {
                var result = await _translator.TranslateAsync(sentence, "en", targetLang);
                translatedSentences.Add(result.Translated);
            }

            translatedParagraphs.Add(string.Join(" ", translatedSentences));
        }
    }

    return string.Join("\n\n", translatedParagraphs);
}
```

### Étape 1: Encoder "La"

Étape 2: Encoder "cat"

```csharp
public async Task<string> TranslateMarkdown(string markdown, string targetLang)
{
    // Extract text from markdown while preserving structure
    var doc = Markdig.Markdown.Parse(markdown);
    var textSegments = new List<(string text, int position)>();

    // Walk the AST and extract translatable text
    foreach (var node in doc.Descendants())
    {
        if (node is LiteralInline literal)
        {
            var text = literal.Content.ToString();
            if (!string.IsNullOrWhiteSpace(text) && !IsImagePath(text))
            {
                textSegments.Add((text, literal.Span.Start));
            }
        }
    }

    // Translate all segments
    var translations = await Task.WhenAll(
        textSegments.Select(async seg => new
        {
            seg.position,
            translated = (await _translator.TranslateAsync(seg.text, "en", targetLang)).Translated
        }));

    // Reconstruct markdown with translations
    var result = markdown;
    foreach (var translation in translations.OrderByDescending(t => t.position))
    {
        result = result.Remove(translation.position, textSegments
            .First(s => s.position == translation.position).text.Length)
            .Insert(translation.position, translation.translated);
    }

    return result;
}
```

### Étape 3 : L'auto-attention

Étape 4: Le décoder commence par

```csharp
public async Task<Dictionary<string, string>> TranslateBatch(
    IEnumerable<string> texts,
    string targetLang)
{
    const int batchSize = 32;
    var results = new Dictionary<string, string>();

    foreach (var batch in texts.Chunk(batchSize))
    {
        var request = new TranslationRequest
        {
            Text = batch.ToArray(),
            SourceLang = "en",
            TargetLang = targetLang
        };

        var response = await _httpClient.PostAsJsonAsync(
            $"{_nmtServiceUrl}/translate",
            request);

        var result = await response.Content
            .ReadFromJsonAsync<TranslationResponse>();

        for (int i = 0; i < batch.Length; i++)
        {
            results[batch[i]] = result.Translated[i];
        }
    }

    return results;
}
```

## Étape 5: Générer "Le"

Étape 6: Générer le "chat"

```mermaid
graph TD
    A[Translation Request] --> B{Model Size}
    B -->|Small 100M params| C[Fast: 50-100ms]
    B -->|Medium 500M params| D[Medium: 200-500ms]
    B -->|Large 1B+ params| E[Slow: 1-3 seconds]

    A --> F{Hardware}
    F -->|CPU| G[Slow: 2-5x slower]
    F -->|GPU| H[Fast: Baseline]
    F -->|TPU/Special AI chips| I[Very Fast: 2-3x faster]

    style C stroke-width:2px
    style E stroke-width:2px
```

Étape 7: Continuer jusqu'à

- **Pourquoi les transformateurs ont gagné**L'architecture du transformateur (le "T" dans ChatGPT!) est devenue dominante parce que:
- **Parallélisation**: Contrairement aux anciens modèles récurrents, tous les mots peuvent être traités simultanément
- **Dépendances à long terme**: L'attention peut connecter n'importe quel deux mots, peu importe la distance entre les deux

**Échelle**: Plus de données + plus grand modèle = meilleurs résultats (jusqu'à un point)

**Les réseaux récurrents traitent séquentiellement (lent!), tandis que les transformateurs traitent tous les mots à la fois (rapide!).**Utilisation de NMT dans C#: Un exemple pratique

## Maintenant que vous comprenez comment ça marche, voici comment vous l'utiliseriez dans une application .NET :

Utilisation & #160;:

1. **Défis et solutions communs**1. Le Conseil de l'Europe a adopté une résolution du Conseil de l'Europe sur la situation des droits de l'homme dans le monde.
2. **Manipulation des longs textes**Les modèles NMT ont des limites de longueur d'entrée (typiquement 512-1024 jetons).
3. **Solution : couper !**2. Le Président. — L'ordre du jour appelle le rapport (doc.
4. **Préservation du formatage**Le balisage, le HTML et d'autres balisages peuvent confondre les modèles NMT :
5. **3. Les droits de l'homme sont garantis par le Pacte international relatif aux droits économiques, sociaux et culturels.**Traitement par lots pour l'efficacité

Traduire une phrase à la fois est lent.

Emballez-les !

- **Caractéristiques de performance**Comprendre les coûts de calcul vous aide à concevoir de meilleures solutions :
- **Performance typique (par phrase sur GPU):**Petits modèles
- **(params 100M): 50-100ms**Modèles moyens
- **(params 500M): 200-500ms**Grands modèles

(1B+ params): 1-3 secondes

Now when you hit "translate" on your blog posts, you'll know exactly what's happening under the hood! 🚀

## CPU vs GPU

: GPU est 2-10x plus rapide pour NMT

- [Traitement par lots](https://arxiv.org/abs/1706.03762): Peut atteindre plus de 100 phrases/seconde avec le lotage
- [Le présent règlement entre en vigueur le vingtième jour suivant celui de sa publication au Journal officiel de l'Union européenne.](https://jalammar.github.io/illustrated-transformer/)La traduction automatique neurale peut sembler magique, mais c'est en fait une combinaison élégante de plusieurs idées intelligentes:
- [Assemblages](https://arxiv.org/abs/1409.0473): Représenter les mots comme vecteurs qui saisissent le sens
- [Réseaux neuronaux](/blog/category/EasyNMT): Apprendre les modèles à partir de millions d'exemples