diff --git a/TraiNMT.ipynb b/TraiNMT.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..dde7cb898cc568c5c6f82ee0c6097d6dd4f5dce0
--- /dev/null
+++ b/TraiNMT.ipynb
@@ -0,0 +1,1348 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "vw-zMj1bEbmE"
+      },
+      "source": [
+        "# Entraîner son propre programme de traduction automatique neuronale\n",
+        "\n",
+        "## Ou, comment contraindre un outil de TA au romanesque\n",
+        "\n",
+        "<br>\n",
+        "\n",
+        "Cahier d'exercices préparé à l'occasion du colloque&nbsp;:\n",
+        "\n",
+        "*Traduction littéraire et intelligence artificielle&nbsp;: théorie, pratique, création*\n",
+        "\n",
+        "21 octobre 2022 &mdash; Paris, France\n",
+        "\n",
+        "<br>\n",
+        "\n",
+        "Damien Hansen\n",
+        "\n",
+        "Centre Interdisciplinaire de Recherche en Traduction et en Interprétation (Université de Liège, Belgique)\n",
+        "\n",
+        "Laboratoire d'Informatique de Grenoble (Université Grenoble Alpes, France)\n",
+        "\n",
+        "<br>\n",
+        "\n",
+        "Ce contenu est diffusé sous la licence CC BY-SA 4.0.\n",
+        "\n",
+        "Du moment que l'œuvre originale est dûment créditée et que l'œuvre partagée est diffusée avec la même licence, vous êtes libres de&nbsp;:\n",
+        "- partager &mdash; copier, distribuer et communiquer le matériel par tous moyens et sous tous formats&nbsp;;\n",
+        "- adapter &mdash; remixer, transformer et créer à partir du matériel\n",
+        "pour toute utilisation, y compris commerciale."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "kz0N8YVk5sVa"
+      },
+      "source": [
+        "## Étape 0 &mdash; Initialisation"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Colab, kézako&nbsp;?"
+      ],
+      "metadata": {
+        "id": "BslB9R6LzSer"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Le format du cahier d'exercices (ici, un notebook Jupyter) est très pratique, car il permet de combiner du texte et du code au sein d'un même environnement interactif.\n",
+        "\n",
+        "Son hébergement sur Colaboratory permet de le partager facilement, de suivre et lancer les commandes sans avoir à configurer quoi que ce soit, mais aussi et surtout d'avoir accès à des ressources (GPU, espace disque), limitées, certes, mais suffisantes pour ce qui est proposé ici."
+      ],
+      "metadata": {
+        "id": "fu5dth3NzmEM"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Prise en main"
+      ],
+      "metadata": {
+        "id": "fE-1hTxGziKA"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "ZKp5RjmXFNaY"
+      },
+      "source": [
+        "Avant toute chose, aller dans le menu horizontal (en haut à gauche) et sélectionner&nbsp;:\n",
+        "\n",
+        "    Exécution > Modifier le type d'exécution > Accélérateur matériel > GPU\n",
+        "\n",
+        "Si l'environnement est en anglais&nbsp;:\n",
+        "\n",
+        "    Runtime > Change Runtime Type > Hardware Accelerator > GPU\n",
+        "\n",
+        "Un avertissement apparaîtra inévitablement après quelques minutes indiquant que le GPU n'est pas utilisé, mais la manipulation est nécessaire. Sans cela, nous ne pourrons pas lancer l'entraînement du système plus loin dans le notebook et il nous faudra tout reprendre depuis le début."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "jXqomm_zmlTW"
+      },
+      "source": [
+        "![exécution notebook.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAY0AAAEZCAIAAADkMu7TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0xMC0yNFQxNToyNjoxMyswMjowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTAtMjRUMTU6Mjk6NDUrMDI6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMTAtMjRUMTU6Mjk6NDUrMDI6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmM3YWQyM2M1LWUzNzctZTI0Yi04NDBhLWVhN2Q2MTY2MDNiMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1w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) &emsp; ![paramètres notebook](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAY0AAAEZCAIAAADkMu7TAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0xMC0xNFQxNTowNjowNyswMjowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTAtMTRUMTU6MTI6MTQrMDI6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMTAtMTRUMTU6MTI6MTQrMDI6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmEwZmUxMDY0LTNmODMtZTI0Ny04ZDFkLWQyZWIzMzc2N2MwMiIgeG1wTU06RG9jdW1lbnRJRD0ieG1w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)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "GiA5YukAiMyF"
+      },
+      "source": [
+        "Lançons ensuite cette petite commande pour enlever le dossier par défaut de Colab et créer les nôtres. Cette manipulation fera office d'exemple&nbsp;: elle nous permettra de voir comment fonctionne Colab et comment l'on peut interagir avec cet environnement.\n",
+        "\n",
+        "Pour lancer une commande, cliquer simplement sur la flèche qui apparaîtra entre les crochets en survolant la zone de code avec le curseur. Pour la suite du parcours, laissez-vous simplement guider par les explications et lancez une à une les commandes proposées. Si une erreur survient, il est fort probable qu'elle soit liée à l'échec ou à l'oubli d'une commande précédente (chaque étape est importante)."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "ktPVIvC37KcM"
+      },
+      "outputs": [],
+      "source": [
+        "!rm -rf sample_data                                                               # Supprimer un dossier et son contenu\n",
+        "!mkdir datasets subword output output/{log,models,tensor,translations,vocab}      # Créer de nouveaux dossiers"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Commençons aussi par télécharger quelques fichiers qui nous serviront plus tard. Nous verrons ainsi comment afficher et garder un &oelig;il sur les fichiers utilisés tout au long de l'exercice.\n",
+        "\n",
+        "Vous remarquerez que l'on voit déjà le résultat de certaines commandes sous la zone de code. Il s'agit du résultat attendu et obtenu lors de la mise au point du notebook, mais cela ne signifie pas pour autant que la commande a été exécutée dans votre environnement. Certaines étapes prennent un peu plus de temps que d'autres pour aboutir et il n'est possible de n'en lancer qu'une seule à la fois, mais vous pouvez vérifier la bonne exécution du code de votre côté grâce au symbole ✔️ qui apparaîtra à gauche de la cellule, accompagné du temps d'exécution."
+      ],
+      "metadata": {
+        "id": "qXm4N5rxkQXj"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "!wget https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/subword_models/unigram_en.{model,vocab} -P subword\n",
+        "!wget https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/subword_models/unigram_fr.{model,vocab} -P subword"
+      ],
+      "metadata": {
+        "id": "n9iSh66QdUE0"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Pour afficher la liste des fichiers, cliquer sur l'icône représentant un dossier dans le menu vertical de gauche.\n",
+        "\n",
+        "Lorsque nous téléchargeons des fichiers sur Colab et que nous les modifions avec des commandes, il est possible que les changements ne soient pas immédiatement visibles, car la liste n'est pas automatiquement rafraîchie. Pour contourner ce problème, il suffit de l'actualiser en cliquant sur l'icône correspondante."
+      ],
+      "metadata": {
+        "id": "ZZ5dZcPLCxDt"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "![fichiers notebook.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUwAAADWCAIAAAA1hiyZAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMi0xMC0yNFQxNTowMjo1MCswMjowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjItMTAtMjRUMTU6MjI6MTErMDI6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjItMTAtMjRUMTU6MjI6MTErMDI6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmZiY2NhY2EzLWE5YWQtOTQ0Yi1hNTZmLTllZDRmOGFiOTI3OSIgeG1wTU06RG9jdW1lbnRJRD0ieG1w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) &emsp; ![actualiser notebook.png](data:image/png;base64,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0q1YqK9evZonnniCJUuW0KhRIyZNmkT9+vUZNGgQq1ev5sYbb2T79u1s2bIF+N8CeIA77riDpk2bnnDCTjj3nPY7Utd1AoEAgUAgPsN5roktts7KyuLyyy9nzJgxDBkyhFtuuYWsrCwMwzgngtKyrPhWzhtvvJHhw4czePBg0tPT+c9//sNdd93Fgw8+CFApM7iWZeF2u8nPz2fatGlIksTevXvZt28fN998M5FIBJvNxqeffsrq1avPWrt0XadBgwbHLLmKjbEGg0EikQhbt24FoEGDBkyePJmmTZsybtw41qxZQ1JSUqmhmJqaSt26dePDC8K575QCM/YpmpOTg67rVKtWjerVq2OaJjk5OUSj0bPWOzgTDMMgKyuLK664gtGjR5OYmAjA008/zY033kh2dvZZG0s7VZIk4ff7ueyyy3j33XcZPnw4V199NV27duX111/njTfe4KabbqJBgwbxS92zLTaWN3v2bNatW0diYiKSJNGwYUMefvhhmjRpQl5eHjt37mTChAnoul5hS6CO5nA4mDdvHjt37owvFYt9SNaqVQtN01i3bl189r9hw4ZMmDCBxo0bs379ehwOB82aNQOO3Ye+atUqli1bJiZ+fkfKPRotSVL8ku+aa66hS5cutGnTBkmS+Pnnn1mwYAELFy7E5/OdMwt4o9EoN910E8888ww1atQgFAphmiZut5vhw4fj8Xj45JNPMAyjsptaKkmSKC4ujv8ie71eRowYwcqVK6lbty533XUXnTt3BiA/P7/S2mm329m4cSPvvfdevFd22WWXcddddwHwt7/9jRYtWqBpGuFwmNzc3LOyNEdVVQ4ePMjUqVMZOXIkqqrGL6vbtWtH69at+eyzz6hfvz533nknaWlptGjRgldffZX+/fuzY8cOli5dykUXXYSqqqiqis/n45133iEajcbHY4VzX7m7gYZh4Pf7ue+++5g8eTK33XYbBw8e5MCBA9xwww2MHz+eZ599FpvNht/vr4g2n1GWZSHLMp07d6ZOnTosWLCAAwcOUFxczNy5c0lJSeH666/HbrdX2cA0TZNAIMBdd91FSkoKffv2ZcaMGezYsYMLL7yQxo0bx+/rcDgqpY2xnVWffPIJ2dnZaJpGUlISN998M6NGjaJ///6sWLGClJQUPB4PiYmJvPXWW+Tk5JyVWWabzcbnn3/O9OnTsdvt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)"
+      ],
+      "metadata": {
+        "id": "51uvJS22FWOK"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Les téléchargements et les installations se font sur un serveur Google. Rien ne sera installé sur votre machine.\n",
+        "\n",
+        "Cependant, à moins de souscrire un abonnement, l'accès au serveur se coupera automatiquement après une période d'inactivité de 90 minutes, après quoi tous les fichiers téléchargés seront supprimés."
+      ],
+      "metadata": {
+        "id": "VWXEdwe90_VT"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "PVTgrS_egRGm"
+      },
+      "source": [
+        "## Étape 1 &mdash; Installation"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "QGuB-yta57qQ"
+      },
+      "source": [
+        "Tout d'abord, nous allons avoir besoin d'installer les outils suivants&nbsp;:\n",
+        "- `OpusFilter` (pour télécharger nos corpus)&nbsp;;\n",
+        "- `mosestokenizer` et `SentencePiece` (pour tokeniser nos textes)&nbsp;;\n",
+        "- `OpenNMT-py` (pour entraîner notre système)&nbsp;;\n",
+        "- `sacreBLEU` (pour évaluer les textes de sortie).\n",
+        "\n",
+        "Le tokeniseur Moses est l'un des plus fréquemment utilisés en TAL. Nous utiliserons ici un module qui nous permettra aussi de nettoyer légèrement nos textes, mais il est un peu lent. Il existe aussi un module `fast-mosestokenizer`, qui est beaucoup plus rapide et qui facilite le traitement de corpus plus larges.\n",
+        "\n",
+        "(SentencePiece et sacreBLEU sont quant à eux installés par défaut avec OpenNMT.)"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "syYQkz7KGQOI"
+      },
+      "outputs": [],
+      "source": [
+        "!pip install opusfilter opennmt-py==2.3.0 mosestokenizer"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "MWqCleaBLGwF"
+      },
+      "source": [
+        "Commençons par télécharger des corpus parallèles bilingues couramment utilisés pour mettre au point des systèmes de TA anglais-français. Tous sont librement disponibles sur le site https://opus.nlpl.eu/, mais nous allons nous concentrer tout d'abord sur l'un de ces jeux de données, le corpus [Books](https://opus.nlpl.eu/Books.php), que nous allons télécharger directement&nbsp;:"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "2cQOxbvqVb5i"
+      },
+      "outputs": [],
+      "source": [
+        "!wget https://opus.nlpl.eu/download.php?f=Books/v1/moses/en-fr.txt.zip -O books.zip # Télécharger le corpus sous un nom donné\n",
+        "!unzip books.zip Books.en-fr.{en,fr}                                                # Décompresser les fichiers en et fr de l'archive\n",
+        "!mv Books.en-fr.en books_raw.en ; mv Books.en-fr.fr books_raw.fr                    # Commande optionnelle pour renommer ces fichiers"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "1j_Kkk3dcPWR"
+      },
+      "source": [
+        "Voyons à quoi ressemblent nos fichiers&nbsp;:"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "XSyIa-jWcZHN",
+        "outputId": "1e50176e-7e73-4b1c-a09b-951f0ba9c817"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "    1\tThe Wanderer\t\t\t\t\t\t \t Le grand Meaulnes\n",
+            "    2\tAlain-Fournier\t\t\t\t\t\t \t Alain-Fournier\n",
+            "    3\tFirst Part\t\t\t\t\t\t \t PREMIÈRE PARTIE\n",
+            "    4\tI\t\t\t\t\t\t\t \t CHAPITRE PREMIER\n",
+            "    5\tTHE BOARDER\t\t\t\t\t\t \t LE PENSIONNAIRE\n",
+            "    6\tHe arrived at our home on a Sunday of November, 189-.\t \t Il arriva chez nous un dimanche de novembre 189-…\n",
+            "    7\tI still say 'our home,' although the house no longer belo\t Je continue à dire « chez nous », bien que la maison ne nous\n",
+            "    8\tWe left that part of the country nearly fifteen years ago\t Nous avons quitté le pays depuis bientôt quinze ans et nous\n",
+            "    9\tWe were living in the building of the Higher Elementary C\t Nous habitions les bâtiments du Cours Supérieur de Sainte-A\n",
+            "   10\tMy father, whom I used to call M. Seurel as did other pup\t Mon père, que j’appelais M. Seurel, comme les autres élèves,\n",
+            "----------------------------------------------------------------------------------------------------------------------------------\n",
+            "76891\tDans ce magnifique que palais de Vignano, que le comte lu\t In this magnificent palace of Vignano, which the Conte ha\n",
+            "76892\tFabrice n’eût pas manqué un jour de venir à Vignano.\t \t Fabrizio had never missed a day in going to Vignano.\n",
+            "76893\tLa comtesse en un mot réunissait toutes les apparences du \t The Contessa, in a word, combined all the outward appeara\n",
+            "76894\tLes prisons de Parme étaient vides, le comte immensément ri\t The prisons of Parma were empty, the Conte immensely rich\n",
+            "76895\tThe Red and The Black\t\t\t\t\t \t Le Rouge et le Noir\n",
+            "76896\tStendhal\t\t\t\t\t\t \t Stendhal\n",
+            "76897\tBOOK ONE\t\t\t\t\t\t \t Livre Premier\n",
+            "76898\tThe truth, the harsh truth\t\t\t\t \t La vérité, l’âpre vérité.\n",
+            "76899\tDANTON\t\t\t\t\t\t\t \t DANTON.\n",
+            "76900\tCHAPTER 1 A Small Town\t\t\t\t\t \t Chapitre premier. Une petite ville\n",
+            "----------------------------------------------------------------------------------------------------------------------------------\n",
+            "19581\t“Well, go,” said I: so the boy jumped into the water and ta\t Aussitôt ce garçon sauta à l'eau, et tenant un petit mousque\n",
+            "19582\tThis was game indeed to us, but this was no food; and I w\t C'était véritablement une chasse pour nous, mais ce n'était\n",
+            "19583\tHowever, Xury said he would have some of him; so he comes\t Xury, néanmoins, voulait en emporter quelque chose. Il vin\n",
+            "19584\t“For what, Xury?” said I. “Me cut off his head,” said he.\t \t --«Pourquoi faire, Xury? lui dis-je.» --«Moi trancher sa tête\n",
+            "19585\tHowever, Xury could not cut off his head, but he cut off \t Toutefois Xury ne put pas la lui trancher, mais il lui co\n",
+            "19586\tI bethought myself, however, that, perhaps the skin of hi\t Cependant je réfléchis que sa peau pourrait sans doute, d'u\n",
+            "19587\tSo Xury and I went to work with him; but Xury was much th\t Xury et moi allâmes donc nous mettre à l'œuvre; mais à cette\n",
+            "19588\tIndeed, it took us both up the whole day, but at last we \t Au fait, cela nous occupa tout deux durant la journée entiè\n",
+            "19589\tAfter this stop, we made on to the southward continually \t Après cette halte, nous naviguâmes continuellement vers le\n",
+            "19590\tMy design in this was to make the river Gambia or Senegal\t Mon dessein était alors d'atteindre le fleuve de Gambie ou\n",
+            "19591\tWhen I had pursued this resolution about ten days longer,\t ROBINSON ET XURY VAINQUEURS D'UN LION Je savais que touts\n",
+            "19592\tI was once inclined to have gone on shore to them; but Xu\t J'eus une fois l'envie de descendre à terre vers eux; mais\n",
+            "19593\tHowever, I hauled in nearer the shore that I might talk t\t Je remarquai qu'ils n'avaient point d'armes à la main, un\n",
+            "19594\tI observed they had no weapons in their hand, except one,\t Sur ce, j'abaissai le haut de ma voile; je m'arrêtai proch\n",
+            "19595\tUpon this I lowered the top of my sail and lay by, and tw\t Je n'osais pas aller à terre vers eux, qui n'étaient pas mo\n",
+            "19596\tWe made signs of thanks to them, for we had nothing to ma\t Toutefois, je pencherais plutôt pour le dernier, parce que\n",
+            "19597\tThe man that had the lance or dart did not fly from them,\t Néanmoins, ces deux créatures coururent droit à la mer, et,\n",
+            "19598\tAs soon as he came fairly within my reach, I fired, and s\t Dès qu'il fut à ma portée, je fis feu, et je le frappai droi\n",
+            "19599\tIt is impossible to express the astonishment of these poo\t Quelques-uns d'entre eux faillirent à en mourir d'effroi,\n",
+            "19600\tI found him by his blood staining the water; and by the h\t Son sang, qui teignait l'eau, me le fit découvrir; et, à l'\n"
+          ]
+        }
+      ],
+      "source": [
+        "!pr --pages 1:1 -m -n -l 10 -w 125 -s$'\\t ' books_raw.{en,fr}\n",
+        "print(\"-\"*130)\n",
+        "!pr --pages 7690:7690 -m -n -l 10 -w 125 -s$'\\t ' books_raw.{en,fr}\n",
+        "print(\"-\"*130)\n",
+        "!pr --pages 980:980 -T -m -n -l 20 -w 125 -s$'\\t ' books_raw.{en,fr}"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "haifLILtq5gI"
+      },
+      "source": [
+        "Comme on le voit, ces fichiers (souvent très longs) posent plusieurs problèmes de qualité&nbsp;:\n",
+        "- les conventions typographiques ne sont pas les mêmes tout au long du fichier&nbsp;;\n",
+        "- les langues sont parfois inversées (lignes 76891-76900)&nbsp;;\n",
+        "- des informations sont parfois présentes dans une langue et pas dans l'autre (ligne 19594)&nbsp;;\n",
+        "- l'alignement n'est pas toujours correct (lignes 19593-19594)&nbsp;;\n",
+        "- ..."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "EcAr2LbC6Lxo"
+      },
+      "source": [
+        "## Étape 2 &mdash; Préparation"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "C-WUOl2H6ReX"
+      },
+      "source": [
+        "On peut régler une petite partie des problèmes typographiques en tokenisant notre texte et en normalisant la ponctuation. La démarche est d'ailleurs nécessaire pour la bonne prise en charge des textes par la machine.\n",
+        "\n",
+        "L'étape de normalisation permet à la fois d'harmoniser la ponctuation et de s'assurer qu'aucun caractère spécial ne vienne perturber le bon traitement du texte (par exemple, l'apostrophe dactylographique droite et l'apostrophe typographique courbe ne sont pas traitées de la même manière).\n",
+        "\n",
+        "La tokenisation quant à elle permet de séparer les mots et la ponctuation (pour la plupart des applications en traitement automatique des langues, on considère généralement que chaque suite de caractères séparée par une espace est un mot différent)."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "7Y1SyquPlRIJ"
+      },
+      "outputs": [],
+      "source": [
+        "from mosestokenizer import *                                      # Importer les fonctions requises\n",
+        "\n",
+        "tokenize = MosesTokenizer('en')                                   # Définir la langue pour la tokenisation\n",
+        "normalize = MosesPunctuationNormalizer('en')                      # Définir la langue pour la normalisation\n",
+        "with open('books_raw.en', 'r', encoding='utf-8') as input:        # Ouvrir le fichier d'origine\n",
+        "  output = open('books_tok.en', 'w', encoding='utf-8')            # Ouvrir le fichier de sortie\n",
+        "  for line in input:                                              # Lire les lignes une à une\n",
+        "    print(*[l for l in tokenize(normalize(line))], file=output)   # Normaliser, tokeniser et reporter la ligne dans le nouveau fichier\n",
+        "output.close()                                                    # Fermer le fichier de sortie\n",
+        "\n",
+        "tokenize = MosesTokenizer('fr')                                   # Même démarche pour le français\n",
+        "normalize = MosesPunctuationNormalizer('fr')\n",
+        "with open('books_raw.fr', 'r', encoding='utf-8') as input:\n",
+        "  output = open('books_tok.fr', 'w', encoding='utf-8')\n",
+        "  for line in input:\n",
+        "    print(*[l for l in tokenize(normalize(line))], file=output)\n",
+        "output.close()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "WRtimmfJw4KQ"
+      },
+      "source": [
+        "Comme le montrent les deux commandes qui suivent, le nombre total de mots (ou tokens) n'est pas le même dans les fichiers avant et après la tokenisation, car la machine compte des occurrences telles que «&nbsp;j'appelais&nbsp;» comme un seul token. Cela signifie que les occurrences telles que «&nbsp;et&nbsp;» / «&nbsp;et,&nbsp;» / «&nbsp;et.&nbsp;» seront comptées comme trois mots différents. La tokenisation réduit ainsi considérablement le nombre d'occurrences différentes et facilite formidablement la lecture informatique du texte."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "MLELmAZUw-z3",
+        "outputId": "bc9e8b12-943d-40d7-b3ec-79bac1325ffa"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "2715071 books_raw.en\n",
+            "3267447 books_tok.en\n"
+          ]
+        }
+      ],
+      "source": [
+        "!wc -w books_raw.en # Compter le nombre de \"mots\" dans le fichier non tokenisé\n",
+        "!wc -w books_tok.en # Compter le nombre de \"mots\" dans le fichier tokenisé"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "xRlWw5UsjDrO"
+      },
+      "source": [
+        "Voyons maintenant à quoi ressemble notre texte."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "VUXjQB9ujHsa",
+        "outputId": "cf3fc5cf-1158-4c20-8cde-2a81b2b53aaa"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            " 1\tThe Wanderer\t\t\t\t\t\t \t Le grand Meaulnes\n",
+            " 2\tAlain @-@ Fournier\t\t\t\t\t \t Alain @-@ Fournier\n",
+            " 3\tFirst Part\t\t\t\t\t\t \t PREMIÈRE PARTIE\n",
+            " 4\tI\t\t\t\t\t\t\t \t CHAPITRE PREMIER\n",
+            " 5\tTHE BOARDER\t\t\t\t\t\t \t LE PENSIONNAIRE\n",
+            " 6\tHe arrived at our home on a Sunday of November , 189- .\t \t Il arriva chez nous un dimanche de novembre 189- ...\n",
+            " 7\tI still say &apos; our home , &apos; although the house n\t Je continue à dire &quot; chez nous &quot; , bien que la m\n",
+            " 8\tWe left that part of the country nearly fifteen years ago\t Nous avons quitté le pays depuis bientôt quinze ans et nous\n",
+            " 9\tWe were living in the building of the Higher Elementary C\t Nous habitions les bâtiments du Cours Supérieur de Sainte @\n",
+            "10\tMy father , whom I used to call M. Seurel as did other pu\t Mon père , que j&apos; appelais M. Seurel , comme les autr\n",
+            "11\tMy mother taught the infants .\t\t\t\t \t Ma mère faisait la petite classe .\n",
+            "12\tAt the extreme end of the small town , a long red house w\t Une longue maison rouge , avec cinq portes vitrées , sous\n",
+            "13\tAt the time of some new &apos; appointments , &apos; a wh\t Le hasard des &quot; changements &quot; , une décision d&a\n",
+            "14\tTowards the end of the summer holidays , a long time ago \t Vers la fin des vacances , il y a bien longtemps , une vo\n",
+            "15\tUrchins who were stealing peaches in the garden silently \t Des gamins qui volaient des pêches dans le jardin s &quot;\n",
+            "16\tShe had come out to impart her trouble to me . While spea\t Tout en me parlant , elle avait essuyé doucement avec son\n",
+            "17\tThen she had gone back to consider what doors and windows\t Puis elle était rentrée faire le compte de toutes les ouver\n",
+            "18\tThus to @-@ day I picture our arrival .\t\t\t \t C&apos; est ainsi , du moins , que j&apos; imagine aujour\n",
+            "19\tFor as soon as I wish to bring back the distant memory of\t Car aussitôt que je veux retrouver le lointain souvenir de\n",
+            "20\tIf I try to imagine that first night which I must have sp\t Et si j&apos; essaie d&apos; imaginer la première nuit que\n",
+            "21\tAnd that quiet countryside - the school , old Father Mart\t Tout ce paysage paisible - l &quot; école , le champ du pèr\n",
+            "22\tYet we had already been ten years in that district when M\t Nous étions pourtant depuis dix ans dans ce pays lorsque M\n",
+            "23\tI was fifteen .\t\t\t\t\t\t \t J&apos; avais quinze ans .\n",
+            "24\tIt was a cold Sunday of November , the first day of autum\t C &quot; était un froid dimanche de novembre , le premier\n",
+            "25\tAll day Millie had waited for the station omnibus to brin\t Toute la journée , Millie avait attendu une voiture de La\n"
+          ]
+        }
+      ],
+      "source": [
+        "!pr --pages 1:1 -T -m -n2 -l 25 -w 125 -s$'\\t ' books_tok.{en,fr}"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "24Gw8RjMf8-c"
+      },
+      "source": [
+        "La majeure partie de notre texte est maintenant correctement tokenisée&nbsp;: la ponctuation est séparée des mots, excepté pour les formes élidées (voir les apostrophes gérées différemment en français et en anglais), et les abréviations sont conservées telles quelles.\n",
+        "\n",
+        "Néanmoins, nous pouvons voir une fois encore que ce traitement entièrement automatique n'est pas parfait (c'est la contrepartie négative du traitement automatique qui permet de prendre en charge un large volume de données textuelles). Regardons, par exemple, les lignes 18 et 24&nbsp;: la première occurrence «&nbsp;C'est&nbsp;» est traitée correctement, mais l'apostrophe est espacée et convertie en guillemet dans le cas de «&nbsp;C'était&nbsp;» (l'étape de normalisation semble poser problème lorsque des caractères spéciaux suivent la ponctuation). Ce genre de problème montre bien l'importance de toujours retourner jeter un &oelig;il aux textes pour repérer les éventuelles fautes ou erreurs liées au traitement des données.\n",
+        "\n",
+        "(La méthode utilisée ici existe aussi sous forme de scripts ou de modules qui ont été mis à jour pour éviter certains problèmes, dont celui évoqué ci-dessus. L'un de ceux-ci est utilisé dans [la version abrégée du cahier d'exercices](https://colab.research.google.com/drive/1aozKjHWeWMsJJ007Vd7p50I_jHqjIn5D?usp=sharing).)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "qo379aNF0nTc"
+      },
+      "source": [
+        "Récemment, les recherches en TAL ont été plus loin encore et ont montré que l'on pouvait atteindre de meilleures performances en découpant le texte à un niveau inférieur au mot (ou token). On peut utiliser pour cela un autre type de tokeniseur tel que [SentencePiece](https://github.com/google/sentencepiece).\n",
+        "\n",
+        "Cette segmentation en sous-mots permet aussi à la machine de gérer des mots non vus. Par exemple, si les occurrences «&nbsp;terriblement&nbsp;» (découpé en «&nbsp;terrible - ment&nbsp;») et «&nbsp;incroyable&nbsp;» ont été vues, «&nbsp;incroyablement&nbsp;» ne sera pas considéré comme un mot nouveau.\n",
+        "\n",
+        "Ce type de découpage a poussé des chercheurs et chercheuses à dire que la machine pouvait ainsi acquérir des compétences linguistiques, mais la segmentation opère parfois à un niveau très abstrait pour l'humain. Regardons comment cela modifie notre texte&nbsp;:"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "YSe-492g2hwZ",
+        "outputId": "71ed07c9-03f1-418b-e851-70a303d648bb"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            " 1\t▁Le ▁grand ▁Mea ulnes\n",
+            " 2\t▁Al ain ▁ @ - @ ▁F our nier\n",
+            " 3\t▁P RE MI È RE ▁ PA RT IE\n",
+            " 4\t▁CHAP ITRE ▁P RE MI ER\n",
+            " 5\t▁ LE ▁P EN SI ON NA I RE\n",
+            " 6\t▁Il ▁arriva ▁chez ▁nous ▁un ▁dimanche ▁de ▁novembre ▁18 9 - ▁...\n",
+            " 7\t▁Je ▁continue ▁à ▁dire ▁& quot ; ▁chez ▁nous ▁& quot ; ▁, ▁bien ▁que ▁la ▁maison ▁ne ▁nous ▁appartien ne ▁plus\n",
+            " 8\t▁Nous ▁avons ▁quitté ▁le ▁pays ▁depuis ▁bientôt ▁qui nze ▁ans ▁et ▁nous ▁n & apos ; ▁y ▁reviendrons ▁certaine\n",
+            " 9\t▁Nous ▁habit ions ▁les ▁bâtiment s ▁du ▁Cour s ▁Su péri eur ▁de ▁Saint e ▁ @ - @ ▁Ag ath e ▁.\n",
+            "10\t▁Mon ▁père ▁, ▁que ▁j & apos ; ▁appel ais ▁M . ▁S eur el ▁, ▁comme ▁les ▁autres ▁élèves ▁, ▁y ▁dirige ait ▁à ▁la ▁f\n",
+            "11\t▁Ma ▁mère ▁faisait ▁la ▁petite ▁classe ▁.\n",
+            "12\t▁Une ▁longue ▁maison ▁rouge ▁, ▁avec ▁cinq ▁portes ▁vit r ées ▁, ▁sous ▁des ▁vigne s ▁vierge s ▁, ▁à ▁l & apos \n",
+            "13\t▁Le ▁hasard ▁des ▁& quot ; ▁changements ▁& quot ; ▁, ▁une ▁décision ▁d & apos ; ▁in spect eur ▁ou ▁de ▁pré f\n",
+            "14\t▁Ver s ▁la ▁fin ▁des ▁vacances ▁, ▁il ▁y ▁a ▁bien ▁longtemps ▁, ▁une ▁voiture ▁de ▁pays an ▁, ▁qui ▁précéd ait ▁no\n",
+            "15\t▁Des ▁gamin s ▁qui ▁vol aient ▁des ▁pêche s ▁dans ▁le ▁jardin ▁s ▁& quot ; ▁étaient ▁enfui s ▁silencieuse me\n"
+          ]
+        }
+      ],
+      "source": [
+        "# Les modèles utilisés pour la segmentation doivent être entraîné sur l'ensemble des corpus qui seront utilisés pour notre tâche.\n",
+        "# Cela peut prendre un certain temps, nous utiliserons donc des modèles pré-entraînés que nous avons téléchargés plus haut.\n",
+        "\n",
+        "import sentencepiece as spm\n",
+        "\n",
+        "#spm.SentencePieceTrainer.train(input='books_tok.en', model_prefix='unigram_en', vocab_size=16000, character_coverage=1.0)\n",
+        "#spm.SentencePieceTrainer.train(input='books_tok.fr', model_prefix='unigram_fr', vocab_size=16000, character_coverage=1.0)\n",
+        "\n",
+        "sp = spm.SentencePieceProcessor(model_file='subword/unigram_en.model')\n",
+        "with open('books_tok.en', 'r', encoding='utf-8') as input, open('books_sub.en', 'w', encoding='utf-8') as output:\n",
+        "    for line in input:\n",
+        "        print(*[l for l in sp.encode(line, out_type=str)], file=output)\n",
+        "\n",
+        "sp = spm.SentencePieceProcessor(model_file='subword/unigram_fr.model')\n",
+        "with open('books_tok.fr', 'r', encoding='utf-8') as input, open('books_sub.fr', 'w', encoding='utf-8') as output:\n",
+        "    for line in input:\n",
+        "        print(*[l for l in sp.encode(line, out_type=str)], file=output)\n",
+        "\n",
+        "!pr --pages 1:1 -T -m -n2 -l 15 -w 100 books_sub.fr"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "zkfcpPwnxbaI"
+      },
+      "source": [
+        "Ce découpage est opéré de manière purement statistique. Cela signifie que certaines divisions peuvent faire sens pour nous, humains francophones (p. ex. «&nbsp;gamin-s&nbsp;», «&nbsp;vol-aient&nbsp;», «&nbsp;pêche-s&nbsp;», «&nbsp;enfui-s&nbsp;»...), tandis que d'autres divisions nous sembleront beaucoup plus abstraites (p. ex. pourquoi «&nbsp;Mea-ulnes&nbsp;» ou «&nbsp;vit-r-ées&nbsp;»&nbsp;?). Toutefois, le découpage en sous-mots fonctionne très bien en pratique et améliore véritablement le résultat.\n",
+        "\n",
+        "L'avantage principal de cette étape est qu'elle permet de fixer la taille de notre vocabulaire à un nombre donné (ici, 16 000 tokens), où tout ce qui apparaît dans notre corpus est représenté d'une manière ou d'une autre. Sans cela, il aurait fallu définir une taille de vocabulaire beaucoup plus élevée (p. ex. les 50&nbsp;000 tokens les plus fréquents du corpus) et laisser irrévocablement de côté tout ce qui n'apparaît pas dans cette liste.\n",
+        "\n",
+        "Passons à présent à l'entraînement de notre système, en espérant que nous ayons suffisamment de données pour que les quelques problèmes soulevés jusqu'ici n'influent pas (trop) sur la suite du processus."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "yFWx-E1h6gkS"
+      },
+      "source": [
+        "## Étape 3 &mdash; Entraînement"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Le corpus Books n'est évidemment pas suffisant pour entraîner à lui seul un système de TA neuronale (plus gourmande en données que les paradigmes précédents). Idéalement, plus d'un ou deux millions de phrases alignées dans les deux langues sont nécessaires ; en pratique, plusieurs dizaines de millions sont utilisées.\n",
+        "\n",
+        "Le code ci-dessous permet de télécharger d'un seul coup plusieurs corpus et de pré-traiter automatiquement ces données grâce à un fichier de configuration, mais le téléchargement de tous ces fichiers serait excessivement long (~ 40 minutes). Regardons donc simplement à quoi ressemble ce fichier et téléchargeons à la place une version pré-traitée de ces 4 corpus, ainsi qu'une version corrigée du corpus Books, mises à disposition sur le dépôt de ce projet."
+      ],
+      "metadata": {
+        "id": "w0HKlqYBzHAa"
+      }
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "h0ujhKYxwqQD"
+      },
+      "outputs": [],
+      "source": [
+        "with open('corpus.yaml', 'w', encoding='utf-8') as config:\n",
+        "  config.write('''common:\n",
+        "\n",
+        "  output_directory: datasets\n",
+        "\n",
+        "steps:\n",
+        "\n",
+        "  - type: opus_read\n",
+        "    parameters:\n",
+        "      corpus_name: Europarl\n",
+        "      source_language: en\n",
+        "      target_language: fr\n",
+        "      release: v8\n",
+        "      preprocessing: raw\n",
+        "      src_output: europarl.en\n",
+        "      tgt_output: europarl.fr\n",
+        "      suppress_prompts: true\n",
+        "\n",
+        "  - type: opus_read\n",
+        "    parameters:\n",
+        "      corpus_name: GlobalVoices\n",
+        "      source_language: en\n",
+        "      target_language: fr\n",
+        "      release: v2018q4\n",
+        "      preprocessing: raw\n",
+        "      src_output: globalvoices.en\n",
+        "      tgt_output: globalvoices.fr\n",
+        "      suppress_prompts: true\n",
+        "\n",
+        "  - type: opus_read\n",
+        "    parameters:\n",
+        "      corpus_name: News-Commentary\n",
+        "      source_language: en\n",
+        "      target_language: fr\n",
+        "      release: v16\n",
+        "      preprocessing: raw\n",
+        "      src_output: news.en\n",
+        "      tgt_output: news.fr\n",
+        "      suppress_prompts: true\n",
+        "\n",
+        "  - type: opus_read\n",
+        "    parameters:\n",
+        "      corpus_name: TED2020\n",
+        "      source_language: en\n",
+        "      target_language: fr\n",
+        "      release: v1\n",
+        "      preprocessing: raw\n",
+        "      src_output: ted.en\n",
+        "      tgt_output: ted.fr\n",
+        "      suppress_prompts: true\n",
+        "\n",
+        "  - type: subset\n",
+        "    parameters:\n",
+        "      inputs: [europarl.en, globalvoices.en, news.en, ted.en]\n",
+        "      outputs: [europarl_small.en, globalvoices_small.en, news_small.en, ted_small.en]\n",
+        "      seed: 123\n",
+        "      size: 40000\n",
+        "\n",
+        "  - type: subset\n",
+        "    parameters:\n",
+        "      inputs: [europarl.fr, globalvoices.fr, news.fr, ted.fr]\n",
+        "      outputs: [europarl_small.fr, globalvoices_small.fr, news_small.fr, ted_small.fr]\n",
+        "      seed: 123\n",
+        "      size: 40000\n",
+        "\n",
+        "  - type: preprocess\n",
+        "    parameters:\n",
+        "      inputs: [europarl_small.en, globalvoices_small.en, news_small.en, ted_small.en]\n",
+        "      outputs: [europarl_tok.en, globalvoices_tok.en, news_tok.en, ted_tok.en]\n",
+        "      preprocessors:\n",
+        "        - Tokenizer:\n",
+        "            tokenizer: moses\n",
+        "            languages: [en, en, en, en]\n",
+        "\n",
+        "  - type: preprocess\n",
+        "    parameters:\n",
+        "      inputs: [europarl_small.fr, globalvoices_small.fr, news_small.fr, ted_small.fr]\n",
+        "      outputs: [europarl_tok.fr, globalvoices_tok.fr, news_tok.fr, ted_tok.fr]\n",
+        "      preprocessors:\n",
+        "        - Tokenizer:\n",
+        "            tokenizer: moses\n",
+        "            languages: [fr, fr, fr, fr]''')\n",
+        "config.close()\n",
+        "\n",
+        "#!opusfilter corpus.yaml\n",
+        "#!rm ./data/*.{gz,zip}\n",
+        "#!rm ./data/*_small.{en,fr}"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Nous ne téléchargerons que les 10 000 premières lignes de chaque document pour éviter de gaspiller du temps et des ressources&nbsp;:"
+      ],
+      "metadata": {
+        "id": "N96pmR_9uijk"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Corpus génériques\n",
+        "\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/globalvoices.en\" -s | head -10000 > datasets/globalvoices.en\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/globalvoices.fr\" -s | head -10000 > datasets/globalvoices.fr\n",
+        "\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/europarl.en\" -s | head -10000 > datasets/europarl.en\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/europarl.fr\" -s | head -10000 > datasets/europarl.fr\n",
+        "\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/news.en\" -s | head -10000 > datasets/news.en\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/news.fr\" -s | head -10000 > datasets/news.fr\n",
+        "\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/ted.en\" -s | head -10000 > datasets/ted.en\n",
+        "!curl -r0-1 \"https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/ted.fr\" -s | head -10000 > datasets/ted.fr\n",
+        "\n",
+        "# Corpus spécialisé\n",
+        "\n",
+        "!wget https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/datasets/books.{en,fr} -P datasets"
+      ],
+      "metadata": {
+        "id": "fUq6bEH1vDvl"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Ces corpus divers nous serviront à entraîner un système (ou modèle) dit «&nbsp;générique&nbsp;». En effet, la taille de nos corpus est aussi importante que leur qualité et leur pertinence par rapport au domaine traité&nbsp;:\n",
+        "\n",
+        "- le volume des données permet de mettre au point un système robuste, qui produira des phrases grammaticalement correctes&nbsp;;\n",
+        "- les données spécialisées permettront à ce même système de s'adapter à une terminologie et à un style donnés.\n",
+        "\n",
+        "Toutefois, comme notre but est d'adapter un de ces modèles au domaine littéraire, nous l'affinerons sur notre corpus Books préalablement traité. La dernière chose à faire est de séparer ce corpus d'entraînement en trois jeux distincts&nbsp;:\n",
+        "\n",
+        "- un jeu d'entraînement (la majeure partie du corpus)&nbsp;;\n",
+        "- un jeu de validation (utilisé durant l'entraînement pour en suivre l'évolution)&nbsp;;\n",
+        "- un jeu de test (pour évaluer notre système sur des données non vues).\n",
+        "\n",
+        "Il est extrêmement important que ces deux derniers jeux de données ne fassent pas partie des données d'entraînement, car le système doit être testé sur des phrases auxquelles il n'a pas été confronté durant sa mise au point."
+      ],
+      "metadata": {
+        "id": "XQNHuksbJmFi"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Pour notre cas, créons un jeu de test à partir de 2 chapitres (~150 lignes) d'un même livre.\n",
+        "\n",
+        "!sed -n '112551,112705p;112706q' datasets/books.en > datasets/tra.en ; truncate -s -1 datasets/tra.en\n",
+        "!sed -n '112551,112705p;112706q' datasets/books.fr > datasets/tra.fr ; truncate -s -1 datasets/tra.fr\n",
+        "\n",
+        "# Enlevons maintenant du jeu d'entraînement les phrases utilisées pour le jeu de test :\n",
+        "\n",
+        "!sed '112551,112705d' datasets/books.en > temp.txt ; mv temp.txt datasets/books.en\n",
+        "!sed '112551,112705d' datasets/books.fr > temp.txt ; mv temp.txt datasets/books.fr\n",
+        "\n",
+        "# Passons ensuite au corpus de validation et extrayons les 9 chapitres qui précèdent notre jeu de test :\n",
+        "\n",
+        "!sed -n '111671,112550p;112551q' datasets/books.en > datasets/val.en ; truncate -s -1 datasets/val.en\n",
+        "!sed -n '111671,112550p;112551q' datasets/books.fr > datasets/val.fr ; truncate -s -1 datasets/val.fr\n",
+        "\n",
+        "# Supprimons à nouveau les lignes utilisées pour le jeu de validation :\n",
+        "\n",
+        "!sed '111671,112550d' datasets/books.en > temp.txt ; mv temp.txt datasets/books.en\n",
+        "!sed '111671,112550d' datasets/books.fr > temp.txt ; mv temp.txt datasets/books.fr\n",
+        "\n",
+        "# Supprimons enfin les fichiers qui ne nous serviront plus :\n",
+        "\n",
+        "!rm ./*_{raw,tok,sub}.en ; rm ./*_{raw,tok,sub}.fr ; rm ./books.zip"
+      ],
+      "metadata": {
+        "id": "rmDC_55Pykjn"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "9AMicn9V8ATl"
+      },
+      "source": [
+        "Dans un cas réel, il nous faudrait environ 10x plus d'exemples pour le test et la validation, mais ceci nous servira pour l'exercice. Nous pouvons à présent passer à l'entraînement.\n",
+        "\n",
+        "Tous les paramètres et les fichiers liés à l'entraînement de notre système sont repris dans un fichier de configuration que nous allons créer immédiatement. Il faut y spécifier le chemin vers les fichiers de vocabulaire, vers les corpus d'entraînement (ici, uniquement nos corpus réduits et notre sous-corpus de validation&nbsp;; idéalement, plusieurs corpus auxquels on donne un poids différent), mais aussi le chemin vers le modèle de segmentation et enfin les dossiers de sortie et les paramètres (nous utilisons ici le modèle Transformer basique, avec les paramètres recommandés dans la documentation d'[OpenNMT](https://opennmt.net/OpenNMT-py/FAQ.html#how-do-i-use-the-transformer-model))."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "rd4eo4ZY2vnZ"
+      },
+      "outputs": [],
+      "source": [
+        "with open('config_train.yaml', 'w', encoding='utf-8') as config:\n",
+        "  config.write('''# Data output:\n",
+        "overwrite: false\n",
+        "save_data: ./output/vocab/voc\n",
+        "src_vocab: ./output/vocab/voc.vocab.src\n",
+        "tgt_vocab: ./output/vocab/voc.vocab.tgt\n",
+        "\n",
+        "# Training corpora:\n",
+        "data:\n",
+        "    europarl:\n",
+        "        path_src: ./datasets/europarl.en\n",
+        "        path_tgt: ./datasets/europarl.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    globalvoices:\n",
+        "        path_src: ./datasets/globalvoices.en\n",
+        "        path_tgt: ./datasets/globalvoices.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    news:\n",
+        "        path_src: ./datasets/news.en\n",
+        "        path_tgt: ./datasets/news.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    ted:\n",
+        "        path_src: ./datasets/ted.en\n",
+        "        path_tgt: ./datasets/ted.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    valid:\n",
+        "        path_src: ./datasets/val.en\n",
+        "        path_tgt: ./datasets/val.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "src_seq_length: 200\n",
+        "tgt_seq_length: 200\n",
+        "skip_empty_level: silent\n",
+        "src_subword_model: ./subword/unigram_en.model\n",
+        "tgt_subword_model: ./subword/unigram_fr.model\n",
+        "src_subword_vocab: ./subword/unigram_en.vocab\n",
+        "tgt_subword_vocab: ./subword/unigram_fr.vocab\n",
+        "src_subword_alpha: 0.5\n",
+        "tgt_subword_alpha: 0.5\n",
+        "\n",
+        "# Training parameters:\n",
+        "batch_type: \"tokens\"\n",
+        "batch_size: 4096\n",
+        "valid_batch_size: 16\n",
+        "batch_size_multiple: 1\n",
+        "max_generator_batches: 0\n",
+        "accum_count: [3]\n",
+        "accum_steps: [0]\n",
+        "train_steps: 100            # Fortement réduit pour les besoins de l'exercice. Habituellement en dizaines ou centaines de milliers.\n",
+        "valid_steps: 100            # Fortement réduit pour les besoins de l'exercice. Habituellement 5 ou 10 000.\n",
+        "report_every: 10            # Fortement réduit pour les besoins de l'exercice. Habituellement autour de 100.\n",
+        "save_checkpoint_steps: 100  # Fortement réduit pour les besoins de l'exercice. Habituellement autour de 10 000.\n",
+        "queue_size: 10000\n",
+        "bucket_size: 32768\n",
+        "\n",
+        "# Optimization\n",
+        "model_dtype: \"fp32\"\n",
+        "optim: \"adam\"\n",
+        "learning_rate: 2\n",
+        "warmup_steps: 8000\n",
+        "decay_method: \"noam\"\n",
+        "average_decay: 0.0005\n",
+        "adam_beta2: 0.998\n",
+        "max_grad_norm: 0\n",
+        "label_smoothing: 0.1\n",
+        "param_init: 0\n",
+        "param_init_glorot: true\n",
+        "normalization: \"tokens\"\n",
+        "\n",
+        "# Model\n",
+        "encoder_type: transformer\n",
+        "decoder_type: transformer\n",
+        "enc_layers: 6\n",
+        "dec_layers: 6\n",
+        "heads: 8\n",
+        "rnn_size: 512\n",
+        "word_vec_size: 512\n",
+        "transformer_ff: 2048\n",
+        "dropout_steps: [0]\n",
+        "dropout: [0.1]\n",
+        "attention_dropout: [0.1]\n",
+        "position_encoding: true\n",
+        "\n",
+        "# Model output:\n",
+        "save_model: ./output/models/train\n",
+        "\n",
+        "# Logs:\n",
+        "log_file: ./output/log/train\n",
+        "tensorboard: true\n",
+        "tensorboard_log_dir: ./output/tensor/train\n",
+        "\n",
+        "# GPU settings:\n",
+        "world_size: 1\n",
+        "gpu_ranks: [0]\n",
+        "\n",
+        "# Reproducibility:\n",
+        "seed: 123''')\n",
+        "config.close()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Il nous faut maintenant créer des fichiers de vocabulaire qui seront utilisés par OpenNMT.\n",
+        "\n",
+        "(Normalement, nous devrions utiliser le fichier de configuration utilisé pour l'affinage (*fine-tuning*) du système, car vous aurez remarqué que le corpus Books ne fait pas encore partie des données d'entraînement. Pour l'exercice, cependant, nous aborderons cette étape juste après.)"
+      ],
+      "metadata": {
+        "id": "cJrh9tQwVxFE"
+      }
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "RqVYEHDaDdry"
+      },
+      "outputs": [],
+      "source": [
+        "!onmt_build_vocab --config config_train.yaml --n_sample 5000 # Réduit pour les besoins de l'exercice (normalement paramétré à -1)."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "lwPQFT1REnyq"
+      },
+      "source": [
+        "Enfin, tout est prêt&nbsp;! Nous pouvons lancer l'entraînement de notre système générique.\n",
+        "\n",
+        "(Nous ne laisserons tourner notre modèle que très brièvement, car cela prendrait des jours autrement.)"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {
+        "id": "pbByrJ8uEK95"
+      },
+      "outputs": [],
+      "source": [
+        "!onmt_train --config config_train.yaml"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Nous avons à présent un modèle générique, certes prématuré, mais qui peut être utilisé pour traduire de l'anglais vers le français. Ce modèle est sauvegardé sous la forme d'un fichier PT («&nbsp;checkpoint&nbsp;»). Au terme d'un processus d'entraînement complet, plusieurs modèles sont créés. Il faut alors les tester pour vérifier lequel est le plus performant (c'est dans ce contexte que les métriques d'évaluation automatiques se révèlent les plus utiles).\n",
+        "\n",
+        "Mais à ce stade, nous n'avons pas encore fourni de données littéraires à notre système. Il nous faut donc relancer le processus, en y ajoutant cette fois le corpus Books. Pour ce faire, nous créons à nouveau un fichier de configuration, dans lequel nous allons simplement indiquer où trouver le modèle générique précédent, augmenter le nombre d'étapes et changer le nom des fichiers de sortie. Il nous faut aussi ajouter les données spécialisées dans la liste des corpus.\n",
+        "\n",
+        "(Il est important de conserver ici les corpus génériques, sans quoi notre système oublierait en quelque sorte ce qu'il a appris auparavant. Néanmoins, là où, dans un processus d'apprentissage normal, ces corpus se seraient vus assigner un poids variable supérieur à 1, il faudra ici réduire ce score de manière à ce que les données spécialisées soient surreprésentées.)"
+      ],
+      "metadata": {
+        "id": "27Lp42b6ZLaO"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "with open('config_tuned.yaml', 'w', encoding='utf-8') as config:\n",
+        "  config.write('''# Data output:\n",
+        "overwrite: false\n",
+        "save_data: ./output/vocab/voc\n",
+        "src_vocab: ./output/vocab/voc.vocab.src\n",
+        "tgt_vocab: ./output/vocab/voc.vocab.tgt\n",
+        "\n",
+        "# Training corpora:\n",
+        "data:\n",
+        "    europarl:\n",
+        "        path_src: ./datasets/europarl.en\n",
+        "        path_tgt: ./datasets/europarl.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    globalvoices:\n",
+        "        path_src: ./datasets/globalvoices.en\n",
+        "        path_tgt: ./datasets/globalvoices.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    news:\n",
+        "        path_src: ./datasets/news.en\n",
+        "        path_tgt: ./datasets/news.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    ted:\n",
+        "        path_src: ./datasets/ted.en\n",
+        "        path_tgt: ./datasets/ted.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 1\n",
+        "    books:\n",
+        "        path_src: ./datasets/books.en\n",
+        "        path_tgt: ./datasets/books.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "        weight: 5\n",
+        "    valid:\n",
+        "        path_src: ./datasets/val.en\n",
+        "        path_tgt: ./datasets/val.fr\n",
+        "        transforms: [filtertoolong, sentencepiece]\n",
+        "src_seq_length: 200\n",
+        "tgt_seq_length: 200\n",
+        "skip_empty_level: silent\n",
+        "src_subword_model: ./subword/unigram_en.model\n",
+        "tgt_subword_model: ./subword/unigram_fr.model\n",
+        "src_subword_vocab: ./subword/unigram_en.vocab\n",
+        "tgt_subword_vocab: ./subword/unigram_fr.vocab\n",
+        "src_subword_alpha: 0.5\n",
+        "tgt_subword_alpha: 0.5\n",
+        "\n",
+        "# Training parameters:\n",
+        "batch_type: \"tokens\"\n",
+        "batch_size: 4096\n",
+        "valid_batch_size: 16\n",
+        "batch_size_multiple: 1\n",
+        "max_generator_batches: 0\n",
+        "accum_count: [3]\n",
+        "accum_steps: [0]\n",
+        "train_steps: 200            # Fortement réduit pour les besoins de l'exercice. Habituellement en dizaines ou centaines de milliers.\n",
+        "valid_steps: 100            # Fortement réduit pour les besoins de l'exercice. Habituellement 5 ou 10 000.\n",
+        "report_every: 10            # Fortement réduit pour les besoins de l'exercice. Habituellement autour de 100.\n",
+        "save_checkpoint_steps: 100  # Fortement réduit pour les besoins de l'exercice. Habituellement autour de 10 000.\n",
+        "queue_size: 10000\n",
+        "bucket_size: 32768\n",
+        "train_from: ./output/models/train_step_100.pt\n",
+        "\n",
+        "# Optimization\n",
+        "model_dtype: \"fp32\"\n",
+        "optim: \"adam\"\n",
+        "learning_rate: 2\n",
+        "warmup_steps: 8000\n",
+        "decay_method: \"noam\"\n",
+        "average_decay: 0.0005\n",
+        "adam_beta2: 0.998\n",
+        "max_grad_norm: 0\n",
+        "label_smoothing: 0.1\n",
+        "param_init: 0\n",
+        "param_init_glorot: true\n",
+        "normalization: \"tokens\"\n",
+        "\n",
+        "# Model\n",
+        "encoder_type: transformer\n",
+        "decoder_type: transformer\n",
+        "enc_layers: 6\n",
+        "dec_layers: 6\n",
+        "heads: 8\n",
+        "rnn_size: 512\n",
+        "word_vec_size: 512\n",
+        "transformer_ff: 2048\n",
+        "dropout_steps: [0]\n",
+        "dropout: [0.1]\n",
+        "attention_dropout: [0.1]\n",
+        "position_encoding: true\n",
+        "\n",
+        "# Model output:\n",
+        "save_model: ./output/models/tuned\n",
+        "\n",
+        "# Logs:\n",
+        "log_file: ./output/log/tuned\n",
+        "tensorboard: true\n",
+        "tensorboard_log_dir: ./output/tensor/tuned\n",
+        "\n",
+        "# GPU settings:\n",
+        "world_size: 1\n",
+        "gpu_ranks: [0]\n",
+        "\n",
+        "# Reproducibility:\n",
+        "seed: 123''')\n",
+        "config.close()\n",
+        "\n",
+        "!onmt_train --config config_tuned.yaml"
+      ],
+      "metadata": {
+        "id": "N1FtMObzZLy9"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "Df6-Izu9gCZs"
+      },
+      "source": [
+        "## Étape 4 &mdash; Traduction et évaluation"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "OpenNMT segmente les phrases à la volée pendant l'entraînement, il n'y a donc pas besoin de lui soumettre des corpus segmentés (si vous jetez un &oelig;il aux corpus utilisés, vous remarquerez qu'ils sont simplement tokenisés).\n",
+        "\n",
+        "Notre fichier de test, en revanche, doit être segmenté (puisque notre système aura été entraîné sur des données similaires). À l'inverse, la référence qui nous servira pour l'évaluation doit toujours être détokenisée et non segmentée.\n",
+        "\n",
+        "Faisons cela rapidement&nbsp;:"
+      ],
+      "metadata": {
+        "id": "7EpXsYMy5zhy"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Segmenter le jeu de test\n",
+        "\n",
+        "sp = spm.SentencePieceProcessor(model_file='subword/unigram_en.model')\n",
+        "with open('datasets/tra.en', 'r', encoding='utf-8') as input, open('datasets/tra_sub.en', 'w', encoding='utf-8') as output:\n",
+        "    for line in input:\n",
+        "        print(*[l for l in sp.encode(line, out_type=str)], file=output)\n",
+        "\n",
+        "!rm datasets/tra.en ; mv datasets/tra_sub.en datasets/tra.en ; truncate -s -1 datasets/tra.en\n",
+        "\n",
+        "# Détokeniser la référence\n",
+        "\n",
+        "tk = MosesDetokenizer('fr')\n",
+        "with open('datasets/tra.fr', 'r') as input, open('datasets/tra_detok.fr', 'w') as output:\n",
+        "  for line in input:\n",
+        "    print(tk(line.split()), file=output)\n",
+        "\n",
+        "!rm datasets/tra.fr ; mv datasets/tra_detok.fr datasets/tra.fr ; truncate -s -1 datasets/tra.fr"
+      ],
+      "metadata": {
+        "id": "q2Heb8De86hK"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Si nous lancions une traduction avec le modèle affiné obtenu à ce stade, nous pourrions prédire avec certitude que le résultat sera catastrophique au vu du temps d'entraînement (un essai durant le colloque a d'ailleurs montré que celui-ci ne produisait que des espaces).\n",
+        "\n",
+        "Téléchargeons donc deux modèles (générique et affiné) qui ont été entraînés un peu plus longtemps pour être mis à disposition sur le dépôt&nbsp;:"
+      ],
+      "metadata": {
+        "id": "VruWUmoDHe5n"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "!wget https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/translation_models/{train,tuned}.pt -P output/models"
+      ],
+      "metadata": {
+        "id": "aSMpRfwQ_h9q"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Et lançons la traduction&nbsp;:"
+      ],
+      "metadata": {
+        "id": "z6Mvjk8F5iLt"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "!onmt_translate \\\n",
+        "  --verbose \\\n",
+        "  --model ./output/models/train.pt \\\n",
+        "  --src ./datasets/tra.en \\\n",
+        "  --output ./output/translations/train_sub.fr\n",
+        "\n",
+        "!onmt_translate \\\n",
+        "  --verbose \\\n",
+        "  --model ./output/models/tuned.pt \\\n",
+        "  --src ./datasets/tra.en \\\n",
+        "  --output ./output/translations/tuned_sub.fr"
+      ],
+      "metadata": {
+        "id": "in94msdUJq4N"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Il faut à présent prendre le chemin inverse de l'étape de préparation des données&nbsp;: défaire la segmentation en sous-mots et détokeniser le fichier de sortie.\n",
+        "\n",
+        "(Notre système a été entraîné sur des fichiers segmentés et tokenisés, il retourne donc des sorties similaires. Or, l'évaluation doit toujours se faire sur un fichier détokenisé.)"
+      ],
+      "metadata": {
+        "id": "qdmPa1kZZl2-"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "tk = MosesDetokenizer('fr') \n",
+        "sp = spm.SentencePieceProcessor(model_file='subword/unigram_fr.model')\n",
+        "\n",
+        "with open('output/translations/train_sub.fr', 'r') as input, open('output/translations/train.fr', 'w') as output:\n",
+        "  for line in input:\n",
+        "    segment = sp.decode(line.split())\n",
+        "    print(tk(segment.split()), file=output)\n",
+        "\n",
+        "with open('output/translations/tuned_sub.fr', 'r') as input, open('output/translations/tuned.fr', 'w') as output:\n",
+        "  for line in input:\n",
+        "    segment = sp.decode(line.split())\n",
+        "    print(tk(segment.split()), file=output)"
+      ],
+      "metadata": {
+        "id": "RLpYxpA-bmtl"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Pour l'évaluation, nous pouvons utiliser [sacreBLEU](https://github.com/mjpost/sacrebleu), qui nous donnera trois métriques différentes&nbsp;:\n",
+        "\n",
+        "- BLEU, qui compare des suites de mots (ou n-grammes) pour estimer la ressemblance par rapport à une référence&nbsp;;\n",
+        "\n",
+        "- chrF2++, qui fait de même en comparant des suites de caractères à la place des mots&nbsp;; et\n",
+        "\n",
+        "- TER, qui calcule de nombre d'opérations à produire sur la sortie de TA pour qu'elle soit identique à la référence donnée."
+      ],
+      "metadata": {
+        "id": "YJheULW70C-o"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "!sacrebleu ./datasets/tra.fr \\\n",
+        "\t--input ./output/translations/{train,tuned}.fr \\\n",
+        "\t--language-pair en-fr \\\n",
+        "\t--metrics bleu chrf ter \\\n",
+        "\t--chrf-word-order 2 \\\n",
+        "\t--tokenize 13a \\\n",
+        "\t--width 2 \\\n",
+        "\t--format text"
+      ],
+      "metadata": {
+        "id": "nJX6Dj-bY6ZW",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "29a174d2-6437-41c1-85f0-2beb56f98ab9"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "sacreBLEU: Found 2 systems.\n",
+            "╒════════════════════════════════╤════════╤═══════════╤═══════╕\n",
+            "│                         System │  BLEU  │  chrF2++  │  TER  │\n",
+            "╞════════════════════════════════╪════════╪═══════════╪═══════╡\n",
+            "│ ./output/translations/train.fr │ 14.49  │   41.79   │ 83.81 │\n",
+            "├────────────────────────────────┼────────┼───────────┼───────┤\n",
+            "│ ./output/translations/tuned.fr │ 17.34  │   42.52   │ 79.74 │\n",
+            "╘════════════════════════════════╧════════╧═══════════╧═══════╛\n",
+            "\n",
+            "-----------------\n",
+            "Metric signatures\n",
+            "-----------------\n",
+            " - BLEU       nrefs:1|case:mixed|eff:no|tok:13a|smooth:exp|version:2.3.1\n",
+            " - chrF2++    nrefs:1|case:mixed|eff:yes|nc:6|nw:2|space:no|version:2.3.1\n",
+            " - TER        nrefs:1|case:lc|tok:tercom|norm:no|punct:yes|asian:no|version:2.3.1\n",
+            "\u001b[0m"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Malgré le temps d'entraînement réduit de ces deux systèmes et la petite taille de notre corpus spécialisé, nous pouvons voir que l'affinage apporte déjà une amélioration. Ceci est évidemment prévisible, car plus les données sont pertinentes et cohérentes (p. ex. même domaine, même genre littéraire, même auteur·trice, même traducteur·trice&hellip;), plus les traductions seront pertinentes elles aussi.\n",
+        "\n",
+        "Pour terminer, voici quelques traductions d'autres modèles entraînés rapidement et affinés sur une saga en particulier. Quelles différences notez-vous entre le système générique et le système affiné (gardez à l'esprit qu'il s'agit de modèles peu robustes)&nbsp;?"
+      ],
+      "metadata": {
+        "id": "WbsleCkRfZJE"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "!wget -q https://gitlab.uliege.be/dhansen/tutorielmt/-/raw/main/translation_examples.csv\n",
+        "\n",
+        "import pandas\n",
+        "from google.colab import data_table\n",
+        "data_table.enable_dataframe_formatter()\n",
+        "df = pandas.read_csv('translation_examples.csv', sep='\\t', on_bad_lines='skip')\n",
+        "df"
+      ],
+      "metadata": {
+        "id": "bfkwatPOMaYd"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Quelques exemples plus précis&nbsp;:"
+      ],
+      "metadata": {
+        "id": "rMRjpZvb-cFb"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "|Source|Générique|Affiné|Référence|\n",
+        "|:---|:---|:---|:---|\n",
+        "|Temps&nbsp;: plutôt ✅<br><br>(Pas systématiquement&nbsp;!)|\n",
+        "|Rincewind grabbed Twoflower's arm,<br>kicked the nearest guard in the groin,<br>and dragged the startled tourist into the corridor.|Garhartra a pris le bras, a botté le garde<br>le plus proche dans l'entrejambe et a traîné le touriste<br>surpris dans le couloir.|Rincevent <u>empoigna</u> le bras de Deuxfleurs,<br><u>flanqua</u> un coup de pied dans l'entrejambe du garde<br>le plus proche et <u>entraîna</u> le touriste ahuri dans le couloir.|Rincevent attrapa le bras de Deuxfleurs,<br>flanqua un coup de pied dans l'entrejambe du garde<br>le plus proche et entraîna le touriste ahuri dans le couloir.|\n",
+        "|Choix lexicaux&nbsp;: généralement ✅<br><br>Parfois toujours très ❌|\n",
+        "|Close into the lip of the Rimfall were the<br>seven lesser colors, sparkling and dancing<br>in the spray of the dying seas.<br><br>A double rainbow corruscated into being.|Près de la lèvre de la cascade se trouvaient<br>les sept couleurs inférieures, étincelantes et dansantes<br>dans l'eau des mers mourantes.<br><br>Un double arc-en-ciel s'assembla.|<u>Au bord de</u> la Grande Cataracte se trouvaient<br>les sept couleurs inférieures qui scintillaient et dansaient<br>dans les <u>embruns</u> des mers mourantes.<br><br>Un double arc-en-ciel <u>se mit en branle</u>.|Près du bord de la Cataracte,<br>les sept couleurs mineures étincelaient et dansaient<br>dans les embruns des mers expirantes.<br><br>Un double arc-en-ciel irisé se formait.|\n",
+        "|Termes de l'univers fictionnel&nbsp;: plutôt ✅<br><br>(Quelques incohérences)|\n",
+        "|“Yes,” said the Lady. “The Krullians intend to<br>launch a bronze vessel over the edge of the Disc.<br>Their prime purpose is to learn the sex of A'Tuin<br>the World Turtle.”|« Oui », dit la Dame, « les Krolliens ont l'intention de lancer<br>un navire en bronze au-dessus du bord de la Discussion.<br>Leur objectif premier est d'apprendre le sexe d'A'Suin<br>la Tourelle du Monde. »|— Oui, fit la Dame. Les <u>Krulliens</u> ont l'intention de lancer<br>un bateau de bronze au-dessus du bord du <u>Disque</u>.<br>Leur objectif premier est d'apprendre le sexe d'<u>A'Tuin</u><br><u>la Tortue du Monde</u>.|— Si, fit la Dame. Les Krulliens ont l'intention de lancer<br>un vaisseau de bronze par-dessus le bord du Disque.<br>Leur principal objectif est de connaître le sexe d'A'Tuin,<br>la Tortue du Monde.|\n",
+        "|Texte en majuscules&nbsp;: plutôt ❌<br><br>(Nécessite un traitement particulier)|\n",
+        "|I DID INDEED CHASE THEM MIGHTILY, ONCE,<br>he said, BUT AT LAST THE THOUGHT CAME TO<br>ME THAT SOONER OR LATER ALL MEN MUST DIE.<br>EVERYTHING DIES IN THE END.|J'AI DANS LE CHASE D'AUTRE, a-t-il dit,<br>MAIS AVEC LE THOUGHT ME CAME POUR MOI QUE<br>CHOSE OU LA TOUS LES MENS DOIT MOURIR. TOUS<br>LES CHOSES DANS L'ET.|« J'AI FAIT MIEUX QU'ELLES M'ATTENDENT À LA FOIS,<br>MAIS ENFIN DERNIÈRE LE CHAME À MOI QUE TOUS<br>LES HOMMES DOIVENT MOURIR. TOUS LES HOMMES<br>DONT MOURIR.|« JE LEUR AI DONNE LA CHASSE IL Y A QUELQUE TEMPS,<br>C'EST VRAI, FIT-IL, MAIS J'AI FINI PAR ME DIRE QUE TÔT<br>OU TARD TOUS LES HOMMES DOIVENT MOURIR.<br>TOUTE CHOSE MEURT UN JOUR.|\n",
+        "|Ponctuation&nbsp;: plutôt ✅<br><br>(Pas systématiquement&nbsp;!)|\n",
+        "|“Twoflower?” he said.<br><br>“Yes?”<br><br>“If I turn around, what will I see?”<br><br>“His name is Tethis. He says he's a sea troll.<br>This is his boat.<br>He rescued us,” explained Twoflower.<br>“Will you look around now?”<br><br>“Not just at the moment, thank you.<br>So why aren't we going over the Edge, then?”<br>asked Rincewind with glassy calmness.<br><br>“Because your boat hit the Circumfence,”<br>said the voice behind him (in tones that made<br>Rincewind imagine submarine chasms and<br>lurking Things in coral reefs).|« & # 160 ; ?<br><br>“Oui ? ”<br><br>“Si je me retourne, que verrai-je ? ”<br><br>“Il s'appelle Téthis. Il dit qu'il s'agit d'un troll des mers.<br>C'est son bateau.<br>Il nous a sauvés, ” explique-t-il autour de lui :“<br>Allez-vous regarder maintenant ? ”<br><br>“Pas seulement pour l'instant, merci.<br>Alors pourquoi ne passons-nous pas à l'Avantage ? ”<br>a demandé avec un calme vitreux.<br><br>“Parce que votre bateau a heurté le Circumfence, ”<br>a dit la voix derrière lui<br>(d'un ton qui faisait croire à des gouffres sous-marins et<br>qui rôdaient dans les récifs coralliens).|« Deuxfleurs ? fit-il.<br><br>— Oui ?<br><br>— Si je me retourne, qu'est-ce que je vais voir ?<br><br>— Il s'appelle Téthis. Il dit que c'est un troll des mers.<br>C'est son bateau.<br>Il nous a sauvés, expliqua Deuxfleurs.<br>Tu veux bien regarder autour de toi, maintenant ?<br><br>— Pas pour l'instant, merci.<br>Alors pourquoi est-ce qu'on ne passe pas par-dessus le Bord ?<br>demanda Rincevent avec un calme vitreux.<br><br>— Parce que votre bateau a percuté le Périfilet,<br>répondit la voix derrière lui<br>(d'un ton qui donna à Rincevent l'image de gouffres sous-marins et<br>de créatures tapies dans les récifs coralliens).|« Deuxfleurs ? fit-il.<br><br>— Oui ?<br><br>— Si je me retourne, je vais voir quoi ?<br><br>— Il s'appelle Téthis. Il dit qu'il est un troll marin.<br>Ça, c'est son bateau.<br>Il nous a sauvés, expliqua Deuxfleurs. Tu veux te retourner, maintenant ?<br><br>— Pas pour l'instant, merci.<br>Alors, pourquoi on ne passe pas par-dessus Bord ?<br>demanda le mage avec un calme vitreux.<br><br>— Parce que votre bateau a heurté le Périfilet,<br>répondit la voix dans son dos<br>(rien qu'à l'entendre, Rincevent imaginait déjà des abîmes sous-marins et<br>des Choses à l'affût dans des récifs de corail).|\n",
+        "|Longs segments&nbsp;: plutôt ❌<br><br>(le système peut être paramétré en ce sens)|\n",
+        "|The captain, a thickset man who wore the<br>elbow-turbans typical of a Great Nef tribesman,<br>was much traveled and had seen many strange<br>peoples and curious things, many of which he<br>had subsequently enslaved or stolen. He had<br>begun his career as a sailor on the Dehydrated<br>Ocean in the heart of the Disc's driest desert.<br>(Water on the Disc has an uncommon fourth<br>state, caused by intense heat combined with<br>the strange dessicating effects of octarine<br>light; it dehydrates, leaving a silvery residue<br>like free-flowing sand through which a<br>well-designed hull can glide with ease.<br>The Dehydrated Ocean is a strange place,<br>but not so strange as its fish.)|Le capitaine, un homme d'épaisseur qui portait les<br>turbans du coude typiques d'un grand nef, voyageait<br>beaucoup et avait vu des gens étranges et des choses<br>étranges, dont beaucoup avaient ensuite été asservis<br>ou volés. Il avait commencé sa carrière de marin sur<br>l'Océan déshydraté au cœur du désert le plus sec du Disc.<br>(L'eau sur le Disque|Le capitaine, un costaud qui portait les<br>turbans à coude typique d'un membre de la tribu du Grand Nef,<br>voyageait beaucoup et avait vu beaucoup de peuples<br>étranges et de phénomènes curieux, dont beaucoup avaient<br>été ensuite réduits en esclavage ou volés.<br>Il avait commencé sa carrière de marin sur<br>l'océan Déshydraté au cœur du désert le plus sec du Disque.<br><u>(L'eau sur le Disque</u>|Le capitaine, un costaud qui portait les<br>turbans de coude propres aux tribus du Grand Nef,<br>avait beaucoup bourlingué, beaucoup vu de choses étranges et<br>de gens bizarres, qu'il avait ensuite pour la plupart volées ou réduits<br>en esclavage. Il avait commencé sa carrière comme marin sur l'océan<br>Déshydraté au cœur du désert le plus aride du Disque.<br>(Sur le Disque, l'eau se présente sous un quatrième état inhabituel,<br>dû à la chaleur intense combinée aux curieux effets dessiccatifs de la<br>lumière octarine ; elle se déshydrate en laissant un résidu argenté,<br>comme du sable fluide, dans lequel une coque bien conçue peut<br>évoluer sans peine. L'océan Déshydraté est une région qui sort<br>de l'ordinaire, quoique moins que les poissons qu'il contient.)|"
+      ],
+      "metadata": {
+        "id": "eYhky6qW2caU"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Et voilà, nous venons de voir un exemple de bout en bout !\n",
+        "\n",
+        "N'hésitez pas à partager ce cahier, à le modifier et à expérimenter pour mieux comprendre l'importance et le déroulement de chaque étape."
+      ],
+      "metadata": {
+        "id": "ofyz6B5fd_Nd"
+      }
+    }
+  ],
+  "metadata": {
+    "colab": {
+      "provenance": []
+    },
+    "kernelspec": {
+      "display_name": "Python 3",
+      "name": "python3"
+    },
+    "language_info": {
+      "name": "python"
+    },
+    "gpuClass": "standard",
+    "accelerator": "GPU"
+  },
+  "nbformat": 4,
+  "nbformat_minor": 0
+}
\ No newline at end of file