{
  "id": 684847,
  "title": "[5th] Synthetic Data via Back-Translation",
  "url": "/competitions/deep-past-initiative-machine-translation/writeups/5th-solution",
  "author_name": "",
  "post_date": "2026-03-26T08:13:33.100Z",
  "votes": 13,
  "comment_count": 4,
  "views": 0,
  "content": "<h1>Comment</h1>\n<p>Thank you to the organizers for hosting this competition. The two key elements of our approach were extracting ~20K transliteration–translation pairs from published scholarly PDFs using a VLM-based pipeline, and generating synthetic data via pseudo-labeling and back-translation.</p>\n<h1>Solution summary</h1>\n<ul>\n<li>Model: ByT5 variants (best submission: ByT5-xl)</li>\n<li>Data: <ul>\n<li>PDF data: ~20K transliteration–translation pairs extracted from AKT series and other scholarly PDFs with a VLM-based pipeline</li>\n<li>EvaCun (ORACC Akkadian Parallel Corpus)</li>\n<li>Synthetic data generated via pseudo-labeling and back-translation</li></ul></li>\n<li>Training pipeline:<ul>\n<li>stage1: CPT on transliterations from published_test.csv → FT on EvaCun → FT on PDF data</li>\n<li>stage2: Synthetic data generation via pseudo-labeling and back-translation</li>\n<li>stage3: FT on synthetic data from EvaCun checkpoint → Final FT on PDF data with tablet context</li></ul></li>\n<li>Inference: CTranslate2 with weight-averaged fold models and beam search (no ensemble in test time)</li>\n</ul>\n<h1>Data Preparation</h1>\n<p>Initially, we fine-tuned in two stages — first on <a href=\"https://zenodo.org/records/17220688\" target=\"_blank\">EvaCun (ORACC Akkadian Parallel Corpus)</a>, then on PDF-extracted data — so we describe the preparation for each below. </p>\n<h2>PDF Extraction Pipeline</h2>\n<p>Competition <code>train.csv</code> has only 1,561 Akkadian–English pairs. We built ~20,251 pairs by extracting transliteration–translation pairs directly from the AKT series and other published scholarly PDFs (20 volumes total) using a VLM-based 4-phase pipeline: Detect excavation numbers → Link references → Extract pairs → Translate to English. <code>train.csv</code> was only used as reference within the pipeline (linking and few-shot).</p>\n<table>\n<thead>\n<tr>\n<th>Volume</th>\n<th>Language</th>\n<th>Pairs</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>AKT 1–4</td>\n<td>Turkish / German</td>\n<td>1,924</td>\n</tr>\n<tr>\n<td>AKT 5, 6A–6E, 8, 12</td>\n<td>English</td>\n<td>9,202</td>\n</tr>\n<tr>\n<td>AKT 7A–7B, 9A, 10, 11A–11B</td>\n<td>Turkish</td>\n<td>6,517</td>\n</tr>\n<tr>\n<td>Larsen 2002 (PIHANS 96)</td>\n<td>English</td>\n<td>1,199</td>\n</tr>\n<tr>\n<td>ICK 4 (1998)</td>\n<td>German</td>\n<td>1,415</td>\n</tr>\n<tr>\n<td><strong>Total</strong></td>\n<td></td>\n<td><strong>~20,251</strong></td>\n</tr>\n</tbody>\n</table>\n<h3>Phase 1: Detect excavation numbers</h3>\n<p>PDF pages are rendered to PNG images and sent to Qwen 3.5 Plus (397B) to detect excavation numbers (tablet headings like <code>\"Kt. 86/k 39\"</code>, <code>\"I 427\"</code>) and their page numbers.</p>\n<h3>Phase 2: Link references</h3>\n<p>Detected excavation numbers are matched against the <code>published_texts.csv</code> to retrieve known transliterations and against <code>train.csv</code> to retrieve known English translations. Both are provided to the VLM as reference in Phase 3. Matching handles notation variants by trying multiple alias formats (e.g., <code>\"Kt n/k 594\"</code> ↔ <code>\"Kt. n/k 594\"</code>, museum numbers, pipe-separated aliases).</p>\n<h3>Phase 3: Extract pairs</h3>\n<p>For each excavation number, the VLM is given the page image(s) where it appears along with the linked references as context, and extracts transliteration line-by-line and translation by the grouping defined in the PDF (e.g., lines 1–3 grouped together, line 4 alone). We chose this granularity because we expected the test data to be segmented at these same group boundaries.</p>\n<p>The PDFs have two distinct layouts, so we prepared separate extraction prompts for each:</p>\n<ul>\n<li>Side-by-side: transliteration and translation appear in parallel columns on the same page (English volumes: AKT 5, 6, 8, 12, Larsen)</li>\n<li>Sequential: transliteration block followed by translation block below (Turkish/German volumes: AKT 1–4, 7, 9–11, ICK 4)</li>\n</ul>\n<h3>Example: AKT 12, Kt. 86/k 39 (side-by-side)</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2F491e90cf7b492d7e0676a56ab0ca084f%2Fakt12_page043_crop.png?generation=1774512354416002&amp;alt=media\"></p>\n<pre><code>{\n  \"transliteration_lines\": {\n    \"1\": \"[ ]-ši-nim\",\n    \"2\": \"Šu-Sú-in : lu i-na GÁ[N]\",\n    \"3\": \"lu i-na a-lim\",\n    \"5\": \"i-ta-áb-ši : ša A-[mur]-A-š[ùr]\",\n    \"6\": \"E-mu-a ù-lá ṭá-hu\",\n    \"7\": \"A-mur-A-šùr ù E-mu-a\",\n    \"8\": \"zi-zu-ú-[ma] : a-hu-um\",\n    \"9\": \"a-na a-hi-im a-n[a KÙ.B]\",\n    \"10\": \"ù-lá i-tù-[ar]\",\n     \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1\": \"If silver of\",\n    \"2-4\": \"Šū-Suen proves to be either in the countryside (Anatolia) or in the City, is belongs to Amur-Aššur,\",\n    \"5-10\": \"Emua is not entitled to it. Amur-Aššur and Emua have divided (the inheritance) and they will not raise claims against each other for silver.\"\n    \"...\": \"...\"\n  }\n}\n</code></pre>\n<h3>Example: AKT 9A, Kt. c/k 1249 (sequential)</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2Fba4676b27f78bf466909751a68cd7a72%2Fakt9a_page157_crop.png?generation=1774512324980388&amp;alt=media\"></p>\n<pre><code>{\n  \"transliteration_lines\": {\n    \"1\": \"15 GÍN KÙ.BABBAR\",\n    \"2\": \"i-ṣé-er\",\n    \"3\": \"Ḫa-šu-i-li\",\n    \"4\": \"Šu-Ištar i-šu a-na\",\n    \"5\": \"ku-bu-ur ú-ṭí-tim\",\n    \"6\": \"i-ša-qal\",\n    \"7\": \"šu-ma lá iš-qúl\",\n    \"8\": \"2/3 GÍN 15 ŠE.TA\",\n    \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1-4\": \"Šu-Ištar'ın, Ḫaššuli'nin üzerinde 15 šeḳel gümüšü vardır.\",\n    \"4-6\": \"(Ḫaššuli) hububatın olgunlaşmasında ödeyecek.\",\n    \"...\": \"...\"\n  }\n}\n</code></pre>\n<p>In practice, tablet records often span multiple pages. To handle this, the target page and subsequent context pages are stitched into a single image before sending to the VLM. Some source PDFs had misordered pages, so we manually fixed the page order before running the extraction pipeline. For example, in AKT 1 we observed page sequences such as 73, 76, 77, 78, 79, 78, 79, 74, suggesting page ordering and duplication issues in the source PDF.</p>\n<p>After extraction, a validation step checks for inconsistencies (e.g., transliteration present but translation missing, uncovered line ranges). Failed records are re-sent to the VLM with a description of what went wrong, prompting it to correct the extraction.</p>\n<h3>Phase 4: Translate to English</h3>\n<p>Turkish/German volumes are translated to English using Gemini 3.1 Flash Lite with similar few-shot examples retrieved by Levenshtein distance on transliterations from <code>train.csv</code>.</p>\n<h3>Postprocessing</h3>\n<ul>\n<li>Quality filter: remove pairs with translation/transliteration length ratio outside [0.3, 4.0]</li>\n</ul>\n<h3>API Cost</h3>\n<ul>\n<li>Approximately 15$ for the entire extraction process, OpenRouter is used as the API gateway.</li>\n</ul>\n<h2>EvaCun(ORACC Akkadian Parallel Corpus) Preparation</h2>\n<h3>Used Files</h3>\n<ul>\n<li>45k transliteration-translation pairs from ranscription_train.txt, transcription_val.txt, english_train.txt, english_val.txt.</li>\n</ul>\n<h3>Preprocessing</h3>\n<p>In addition to the standard preprocessing used for the competition dataset, we applied an extra normalization step to the <strong>transliteration side</strong> of EvaCun: immediately repeated consecutive words were collapsed into a single token. This was motivated by the fact that the transliterations occasionally contain local repetition artifacts that are unlikely to be meaningful for translation and can introduce unnecessary noise during training.</p>\n<p>For example, the transliteration</p>\n<p><code>ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te É-hi-il-la-na-te ma-a im-ma-te im-ma-te ú-šá-ra-qu</code></p>\n<p>was normalized to</p>\n<p><code>ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te ma-a im-ma-te ú-šá-ra-qu</code></p>\n<h1>Training Pipeline</h1>\n<p>Training on ByT5 variants (best submission used byt5-xl):</p>\n<p><strong>Stage 1: Build base models</strong></p>\n<ol>\n<li>Continued pre-training — T5 span corruption on transliterations from <code>published_texts.csv</code>.</li>\n<li>Fine-tuning on EvaCun. </li>\n<li>Fine-tuning on PDF data.</li>\n</ol>\n<p>A reverse model (English → Akkadian) is also trained with the same pipeline by swapping transliteration and translation.</p>\n<p><strong>Stage 2: Synthetic Data Generation</strong></p>\n<p>Using the reverse model from Stage 1, we generate additional training pairs:</p>\n<ul>\n<li>Pseudo-label: translate <code>published_texts.csv</code> transliterations to English with the forward model using beam search.</li>\n<li>Back-translation: first generate 10,000 translation-like English sentences with Qwen3.5-27B, using translations from both <code>train.csv</code> and the PDF-extracted data as few-shot examples, and then back-translate them into Akkadian with the reverse model.</li>\n</ul>\n<p>The generated dataset is <a href=\"https://www.kaggle.com/datasets/yukiokumura1/deep-past-challenge-back-translated-synthetic-data\" target=\"_blank\">here</a></p>\n<p>We additionally tested scaling this back-translation data to 100,000 examples. Relative to training with 10,000 examples, this resulted in a -0.1 change on the public leaderboard but a +0.3 improvement on the private leaderboard.</p>\n<p><strong>Stage 3: Final training</strong></p>\n<p>Starting from the Stage 1 EvaCun checkpoint:</p>\n<ol>\n<li>Fine-tuning on Stage 2 data.</li>\n<li>Fine-tuning on PDF data with context — previous lines of the same tablet are prepended to the input(max 2 previous lines):</li>\n</ol>\n<p>prompt format:</p>\n<pre><code>[context] &lt;prev_line_1&gt; [sep] &lt;prev_line_2&gt; [/context] &lt;current_input&gt;\n</code></pre>\n<h1>Inference</h1>\n<p>We convert trained models to CTranslate2 format, achieving ~5x speedup over HuggingFace inference. CTranslate2 also enables ByT5-xxl inference on Kaggle's dual T4 GPUs via <code>int8_float32</code> quantization and tensor parallelism (we patched CTranslate2's source to fix a bug in its TP implementation). Note that <code>int8_float32</code> quantization degrades LB score by ~-0.1. xxl was not used in our best submission due to insufficient training time (We changed the training dataset in the last day of the competition).</p>\n<p>We average weights from multiple CV fold models into a single model before inference. At inference time, we use <code>line_start</code> from <code>test.csv</code> to prepend context from previous lines of the same tablet, matching the training format. Decoding is done with beam search.</p>\n<h1>CV Strategy</h1>\n<p>We used 25% of <code>train.csv</code> as a hold-out set. The split was stratified by the transliteration/translation length ratio to preserve the distribution of examples with different source–target length characteristics.</p>\n<p>In practice, validation loss (token-level cross entropy loss) was reasonably well correlated with LB score, so we treated it as the main offline metric throughout development. As a result, we prioritized changes that reliably improved validation loss, and used the hold-out set for checkpoint selection and ablation comparison.</p>\n<h1>Ablation Study</h1>\n<p>All models in the ablation study are ByT5-xl trained with the same parameters (e.g., learning rate, batch size, number of steps)</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>CPT</th>\n<th>EvaCun</th>\n<th>Synthetic data</th>\n<th>Tablet context</th>\n<th>Private LB</th>\n<th>Public LB</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>PDF data only</td>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>35.4</td>\n<td>35.1</td>\n</tr>\n<tr>\n<td>+ CPT</td>\n<td>✓</td>\n<td></td>\n<td></td>\n<td></td>\n<td>38.9</td>\n<td>38.0</td>\n</tr>\n<tr>\n<td>+ EvaCun</td>\n<td>✓</td>\n<td>✓</td>\n<td></td>\n<td></td>\n<td>39.7</td>\n<td>38.7</td>\n</tr>\n<tr>\n<td>+ tablet context</td>\n<td>✓</td>\n<td>✓</td>\n<td></td>\n<td>✓</td>\n<td>39.8</td>\n<td>39.2</td>\n</tr>\n<tr>\n<td>+ synthetic data</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>40.7</td>\n<td>40.2</td>\n</tr>\n<tr>\n<td>+ 4 fold weight average</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>40.8</td>\n<td>40.1</td>\n</tr>\n</tbody>\n</table>\n<h1>What Didn't Work</h1>\n<ul>\n<li>ReRanking<ul>\n<li>LGBM reranker — Reranked beam search candidates using features such as beam confidence and reverse model score. Improved CV by ~+0.2 but had no effect on LB.</li>\n<li>Fine-tuned LLM listwise reranker — Reranked beam search candidates with a fine-tuned LLM. No improvement on CV and LB.</li></ul></li>\n<li>Other back-translation strategies — We kept back-translation as a clearly separate training phase from the main fine-tuning stages, and generated synthetic data with beam search using the reverse model. Sampling-based generation for back-translation did not work well. We also tried tagged back-translation, where competition data and back-translated data were jointly trained with explicit tags to distinguish the two sources, but this also failed to improve performance.</li>\n<li>Decoding-time ensemble — We tried decoding-time ensembling with per-step logit averaging. It gave some improvement early on when combining lower-scoring models, but the benefit disappeared as the models got stronger. In particular, ensembles of models around the 37.x level no longer improved results.</li>\n</ul>",
  "messages": [
    {
      "id": "3429009",
      "postDate": "03/26/2026 08:12:50",
      "content": "<h1>Comment</h1>\n<p>Thank you to the organizers for hosting this competition. The two key elements of our approach were extracting ~20K transliteration–translation pairs from published scholarly PDFs using a VLM-based pipeline, and generating synthetic data via pseudo-labeling and back-translation.</p>\n<h1>Solution summary</h1>\n<ul>\n<li>Model: ByT5 variants (best submission: ByT5-xl)</li>\n<li>Data: <ul>\n<li>PDF data: ~20K transliteration–translation pairs extracted from AKT series and other scholarly PDFs with a VLM-based pipeline</li>\n<li>EvaCun (ORACC Akkadian Parallel Corpus)</li>\n<li>Synthetic data generated via pseudo-labeling and back-translation</li></ul></li>\n<li>Training pipeline:<ul>\n<li>stage1: CPT on transliterations from published_test.csv → FT on EvaCun → FT on PDF data</li>\n<li>stage2: Synthetic data generation via pseudo-labeling and back-translation</li>\n<li>stage3: FT on synthetic data from EvaCun checkpoint → Final FT on PDF data with tablet context</li></ul></li>\n<li>Inference: CTranslate2 with weight-averaged fold models and beam search (no ensemble in test time)</li>\n</ul>\n<h1>Data Preparation</h1>\n<p>Initially, we fine-tuned in two stages — first on <a href=\"https://zenodo.org/records/17220688\" target=\"_blank\">EvaCun (ORACC Akkadian Parallel Corpus)</a>, then on PDF-extracted data — so we describe the preparation for each below. </p>\n<h2>PDF Extraction Pipeline</h2>\n<p>Competition <code>train.csv</code> has only 1,561 Akkadian–English pairs. We built ~20,251 pairs by extracting transliteration–translation pairs directly from the AKT series and other published scholarly PDFs (20 volumes total) using a VLM-based 4-phase pipeline: Detect excavation numbers → Link references → Extract pairs → Translate to English. <code>train.csv</code> was only used as reference within the pipeline (linking and few-shot).</p>\n<table>\n<thead>\n<tr>\n<th>Volume</th>\n<th>Language</th>\n<th>Pairs</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>AKT 1–4</td>\n<td>Turkish / German</td>\n<td>1,924</td>\n</tr>\n<tr>\n<td>AKT 5, 6A–6E, 8, 12</td>\n<td>English</td>\n<td>9,202</td>\n</tr>\n<tr>\n<td>AKT 7A–7B, 9A, 10, 11A–11B</td>\n<td>Turkish</td>\n<td>6,517</td>\n</tr>\n<tr>\n<td>Larsen 2002 (PIHANS 96)</td>\n<td>English</td>\n<td>1,199</td>\n</tr>\n<tr>\n<td>ICK 4 (1998)</td>\n<td>German</td>\n<td>1,415</td>\n</tr>\n<tr>\n<td><strong>Total</strong></td>\n<td></td>\n<td><strong>~20,251</strong></td>\n</tr>\n</tbody>\n</table>\n<h3>Phase 1: Detect excavation numbers</h3>\n<p>PDF pages are rendered to PNG images and sent to Qwen 3.5 Plus (397B) to detect excavation numbers (tablet headings like <code>\"Kt. 86/k 39\"</code>, <code>\"I 427\"</code>) and their page numbers.</p>\n<h3>Phase 2: Link references</h3>\n<p>Detected excavation numbers are matched against the <code>published_texts.csv</code> to retrieve known transliterations and against <code>train.csv</code> to retrieve known English translations. Both are provided to the VLM as reference in Phase 3. Matching handles notation variants by trying multiple alias formats (e.g., <code>\"Kt n/k 594\"</code> ↔ <code>\"Kt. n/k 594\"</code>, museum numbers, pipe-separated aliases).</p>\n<h3>Phase 3: Extract pairs</h3>\n<p>For each excavation number, the VLM is given the page image(s) where it appears along with the linked references as context, and extracts transliteration line-by-line and translation by the grouping defined in the PDF (e.g., lines 1–3 grouped together, line 4 alone). We chose this granularity because we expected the test data to be segmented at these same group boundaries.</p>\n<p>The PDFs have two distinct layouts, so we prepared separate extraction prompts for each:</p>\n<ul>\n<li>Side-by-side: transliteration and translation appear in parallel columns on the same page (English volumes: AKT 5, 6, 8, 12, Larsen)</li>\n<li>Sequential: transliteration block followed by translation block below (Turkish/German volumes: AKT 1–4, 7, 9–11, ICK 4)</li>\n</ul>\n<h3>Example: AKT 12, Kt. 86/k 39 (side-by-side)</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2F491e90cf7b492d7e0676a56ab0ca084f%2Fakt12_page043_crop.png?generation=1774512354416002&amp;alt=media\"></p>\n<pre><code>{\n  \"transliteration_lines\": {\n    \"1\": \"[ ]-ši-nim\",\n    \"2\": \"Šu-Sú-in : lu i-na GÁ[N]\",\n    \"3\": \"lu i-na a-lim\",\n    \"5\": \"i-ta-áb-ši : ša A-[mur]-A-š[ùr]\",\n    \"6\": \"E-mu-a ù-lá ṭá-hu\",\n    \"7\": \"A-mur-A-šùr ù E-mu-a\",\n    \"8\": \"zi-zu-ú-[ma] : a-hu-um\",\n    \"9\": \"a-na a-hi-im a-n[a KÙ.B]\",\n    \"10\": \"ù-lá i-tù-[ar]\",\n     \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1\": \"If silver of\",\n    \"2-4\": \"Šū-Suen proves to be either in the countryside (Anatolia) or in the City, is belongs to Amur-Aššur,\",\n    \"5-10\": \"Emua is not entitled to it. Amur-Aššur and Emua have divided (the inheritance) and they will not raise claims against each other for silver.\"\n    \"...\": \"...\"\n  }\n}\n</code></pre>\n<h3>Example: AKT 9A, Kt. c/k 1249 (sequential)</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2Fba4676b27f78bf466909751a68cd7a72%2Fakt9a_page157_crop.png?generation=1774512324980388&amp;alt=media\"></p>\n<pre><code>{\n  \"transliteration_lines\": {\n    \"1\": \"15 GÍN KÙ.BABBAR\",\n    \"2\": \"i-ṣé-er\",\n    \"3\": \"Ḫa-šu-i-li\",\n    \"4\": \"Šu-Ištar i-šu a-na\",\n    \"5\": \"ku-bu-ur ú-ṭí-tim\",\n    \"6\": \"i-ša-qal\",\n    \"7\": \"šu-ma lá iš-qúl\",\n    \"8\": \"2/3 GÍN 15 ŠE.TA\",\n    \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1-4\": \"Šu-Ištar'ın, Ḫaššuli'nin üzerinde 15 šeḳel gümüšü vardır.\",\n    \"4-6\": \"(Ḫaššuli) hububatın olgunlaşmasında ödeyecek.\",\n    \"...\": \"...\"\n  }\n}\n</code></pre>\n<p>In practice, tablet records often span multiple pages. To handle this, the target page and subsequent context pages are stitched into a single image before sending to the VLM. Some source PDFs had misordered pages, so we manually fixed the page order before running the extraction pipeline. For example, in AKT 1 we observed page sequences such as 73, 76, 77, 78, 79, 78, 79, 74, suggesting page ordering and duplication issues in the source PDF.</p>\n<p>After extraction, a validation step checks for inconsistencies (e.g., transliteration present but translation missing, uncovered line ranges). Failed records are re-sent to the VLM with a description of what went wrong, prompting it to correct the extraction.</p>\n<h3>Phase 4: Translate to English</h3>\n<p>Turkish/German volumes are translated to English using Gemini 3.1 Flash Lite with similar few-shot examples retrieved by Levenshtein distance on transliterations from <code>train.csv</code>.</p>\n<h3>Postprocessing</h3>\n<ul>\n<li>Quality filter: remove pairs with translation/transliteration length ratio outside [0.3, 4.0]</li>\n</ul>\n<h3>API Cost</h3>\n<ul>\n<li>Approximately 15$ for the entire extraction process, OpenRouter is used as the API gateway.</li>\n</ul>\n<h2>EvaCun(ORACC Akkadian Parallel Corpus) Preparation</h2>\n<h3>Used Files</h3>\n<ul>\n<li>45k transliteration-translation pairs from ranscription_train.txt, transcription_val.txt, english_train.txt, english_val.txt.</li>\n</ul>\n<h3>Preprocessing</h3>\n<p>In addition to the standard preprocessing used for the competition dataset, we applied an extra normalization step to the <strong>transliteration side</strong> of EvaCun: immediately repeated consecutive words were collapsed into a single token. This was motivated by the fact that the transliterations occasionally contain local repetition artifacts that are unlikely to be meaningful for translation and can introduce unnecessary noise during training.</p>\n<p>For example, the transliteration</p>\n<p><code>ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te É-hi-il-la-na-te ma-a im-ma-te im-ma-te ú-šá-ra-qu</code></p>\n<p>was normalized to</p>\n<p><code>ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te ma-a im-ma-te ú-šá-ra-qu</code></p>\n<h1>Training Pipeline</h1>\n<p>Training on ByT5 variants (best submission used byt5-xl):</p>\n<p><strong>Stage 1: Build base models</strong></p>\n<ol>\n<li>Continued pre-training — T5 span corruption on transliterations from <code>published_texts.csv</code>.</li>\n<li>Fine-tuning on EvaCun. </li>\n<li>Fine-tuning on PDF data.</li>\n</ol>\n<p>A reverse model (English → Akkadian) is also trained with the same pipeline by swapping transliteration and translation.</p>\n<p><strong>Stage 2: Synthetic Data Generation</strong></p>\n<p>Using the reverse model from Stage 1, we generate additional training pairs:</p>\n<ul>\n<li>Pseudo-label: translate <code>published_texts.csv</code> transliterations to English with the forward model using beam search.</li>\n<li>Back-translation: first generate 10,000 translation-like English sentences with Qwen3.5-27B, using translations from both <code>train.csv</code> and the PDF-extracted data as few-shot examples, and then back-translate them into Akkadian with the reverse model.</li>\n</ul>\n<p>The generated dataset is <a href=\"https://www.kaggle.com/datasets/yukiokumura1/deep-past-challenge-back-translated-synthetic-data\" target=\"_blank\">here</a></p>\n<p>We additionally tested scaling this back-translation data to 100,000 examples. Relative to training with 10,000 examples, this resulted in a -0.1 change on the public leaderboard but a +0.3 improvement on the private leaderboard.</p>\n<p><strong>Stage 3: Final training</strong></p>\n<p>Starting from the Stage 1 EvaCun checkpoint:</p>\n<ol>\n<li>Fine-tuning on Stage 2 data.</li>\n<li>Fine-tuning on PDF data with context — previous lines of the same tablet are prepended to the input(max 2 previous lines):</li>\n</ol>\n<p>prompt format:</p>\n<pre><code>[context] &lt;prev_line_1&gt; [sep] &lt;prev_line_2&gt; [/context] &lt;current_input&gt;\n</code></pre>\n<h1>Inference</h1>\n<p>We convert trained models to CTranslate2 format, achieving ~5x speedup over HuggingFace inference. CTranslate2 also enables ByT5-xxl inference on Kaggle's dual T4 GPUs via <code>int8_float32</code> quantization and tensor parallelism (we patched CTranslate2's source to fix a bug in its TP implementation). Note that <code>int8_float32</code> quantization degrades LB score by ~-0.1. xxl was not used in our best submission due to insufficient training time (We changed the training dataset in the last day of the competition).</p>\n<p>We average weights from multiple CV fold models into a single model before inference. At inference time, we use <code>line_start</code> from <code>test.csv</code> to prepend context from previous lines of the same tablet, matching the training format. Decoding is done with beam search.</p>\n<h1>CV Strategy</h1>\n<p>We used 25% of <code>train.csv</code> as a hold-out set. The split was stratified by the transliteration/translation length ratio to preserve the distribution of examples with different source–target length characteristics.</p>\n<p>In practice, validation loss (token-level cross entropy loss) was reasonably well correlated with LB score, so we treated it as the main offline metric throughout development. As a result, we prioritized changes that reliably improved validation loss, and used the hold-out set for checkpoint selection and ablation comparison.</p>\n<h1>Ablation Study</h1>\n<p>All models in the ablation study are ByT5-xl trained with the same parameters (e.g., learning rate, batch size, number of steps)</p>\n<table>\n<thead>\n<tr>\n<th>Model</th>\n<th>CPT</th>\n<th>EvaCun</th>\n<th>Synthetic data</th>\n<th>Tablet context</th>\n<th>Private LB</th>\n<th>Public LB</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>PDF data only</td>\n<td></td>\n<td></td>\n<td></td>\n<td></td>\n<td>35.4</td>\n<td>35.1</td>\n</tr>\n<tr>\n<td>+ CPT</td>\n<td>✓</td>\n<td></td>\n<td></td>\n<td></td>\n<td>38.9</td>\n<td>38.0</td>\n</tr>\n<tr>\n<td>+ EvaCun</td>\n<td>✓</td>\n<td>✓</td>\n<td></td>\n<td></td>\n<td>39.7</td>\n<td>38.7</td>\n</tr>\n<tr>\n<td>+ tablet context</td>\n<td>✓</td>\n<td>✓</td>\n<td></td>\n<td>✓</td>\n<td>39.8</td>\n<td>39.2</td>\n</tr>\n<tr>\n<td>+ synthetic data</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>40.7</td>\n<td>40.2</td>\n</tr>\n<tr>\n<td>+ 4 fold weight average</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>✓</td>\n<td>40.8</td>\n<td>40.1</td>\n</tr>\n</tbody>\n</table>\n<h1>What Didn't Work</h1>\n<ul>\n<li>ReRanking<ul>\n<li>LGBM reranker — Reranked beam search candidates using features such as beam confidence and reverse model score. Improved CV by ~+0.2 but had no effect on LB.</li>\n<li>Fine-tuned LLM listwise reranker — Reranked beam search candidates with a fine-tuned LLM. No improvement on CV and LB.</li></ul></li>\n<li>Other back-translation strategies — We kept back-translation as a clearly separate training phase from the main fine-tuning stages, and generated synthetic data with beam search using the reverse model. Sampling-based generation for back-translation did not work well. We also tried tagged back-translation, where competition data and back-translated data were jointly trained with explicit tags to distinguish the two sources, but this also failed to improve performance.</li>\n<li>Decoding-time ensemble — We tried decoding-time ensembling with per-step logit averaging. It gave some improvement early on when combining lower-scoring models, but the benefit disappeared as the models got stronger. In particular, ensembles of models around the 37.x level no longer improved results.</li>\n</ul>",
      "rawMarkdown": "# Comment\nThank you to the organizers for hosting this competition. The two key elements of our approach were extracting ~20K transliteration–translation pairs from published scholarly PDFs using a VLM-based pipeline, and generating synthetic data via pseudo-labeling and back-translation.\n\n# Solution summary\n- Model: ByT5 variants (best submission: ByT5-xl)\n- Data: \n  - PDF data: ~20K transliteration–translation pairs extracted from AKT series and other scholarly PDFs with a VLM-based pipeline\n  - EvaCun (ORACC Akkadian Parallel Corpus)\n  - Synthetic data generated via pseudo-labeling and back-translation\n- Training pipeline:\n  - stage1: CPT on transliterations from published_test.csv → FT on EvaCun → FT on PDF data\n  - stage2: Synthetic data generation via pseudo-labeling and back-translation\n  - stage3: FT on synthetic data from EvaCun checkpoint → Final FT on PDF data with tablet context\n- Inference: CTranslate2 with weight-averaged fold models and beam search (no ensemble in test time)\n\n# Data Preparation\n\nInitially, we fine-tuned in two stages — first on [EvaCun (ORACC Akkadian Parallel Corpus)](https://zenodo.org/records/17220688), then on PDF-extracted data — so we describe the preparation for each below. \n\n## PDF Extraction Pipeline\n\nCompetition `train.csv` has only 1,561 Akkadian–English pairs. We built ~20,251 pairs by extracting transliteration–translation pairs directly from the AKT series and other published scholarly PDFs (20 volumes total) using a VLM-based 4-phase pipeline: Detect excavation numbers → Link references → Extract pairs → Translate to English. `train.csv` was only used as reference within the pipeline (linking and few-shot).\n\n| Volume | Language | Pairs |\n| --- | --- | --- |\n| AKT 1–4 | Turkish / German | 1,924 |\n| AKT 5, 6A–6E, 8, 12 | English | 9,202 |\n| AKT 7A–7B, 9A, 10, 11A–11B | Turkish | 6,517 |\n| Larsen 2002 (PIHANS 96) | English | 1,199 |\n| ICK 4 (1998) | German | 1,415 |\n| **Total** |  | **~20,251** |\n\n### Phase 1: Detect excavation numbers\n\nPDF pages are rendered to PNG images and sent to Qwen 3.5 Plus (397B) to detect excavation numbers (tablet headings like `\"Kt. 86/k 39\"`, `\"I 427\"`) and their page numbers.\n\n### Phase 2: Link references\n\nDetected excavation numbers are matched against the `published_texts.csv` to retrieve known transliterations and against `train.csv` to retrieve known English translations. Both are provided to the VLM as reference in Phase 3. Matching handles notation variants by trying multiple alias formats (e.g., `\"Kt n/k 594\"` ↔ `\"Kt. n/k 594\"`, museum numbers, pipe-separated aliases).\n\n### Phase 3: Extract pairs\n\nFor each excavation number, the VLM is given the page image(s) where it appears along with the linked references as context, and extracts transliteration line-by-line and translation by the grouping defined in the PDF (e.g., lines 1–3 grouped together, line 4 alone). We chose this granularity because we expected the test data to be segmented at these same group boundaries.\n\nThe PDFs have two distinct layouts, so we prepared separate extraction prompts for each:\n\n- Side-by-side: transliteration and translation appear in parallel columns on the same page (English volumes: AKT 5, 6, 8, 12, Larsen)\n- Sequential: transliteration block followed by translation block below (Turkish/German volumes: AKT 1–4, 7, 9–11, ICK 4)\n\n### Example: AKT 12, Kt. 86/k 39 (side-by-side)\n\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2F491e90cf7b492d7e0676a56ab0ca084f%2Fakt12_page043_crop.png?generation=1774512354416002&alt=media\" width=\"50%\">\n\n```json\n{\n  \"transliteration_lines\": {\n    \"1\": \"[ ]-ši-nim\",\n    \"2\": \"Šu-Sú-in : lu i-na GÁ[N]\",\n    \"3\": \"lu i-na a-lim\",\n    \"5\": \"i-ta-áb-ši : ša A-[mur]-A-š[ùr]\",\n    \"6\": \"E-mu-a ù-lá ṭá-hu\",\n    \"7\": \"A-mur-A-šùr ù E-mu-a\",\n    \"8\": \"zi-zu-ú-[ma] : a-hu-um\",\n    \"9\": \"a-na a-hi-im a-n[a KÙ.B]\",\n    \"10\": \"ù-lá i-tù-[ar]\",\n     \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1\": \"If silver of\",\n    \"2-4\": \"Šū-Suen proves to be either in the countryside (Anatolia) or in the City, is belongs to Amur-Aššur,\",\n    \"5-10\": \"Emua is not entitled to it. Amur-Aššur and Emua have divided (the inheritance) and they will not raise claims against each other for silver.\"\n    \"...\": \"...\"\n  }\n}\n```\n\n### Example: AKT 9A, Kt. c/k 1249 (sequential)\n\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2Fba4676b27f78bf466909751a68cd7a72%2Fakt9a_page157_crop.png?generation=1774512324980388&alt=media\" width=\"50%\">\n\n```json\n{\n  \"transliteration_lines\": {\n    \"1\": \"15 GÍN KÙ.BABBAR\",\n    \"2\": \"i-ṣé-er\",\n    \"3\": \"Ḫa-šu-i-li\",\n    \"4\": \"Šu-Ištar i-šu a-na\",\n    \"5\": \"ku-bu-ur ú-ṭí-tim\",\n    \"6\": \"i-ša-qal\",\n    \"7\": \"šu-ma lá iš-qúl\",\n    \"8\": \"2/3 GÍN 15 ŠE.TA\",\n    \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1-4\": \"Šu-Ištar'ın, Ḫaššuli'nin üzerinde 15 šeḳel gümüšü vardır.\",\n    \"4-6\": \"(Ḫaššuli) hububatın olgunlaşmasında ödeyecek.\",\n    \"...\": \"...\"\n  }\n}\n```\n\nIn practice, tablet records often span multiple pages. To handle this, the target page and subsequent context pages are stitched into a single image before sending to the VLM. Some source PDFs had misordered pages, so we manually fixed the page order before running the extraction pipeline. For example, in AKT 1 we observed page sequences such as 73, 76, 77, 78, 79, 78, 79, 74, suggesting page ordering and duplication issues in the source PDF.\n\nAfter extraction, a validation step checks for inconsistencies (e.g., transliteration present but translation missing, uncovered line ranges). Failed records are re-sent to the VLM with a description of what went wrong, prompting it to correct the extraction.\n\n### Phase 4: Translate to English\n\nTurkish/German volumes are translated to English using Gemini 3.1 Flash Lite with similar few-shot examples retrieved by Levenshtein distance on transliterations from `train.csv`.\n\n### Postprocessing\n- Quality filter: remove pairs with translation/transliteration length ratio outside [0.3, 4.0]\n\n### API Cost\n- Approximately 15$ for the entire extraction process, OpenRouter is used as the API gateway.\n\n## EvaCun(ORACC Akkadian Parallel Corpus) Preparation\n\n### Used Files\n- 45k transliteration-translation pairs from ranscription_train.txt, transcription_val.txt, english_train.txt, english_val.txt.\n\n### Preprocessing\n\nIn addition to the standard preprocessing used for the competition dataset, we applied an extra normalization step to the **transliteration side** of EvaCun: immediately repeated consecutive words were collapsed into a single token. This was motivated by the fact that the transliterations occasionally contain local repetition artifacts that are unlikely to be meaningful for translation and can introduce unnecessary noise during training.\n\nFor example, the transliteration\n\n`ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te É-hi-il-la-na-te ma-a im-ma-te im-ma-te ú-šá-ra-qu`\n\nwas normalized to\n\n`ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te ma-a im-ma-te ú-šá-ra-qu`\n\n# Training Pipeline\n\nTraining on ByT5 variants (best submission used byt5-xl):\n\n**Stage 1: Build base models**\n\n1. Continued pre-training — T5 span corruption on transliterations from `published_texts.csv`.\n2. Fine-tuning on EvaCun. \n3. Fine-tuning on PDF data.\n\nA reverse model (English → Akkadian) is also trained with the same pipeline by swapping transliteration and translation.\n\n**Stage 2: Synthetic Data Generation**\n\nUsing the reverse model from Stage 1, we generate additional training pairs:\n\n- Pseudo-label: translate `published_texts.csv` transliterations to English with the forward model using beam search.\n- Back-translation: first generate 10,000 translation-like English sentences with Qwen3.5-27B, using translations from both `train.csv` and the PDF-extracted data as few-shot examples, and then back-translate them into Akkadian with the reverse model.\n\nThe generated dataset is [here](https://www.kaggle.com/datasets/yukiokumura1/deep-past-challenge-back-translated-synthetic-data)\n\nWe additionally tested scaling this back-translation data to 100,000 examples. Relative to training with 10,000 examples, this resulted in a -0.1 change on the public leaderboard but a +0.3 improvement on the private leaderboard.\n\n**Stage 3: Final training**\n\nStarting from the Stage 1 EvaCun checkpoint:\n\n1. Fine-tuning on Stage 2 data.\n2. Fine-tuning on PDF data with context — previous lines of the same tablet are prepended to the input(max 2 previous lines):\n\nprompt format:\n```\n[context] <prev_line_1> [sep] <prev_line_2> [/context] <current_input>\n```\n\n# Inference\n\nWe convert trained models to CTranslate2 format, achieving ~5x speedup over HuggingFace inference. CTranslate2 also enables ByT5-xxl inference on Kaggle's dual T4 GPUs via `int8_float32` quantization and tensor parallelism (we patched CTranslate2's source to fix a bug in its TP implementation). Note that `int8_float32` quantization degrades LB score by ~-0.1. xxl was not used in our best submission due to insufficient training time (We changed the training dataset in the last day of the competition).\n\nWe average weights from multiple CV fold models into a single model before inference. At inference time, we use `line_start` from `test.csv` to prepend context from previous lines of the same tablet, matching the training format. Decoding is done with beam search.\n\n# CV Strategy\n\nWe used 25% of `train.csv` as a hold-out set. The split was stratified by the transliteration/translation length ratio to preserve the distribution of examples with different source–target length characteristics.\n\nIn practice, validation loss (token-level cross entropy loss) was reasonably well correlated with LB score, so we treated it as the main offline metric throughout development. As a result, we prioritized changes that reliably improved validation loss, and used the hold-out set for checkpoint selection and ablation comparison.\n\n# Ablation Study\n\nAll models in the ablation study are ByT5-xl trained with the same parameters (e.g., learning rate, batch size, number of steps)\n\n| Model | CPT | EvaCun | Synthetic data | Tablet context | Private LB | Public LB |\n|---|:---:|:---:|:---:|:---:|---:|---:|\n| PDF data only | | | | | 35.4 | 35.1 |\n| + CPT | ✓ | | | | 38.9 | 38.0 |\n| + EvaCun | ✓ | ✓ | | | 39.7 | 38.7 |\n| + tablet context | ✓ | ✓ | | ✓ | 39.8 | 39.2 |\n| + synthetic data | ✓ | ✓ | ✓ | ✓ | 40.7 | 40.2 |\n| + 4 fold weight average | ✓ | ✓ | ✓ | ✓ | 40.8 | 40.1 |\n\n# What Didn't Work\n\n- ReRanking\n  - LGBM reranker — Reranked beam search candidates using features such as beam confidence and reverse model score. Improved CV by ~+0.2 but had no effect on LB.\n  - Fine-tuned LLM listwise reranker — Reranked beam search candidates with a fine-tuned LLM. No improvement on CV and LB.\n- Other back-translation strategies — We kept back-translation as a clearly separate training phase from the main fine-tuning stages, and generated synthetic data with beam search using the reverse model. Sampling-based generation for back-translation did not work well. We also tried tagged back-translation, where competition data and back-translated data were jointly trained with explicit tags to distinguish the two sources, but this also failed to improve performance.\n- Decoding-time ensemble — We tried decoding-time ensembling with per-step logit averaging. It gave some improvement early on when combining lower-scoring models, but the benefit disappeared as the models got stronger. In particular, ensembles of models around the 37.x level no longer improved results.",
      "votes": null
    },
    {
      "id": "3429026",
      "postDate": "03/26/2026 08:43:22",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/ebinan92\" target=\"_blank\">@ebinan92</a> and <a href=\"https://www.kaggle.com/yukiokumura1\" target=\"_blank\">@yukiokumura1</a> on becoming Kaggle Competitions GMs! </p>",
      "rawMarkdown": "Congratulations @ebinan92 and @yukiokumura1 on becoming Kaggle Competitions GMs!",
      "votes": null
    },
    {
      "id": "3440077",
      "postDate": "04/11/2026 21:14:59",
      "content": "<p>Hey, the solution looks great! \nwould you mind sharing working inference code? I'm not managing to run the inference code right now, the one here, because of private dataset dependencies -</p>\n<p><a href=\"https://www.kaggle.com/code/ebinan92/5th-solution/notebook?scriptVersionId=305950408\" target=\"_blank\">https://www.kaggle.com/code/ebinan92/5th-solution/notebook?scriptVersionId=305950408</a></p>\n<p>Thanks and congrats!</p>",
      "rawMarkdown": "Hey, the solution looks great! \nwould you mind sharing working inference code? I'm not managing to run the inference code right now, the one here, because of private dataset dependencies -\n\nhttps://www.kaggle.com/code/ebinan92/5th-solution/notebook?scriptVersionId=305950408\n\nThanks and congrats!",
      "votes": null
    },
    {
      "id": "3440836",
      "postDate": "04/13/2026 05:06:30",
      "content": "<p><a href=\"https://www.kaggle.com/shaharspencer\" target=\"_blank\">@shaharspencer</a> \nHey, thanks for reaching out! I believe the issue has been resolved in the latest version, so could you check it out? </p>",
      "rawMarkdown": "shaharspencer \nHey, thanks for reaching out! I believe the issue has been resolved in the latest version, so could you check it out?",
      "votes": null
    },
    {
      "id": "3457905",
      "postDate": "05/14/2026 15:34:02",
      "content": "<p>Hey Ebi, \nSorry for the late reply, I missed your reply. \nThank you so much, it does work now. The solution works really well, well done 🥳 and thanks again</p>",
      "rawMarkdown": "Hey Ebi, \nSorry for the late reply, I missed your reply. \nThank you so much, it does work now. The solution works really well, well done 🥳 and thanks again",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 3429026,
      "author_name": "samson8",
      "author_url": "",
      "post_date": "03/26/2026 08:43:22",
      "content": "<p>Congratulations <a href=\"https://www.kaggle.com/ebinan92\" target=\"_blank\">@ebinan92</a> and <a href=\"https://www.kaggle.com/yukiokumura1\" target=\"_blank\">@yukiokumura1</a> on becoming Kaggle Competitions GMs! </p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 3440077,
      "author_name": "shaharspencer",
      "author_url": "",
      "post_date": "04/11/2026 21:14:59",
      "content": "<p>Hey, the solution looks great! \nwould you mind sharing working inference code? I'm not managing to run the inference code right now, the one here, because of private dataset dependencies -</p>\n<p><a href=\"https://www.kaggle.com/code/ebinan92/5th-solution/notebook?scriptVersionId=305950408\" target=\"_blank\">https://www.kaggle.com/code/ebinan92/5th-solution/notebook?scriptVersionId=305950408</a></p>\n<p>Thanks and congrats!</p>",
      "votes": null,
      "replies": [
        {
          "id": 3440836,
          "author_name": "ebinan92",
          "author_url": "",
          "post_date": "04/13/2026 05:06:30",
          "content": "<p><a href=\"https://www.kaggle.com/shaharspencer\" target=\"_blank\">@shaharspencer</a> \nHey, thanks for reaching out! I believe the issue has been resolved in the latest version, so could you check it out? </p>",
          "votes": null,
          "replies": [
            {
              "id": 3457905,
              "author_name": "shaharspencer",
              "author_url": "",
              "post_date": "05/14/2026 15:34:02",
              "content": "<p>Hey Ebi, \nSorry for the late reply, I missed your reply. \nThank you so much, it does work now. The solution works really well, well done 🥳 and thanks again</p>",
              "votes": null,
              "replies": []
            }
          ]
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "3429009": "# Comment\nThank you to the organizers for hosting this competition. The two key elements of our approach were extracting ~20K transliteration–translation pairs from published scholarly PDFs using a VLM-based pipeline, and generating synthetic data via pseudo-labeling and back-translation.\n\n# Solution summary\n- Model: ByT5 variants (best submission: ByT5-xl)\n- Data: \n  - PDF data: ~20K transliteration–translation pairs extracted from AKT series and other scholarly PDFs with a VLM-based pipeline\n  - EvaCun (ORACC Akkadian Parallel Corpus)\n  - Synthetic data generated via pseudo-labeling and back-translation\n- Training pipeline:\n  - stage1: CPT on transliterations from published_test.csv → FT on EvaCun → FT on PDF data\n  - stage2: Synthetic data generation via pseudo-labeling and back-translation\n  - stage3: FT on synthetic data from EvaCun checkpoint → Final FT on PDF data with tablet context\n- Inference: CTranslate2 with weight-averaged fold models and beam search (no ensemble in test time)\n\n# Data Preparation\n\nInitially, we fine-tuned in two stages — first on [EvaCun (ORACC Akkadian Parallel Corpus)](https://zenodo.org/records/17220688), then on PDF-extracted data — so we describe the preparation for each below. \n\n## PDF Extraction Pipeline\n\nCompetition `train.csv` has only 1,561 Akkadian–English pairs. We built ~20,251 pairs by extracting transliteration–translation pairs directly from the AKT series and other published scholarly PDFs (20 volumes total) using a VLM-based 4-phase pipeline: Detect excavation numbers → Link references → Extract pairs → Translate to English. `train.csv` was only used as reference within the pipeline (linking and few-shot).\n\n| Volume | Language | Pairs |\n| --- | --- | --- |\n| AKT 1–4 | Turkish / German | 1,924 |\n| AKT 5, 6A–6E, 8, 12 | English | 9,202 |\n| AKT 7A–7B, 9A, 10, 11A–11B | Turkish | 6,517 |\n| Larsen 2002 (PIHANS 96) | English | 1,199 |\n| ICK 4 (1998) | German | 1,415 |\n| **Total** |  | **~20,251** |\n\n### Phase 1: Detect excavation numbers\n\nPDF pages are rendered to PNG images and sent to Qwen 3.5 Plus (397B) to detect excavation numbers (tablet headings like `\"Kt. 86/k 39\"`, `\"I 427\"`) and their page numbers.\n\n### Phase 2: Link references\n\nDetected excavation numbers are matched against the `published_texts.csv` to retrieve known transliterations and against `train.csv` to retrieve known English translations. Both are provided to the VLM as reference in Phase 3. Matching handles notation variants by trying multiple alias formats (e.g., `\"Kt n/k 594\"` ↔ `\"Kt. n/k 594\"`, museum numbers, pipe-separated aliases).\n\n### Phase 3: Extract pairs\n\nFor each excavation number, the VLM is given the page image(s) where it appears along with the linked references as context, and extracts transliteration line-by-line and translation by the grouping defined in the PDF (e.g., lines 1–3 grouped together, line 4 alone). We chose this granularity because we expected the test data to be segmented at these same group boundaries.\n\nThe PDFs have two distinct layouts, so we prepared separate extraction prompts for each:\n\n- Side-by-side: transliteration and translation appear in parallel columns on the same page (English volumes: AKT 5, 6, 8, 12, Larsen)\n- Sequential: transliteration block followed by translation block below (Turkish/German volumes: AKT 1–4, 7, 9–11, ICK 4)\n\n### Example: AKT 12, Kt. 86/k 39 (side-by-side)\n\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2F491e90cf7b492d7e0676a56ab0ca084f%2Fakt12_page043_crop.png?generation=1774512354416002&alt=media\" width=\"50%\">\n\n```json\n{\n  \"transliteration_lines\": {\n    \"1\": \"[ ]-ši-nim\",\n    \"2\": \"Šu-Sú-in : lu i-na GÁ[N]\",\n    \"3\": \"lu i-na a-lim\",\n    \"5\": \"i-ta-áb-ši : ša A-[mur]-A-š[ùr]\",\n    \"6\": \"E-mu-a ù-lá ṭá-hu\",\n    \"7\": \"A-mur-A-šùr ù E-mu-a\",\n    \"8\": \"zi-zu-ú-[ma] : a-hu-um\",\n    \"9\": \"a-na a-hi-im a-n[a KÙ.B]\",\n    \"10\": \"ù-lá i-tù-[ar]\",\n     \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1\": \"If silver of\",\n    \"2-4\": \"Šū-Suen proves to be either in the countryside (Anatolia) or in the City, is belongs to Amur-Aššur,\",\n    \"5-10\": \"Emua is not entitled to it. Amur-Aššur and Emua have divided (the inheritance) and they will not raise claims against each other for silver.\"\n    \"...\": \"...\"\n  }\n}\n```\n\n### Example: AKT 9A, Kt. c/k 1249 (sequential)\n\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2064220%2Fba4676b27f78bf466909751a68cd7a72%2Fakt9a_page157_crop.png?generation=1774512324980388&alt=media\" width=\"50%\">\n\n```json\n{\n  \"transliteration_lines\": {\n    \"1\": \"15 GÍN KÙ.BABBAR\",\n    \"2\": \"i-ṣé-er\",\n    \"3\": \"Ḫa-šu-i-li\",\n    \"4\": \"Šu-Ištar i-šu a-na\",\n    \"5\": \"ku-bu-ur ú-ṭí-tim\",\n    \"6\": \"i-ša-qal\",\n    \"7\": \"šu-ma lá iš-qúl\",\n    \"8\": \"2/3 GÍN 15 ŠE.TA\",\n    \"...\": \"...\"\n  },\n  \"translation_ranges\": {\n    \"1-4\": \"Šu-Ištar'ın, Ḫaššuli'nin üzerinde 15 šeḳel gümüšü vardır.\",\n    \"4-6\": \"(Ḫaššuli) hububatın olgunlaşmasında ödeyecek.\",\n    \"...\": \"...\"\n  }\n}\n```\n\nIn practice, tablet records often span multiple pages. To handle this, the target page and subsequent context pages are stitched into a single image before sending to the VLM. Some source PDFs had misordered pages, so we manually fixed the page order before running the extraction pipeline. For example, in AKT 1 we observed page sequences such as 73, 76, 77, 78, 79, 78, 79, 74, suggesting page ordering and duplication issues in the source PDF.\n\nAfter extraction, a validation step checks for inconsistencies (e.g., transliteration present but translation missing, uncovered line ranges). Failed records are re-sent to the VLM with a description of what went wrong, prompting it to correct the extraction.\n\n### Phase 4: Translate to English\n\nTurkish/German volumes are translated to English using Gemini 3.1 Flash Lite with similar few-shot examples retrieved by Levenshtein distance on transliterations from `train.csv`.\n\n### Postprocessing\n- Quality filter: remove pairs with translation/transliteration length ratio outside [0.3, 4.0]\n\n### API Cost\n- Approximately 15$ for the entire extraction process, OpenRouter is used as the API gateway.\n\n## EvaCun(ORACC Akkadian Parallel Corpus) Preparation\n\n### Used Files\n- 45k transliteration-translation pairs from ranscription_train.txt, transcription_val.txt, english_train.txt, english_val.txt.\n\n### Preprocessing\n\nIn addition to the standard preprocessing used for the competition dataset, we applied an extra normalization step to the **transliteration side** of EvaCun: immediately repeated consecutive words were collapsed into a single token. This was motivated by the fact that the transliterations occasionally contain local repetition artifacts that are unlikely to be meaningful for translation and can introduce unnecessary noise during training.\n\nFor example, the transliteration\n\n`ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te É-hi-il-la-na-te ma-a im-ma-te im-ma-te ú-šá-ra-qu`\n\nwas normalized to\n\n`ša LUGAL be-lí iš-pur-an-ni ma-a gul-la-a-te ša KÁ ša šap-la tim-me ša É-hi-il-la-na-te ma-a im-ma-te ú-šá-ra-qu`\n\n# Training Pipeline\n\nTraining on ByT5 variants (best submission used byt5-xl):\n\n**Stage 1: Build base models**\n\n1. Continued pre-training — T5 span corruption on transliterations from `published_texts.csv`.\n2. Fine-tuning on EvaCun. \n3. Fine-tuning on PDF data.\n\nA reverse model (English → Akkadian) is also trained with the same pipeline by swapping transliteration and translation.\n\n**Stage 2: Synthetic Data Generation**\n\nUsing the reverse model from Stage 1, we generate additional training pairs:\n\n- Pseudo-label: translate `published_texts.csv` transliterations to English with the forward model using beam search.\n- Back-translation: first generate 10,000 translation-like English sentences with Qwen3.5-27B, using translations from both `train.csv` and the PDF-extracted data as few-shot examples, and then back-translate them into Akkadian with the reverse model.\n\nThe generated dataset is [here](https://www.kaggle.com/datasets/yukiokumura1/deep-past-challenge-back-translated-synthetic-data)\n\nWe additionally tested scaling this back-translation data to 100,000 examples. Relative to training with 10,000 examples, this resulted in a -0.1 change on the public leaderboard but a +0.3 improvement on the private leaderboard.\n\n**Stage 3: Final training**\n\nStarting from the Stage 1 EvaCun checkpoint:\n\n1. Fine-tuning on Stage 2 data.\n2. Fine-tuning on PDF data with context — previous lines of the same tablet are prepended to the input(max 2 previous lines):\n\nprompt format:\n```\n[context] <prev_line_1> [sep] <prev_line_2> [/context] <current_input>\n```\n\n# Inference\n\nWe convert trained models to CTranslate2 format, achieving ~5x speedup over HuggingFace inference. CTranslate2 also enables ByT5-xxl inference on Kaggle's dual T4 GPUs via `int8_float32` quantization and tensor parallelism (we patched CTranslate2's source to fix a bug in its TP implementation). Note that `int8_float32` quantization degrades LB score by ~-0.1. xxl was not used in our best submission due to insufficient training time (We changed the training dataset in the last day of the competition).\n\nWe average weights from multiple CV fold models into a single model before inference. At inference time, we use `line_start` from `test.csv` to prepend context from previous lines of the same tablet, matching the training format. Decoding is done with beam search.\n\n# CV Strategy\n\nWe used 25% of `train.csv` as a hold-out set. The split was stratified by the transliteration/translation length ratio to preserve the distribution of examples with different source–target length characteristics.\n\nIn practice, validation loss (token-level cross entropy loss) was reasonably well correlated with LB score, so we treated it as the main offline metric throughout development. As a result, we prioritized changes that reliably improved validation loss, and used the hold-out set for checkpoint selection and ablation comparison.\n\n# Ablation Study\n\nAll models in the ablation study are ByT5-xl trained with the same parameters (e.g., learning rate, batch size, number of steps)\n\n| Model | CPT | EvaCun | Synthetic data | Tablet context | Private LB | Public LB |\n|---|:---:|:---:|:---:|:---:|---:|---:|\n| PDF data only | | | | | 35.4 | 35.1 |\n| + CPT | ✓ | | | | 38.9 | 38.0 |\n| + EvaCun | ✓ | ✓ | | | 39.7 | 38.7 |\n| + tablet context | ✓ | ✓ | | ✓ | 39.8 | 39.2 |\n| + synthetic data | ✓ | ✓ | ✓ | ✓ | 40.7 | 40.2 |\n| + 4 fold weight average | ✓ | ✓ | ✓ | ✓ | 40.8 | 40.1 |\n\n# What Didn't Work\n\n- ReRanking\n  - LGBM reranker — Reranked beam search candidates using features such as beam confidence and reverse model score. Improved CV by ~+0.2 but had no effect on LB.\n  - Fine-tuned LLM listwise reranker — Reranked beam search candidates with a fine-tuned LLM. No improvement on CV and LB.\n- Other back-translation strategies — We kept back-translation as a clearly separate training phase from the main fine-tuning stages, and generated synthetic data with beam search using the reverse model. Sampling-based generation for back-translation did not work well. We also tried tagged back-translation, where competition data and back-translated data were jointly trained with explicit tags to distinguish the two sources, but this also failed to improve performance.\n- Decoding-time ensemble — We tried decoding-time ensembling with per-step logit averaging. It gave some improvement early on when combining lower-scoring models, but the benefit disappeared as the models got stronger. In particular, ensembles of models around the 37.x level no longer improved results.",
    "3429026": "Congratulations @ebinan92 and @yukiokumura1 on becoming Kaggle Competitions GMs!",
    "3440077": "Hey, the solution looks great! \nwould you mind sharing working inference code? I'm not managing to run the inference code right now, the one here, because of private dataset dependencies -\n\nhttps://www.kaggle.com/code/ebinan92/5th-solution/notebook?scriptVersionId=305950408\n\nThanks and congrats!",
    "3440836": "shaharspencer \nHey, thanks for reaching out! I believe the issue has been resolved in the latest version, so could you check it out?",
    "3457905": "Hey Ebi, \nSorry for the late reply, I missed your reply. \nThank you so much, it does work now. The solution works really well, well done 🥳 and thanks again"
  },
  "source": "existing_discussion",
  "complete": true,
  "competition_id": 121150,
  "competition_slug": "deep-past-initiative-machine-translation",
  "team_id": 15046207,
  "solution_url": "/competitions/deep-past-initiative-machine-translation/writeups/5th-solution"
}