{"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":"gpu","dataSources":[{"sourceId":121150,"databundleVersionId":14976537,"sourceType":"competition"},{"sourceId":690748,"sourceType":"modelInstanceVersion","modelInstanceId":523662,"modelId":537682}],"dockerImageVersionId":31236,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"train:\nhttps://www.kaggle.com/code/kageyama/starter-t5-base-nmt-baseline","metadata":{}},{"cell_type":"code","source":"import os\nimport re\nimport glob\nimport torch\nimport numpy as np\nimport pandas as pd\nfrom transformers import T5Tokenizer, T5ForConditionalGeneration, T5Config\n\n# ==========================================\n# 1. Configuration & Path Management\n# ==========================================\nBASE_MODEL_DIR = \"/kaggle/input/t5-base-deep-past/pytorch/default/1/akkadian-t5-finetuned\"\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nBATCH_SIZE = 16\n\ndef get_model_path(base_dir):\n    \"\"\"Automatically finds the root model or the latest checkpoint.\"\"\"\n    if os.path.exists(os.path.join(base_dir, \"config.json\")):\n        return base_dir\n    \n    checkpoints = glob.glob(os.path.join(base_dir, \"checkpoint-*\"))\n    if checkpoints:\n        # Sort by checkpoint number and take the highest\n        latest_checkpoint = max(checkpoints, key=lambda x: int(x.split('-')[-1]))\n        return latest_checkpoint\n    return base_dir\n\nMODEL_PATH = get_model_path(BASE_MODEL_DIR)\nprint(f\"🚀 Using Model Path: {MODEL_PATH}\")\n\n# ==========================================\n# 2. Robust Text Preprocessing\n# ==========================================\ndef clean_text(text, is_transliteration=True):\n    \"\"\"Cleans input to match training-time distribution.\"\"\"\n    if not isinstance(text, str): return \"\"\n    \n    # Remove modern scribal notations: !, ?, /, :, [], ˹, ˺\n    text = re.sub(r'[!?/:\\[\\]˹˺]', '', text)\n    # Remove pointy brackets but keep content\n    text = text.replace('<', '').replace('>', '')\n    \n    if is_transliteration:\n        # Standardize gaps\n        text = text.replace('x', '<gap>')\n        text = re.sub(r'\\.\\.\\.', '<big_gap>', text)\n        \n    return re.sub(r'\\s+', ' ', text).strip()\n\n# ==========================================\n# 3. Safe Model Loading (Handling DiaConfig)\n# ==========================================\nprint(\"📦 Loading Tokenizer and Model...\")\n# Load Tokenizer\ntokenizer = T5Tokenizer.from_pretrained(MODEL_PATH, use_fast=False)\n\n# Load as T5 to bypass DiaConfig unrecognized class error\nconfig = T5Config.from_pretrained(MODEL_PATH)\nmodel = T5ForConditionalGeneration.from_pretrained(\n    MODEL_PATH, \n    config=config, \n    ignore_mismatched_sizes=True\n).to(DEVICE)\n\n# Sync embeddings with tokenizer vocab size\nmodel.resize_token_embeddings(len(tokenizer))\nmodel.eval()\nprint(f\"✅ Model loaded on {DEVICE}\")\n\n# ==========================================\n# 4. Optimized Batch Inference\n# ==========================================\ndef generate_translations(texts, batch_size=BATCH_SIZE):\n    results = []\n    vocab_size = len(tokenizer)\n    \n    for i in range(0, len(texts), batch_size):\n        batch = [\"translate Akkadian to English: \" + t for t in texts[i:i+batch_size]]\n        \n        inputs = tokenizer(\n            batch, \n            return_tensors=\"pt\", \n            padding=True, \n            truncation=True, \n            max_length=128\n        ).to(DEVICE)\n        \n        with torch.no_grad():\n            outputs = model.generate(\n                **inputs, \n                max_length=128, \n                num_beams=4,      # Beam Search for higher quality\n                early_stopping=True\n            )\n        \n        # --- PREVENT INDEX ERROR ---\n        # Clip IDs to stay within valid tokenizer range [0, vocab_size-1]\n        clipped_outputs = torch.clamp(outputs, 0, vocab_size - 1).cpu().numpy()\n        \n        decoded = tokenizer.batch_decode(clipped_outputs, skip_special_tokens=True)\n        results.extend([d.strip() for d in decoded])\n        \n    return results\n\n# ==========================================\n# 5. Bulletproof Execution & Submission\n# ==========================================\nprint(\"📖 Loading test data...\")\n# Load the official test file provided by the environment\ntest_df = pd.read_csv('/kaggle/input/deep-past-initiative-machine-translation/test.csv')\n\n# Preprocess\ntest_df['cleaned_input'] = test_df['transliteration'].apply(lambda x: clean_text(x, True))\n\n# Run Inference\nprint(f\"✨ Generating translations for {len(test_df)} rows...\")\nraw_predictions = generate_translations(test_df['cleaned_input'].tolist())\n\n# --- SAFETY CHECK: Handling Empty Values ---\n# Ensure every prediction is at least a string of some kind\nfinal_predictions = []\nfor p in raw_predictions:\n    if not isinstance(p, str) or len(p.strip()) == 0:\n        final_predictions.append(\"...\") # Placeholder for empty translations\n    else:\n        final_predictions.append(p.strip())\n\n# Create the final dataframe\nsubmission = pd.DataFrame({\n    \"id\": test_df[\"id\"], # Use the original IDs from test_df\n    \"translation\": final_predictions\n})\n\n# --- FINAL VALIDATION ---\n# Check 1: No Nulls\nassert submission.isnull().sum().sum() == 0, \"Submission contains null values!\"\n# Check 2: Row count matches test_df\nassert len(submission) == len(test_df), f\"Row count mismatch! Expected {len(test_df)}, got {len(submission)}\"\n\n# Save with exact formatting\nsubmission.to_csv('submission.csv', index=False)\n\nprint(\"🎉 Submission file saved successfully with correct format.\")\nprint(f\"Sample IDs: {submission['id'].head().tolist()}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-18T03:35:15.485478Z","iopub.execute_input":"2025-12-18T03:35:15.485849Z","iopub.status.idle":"2025-12-18T03:35:18.526487Z","shell.execute_reply.started":"2025-12-18T03:35:15.485820Z","shell.execute_reply":"2025-12-18T03:35:18.525728Z"}},"outputs":[],"execution_count":null}]}