{"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":"gpu","dataSources":[{"sourceType":"competition","sourceId":121150,"databundleVersionId":15833391},{"sourceType":"datasetVersion","sourceId":14899351,"datasetId":9366631,"databundleVersionId":15763950},{"sourceType":"datasetVersion","sourceId":14929273,"datasetId":9553164,"databundleVersionId":15796698},{"sourceType":"modelInstanceVersion","sourceId":750505,"databundleVersionId":15690840,"modelInstanceId":573241,"modelId":585594}],"dockerImageVersionId":31328,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        os.path.join(dirname, filename)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-03-23T19:29:04.923708Z","iopub.execute_input":"2026-03-23T19:29:04.924358Z","iopub.status.idle":"2026-03-23T19:29:04.946415Z","shell.execute_reply.started":"2026-03-23T19:29:04.924322Z","shell.execute_reply":"2026-03-23T19:29:04.945476Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ================================\n# Akkadian → English (FINAL IMPROVED)\n# ================================\n\nimport os\nimport gc\nimport re\nimport warnings\nfrom pathlib import Path\nfrom dataclasses import dataclass\nfrom typing import List\n\nimport pandas as pd\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\nfrom tqdm.auto import tqdm\n\nwarnings.filterwarnings(\"ignore\")\n\n\n# ================================\n# CONFIG\n# ================================\n@dataclass\nclass Config:\n    test_data_path: str = \"/kaggle/input/competitions/deep-past-initiative-machine-translation/test.csv\"\n    model_path: str = \"/kaggle/input/datasets/assiaben/final-byt5/byt5-akkadian-optimized-34x\"\n    output_dir: str = \"/kaggle/working/\"\n\n    max_input_length: int = 512\n    max_new_tokens: int = 128\n\n    batch_size: int = 2\n    num_workers: int = 0\n\n    num_beams: int = 2\n\n    def __post_init__(self):\n        self.device = torch.device(\"cpu\")\n        Path(self.output_dir).mkdir(exist_ok=True, parents=True)\n\n\ncfg = Config()\n\n\n# ================================\n# PREPROCESS\n# ================================\ndef preprocess(texts):\n    return [\"translate Akkadian to English: \" + str(t) for t in texts]\n\n\n# ================================\n# DATASET\n# ================================\nclass AkkadianDataset(Dataset):\n    def __init__(self, df):\n        self.ids = df[\"id\"].tolist()\n        self.texts = preprocess(df[\"transliteration\"].tolist())\n\n    def __len__(self):\n        return len(self.ids)\n\n    def __getitem__(self, i):\n        return self.ids[i], self.texts[i]\n\n\n# ================================\n# MODEL\n# ================================\nclass ModelWrapper:\n    def __init__(self, cfg):\n        self.tokenizer = AutoTokenizer.from_pretrained(cfg.model_path)\n\n        self.model = AutoModelForSeq2SeqLM.from_pretrained(\n            cfg.model_path,\n            dtype=torch.float32\n        )\n\n        self.tokenizer.pad_token = self.tokenizer.eos_token\n        self.model.config.pad_token_id = self.tokenizer.pad_token_id\n        self.model.config.tie_word_embeddings = False\n\n        self.model.eval()\n\n    def collate(self, batch):\n        ids = [b[0] for b in batch]\n        texts = [b[1] for b in batch]\n\n        enc = self.tokenizer(\n            texts,\n            padding=True,\n            truncation=True,\n            max_length=cfg.max_input_length,\n            return_tensors=\"pt\"\n        )\n        return ids, enc\n\n    def generate(self, input_ids, attention_mask):\n        outputs = self.model.generate(\n            input_ids=input_ids,\n            attention_mask=attention_mask,\n            num_beams=cfg.num_beams,\n            max_new_tokens=cfg.max_new_tokens,\n            early_stopping=True\n        )\n\n        return self.tokenizer.batch_decode(outputs, skip_special_tokens=True)\n\n\n# ================================\n# MAIN\n# ================================\ndef main():\n    df = pd.read_csv(cfg.test_data_path)\n\n    dataset = AkkadianDataset(df)\n    model = ModelWrapper(cfg)\n\n    loader = DataLoader(\n        dataset,\n        batch_size=cfg.batch_size,\n        shuffle=False,\n        num_workers=0,\n        collate_fn=model.collate\n    )\n\n    results = []\n\n    for ids, enc in tqdm(loader):\n        outputs = model.generate(enc[\"input_ids\"], enc[\"attention_mask\"])\n\n        for sid, text in zip(ids, outputs):\n            if not text.strip():\n                text = \"The tablet is too damaged to translate.\"\n            results.append((sid, text))\n\n    submission = pd.DataFrame(results, columns=[\"id\", \"translation\"])\n    submission.to_csv(\"/kaggle/working/submission.csv\", index=False)\n\n    print(\"\\n✅ Submission Ready!\")\n    print(submission.head())\n\n\nif __name__ == \"__main__\":\n    main()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-23T19:29:04.948098Z","iopub.execute_input":"2026-03-23T19:29:04.948463Z","iopub.status.idle":"2026-03-23T19:29:50.324381Z","shell.execute_reply.started":"2026-03-23T19:29:04.948439Z","shell.execute_reply":"2026-03-23T19:29:50.323557Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport pandas as pd\nimport os\n\n# ================================\n# 🌙 Dark Theme + Colors\n# ================================\nplt.style.use(\"dark_background\")\n\n# Custom color palette\nCOLORS = {\n    \"cyan\": \"#00FFFF\",\n    \"green\": \"#39FF14\",\n    \"orange\": \"#FFA500\",\n    \"pink\": \"#FF4DFF\",\n    \"yellow\": \"#FFD700\"\n}\n\n# ================================\n# Load results safely\n# ================================\nif \"results\" not in globals():\n    print(\"⚠️ Loading results from submission.csv...\")\n    path = \"/kaggle/working/submission.csv\"\n    if os.path.exists(path):\n        sub_df = pd.read_csv(path)\n        results = list(zip(sub_df[\"id\"], sub_df[\"translation\"]))\n    else:\n        results = []\n\n# ================================\n# 1. Translation Length Distribution\n# ================================\nif results:\n    lengths = [len(str(t).split()) for _, t in results]\n\n    plt.figure()\n    plt.hist(lengths, bins=20, color=COLORS[\"cyan\"], edgecolor=\"white\", alpha=0.8)\n    plt.title(\"Translation Length Distribution\", color=COLORS[\"yellow\"])\n    plt.xlabel(\"Words\")\n    plt.ylabel(\"Frequency\")\n    plt.grid(alpha=0.2)\n    plt.show()\n\n# ================================\n# 2. Input vs Output Length\n# ================================\nif \"dataset\" in globals() and results:\n    input_lengths = [len(t.split()) for t in dataset.texts]\n    output_lengths = [len(t.split()) for _, t in results]\n\n    plt.figure()\n    plt.scatter(\n        input_lengths,\n        output_lengths,\n        color=COLORS[\"green\"],\n        edgecolors=\"white\",\n        alpha=0.8\n    )\n    plt.title(\"Input vs Output Length\", color=COLORS[\"yellow\"])\n    plt.xlabel(\"Input Length\")\n    plt.ylabel(\"Output Length\")\n    plt.grid(alpha=0.2)\n    plt.show()\n\n# ================================\n# 3. Candidate Diversity\n# ================================\nif \"all_pools\" in globals():\n    diversity = [len(set(all_pools[str(sid)])) for sid in dataset.ids]\n\n    plt.figure()\n    plt.hist(diversity, bins=10, color=COLORS[\"orange\"], edgecolor=\"white\", alpha=0.8)\n    plt.title(\"Candidate Diversity\", color=COLORS[\"yellow\"])\n    plt.xlabel(\"Unique Candidates\")\n    plt.ylabel(\"Count\")\n    plt.grid(alpha=0.2)\n    plt.show()\n\n# ================================\n# 4. Raw vs Processed Length\n# ================================\nif \"df\" in globals() and \"dataset\" in globals():\n    raw_lengths = [len(str(t)) for t in df[\"transliteration\"]]\n    processed_lengths = [len(t) for t in dataset.texts]\n\n    plt.figure()\n    plt.hist(raw_lengths, bins=20, color=COLORS[\"pink\"], alpha=0.5, label=\"Raw\")\n    plt.hist(processed_lengths, bins=20, color=COLORS[\"cyan\"], alpha=0.5, label=\"Processed\")\n    plt.legend()\n    plt.title(\"Text Length Comparison\", color=COLORS[\"yellow\"])\n    plt.grid(alpha=0.2)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-23T19:29:50.325501Z","iopub.execute_input":"2026-03-23T19:29:50.325767Z","iopub.status.idle":"2026-03-23T19:29:50.751636Z","shell.execute_reply.started":"2026-03-23T19:29:50.325741Z","shell.execute_reply":"2026-03-23T19:29:50.751043Z"}},"outputs":[],"execution_count":null}]}