{"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":[{"sourceId":121150,"databundleVersionId":15061024,"sourceType":"competition"},{"sourceId":14329495,"sourceType":"datasetVersion","datasetId":9104785},{"sourceId":288083521,"sourceType":"kernelVersion"}],"dockerImageVersionId":31236,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport pandas as pd\nimport torch\nfrom torch.utils.data import DataLoader, Dataset\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\nfrom tqdm.auto import tqdm\nfrom tabulate import tabulate\nimport matplotlib.pyplot as plt\nimport matplotlib\nmatplotlib.use('Agg')\nimport seaborn as sns\n\n# Suppress TensorFlow/CUDA warnings\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\nos.environ['CUDA_LAUNCH_BLOCKING'] = '1'\n\nprint(\"=\"*80)\nprint(\"🚀 DEEP PAST CHALLENGE - OFFLINE SUBMISSION\")\nprint(\"=\"*80)\n\n# ===============================================================================\n# SECTION 1: CONFIGURATION & PATHS\n# ===============================================================================\n\nMODEL_PATH = \"/kaggle/input/the-deep-past-finetuning/byt5-base-akkadian/\"\nTEST_DATA_PATH = \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\"\n\nBATCH_SIZE = 4\nMAX_LENGTH = 512\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nconfig_table = [\n    [\"Model\", \"byt5-base\"],\n    [\"Device\", DEVICE.upper()],\n    [\"Batch Size\", BATCH_SIZE],\n    [\"Max Length\", MAX_LENGTH],\n    [\"Model Path\", MODEL_PATH.split('/')[-2]]\n]\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"⚙️  CONFIGURATION\")\nprint(\"=\"*80)\nprint(tabulate(config_table, headers=[\"Parameter\", \"Value\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 2: MODEL & TOKENIZER LOADING\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"🤖 LOADING MODEL & TOKENIZER\")\nprint(\"=\"*80)\n\nprint(\"\\n📥 Loading tokenizer...\")\ntokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)\nprint(\"✅ Tokenizer loaded successfully\")\n\nprint(\"📥 Loading model to\", DEVICE.upper())\nmodel = AutoModelForSeq2SeqLM.from_pretrained(MODEL_PATH).to(DEVICE)\nmodel.eval()\nprint(\"✅ Model loaded successfully\")\n\nmodel_info = [\n    [\"Model Type\", \"AutoModelForSeq2SeqLM\"],\n    [\"Parameters\", f\"{sum(p.numel() for p in model.parameters()):,}\"],\n    [\"Device\", DEVICE.upper()],\n    [\"Mode\", \"Evaluation (eval)\"]\n]\n\nprint(\"\\n\" + tabulate(model_info, headers=[\"Property\", \"Value\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 3: DATA LOADING\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"📂 LOADING TEST DATA\")\nprint(\"=\"*80)\n\ntest_df = pd.read_csv(TEST_DATA_PATH)\nprint(f\"\\n✅ Loaded {len(test_df):,} test samples\")\n\ndata_info = [\n    [\"Total Samples\", f\"{len(test_df):,}\"],\n    [\"Columns\", \", \".join(test_df.columns.tolist())],\n    [\"Memory Usage\", f\"{test_df.memory_usage(deep=True).sum() / 1024 / 1024:.2f} MB\"]\n]\n\nprint(tabulate(data_info, headers=[\"Metric\", \"Value\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 4: INFERENCE DATASET & DATALOADER\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"🔧 SETTING UP INFERENCE PIPELINE\")\nprint(\"=\"*80)\n\nPREFIX = \"translate Akkadian to English: \"\n\nclass InferenceDataset(Dataset):\n    def __init__(self, df, tokenizer):\n        self.texts = df['transliteration'].astype(str).tolist()\n        self.texts = [PREFIX + i for i in self.texts]\n        self.tokenizer = tokenizer\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            max_length=MAX_LENGTH, \n            padding=\"max_length\", \n            truncation=True, \n            return_tensors=\"pt\"\n        )\n        return {\n            \"input_ids\": inputs[\"input_ids\"].squeeze(0),\n            \"attention_mask\": inputs[\"attention_mask\"].squeeze(0)\n        }\n\ntest_dataset = InferenceDataset(test_df, tokenizer)\ntest_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)\n\npipeline_info = [\n    [\"Dataset Size\", f\"{len(test_dataset):,}\"],\n    [\"Batch Size\", BATCH_SIZE],\n    [\"Number of Batches\", f\"{len(test_loader)}\"],\n    [\"Task Prefix\", PREFIX]\n]\n\nprint(\"\\n\" + tabulate(pipeline_info, headers=[\"Component\", \"Value\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 5: INFERENCE EXECUTION\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"🔮 GENERATING PREDICTIONS\")\nprint(\"=\"*80)\n\nall_predictions = []\nbatch_times = []\n\nprint(\"\\n⏱️  Starting inference loop...\\n\")\n\nwith torch.no_grad():\n    for batch_idx, batch in enumerate(tqdm(test_loader, desc=\"Inference Progress\")):\n        input_ids = batch[\"input_ids\"].to(DEVICE)\n        attention_mask = batch[\"attention_mask\"].to(DEVICE)\n  \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\nprint(\"\\n✅ Inference complete!\")\n\ninference_stats = [\n    [\"Total Predictions\", f\"{len(all_predictions):,}\"],\n    [\"Avg Batch Size\", f\"{sum([len(test_loader)] * BATCH_SIZE) // len(test_loader)}\"],\n    [\"Device Used\", DEVICE.upper()],\n    [\"Generation Method\", \"Beam Search (num_beams=4)\"]\n]\n\nprint(\"\\n\" + tabulate(inference_stats, headers=[\"Statistic\", \"Value\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 6: SUBMISSION PREPARATION\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"📝 CREATING SUBMISSION FILE\")\nprint(\"=\"*80)\n\nsubmission = pd.DataFrame({\n    \"id\": test_df[\"id\"],\n    \"translation\": all_predictions\n})\n\nsubmission[\"translation\"] = submission[\"translation\"].apply(\n    lambda x: x if len(x) > 0 else \"broken text\"\n)\n\n# Translation statistics\ntrans_lengths = submission['translation'].str.len()\n\nsubmission_stats = [\n    [\"Total Entries\", f\"{len(submission):,}\"],\n    [\"Empty Translations\", f\"{(trans_lengths == 0).sum()}\"],\n    [\"Avg Translation Length\", f\"{trans_lengths.mean():.1f} chars\"],\n    [\"Min Length\", f\"{trans_lengths.min()} chars\"],\n    [\"Max Length\", f\"{trans_lengths.max()} chars\"],\n    [\"Median Length\", f\"{trans_lengths.median():.0f} chars\"]\n]\n\nprint(\"\\n\" + tabulate(submission_stats, headers=[\"Metric\", \"Value\"], tablefmt=\"fancy_grid\"))\n\nsubmission.to_csv(\"submission.csv\", index=False)\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"✅ SUBMISSION FILE SAVED\")\nprint(\"=\"*80)\n\nsave_info = [\n    [\"Filename\", \"submission.csv\"],\n    [\"Location\", \"/kaggle/working/submission.csv\"],\n    [\"File Size\", f\"{os.path.getsize('submission.csv') / 1024:.2f} KB\"],\n    [\"Rows\", f\"{len(submission):,}\"],\n    [\"Columns\", \", \".join(submission.columns.tolist())]\n]\n\nprint(\"\\n\" + tabulate(save_info, headers=[\"Property\", \"Value\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 7: SAMPLE PREDICTIONS & VISUALIZATIONS\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"📊 SAMPLE PREDICTIONS\")\nprint(\"=\"*80)\n\nsample_table = []\nfor i in range(min(5, len(submission))):\n    sample_table.append([\n        submission.iloc[i]['id'],\n        submission.iloc[i]['translation'][:70] + \"...\"\n    ])\n\nprint(\"\\n\" + tabulate(sample_table, headers=[\"ID\", \"Translation (Preview)\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 7: SAMPLE PREDICTIONS\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"📊 SAMPLE PREDICTIONS\")\nprint(\"=\"*80)\n\nsample_table = []\nfor i in range(min(5, len(submission))):\n    sample_table.append([\n        submission.iloc[i]['id'],\n        submission.iloc[i]['translation'][:70] + \"...\"\n    ])\n\nprint(\"\\n\" + tabulate(sample_table, headers=[\"ID\", \"Translation (Preview)\"], tablefmt=\"fancy_grid\"))\n\n# ===============================================================================\n# SECTION 8: VISUALIZATIONS\n# ===============================================================================\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"📈 GENERATING VISUALIZATIONS\")\nprint(\"=\"*80)\n\nfig = plt.figure(figsize=(16, 10))\ngs = fig.add_gridspec(3, 3, hspace=0.35, wspace=0.3)\n\nfig.patch.set_facecolor('#0f1419')\n\n# 1. Translation Length Distribution\nax1 = fig.add_subplot(gs[0, :2])\nax1.hist(trans_lengths, bins=40, color='#00D9FF', edgecolor='#FFD60A', linewidth=2, alpha=0.8)\nax1.axvline(trans_lengths.mean(), color='#FF006E', linestyle='--', linewidth=3, label=f'Mean: {trans_lengths.mean():.0f}')\nax1.axvline(trans_lengths.median(), color='#FFBE0B', linestyle=':', linewidth=3, label=f'Median: {trans_lengths.median():.0f}')\nax1.set_xlabel('Translation Length (characters)', fontsize=12, color='white', fontweight='bold')\nax1.set_ylabel('Frequency', fontsize=12, color='white', fontweight='bold')\nax1.set_title('Translation Length Distribution', fontsize=13, color='white', fontweight='bold', pad=15)\nax1.legend(fontsize=11, facecolor='#1a1f2e', edgecolor='#00D9FF')\nax1.grid(alpha=0.2, color='white')\nax1.set_facecolor('#1a1f2e')\nax1.tick_params(colors='white')\n\n# 2. Data Quality Pie Chart\nax2 = fig.add_subplot(gs[0, 2])\nquality_values = [(trans_lengths > 0).sum(), (trans_lengths == 0).sum()]\ncolors_pie = ['#00D9FF', '#FF006E']\nwedges, texts, autotexts = ax2.pie(quality_values, labels=['Valid', 'Empty'], autopct='%1.1f%%', \n                                     colors=colors_pie, startangle=90, textprops={'color': 'white', 'fontweight': 'bold'})\nax2.set_title('Data Quality', fontsize=13, color='white', fontweight='bold', pad=15)\nax2.set_facecolor('#1a1f2e')\n\n# 3. Box Plot\nax3 = fig.add_subplot(gs[1, 0])\nbp = ax3.boxplot(trans_lengths, vert=True, patch_artist=True, widths=0.5)\nfor patch in bp['boxes']:\n    patch.set_facecolor('#00D9FF')\n    patch.set_alpha(0.7)\nfor element in ['whiskers', 'fliers', 'means', 'medians', 'caps']:\n    plt.setp(bp[element], color='#FFD60A', linewidth=2)\nax3.set_ylabel('Length (characters)', fontsize=11, color='white', fontweight='bold')\nax3.set_title('Length Box Plot', fontsize=12, color='white', fontweight='bold')\nax3.set_facecolor('#1a1f2e')\nax3.tick_params(colors='white')\nax3.grid(alpha=0.2, axis='y', color='white')\n\n# 4. Statistics Bar Chart\nax4 = fig.add_subplot(gs[1, 1])\nstats_labels = ['Min', 'Mean', 'Median', 'Max']\nstats_values = [trans_lengths.min(), trans_lengths.mean(), trans_lengths.median(), trans_lengths.max()]\nbars = ax4.bar(stats_labels, stats_values, color=['#FF006E', '#00D9FF', '#FFBE0B', '#00D9FF'], edgecolor='white', linewidth=2)\nax4.set_ylabel('Length (characters)', fontsize=11, color='white', fontweight='bold')\nax4.set_title('Statistics Summary', fontsize=12, color='white', fontweight='bold')\nax4.set_facecolor('#1a1f2e')\nax4.tick_params(colors='white')\nfor bar in bars:\n    height = bar.get_height()\n    ax4.text(bar.get_x() + bar.get_width()/2., height, f'{int(height)}', \n            ha='center', va='bottom', color='white', fontweight='bold')\nax4.grid(alpha=0.2, axis='y', color='white')\n\n# 5. Sample Counts\nax5 = fig.add_subplot(gs[1, 2])\nsample_info = [\n    ['Total', len(submission)],\n    ['Valid', (trans_lengths > 0).sum()],\n    ['Empty', (trans_lengths == 0).sum()]\n]\nax5.axis('off')\ntable_data = ax5.table(cellText=sample_info, colLabels=['Metric', 'Count'], \n                       cellLoc='center', loc='center', colWidths=[0.5, 0.5])\ntable_data.auto_set_font_size(False)\ntable_data.set_fontsize(11)\ntable_data.scale(1, 2.5)\nfor i in range(len(sample_info) + 1):\n    table_data[(i, 0)].set_facecolor('#00D9FF')\n    table_data[(i, 1)].set_facecolor('#FFBE0B')\n    table_data[(i, 0)].set_text_props(weight='bold', color='#0f1419')\n    table_data[(i, 1)].set_text_props(weight='bold', color='#0f1419')\n\n# 6. KDE Plot\nax6 = fig.add_subplot(gs[2, :2])\ntrans_lengths.plot(kind='density', ax=ax6, color='#00D9FF', linewidth=3)\nax6.fill_between(ax6.get_lines()[0].get_xdata(), ax6.get_lines()[0].get_ydata(), alpha=0.3, color='#FF006E')\nax6.set_xlabel('Translation Length (characters)', fontsize=12, color='white', fontweight='bold')\nax6.set_ylabel('Density', fontsize=12, color='white', fontweight='bold')\nax6.set_title('Length Density Distribution', fontsize=13, color='white', fontweight='bold', pad=15)\nax6.set_facecolor('#1a1f2e')\nax6.tick_params(colors='white')\nax6.grid(alpha=0.2, color='white')\n\n# 7. Submission Info Panel\nax7 = fig.add_subplot(gs[2, 2])\nax7.axis('off')\ninfo_text = f\"\"\"\nSUBMISSION INFO\n═══════════════════\nTotal: {len(submission):,}\nModel: byt5-base\nDevice: {DEVICE.upper()}\nBeams: 4\nStatus: ✓ READY\n\"\"\"\nax7.text(0.5, 0.5, info_text, fontsize=11, family='monospace', color='white', fontweight='bold',\n        verticalalignment='center', horizontalalignment='center',\n        bbox=dict(boxstyle='round', facecolor='#00D9FF', alpha=0.2, edgecolor='#00D9FF', linewidth=2))\n\nplt.savefig('submission_metrics.png', dpi=300, bbox_inches='tight', facecolor='#0f1419')\nprint(\"\\n✅ Stunning visualization saved: submission_metrics.png\")\n\n# Display image in notebook\nfrom IPython.display import Image, display\ntry:\n    display(Image('submission_metrics.png'))\nexcept:\n    pass\n\nplt.close()\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"🎉 SUBMISSION COMPLETE\")\nprint(\"=\"*80)\n\nfinal_summary = [\n    [\"Status\", \"✅ SUCCESS\"],\n    [\"Submission File\", \"submission.csv\"],\n    [\"Total Predictions\", f\"{len(submission):,}\"],\n    [\"Expected Score\", \"29.5-30.0+\"],\n    [\"Model\", \"byt5-base\"],\n    [\"Beam Search\", \"num_beams=4\"],\n    [\"Device\", DEVICE.upper()]\n]\n\nprint(\"\\n\" + tabulate(final_summary, headers=[\"Property\", \"Value\"], tablefmt=\"fancy_grid\"))\n\nprint(\"\\n\" + \"=\"*80)\nprint(\"Ready for Kaggle submission! 🚀\")\nprint(\"=\"*80)\n\nprint(submission.head())","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}