{"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":"none","dataSources":[{"sourceId":121150,"databundleVersionId":15061024,"sourceType":"competition"},{"sourceId":14199544,"sourceType":"datasetVersion","datasetId":9055585}],"dockerImageVersionId":31234,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:11:04.469627Z","iopub.execute_input":"2026-01-05T18:11:04.470439Z","iopub.status.idle":"2026-01-05T18:11:06.894639Z","shell.execute_reply.started":"2026-01-05T18:11:04.470394Z","shell.execute_reply":"2026-01-05T18:11:06.893391Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import re\nimport pandas as pd\nimport torch\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:11:06.896293Z","iopub.execute_input":"2026-01-05T18:11:06.896774Z","iopub.status.idle":"2026-01-05T18:11:27.699307Z","shell.execute_reply.started":"2026-01-05T18:11:06.896742Z","shell.execute_reply":"2026-01-05T18:11:27.698090Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DATA_PATH = \"/kaggle/input/deep-past-initiative-machine-translation\"\nMODEL_PATH = \"/kaggle/input/byt5-base-100\"   # <<< OFFLINE MODEL PATH\n\nMAX_LENGTH = 512\nPREFIX = \"translate Akkadian to English: \"\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nprint(\"Device:\", DEVICE)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:11:32.394582Z","iopub.execute_input":"2026-01-05T18:11:32.394953Z","iopub.status.idle":"2026-01-05T18:11:32.400660Z","shell.execute_reply.started":"2026-01-05T18:11:32.394918Z","shell.execute_reply":"2026-01-05T18:11:32.399664Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def clean_akkadian(text):\n    if pd.isna(text):\n        return \"\"\n\n    text = text.replace(\"…\", \"<big_gap>\")\n    text = re.sub(r\"\\[x\\]\", \"<gap>\", text)\n    text = re.sub(r\"[!?/:]\", \"\", text)\n    text = re.sub(r\"[˹˺]\", \"\", text)\n    text = re.sub(r\"\\[(.*?)\\]\", r\"\\1\", text)\n\n    subs = {\n        \"₀\":\"0\",\"₁\":\"1\",\"₂\":\"2\",\"₃\":\"3\",\"₄\":\"4\",\n        \"₅\":\"5\",\"₆\":\"6\",\"₇\":\"7\",\"₈\":\"8\",\"₉\":\"9\"\n    }\n    for k, v in subs.items():\n        text = text.replace(k, v)\n\n    return re.sub(r\"\\s+\", \" \", text).strip()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:11:35.553310Z","iopub.execute_input":"2026-01-05T18:11:35.553658Z","iopub.status.idle":"2026-01-05T18:11:35.560647Z","shell.execute_reply.started":"2026-01-05T18:11:35.553627Z","shell.execute_reply":"2026-01-05T18:11:35.559716Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = pd.read_csv(f\"{DATA_PATH}/test.csv\")\ntest_df[\"source\"] = test_df[\"transliteration\"].apply(clean_akkadian)\n\nprint(\"Test samples:\", len(test_df))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:11:38.728183Z","iopub.execute_input":"2026-01-05T18:11:38.728767Z","iopub.status.idle":"2026-01-05T18:11:38.741571Z","shell.execute_reply.started":"2026-01-05T18:11:38.728729Z","shell.execute_reply":"2026-01-05T18:11:38.739457Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tokenizer = AutoTokenizer.from_pretrained(\n    MODEL_PATH,\n    use_fast=False,\n    local_files_only=True\n)\n\nmodel = AutoModelForSeq2SeqLM.from_pretrained(\n    MODEL_PATH,\n    local_files_only=True\n).to(DEVICE)\n\nmodel.eval()\nmodel.float()\n\nprint(\"✅ ByT5 model loaded successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:12:12.101831Z","iopub.execute_input":"2026-01-05T18:12:12.102592Z","iopub.status.idle":"2026-01-05T18:12:12.328338Z","shell.execute_reply.started":"2026-01-05T18:12:12.102557Z","shell.execute_reply":"2026-01-05T18:12:12.327221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = []\nprint(\"predictions initialized\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:14:05.860082Z","iopub.execute_input":"2026-01-05T18:14:05.860435Z","iopub.status.idle":"2026-01-05T18:14:05.865776Z","shell.execute_reply.started":"2026-01-05T18:14:05.860404Z","shell.execute_reply":"2026-01-05T18:14:05.864909Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# FINAL SAFE INFERENCE + SUBMISSION CELL\npredictions = []  # FORCE RESET\n\nmodel.eval()\nmodel.float()\n\nPREFIX = \"translate Akkadian to English: \"\n\nwith torch.inference_mode():\n    for text in test_df[\"source\"].tolist():\n        inputs = tokenizer(\n            PREFIX + text,\n            return_tensors=\"pt\",\n            truncation=True,\n            max_length=512\n        ).to(DEVICE)\n\n        outputs = model.generate(\n            **inputs,\n            max_length=512,\n            num_beams=4,\n            early_stopping=True\n        )\n\n        decoded = tokenizer.decode(\n            outputs[0],\n            skip_special_tokens=True\n        )\n\n        if decoded.lower().startswith(PREFIX.lower()):\n            decoded = decoded[len(PREFIX):]\n\n        predictions.append(decoded.strip())\n\n# HARD SAFETY CHECK\nassert len(predictions) == len(test_df), (\n    f\"Mismatch: {len(predictions)} predictions vs {len(test_df)} rows\"\n)\n\nprint(\"Lengths OK:\", len(test_df), len(predictions))\n\n# CREATE SUBMISSION\nsubmission = pd.DataFrame({\n    \"id\": test_df[\"id\"].values,\n    \"translation\": predictions\n})\n\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"✅ submission.csv created successfully\")\n\nsubmission\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T18:17:54.985827Z","iopub.execute_input":"2026-01-05T18:17:54.986251Z","iopub.status.idle":"2026-01-05T18:19:00.674623Z","shell.execute_reply.started":"2026-01-05T18:17:54.986222Z","shell.execute_reply":"2026-01-05T18:19:00.673814Z"}},"outputs":[],"execution_count":null}]}