{"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":[{"sourceType":"competition","sourceId":121150,"databundleVersionId":15833391},{"sourceType":"datasetVersion","sourceId":14984563,"datasetId":9592104,"databundleVersionId":15858198}],"dockerImageVersionId":31287,"isInternetEnabled":false,"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},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# The following code will only execute\n# successfully when compression is complete\n\nimport kagglehub\n\n# Download latest version\npath = kagglehub.dataset_download(\"suman2208/akkadian-cleaned-pristine\")\n\nprint(\"Path to dataset files:\", path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-02T07:37:43.746208Z","iopub.execute_input":"2026-03-02T07:37:43.746936Z","iopub.status.idle":"2026-03-02T07:37:44.569979Z","shell.execute_reply.started":"2026-03-02T07:37:43.746905Z","shell.execute_reply":"2026-03-02T07:37:44.569278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ==========================================================\n# 🔥 DEEP PAST – FINAL STABLE MAX BLEU ENGINE\n# No Index Errors\n# Log-Weighted MBR\n# Fully Offline Safe\n# ==========================================================\n\nimport os\nos.environ[\"OMP_NUM_THREADS\"] = \"4\"\nos.environ[\"MKL_NUM_THREADS\"] = \"4\"\nos.environ[\"TOKENIZERS_PARALLELISM\"] = \"true\"\n\nimport re\nimport math\nfrom contextlib import nullcontext\nfrom collections import Counter\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn.functional as F\nfrom tqdm.auto import tqdm\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoConfig\nfrom torch.utils.data import Dataset, DataLoader\n\n# ==========================================================\n# CONFIG\n# ==========================================================\n\nclass Config:\n    MODEL_PATH = \"/kaggle/input/datasets/suman2208/akkadian-cleaned-pristine\"\n    TEST_PATH = \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\"\n    OUTPUT_PATH = \"/kaggle/working/submission.csv\"\n\n    MAX_LENGTH = 512\n    MAX_NEW_TOKENS = 384\n    BATCH_SIZE = 4\n\n    NUM_BEAMS = 10\n    LENGTH_PENALTY = 1.15\n    REPETITION_PENALTY = 1.2\n    NO_REPEAT_NGRAM = 3\n\n    MBR_BEAM = 6\n    MBR_SAMPLE = 4\n    TOP_P = 0.92\n    TEMP = 0.7\n    POOL_CAP = 24\n\ntorch.manual_seed(42)\nnp.random.seed(42)\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\ndef bf16_ctx():\n    if torch.cuda.is_available() and torch.cuda.is_bf16_supported():\n        return torch.autocast(device_type=\"cuda\", dtype=torch.bfloat16)\n    return nullcontext()\n\n# ==========================================================\n# LOAD MODEL\n# ==========================================================\n\nconfig_model = AutoConfig.from_pretrained(Config.MODEL_PATH, local_files_only=True)\nconfig_model.tie_word_embeddings = False\n\ntokenizer = AutoTokenizer.from_pretrained(Config.MODEL_PATH, local_files_only=True)\n\nmodel = AutoModelForSeq2SeqLM.from_pretrained(\n    Config.MODEL_PATH,\n    config=config_model,\n    local_files_only=True,\n    torch_dtype=torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float32\n).to(device)\n\nmodel.eval()\n\n# ==========================================================\n# chrF++\n# ==========================================================\n\ndef extract_ngrams(text, n):\n    return [text[i:i+n] for i in range(len(text)-n+1)]\n\ndef chrfpp(a, b):\n    if not a or not b:\n        return 0.0\n    scores = []\n    for n in range(1,7):\n        A = Counter(extract_ngrams(a,n))\n        B = Counter(extract_ngrams(b,n))\n        overlap = sum((A&B).values())\n        p = overlap / max(1,sum(A.values()))\n        r = overlap / max(1,sum(B.values()))\n        if p+r == 0:\n            scores.append(0)\n        else:\n            beta2 = 4\n            scores.append((1+beta2)*p*r/(r+beta2*p))\n    return sum(scores)/len(scores)\n\n# ==========================================================\n# POSTPROCESSING\n# ==========================================================\n\ndef postprocess(text):\n\n    text = str(text)\n\n    text = re.sub(r'\\bPN\\b', '<gap>', text)\n    text = re.sub(r'\\b(fem\\.?|sing\\.?|pl\\.?|plural|\\(\\?\\))\\b', '', text, flags=re.I)\n\n    text = re.sub(r'-tax\\b', ' šadduātum tax', text)\n    text = re.sub(r'-gold\\b', ' pašallum gold', text)\n    text = re.sub(r'(?<!kutānu\\s)(?<!kutānum\\s)\\btextiles\\b', 'kutānum textiles', text)\n\n    text = re.sub(r'(<gap>\\s*)+', '<gap>', text)\n    text = re.sub(r'\\b(\\w+)(?:\\s+\\1\\b)+', r'\\1', text)\n    text = re.sub(r'\\s+', ' ', text).strip()\n\n    return text\n\n# ==========================================================\n# SAFE SCORE COMPUTATION (NO INDEXING)\n# ==========================================================\n\ndef compute_sampling_scores(outputs):\n    \"\"\"\n    Compute approximate sequence probability using step log-probs.\n    No sequence indexing → no crash.\n    \"\"\"\n    scores = []\n    step_logits = outputs.scores  # tuple of (batch*returns, vocab)\n\n    if step_logits is None:\n        return np.ones(outputs.sequences.size(0))\n\n    for seq_idx in range(outputs.sequences.size(0)):\n\n        total = 0.0\n        steps = 0\n\n        for step in step_logits:\n            log_probs = F.log_softmax(step[seq_idx], dim=-1)\n            total += torch.max(log_probs).item()\n            steps += 1\n\n        scores.append(math.exp(total / max(1, steps)))\n\n    return np.array(scores)\n\n# ==========================================================\n# DATASET\n# ==========================================================\n\nclass DatasetMT(Dataset):\n    def __init__(self, df):\n        self.ids = df[\"id\"].tolist()\n        self.texts = df[\"transliteration\"].tolist()\n\n    def __len__(self):\n        return len(self.ids)\n\n    def __getitem__(self, idx):\n        return self.ids[idx], self.texts[idx]\n\n# ==========================================================\n# MBR\n# ==========================================================\n\ndef select_mbr(pool, scores):\n\n    pool = list(dict.fromkeys([p.strip() for p in pool if p.strip()]))[:Config.POOL_CAP]\n\n    if len(pool) <= 1:\n        return pool[0] if pool else \"\"\n\n    final_scores = []\n\n    for i, cand in enumerate(pool):\n        sim = np.mean([chrfpp(cand, other) for j, other in enumerate(pool) if i!=j])\n        weighted = sim * float(scores[i])\n        final_scores.append(weighted)\n\n    return pool[int(np.argmax(final_scores))]\n\n# ==========================================================\n# INFERENCE\n# ==========================================================\n\ndf = pd.read_csv(Config.TEST_PATH)\ndf[\"transliteration\"] = df[\"transliteration\"].fillna(\"\")\ndf[\"id\"] = df[\"id\"].astype(int)\n\ndataset = DatasetMT(df)\nloader = DataLoader(dataset, batch_size=Config.BATCH_SIZE)\n\nresults = []\n\nwith torch.inference_mode():\n\n    for ids, texts in tqdm(loader, desc=\"🚀 Translating\"):\n\n        inputs = tokenizer(\n            list(texts),\n            return_tensors=\"pt\",\n            padding=True,\n            truncation=True,\n            max_length=Config.MAX_LENGTH\n        ).to(device)\n\n        with bf16_ctx():\n\n            beam_outputs = model.generate(\n                **inputs,\n                num_beams=Config.NUM_BEAMS,\n                num_return_sequences=Config.MBR_BEAM,\n                max_new_tokens=Config.MAX_NEW_TOKENS,\n                repetition_penalty=Config.REPETITION_PENALTY,\n                no_repeat_ngram_size=Config.NO_REPEAT_NGRAM,\n                length_penalty=Config.LENGTH_PENALTY,\n                return_dict_in_generate=True,\n                output_scores=True\n            )\n\n            sample_outputs = model.generate(\n                **inputs,\n                do_sample=True,\n                top_p=Config.TOP_P,\n                temperature=Config.TEMP,\n                num_return_sequences=Config.MBR_SAMPLE,\n                repetition_penalty=Config.REPETITION_PENALTY,\n                no_repeat_ngram_size=Config.NO_REPEAT_NGRAM,\n                max_new_tokens=Config.MAX_NEW_TOKENS,\n                return_dict_in_generate=True,\n                output_scores=True\n            )\n\n        beam_txt = tokenizer.batch_decode(beam_outputs.sequences, skip_special_tokens=True)\n        sample_txt = tokenizer.batch_decode(sample_outputs.sequences, skip_special_tokens=True)\n\n        beam_scores = beam_outputs.sequences_scores.cpu().numpy()\n        sample_scores = compute_sampling_scores(sample_outputs)\n\n        B = len(ids)\n\n        for i in range(B):\n\n            pool = []\n            scores = []\n\n            for j in range(Config.MBR_BEAM):\n                pool.append(beam_txt[i*Config.MBR_BEAM+j])\n                scores.append(math.exp(beam_scores[i*Config.MBR_BEAM+j]))\n\n            for j in range(Config.MBR_SAMPLE):\n                pool.append(sample_txt[i*Config.MBR_SAMPLE+j])\n                scores.append(sample_scores[i*Config.MBR_SAMPLE+j])\n\n            best = select_mbr(pool, scores)\n            results.append((int(ids[i]), postprocess(best)))\n\nout = pd.DataFrame(results, columns=[\"id\",\"translation\"])\nout = out.set_index(\"id\").reindex(df[\"id\"]).reset_index()\nout.to_csv(Config.OUTPUT_PATH, index=False)\n\nprint(\"✅ Submission saved:\", Config.OUTPUT_PATH)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-02T08:30:55.248620Z","iopub.execute_input":"2026-03-02T08:30:55.248969Z","iopub.status.idle":"2026-03-02T08:32:39.164873Z","shell.execute_reply.started":"2026-03-02T08:30:55.248938Z","shell.execute_reply":"2026-03-02T08:32:39.164281Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pd.read_csv(\"/kaggle/working/submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-02T08:32:43.365718Z","iopub.execute_input":"2026-03-02T08:32:43.366455Z","iopub.status.idle":"2026-03-02T08:32:43.385282Z","shell.execute_reply.started":"2026-03-02T08:32:43.366423Z","shell.execute_reply":"2026-03-02T08:32:43.384706Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\npd.set_option('display.max_colwidth', None)\n\ndf = pd.read_csv(\"/kaggle/working/submission.csv\")\nprint(df.loc[[0,1,2,3], \"translation\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-02T08:32:47.044536Z","iopub.execute_input":"2026-03-02T08:32:47.045182Z","iopub.status.idle":"2026-03-02T08:32:47.052454Z","shell.execute_reply.started":"2026-03-02T08:32:47.045146Z","shell.execute_reply":"2026-03-02T08:32:47.051572Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}