{"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,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":714671,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":543135,"modelId":556301},{"sourceId":721543,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":543118,"modelId":556282}],"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-16T06:03:40.047874Z","iopub.execute_input":"2026-01-16T06:03:40.048387Z","iopub.status.idle":"2026-01-16T06:03:41.619326Z","shell.execute_reply.started":"2026-01-16T06:03:40.048344Z","shell.execute_reply":"2026-01-16T06:03:41.618028Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport re\nimport unicodedata\nimport pandas as pd\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\nfrom tqdm.auto import tqdm\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n\n# --- CONFIGURATION ---\nTEST_PATH = \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\"\nMODEL_PATH = \"/kaggle/input/flan-t5-small-kf-cleaned/pytorch/default/2\" \n\nBATCH_SIZE = 16   # Safe inference batch size\nMAX_LENGTH = 384  # Must match training length\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\n# --- CLEANING FUNCTION (Must match training!) ---\ndef clean_text(text):\n    if pd.isna(text): return \"\"\n    text = str(text)\n    text = unicodedata.normalize('NFC', text)\n    text = text.replace(\"…\", \"...\")\n    text = re.sub(r'\\.\\s*\\.\\s*\\.', '...', text)\n    text = text.replace('“', '\"').replace('”', '\"')\n    text = re.sub(r'\\s+', ' ', text).strip()\n    return text\n\nprint(f\"Loading model from {MODEL_PATH}...\")\n\n# Load Model Offline\ntry:\n    tokenizer = AutoTokenizer.from_pretrained('/kaggle/input/flant5/pytorch/default/1', local_files_only=True)\n    model = AutoModelForSeq2SeqLM.from_pretrained('/kaggle/input/flant5/pytorch/default/1', local_files_only=True)\n    model = model.to(DEVICE)\n    model.eval()\n    print(\"✅ Model loaded successfully!\")\nexcept Exception as e:\n    print(f\"❌ Error loading model: {e}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-16T06:03:41.622379Z","iopub.execute_input":"2026-01-16T06:03:41.622813Z","iopub.status.idle":"2026-01-16T06:04:20.954199Z","shell.execute_reply.started":"2026-01-16T06:03:41.622779Z","shell.execute_reply":"2026-01-16T06:04:20.953346Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class InferenceDataset(Dataset):\n    def __init__(self, df, tokenizer):\n        self.texts = [clean_text(t) for t in df['transliteration']]\n        # Add prefix\n        self.texts = [\"translate Akkadian to English: \" + t for t in self.texts]\n        self.tokenizer = tokenizer\n        self.ids = df['id'].tolist()\n        \n    def __len__(self):\n        return len(self.texts)\n    \n    def __getitem__(self, idx):\n        text = self.texts[idx]\n        inputs = self.tokenizer(\n            text, \n            padding=\"max_length\", \n            truncation=True, \n            max_length=MAX_LENGTH, \n            return_tensors=\"pt\"\n        )\n        return {\n            \"input_ids\": inputs[\"input_ids\"].squeeze(0),\n            \"attention_mask\": inputs[\"attention_mask\"].squeeze(0),\n            \"id\": self.ids[idx]\n        }\n\n# Load Test Data\ntest_df = pd.read_csv(TEST_PATH)\ntest_dataset = InferenceDataset(test_df, tokenizer)\ntest_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)\n\nall_predictions = []\nall_ids = []\n\nprint(f\"Starting Inference on {len(test_df)} rows...\")\n\nwith torch.no_grad():\n    for batch in tqdm(test_loader):\n        input_ids = batch[\"input_ids\"].to(DEVICE)\n        attention_mask = batch[\"attention_mask\"].to(DEVICE)\n        \n        # Beam Search for best translation quality\n        outputs = model.generate(\n            input_ids=input_ids,\n            attention_mask=attention_mask,\n            max_length=MAX_LENGTH,\n            num_beams=4,\n            early_stopping=True\n        )\n        \n        decoded = tokenizer.batch_decode(outputs, skip_special_tokens=True)\n        all_predictions.extend([d.strip() for d in decoded])\n        all_ids.extend(batch[\"id\"].tolist())\n\nprint(\"Inference Complete.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-16T06:04:20.955341Z","iopub.execute_input":"2026-01-16T06:04:20.956449Z","iopub.status.idle":"2026-01-16T06:04:56.989082Z","shell.execute_reply.started":"2026-01-16T06:04:20.956378Z","shell.execute_reply":"2026-01-16T06:04:56.987892Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create DataFrame\nsubmission = pd.DataFrame({\n    \"id\": all_ids,\n    \"translation\": all_predictions\n})\n\n# Final Sanity Check: Fill empty predictions if any exist\nsubmission[\"translation\"] = submission[\"translation\"].apply(lambda x: x if len(x) > 0 else \"...\")\n\n# Save\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"submission.csv saved.\")\nprint(submission.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-16T06:04:56.990451Z","iopub.execute_input":"2026-01-16T06:04:56.990887Z","iopub.status.idle":"2026-01-16T06:04:57.016916Z","shell.execute_reply.started":"2026-01-16T06:04:56.990858Z","shell.execute_reply":"2026-01-16T06:04:57.015461Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}