{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.11.13","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":14976537,"sourceType":"competition"},{"sourceId":692580,"sourceType":"modelInstanceVersion","modelInstanceId":525132,"modelId":539167}],"dockerImageVersionId":31234,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Akkadian Translation - Inference Only\n\n**Purpose**: Load pre-trained model and generate translations.\n\n**Required Inputs**:\n1. `akkadian-byt5-trained` (your trained model uploaded as a Dataset)\n2. Competition test data (auto-included)","metadata":{}},{"cell_type":"code","source":"import os\nimport re\nimport pandas as pd\nimport torch\nfrom transformers import T5ForConditionalGeneration, AutoTokenizer\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Device: {device}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-19T17:29:34.444947Z","iopub.execute_input":"2025-12-19T17:29:34.445356Z","iopub.status.idle":"2025-12-19T17:30:20.475531Z","shell.execute_reply.started":"2025-12-19T17:29:34.445305Z","shell.execute_reply":"2025-12-19T17:30:20.474360Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 1. Load Test Data","metadata":{}},{"cell_type":"code","source":"DATA_DIR = \"/kaggle/input/deep-past-initiative-machine-translation\"\ntest_df = pd.read_csv(f\"{DATA_DIR}/test.csv\")\nprint(f\"Test samples: {len(test_df)}\")\n\n# Load lexicon if available\nlexicon_path = f\"{DATA_DIR}/OA_Lexicon_eBL.csv\"\nLEXICON_MAP = {}\nif os.path.exists(lexicon_path):\n    lex_df = pd.read_csv(lexicon_path)\n    LEXICON_MAP = dict(zip(lex_df['form'].dropna(), lex_df['norm'].dropna()))\n    print(f\"Loaded {len(LEXICON_MAP)} lexicon entries\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-19T17:30:20.477202Z","iopub.execute_input":"2025-12-19T17:30:20.477919Z","iopub.status.idle":"2025-12-19T17:30:20.667132Z","shell.execute_reply.started":"2025-12-19T17:30:20.477889Z","shell.execute_reply":"2025-12-19T17:30:20.666359Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2. Load Trained Model","metadata":{}},{"cell_type":"code","source":"# Find the trained model in inputs\nMODEL_PATH = None\n\nprint(\"Available inputs:\", os.listdir('/kaggle/input'))\nprint(\"\\nSearching for trained model...\")\n\nfor root, dirs, files in os.walk('/kaggle/input'):\n    if 'config.json' in files and ('pytorch_model.bin' in files or 'model.safetensors' in files):\n        # Prefer our trained model\n        if 'akkadian' in root.lower() or 'trained' in root.lower():\n            MODEL_PATH = root\n            print(f\"[FOUND TRAINED] {root}\")\n            break\n        elif MODEL_PATH is None:\n            MODEL_PATH = root\n            print(f\"[FOUND] {root}\")\n\nif MODEL_PATH is None:\n    raise FileNotFoundError(\"No model found! Add your trained model dataset.\")\n\nprint(f\"\\nLoading from: {MODEL_PATH}\")\ntokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, local_files_only=True)\nmodel = T5ForConditionalGeneration.from_pretrained(MODEL_PATH, local_files_only=True)\nmodel = model.to(device)\nmodel.eval()\nprint(f\"✓ Model loaded: {model.num_parameters():,} parameters\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-19T17:30:20.668018Z","iopub.execute_input":"2025-12-19T17:30:20.668286Z","iopub.status.idle":"2025-12-19T17:30:21.867661Z","shell.execute_reply.started":"2025-12-19T17:30:20.668267Z","shell.execute_reply":"2025-12-19T17:30:21.866591Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 3. Preprocessing (Same as Training)","metadata":{}},{"cell_type":"code","source":"def normalize_with_lexicon(text, lexicon):\n    if not lexicon:\n        return text\n    words = text.split()\n    return ' '.join([lexicon.get(w, w) for w in words])\n\ndef preprocess_akkadian(text):\n    if pd.isna(text):\n        return \"\"\n    text = str(text)\n    text = re.sub(r'<big_gap>', ' [BREAK] ', text)\n    text = re.sub(r'<gap>', ' [GAP] ', text)\n    text = re.sub(r'\\.\\.\\.', ' [GAP] ', text)\n    text = re.sub(r'\\{(\\w+)\\}', r' \\1 ', text)\n    text = re.sub(r'(\\d+\\.?\\d*)', r' \\1 ', text)\n    text = ' '.join(text.split())\n    text = normalize_with_lexicon(text, LEXICON_MAP)\n    return text.strip()\n\ntest_df['source'] = test_df['transliteration'].apply(preprocess_akkadian)\nprint(\"Preprocessing complete.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-19T17:30:21.868624Z","iopub.execute_input":"2025-12-19T17:30:21.868969Z","iopub.status.idle":"2025-12-19T17:30:21.879532Z","shell.execute_reply.started":"2025-12-19T17:30:21.868945Z","shell.execute_reply":"2025-12-19T17:30:21.878558Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 4. Generate Translations","metadata":{}},{"cell_type":"code","source":"TASK_PREFIX = \"translate Akkadian to English: \"\nMAX_SOURCE_LEN = 1024\nMAX_TARGET_LEN = 1024\n\ndef generate_translation(text):\n    input_text = TASK_PREFIX + preprocess_akkadian(text)\n    inputs = tokenizer(\n        input_text,\n        return_tensors=\"pt\",\n        max_length=MAX_SOURCE_LEN,\n        truncation=True\n    ).to(device)\n    \n    with torch.no_grad():\n        outputs = model.generate(\n            **inputs,\n            max_length=MAX_TARGET_LEN,\n            num_beams=5,\n            early_stopping=True,\n            repetition_penalty=2.5,\n            no_repeat_ngram_size=3,\n            length_penalty=1.0,\n        )\n    \n    return tokenizer.decode(outputs[0], skip_special_tokens=True).strip()\n\nprint(\"🎯 Generating translations...\")\ntranslations = []\nfor idx, row in test_df.iterrows():\n    translations.append(generate_translation(row['transliteration']))\n    if (idx + 1) % 10 == 0:\n        print(f\"  {idx + 1}/{len(test_df)}\")\n\nprint(f\"\\n✓ Generated {len(translations)} translations\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-19T17:30:21.881970Z","iopub.execute_input":"2025-12-19T17:30:21.882264Z","iopub.status.idle":"2025-12-19T17:31:40.111556Z","shell.execute_reply.started":"2025-12-19T17:30:21.882243Z","shell.execute_reply":"2025-12-19T17:31:40.110405Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 5. Create Submission","metadata":{}},{"cell_type":"code","source":"test_df['translation'] = translations\nsubmission = test_df[['id', 'translation']]\nsubmission.to_csv('submission.csv', index=False)\n\nprint(\"✅ submission.csv saved!\")\nprint(\"\\n📋 Preview:\")\nprint(submission.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-19T17:31:40.112380Z","iopub.execute_input":"2025-12-19T17:31:40.113437Z","iopub.status.idle":"2025-12-19T17:31:40.140708Z","shell.execute_reply.started":"2025-12-19T17:31:40.113405Z","shell.execute_reply":"2025-12-19T17:31:40.139344Z"}},"outputs":[],"execution_count":null}]}