{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "7374bcb9-58a6-4cad-b50b-2324c7290400", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Installation terminée.\n" ] } ], "source": [ "# Installation des librairies nécessaires\n", "!pip install datasets transformers[torch] accelerate -q\n", "# Librairie pour la métrique d'évaluation ROUGE\n", "!pip install rouge_score -q\n", "\n", "print(\"Installation terminée.\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "02ccff69-deac-4188-9478-3a0eded45a16", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Modèle choisi pour cette session : moussaKam/barthez\n" ] } ], "source": [ "import re\n", "import pandas as pd\n", "from datasets import load_dataset\n", "from transformers import AutoTokenizer\n", "\n", "# --- PARAMÈTRE PRINCIPAL DU NOTEBOOK ---\n", "# Changez cette variable pour tester un autre modèle (ex: \"plguillou/t5-base-fr\")\n", "model_checkpoint = \"moussaKam/barthez\" \n", "\n", "print(f\"Modèle choisi pour cette session : {model_checkpoint}\")" ] }, { "cell_type": "code", "execution_count": 3, "id": "1301a599-a67e-4566-875e-64917eaa2f0f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Chargement du jeu de données PleIAs/French-PD-Books...\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "db73dc72d8a74927b2c6267c5783b007", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Resolving data files: 0%| | 0/145 [00:00 50 # Garder des textes d'une longueur minimale\n", ")\n", "\n", "print(f\"Nombre d'exemples après nettoyage et filtrage : {len(ds_filtered)}\")\n", "\n", "# Affichage d'un exemple pour vérification\n", "print(\"\\n--- Exemple après nettoyage ---\")\n", "example = ds_filtered[500]\n", "print(f\"Date: {example['date']}\")\n", "print(f\"Texte: {example['text'][:400]}\")" ] }, { "cell_type": "code", "execution_count": 4, "id": "c761be3f-049c-4b48-aa37-4e2f445eac6a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Formatage des données pour la tâche sequence-to-sequence...\n", "Formatage terminé.\n", "\n", "--- Exemple au format Seq2Seq ---\n", "SOURCE (entrée modèle):\n", "réécris ce texte dans le style des années 1920: MINISTÈRE DES AFFAIRES ÉTRANGÈRES DOCUMENTS DIPLOMATIQUES REPONSE DU GOUVERNEMENT FRANÇAIS À LA LETTRE DU GOUVERNEMENT BRITANNIQUE DU il AOÛT 1923 SUR LES RÉPARATIONS 20 AOUT 1923 PARIS IMPRIMERIE NATIONALE MDCGCCXMII MINISTÈRE DES AFFAIRES ÉTRANGÈRES DOCUMENTS DIPLOMATIQUES REPONSE DU GOUVERNEMENT FRANÇAIS À LA LETTRE DU GOUVERNEMENT RRITANNIQUE DU 11 AOÛT 1923 SUR LES RÉPARATIONS 20 AOUT 1923 LIVRE «.UNE. Réponse du Gouv. français. MINISTÈRE DES \n", "\n", "TARGET (sortie attendue):\n", "MINISTÈRE DES AFFAIRES ÉTRANGÈRES DOCUMENTS DIPLOMATIQUES REPONSE DU GOUVERNEMENT FRANÇAIS À LA LETTRE DU GOUVERNEMENT BRITANNIQUE DU il AOÛT 1923 SUR LES RÉPARATIONS 20 AOUT 1923 PARIS IMPRIMERIE NATIONALE MDCGCCXMII MINISTÈRE DES AFFAIRES ÉTRANGÈRES DOCUMENTS DIPLOMATIQUES REPONSE DU GOUVERNEMENT FRANÇAIS À LA LETTRE DU GOUVERNEMENT RRITANNIQUE DU 11 AOÛT 1923 SUR LES RÉPARATIONS 20 AOUT 1923 LI\n" ] } ], "source": [ "# Fonction pour créer les entrées et sorties du modèle\n", "def create_seq2seq_format(example):\n", " text = example['text']\n", " year = int(example['date'])\n", " \n", " # Création de la décennie (ex: 1854 -> 1850)\n", " decade = (year // 10) * 10\n", " \n", " # Formatage de l'entrée pour le modèle\n", " # Le préfixe est crucial pour que le modèle comprenne la tâche\n", " prefix = f\"réécris ce texte dans le style des années {decade}: \"\n", " \n", " # Source : ce que le modèle voit en entrée\n", " example['source'] = prefix + text\n", " # Cible : ce que le modèle doit apprendre à prédire\n", " example['target'] = text\n", " \n", " return example\n", "\n", "print(\"\\nFormatage des données pour la tâche sequence-to-sequence...\")\n", "ds_seq2seq = ds_filtered.map(create_seq2seq_format, num_proc=4)\n", "\n", "print(\"Formatage terminé.\")\n", "print(\"\\n--- Exemple au format Seq2Seq ---\")\n", "example = ds_seq2seq[500]\n", "print(f\"SOURCE (entrée modèle):\\n{example['source'][:500]}\\n\")\n", "print(f\"TARGET (sortie attendue):\\n{example['target'][:400]}\")" ] }, { "cell_type": "code", "execution_count": 5, "id": "4861e244-c3e1-4f94-9c7f-9afb8cd30028", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Lancement de la tokenisation avec le tokenizer de 'moussaKam/barthez'...\n", "\n", "--- Traitement manuel des 1000 premiers exemples ---\n", "--- Traitement et tokenisation des 1000 exemples ---\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0b9ca76da4d040b098455e50f23f1fca", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/1000 [00:00 \u001b[39m\u001b[32m3\u001b[39m \u001b[43mtrainer\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtrain\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 4\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33m✅ Entraînement terminé !\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 6\u001b[39m \u001b[38;5;66;03m# Sauvegarde du meilleur modèle dans le dossier de sortie\u001b[39;00m\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/transformers/trainer.py:2325\u001b[39m, in \u001b[36mTrainer.train\u001b[39m\u001b[34m(self, resume_from_checkpoint, trial, ignore_keys_for_eval, **kwargs)\u001b[39m\n\u001b[32m 2323\u001b[39m hf_hub_utils.enable_progress_bars()\n\u001b[32m 2324\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m2325\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43minner_training_loop\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 2326\u001b[39m \u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m=\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2327\u001b[39m \u001b[43m \u001b[49m\u001b[43mresume_from_checkpoint\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresume_from_checkpoint\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2328\u001b[39m \u001b[43m \u001b[49m\u001b[43mtrial\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtrial\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2329\u001b[39m \u001b[43m \u001b[49m\u001b[43mignore_keys_for_eval\u001b[49m\u001b[43m=\u001b[49m\u001b[43mignore_keys_for_eval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 2330\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/transformers/trainer.py:2674\u001b[39m, in \u001b[36mTrainer._inner_training_loop\u001b[39m\u001b[34m(self, batch_size, args, resume_from_checkpoint, trial, ignore_keys_for_eval)\u001b[39m\n\u001b[32m 2667\u001b[39m context = (\n\u001b[32m 2668\u001b[39m functools.partial(\u001b[38;5;28mself\u001b[39m.accelerator.no_sync, model=model)\n\u001b[32m 2669\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m i != \u001b[38;5;28mlen\u001b[39m(batch_samples) - \u001b[32m1\u001b[39m\n\u001b[32m 2670\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m.accelerator.distributed_type != DistributedType.DEEPSPEED\n\u001b[32m 2671\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m contextlib.nullcontext\n\u001b[32m 2672\u001b[39m )\n\u001b[32m 2673\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m context():\n\u001b[32m-> \u001b[39m\u001b[32m2674\u001b[39m tr_loss_step = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtraining_step\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnum_items_in_batch\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 2676\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[32m 2677\u001b[39m args.logging_nan_inf_filter\n\u001b[32m 2678\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m is_torch_xla_available()\n\u001b[32m 2679\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m (torch.isnan(tr_loss_step) \u001b[38;5;129;01mor\u001b[39;00m torch.isinf(tr_loss_step))\n\u001b[32m 2680\u001b[39m ):\n\u001b[32m 2681\u001b[39m \u001b[38;5;66;03m# if loss is nan or inf simply add the average of previous logged losses\u001b[39;00m\n\u001b[32m 2682\u001b[39m tr_loss = tr_loss + tr_loss / (\u001b[32m1\u001b[39m + \u001b[38;5;28mself\u001b[39m.state.global_step - \u001b[38;5;28mself\u001b[39m._globalstep_last_logged)\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/transformers/trainer.py:4071\u001b[39m, in \u001b[36mTrainer.training_step\u001b[39m\u001b[34m(***failed resolving arguments***)\u001b[39m\n\u001b[32m 4068\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.accelerator.distributed_type == DistributedType.DEEPSPEED:\n\u001b[32m 4069\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mscale_wrt_gas\u001b[39m\u001b[33m\"\u001b[39m] = \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m4071\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43maccelerator\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\u001b[43mloss\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 4073\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m loss.detach()\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/accelerate/accelerator.py:2734\u001b[39m, in \u001b[36mAccelerator.backward\u001b[39m\u001b[34m(self, loss, **kwargs)\u001b[39m\n\u001b[32m 2732\u001b[39m \u001b[38;5;28mself\u001b[39m.lomo_backward(loss, learning_rate)\n\u001b[32m 2733\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m2734\u001b[39m \u001b[43mloss\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/torch/_tensor.py:647\u001b[39m, in \u001b[36mTensor.backward\u001b[39m\u001b[34m(self, gradient, retain_graph, create_graph, inputs)\u001b[39m\n\u001b[32m 637\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m has_torch_function_unary(\u001b[38;5;28mself\u001b[39m):\n\u001b[32m 638\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m handle_torch_function(\n\u001b[32m 639\u001b[39m Tensor.backward,\n\u001b[32m 640\u001b[39m (\u001b[38;5;28mself\u001b[39m,),\n\u001b[32m (...)\u001b[39m\u001b[32m 645\u001b[39m inputs=inputs,\n\u001b[32m 646\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m647\u001b[39m \u001b[43mtorch\u001b[49m\u001b[43m.\u001b[49m\u001b[43mautograd\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 648\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgradient\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mretain_graph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcreate_graph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m=\u001b[49m\u001b[43minputs\u001b[49m\n\u001b[32m 649\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/torch/autograd/__init__.py:354\u001b[39m, in \u001b[36mbackward\u001b[39m\u001b[34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)\u001b[39m\n\u001b[32m 349\u001b[39m retain_graph = create_graph\n\u001b[32m 351\u001b[39m \u001b[38;5;66;03m# The reason we repeat the same comment below is that\u001b[39;00m\n\u001b[32m 352\u001b[39m \u001b[38;5;66;03m# some Python versions print out the first line of a multi-line function\u001b[39;00m\n\u001b[32m 353\u001b[39m \u001b[38;5;66;03m# calls in the traceback and some print out the last line\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m354\u001b[39m \u001b[43m_engine_run_backward\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 355\u001b[39m \u001b[43m \u001b[49m\u001b[43mtensors\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 356\u001b[39m \u001b[43m \u001b[49m\u001b[43mgrad_tensors_\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 357\u001b[39m \u001b[43m \u001b[49m\u001b[43mretain_graph\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 358\u001b[39m \u001b[43m \u001b[49m\u001b[43mcreate_graph\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 359\u001b[39m \u001b[43m \u001b[49m\u001b[43minputs_tuple\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 360\u001b[39m \u001b[43m \u001b[49m\u001b[43mallow_unreachable\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 361\u001b[39m \u001b[43m \u001b[49m\u001b[43maccumulate_grad\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 362\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/opt/conda/lib/python3.13/site-packages/torch/autograd/graph.py:829\u001b[39m, in \u001b[36m_engine_run_backward\u001b[39m\u001b[34m(t_outputs, *args, **kwargs)\u001b[39m\n\u001b[32m 827\u001b[39m unregister_hooks = _register_logging_hooks_on_whole_graph(t_outputs)\n\u001b[32m 828\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m829\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mVariable\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_execution_engine\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrun_backward\u001b[49m\u001b[43m(\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Calls into the C++ engine to run the backward pass\u001b[39;49;00m\n\u001b[32m 830\u001b[39m \u001b[43m \u001b[49m\u001b[43mt_outputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\n\u001b[32m 831\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# Calls into the C++ engine to run the backward pass\u001b[39;00m\n\u001b[32m 832\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 833\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m attach_logging_hooks:\n", "\u001b[31mRuntimeError\u001b[39m: element 0 of tensors does not require grad and does not have a grad_fn" ] } ], "source": [ "# Lancement de l'entraînement !\n", "print(\"🚀 Début de l'entraînement...\")\n", "trainer.train()\n", "print(\"✅ Entraînement terminé !\")\n", "\n", "# Sauvegarde du meilleur modèle dans le dossier de sortie\n", "trainer.save_model()\n", "print(f\"Meilleur modèle sauvegardé dans le dossier : {output_dir}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "5c62301f", "metadata": {}, "outputs": [], "source": [ "# Évaluation finale du meilleur modèle sur le jeu de validation\n", "print(\"\\nÉvaluation finale du modèle...\")\n", "eval_results = trainer.evaluate()\n", "\n", "print(\"\\n--- Résultats de l'évaluation ---\")\n", "for key, value in eval_results.items():\n", " print(f\"{key}: {value}\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.7" } }, "nbformat": 4, "nbformat_minor": 5 }