{"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":14976537,"sourceType":"competition"}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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":"2025-12-17T09:20:17.772207Z","iopub.execute_input":"2025-12-17T09:20:17.773028Z","iopub.status.idle":"2025-12-17T09:20:18.062088Z","shell.execute_reply.started":"2025-12-17T09:20:17.772996Z","shell.execute_reply":"2025-12-17T09:20:18.061544Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/train.csv\")\ndt = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/test.csv\")\nbib = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/bibliography.csv\")\npub = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/publications.csv\")\noa = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/OA_Lexicon_eBL.csv\")\npt = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/published_texts.csv\")\nssub = pd.read_csv(\"/kaggle/input/deep-past-initiative-machine-translation/sample_submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:18.063628Z","iopub.execute_input":"2025-12-17T09:20:18.064042Z","iopub.status.idle":"2025-12-17T09:20:27.096163Z","shell.execute_reply.started":"2025-12-17T09:20:18.064019Z","shell.execute_reply":"2025-12-17T09:20:27.095234Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.097345Z","iopub.execute_input":"2025-12-17T09:20:27.097681Z","iopub.status.idle":"2025-12-17T09:20:27.129475Z","shell.execute_reply.started":"2025-12-17T09:20:27.097656Z","shell.execute_reply":"2025-12-17T09:20:27.128544Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.131466Z","iopub.execute_input":"2025-12-17T09:20:27.131720Z","iopub.status.idle":"2025-12-17T09:20:27.157410Z","shell.execute_reply.started":"2025-12-17T09:20:27.131699Z","shell.execute_reply":"2025-12-17T09:20:27.156564Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dt.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.158536Z","iopub.execute_input":"2025-12-17T09:20:27.158815Z","iopub.status.idle":"2025-12-17T09:20:27.179708Z","shell.execute_reply.started":"2025-12-17T09:20:27.158782Z","shell.execute_reply":"2025-12-17T09:20:27.178991Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dt.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.180901Z","iopub.execute_input":"2025-12-17T09:20:27.181248Z","iopub.status.idle":"2025-12-17T09:20:27.200179Z","shell.execute_reply.started":"2025-12-17T09:20:27.181195Z","shell.execute_reply":"2025-12-17T09:20:27.199357Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"bib.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.201357Z","iopub.execute_input":"2025-12-17T09:20:27.201620Z","iopub.status.idle":"2025-12-17T09:20:27.220903Z","shell.execute_reply.started":"2025-12-17T09:20:27.201593Z","shell.execute_reply":"2025-12-17T09:20:27.220105Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"bib.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.221862Z","iopub.execute_input":"2025-12-17T09:20:27.222123Z","iopub.status.idle":"2025-12-17T09:20:27.242398Z","shell.execute_reply.started":"2025-12-17T09:20:27.222090Z","shell.execute_reply":"2025-12-17T09:20:27.241738Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pub.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.243327Z","iopub.execute_input":"2025-12-17T09:20:27.243853Z","iopub.status.idle":"2025-12-17T09:20:27.262239Z","shell.execute_reply.started":"2025-12-17T09:20:27.243818Z","shell.execute_reply":"2025-12-17T09:20:27.261540Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pub.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.264861Z","iopub.execute_input":"2025-12-17T09:20:27.265091Z","iopub.status.idle":"2025-12-17T09:20:27.312785Z","shell.execute_reply.started":"2025-12-17T09:20:27.265073Z","shell.execute_reply":"2025-12-17T09:20:27.312016Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"oa.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.313765Z","iopub.execute_input":"2025-12-17T09:20:27.314614Z","iopub.status.idle":"2025-12-17T09:20:27.330764Z","shell.execute_reply.started":"2025-12-17T09:20:27.314589Z","shell.execute_reply":"2025-12-17T09:20:27.330093Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"oa.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.331743Z","iopub.execute_input":"2025-12-17T09:20:27.332089Z","iopub.status.idle":"2025-12-17T09:20:27.364410Z","shell.execute_reply.started":"2025-12-17T09:20:27.332064Z","shell.execute_reply":"2025-12-17T09:20:27.363704Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pt.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.365359Z","iopub.execute_input":"2025-12-17T09:20:27.365673Z","iopub.status.idle":"2025-12-17T09:20:27.385198Z","shell.execute_reply.started":"2025-12-17T09:20:27.365640Z","shell.execute_reply":"2025-12-17T09:20:27.384649Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pt.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.385997Z","iopub.execute_input":"2025-12-17T09:20:27.386287Z","iopub.status.idle":"2025-12-17T09:20:27.410719Z","shell.execute_reply.started":"2025-12-17T09:20:27.386259Z","shell.execute_reply":"2025-12-17T09:20:27.410005Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ssub.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.411466Z","iopub.execute_input":"2025-12-17T09:20:27.411724Z","iopub.status.idle":"2025-12-17T09:20:27.425312Z","shell.execute_reply.started":"2025-12-17T09:20:27.411701Z","shell.execute_reply":"2025-12-17T09:20:27.424719Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ssub.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.426129Z","iopub.execute_input":"2025-12-17T09:20:27.426401Z","iopub.status.idle":"2025-12-17T09:20:27.445013Z","shell.execute_reply.started":"2025-12-17T09:20:27.426375Z","shell.execute_reply":"2025-12-17T09:20:27.444267Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -q transformers sentencepiece sacrebleu accelerate\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:27.445810Z","iopub.execute_input":"2025-12-17T09:20:27.446138Z","iopub.status.idle":"2025-12-17T09:20:33.627749Z","shell.execute_reply.started":"2025-12-17T09:20:27.446114Z","shell.execute_reply":"2025-12-17T09:20:33.627086Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport re\nimport torch\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:33.629065Z","iopub.execute_input":"2025-12-17T09:20:33.629366Z","iopub.status.idle":"2025-12-17T09:20:40.291414Z","shell.execute_reply.started":"2025-12-17T09:20:33.629336Z","shell.execute_reply":"2025-12-17T09:20:40.290730Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def split_akkadian(text):\n    text = re.sub(r\"\\.{2,}\", \".\", text)\n    parts = re.split(r\"[\\n:;]\", text)\n    return [p.strip() for p in parts if len(p.strip()) > 3]\n\ndef split_english(text):\n    parts = re.split(r\"[.;]\", text)\n    return [p.strip() for p in parts if len(p.strip()) > 3]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:40.292384Z","iopub.execute_input":"2025-12-17T09:20:40.292776Z","iopub.status.idle":"2025-12-17T09:20:40.297993Z","shell.execute_reply.started":"2025-12-17T09:20:40.292752Z","shell.execute_reply":"2025-12-17T09:20:40.297278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pairs = []\n\nfor _, row in df.iterrows():\n    src = split_akkadian(row.transliteration)\n    tgt = split_english(row.translation)\n    \n    n = min(len(src), len(tgt))\n    for i in range(n):\n        pairs.append({\n            \"src\": src[i],\n            \"tgt\": tgt[i]\n        })\n\ntrain_sent = pd.DataFrame(pairs)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:40.298783Z","iopub.execute_input":"2025-12-17T09:20:40.299037Z","iopub.status.idle":"2025-12-17T09:20:40.434916Z","shell.execute_reply.started":"2025-12-17T09:20:40.299017Z","shell.execute_reply":"2025-12-17T09:20:40.434406Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"lex_map = dict(zip(\n    oa[\"form\"].dropna(),\n    oa[\"lexeme\"].loc[oa[\"form\"].notna()]\n))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:40.435652Z","iopub.execute_input":"2025-12-17T09:20:40.435862Z","iopub.status.idle":"2025-12-17T09:20:40.460327Z","shell.execute_reply.started":"2025-12-17T09:20:40.435842Z","shell.execute_reply":"2025-12-17T09:20:40.459745Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def add_lexicon_hint(sentence):\n    toks = sentence.split()\n    lexemes = []\n    for t in toks:\n        if t in lex_map:\n            lexemes.append(lex_map[t])\n    if lexemes:\n        return sentence + \" <LEX> \" + \" \".join(set(lexemes))\n    return sentence\n\ntrain_sent[\"src_aug\"] = train_sent[\"src\"].apply(add_lexicon_hint)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:40.461205Z","iopub.execute_input":"2025-12-17T09:20:40.461514Z","iopub.status.idle":"2025-12-17T09:20:40.499660Z","shell.execute_reply.started":"2025-12-17T09:20:40.461491Z","shell.execute_reply":"2025-12-17T09:20:40.499148Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_sent[\"src_aug\"].iloc[0]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:40.500515Z","iopub.execute_input":"2025-12-17T09:20:40.500834Z","iopub.status.idle":"2025-12-17T09:20:40.505692Z","shell.execute_reply.started":"2025-12-17T09:20:40.500812Z","shell.execute_reply":"2025-12-17T09:20:40.505041Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n\nMODEL = \"facebook/mbart-large-50-many-to-one-mmt\"\n\ntokenizer = AutoTokenizer.from_pretrained(MODEL)\nmodel = AutoModelForSeq2SeqLM.from_pretrained(MODEL)\n\n# mBART language setup (required)\ntokenizer.src_lang = \"en_XX\"   # fake source language\ntokenizer.tgt_lang = \"en_XX\"\n\nmodel.config.use_cache = False\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:20:40.506586Z","iopub.execute_input":"2025-12-17T09:20:40.506821Z","iopub.status.idle":"2025-12-17T09:21:32.131922Z","shell.execute_reply.started":"2025-12-17T09:20:40.506802Z","shell.execute_reply":"2025-12-17T09:21:32.130929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:21:32.136046Z","iopub.execute_input":"2025-12-17T09:21:32.136899Z","iopub.status.idle":"2025-12-17T09:21:32.172760Z","shell.execute_reply.started":"2025-12-17T09:21:32.136857Z","shell.execute_reply":"2025-12-17T09:21:32.170008Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch.utils.data import Dataset\nimport torch\n\nclass MTDataset(Dataset):\n    def __init__(self, df):\n        self.src = df[\"src_aug\"].tolist()\n        self.tgt = df[\"tgt\"].tolist()\n\n    def __len__(self):\n        return len(self.src)\n\n    def __getitem__(self, idx):\n        x = tokenizer(\n            self.src[idx],\n            truncation=True,\n            max_length=128\n        )\n\n        y = tokenizer(\n            self.tgt[idx],\n            truncation=True,\n            max_length=128,\n            text_target=self.tgt[idx]\n        )\n\n        labels = y[\"input_ids\"]\n        labels = [l if l != tokenizer.pad_token_id else -100 for l in labels]\n\n        return {\n            \"input_ids\": torch.tensor(x[\"input_ids\"]),\n            \"attention_mask\": torch.tensor(x[\"attention_mask\"]),\n            \"labels\": torch.tensor(labels),\n        }\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:21:32.173733Z","iopub.execute_input":"2025-12-17T09:21:32.174059Z","iopub.status.idle":"2025-12-17T09:21:37.437496Z","shell.execute_reply.started":"2025-12-17T09:21:32.174022Z","shell.execute_reply":"2025-12-17T09:21:37.436608Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nimport torch\nfrom transformers import (\n    AutoTokenizer,\n    AutoModelForSeq2SeqLM,\n    Seq2SeqTrainer,\n    TrainingArguments,\n    DataCollatorForSeq2Seq,\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:21:37.438815Z","iopub.execute_input":"2025-12-17T09:21:37.439196Z","iopub.status.idle":"2025-12-17T09:21:46.305919Z","shell.execute_reply.started":"2025-12-17T09:21:37.439154Z","shell.execute_reply":"2025-12-17T09:21:46.305368Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from transformers import (\n    Seq2SeqTrainer,\n    Seq2SeqTrainingArguments,\n    DataCollatorForSeq2Seq,\n)\n\nmodel.config.use_cache = False\n\nargs = Seq2SeqTrainingArguments(\n    output_dir=\"model\",\n    per_device_train_batch_size=2,\n    gradient_accumulation_steps=8,\n    learning_rate=3e-5,\n    num_train_epochs=6,\n    logging_steps=200,\n    save_steps=2000,\n    fp16=True,\n    report_to=\"none\",\n    predict_with_generate=True,\n)\n\ndata_collator = DataCollatorForSeq2Seq(\n    tokenizer,\n    model=model,\n    padding=True\n)\n\ntrainer = Seq2SeqTrainer(\n    model=model,\n    args=args,\n    train_dataset=MTDataset(train_sent),\n    data_collator=data_collator,\n    tokenizer=tokenizer,\n)\n\ntorch.cuda.empty_cache()\ntrainer.train()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:21:46.308878Z","iopub.execute_input":"2025-12-17T09:21:46.309394Z","iopub.status.idle":"2025-12-17T09:52:06.698721Z","shell.execute_reply.started":"2025-12-17T09:21:46.309370Z","shell.execute_reply":"2025-12-17T09:52:06.698013Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"SAVE_DIR = \"mbart_assyrian_en_model\"\n\ntrainer.save_model(SAVE_DIR)      # saves model + config\ntokenizer.save_pretrained(SAVE_DIR)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:52:06.699805Z","iopub.execute_input":"2025-12-17T09:52:06.700287Z","iopub.status.idle":"2025-12-17T09:52:16.989091Z","shell.execute_reply.started":"2025-12-17T09:52:06.700233Z","shell.execute_reply":"2025-12-17T09:52:16.988160Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def build_context(df, idx, window=1):\n    tid = df.loc[idx, \"text_id\"]\n    rows = df[df.text_id == tid].reset_index(drop=True)\n\n    pos = rows[rows[\"transliteration\"] == df.loc[idx, \"transliteration\"]].index[0]\n\n    start = max(0, pos - window)\n    end = min(len(rows), pos + window + 1)\n\n    return \" <SEP> \".join(rows.loc[start:end-1, \"transliteration\"].tolist())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:52:16.990275Z","iopub.execute_input":"2025-12-17T09:52:16.991002Z","iopub.status.idle":"2025-12-17T09:52:37.841510Z","shell.execute_reply.started":"2025-12-17T09:52:16.990977Z","shell.execute_reply":"2025-12-17T09:52:37.840812Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\npreds = []\n\nfor i in range(len(dt)):\n    src = build_context(dt, i)\n    src = add_lexicon_hint(src)\n\n    inputs = tokenizer(\n        src,\n        return_tensors=\"pt\",\n        truncation=True,\n        max_length=256\n    ).to(model.device)\n\n    with torch.no_grad():\n        out = model.generate(\n            **inputs,\n            max_length=128,\n            num_beams=4,\n            early_stopping=True\n        )\n\n    text = tokenizer.decode(out[0], skip_special_tokens=True)\n    preds.append(text)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:52:37.842460Z","iopub.execute_input":"2025-12-17T09:52:37.842692Z","iopub.status.idle":"2025-12-17T09:52:41.340893Z","shell.execute_reply.started":"2025-12-17T09:52:37.842661Z","shell.execute_reply":"2025-12-17T09:52:41.340206Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    \"id\": dt[\"id\"],\n    \"translation\": preds\n})\n\nsubmission.to_csv(\"submission.csv\", index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:52:41.341824Z","iopub.execute_input":"2025-12-17T09:52:41.342065Z","iopub.status.idle":"2025-12-17T09:52:41.363369Z","shell.execute_reply.started":"2025-12-17T09:52:41.342033Z","shell.execute_reply":"2025-12-17T09:52:41.362789Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:52:41.364121Z","iopub.execute_input":"2025-12-17T09:52:41.364440Z","iopub.status.idle":"2025-12-17T09:52:41.372199Z","shell.execute_reply.started":"2025-12-17T09:52:41.364405Z","shell.execute_reply":"2025-12-17T09:52:41.371467Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-17T09:52:41.373319Z","iopub.execute_input":"2025-12-17T09:52:41.373562Z","iopub.status.idle":"2025-12-17T09:52:41.392798Z","shell.execute_reply.started":"2025-12-17T09:52:41.373540Z","shell.execute_reply":"2025-12-17T09:52:41.392115Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}