{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":121150,"databundleVersionId":15061024,"sourceType":"competition"},{"sourceId":288315983,"sourceType":"kernelVersion"},{"sourceId":694614,"sourceType":"modelInstanceVersion","modelInstanceId":526756,"modelId":540799}],"dockerImageVersionId":31236,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport torch\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\nfrom tqdm.auto import tqdm\nimport gc\nimport os\n\n# ==============================================================================\n# 1. CHEMINS DES MODÈLES (VÉRIFIÉS)\n# ==============================================================================\n# Modèle A : Le record à 28.9\nPATH_A = \"/kaggle/input/deep-past-challenge-byt5-base-training-v2/byt5-base-akkadian/\"\n\n# Modèle B : L'Elite à 27.2\nPATH_B = \"/kaggle/input/byt5-adafactor-comp-dataset-train/transformers/default/1/byt5-elite-logs/final_model_elite\"\n\nPREFIX = \"translate Akkadian to English: \"\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\ndef get_model_and_tokenizer(path):\n    print(f\"🔄 Chargement de {path}...\")\n    tokenizer = AutoTokenizer.from_pretrained(path)\n    model = AutoModelForSeq2SeqLM.from_pretrained(path).to(DEVICE)\n    model.eval()\n    return tokenizer, model\n\n# ==============================================================================\n# 2. GÉNÉRATION OPTIMISÉE (SAMPLING CONTRÔLÉ)\n# ==============================================================================\ndef generate_optimized(df, tokenizer, model, desc):\n    results = []\n    with torch.no_grad():\n        for text in tqdm(df['transliteration'].tolist(), desc=desc):\n            input_text = PREFIX + str(text)\n            inputs = tokenizer(input_text, return_tensors=\"pt\", truncation=True, max_length=512).to(DEVICE)\n            \n            # Utilisation de Top-P sampling pour plus de nuances que le Beam Search pur\n            outputs = model.generate(\n                **inputs, \n                max_length=512, \n                num_beams=4,\n                do_sample=True,      # Permet de sortir de la rigidité du beam search\n                top_p=0.95,          # Filtre les queues de distribution improbables\n                temperature=0.7,     # Équilibre entre créativité et précision\n                early_stopping=True\n            )\n            \n            decoded = tokenizer.decode(outputs[0], skip_special_tokens=True)\n            results.append(decoded.strip())\n    return results\n\n# ==============================================================================\n# 3. CHARGEMENT DU TEST ET GÉNÉRATION\n# ==============================================================================\n# Recherche du fichier test.csv\nTEST_FILE = \"\"\nfor root, dirs, files in os.walk(\"/kaggle/input\"):\n    for file in files:\n        if file == \"test.csv\": TEST_FILE = os.path.join(root, file); break\ntest_df = pd.read_csv(TEST_FILE)\n\n# Génération avec le Modèle A (28.9)\ntok_a, mod_a = get_model_and_tokenizer(PATH_A)\npreds_a = generate_optimized(test_df, tok_a, mod_a, \"Génération Modèle 28.9\")\ndel tok_a, mod_a; gc.collect(); torch.cuda.empty_cache()\n\n# Génération avec le Modèle B (27.2)\ntok_b, mod_b = get_model_and_tokenizer(PATH_B)\npreds_b = generate_optimized(test_df, tok_b, mod_b, \"Génération Modèle Elite\")\ndel tok_b, mod_b; gc.collect(); torch.cuda.empty_cache()\n\n# ==============================================================================\n# 4. LE VOTING (ENSEMBLE)\n# ==============================================================================\nfinal_preds = []\nprint(\"🗳️ Arbitrage entre les deux modèles pour submission.csv...\")\n\nfor a, b in zip(preds_a, preds_b):\n    # Logique d'arbitrage :\n    # Si le modèle B (Elite) propose une phrase nettement plus riche/longue,\n    # on considère qu'il a capturé un fragment que le modèle A a ignoré.\n    if len(b) > len(a) * 1.4:\n        final_preds.append(b)\n    else:\n        # Par défaut, on garde la prédiction du modèle au score le plus élevé\n        final_preds.append(a)\n\n# ==============================================================================\n# 5. FINALISATION DU FICHIER SUBMISSION.CSV\n# ==============================================================================\nsubmission = pd.DataFrame()\n\n# On s'assure de récupérer les bons IDs\nif 'oare_id' in test_df.columns:\n    submission['id'] = test_df['oare_id']\nelif 'id' in test_df.columns:\n    submission['id'] = test_df['id']\nelse:\n    submission['id'] = test_df.index\n\nsubmission['translation'] = final_preds\n\n# Le nom de fichier doit être strictement submission.csv\nsubmission.to_csv(\"/kaggle/working/submission.csv\", index=False)\n\nprint(\"\\n✨ TERMINÉ ! Le fichier 'submission.csv' est prêt pour l'envoi.\")\nprint(\"Aperçu des résultats combinés :\")\nprint(submission.head())","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-28T11:30:02.588053Z","iopub.execute_input":"2025-12-28T11:30:02.588434Z","iopub.status.idle":"2025-12-28T11:30:22.077733Z","shell.execute_reply.started":"2025-12-28T11:30:02.588383Z","shell.execute_reply":"2025-12-28T11:30:22.077054Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}