{
  "id": 684910,
  "title": "[32nd] ByT5-base Fine-tuning | No LLMs, No Synthetic Data, No Ensembles",
  "url": "/competitions/deep-past-initiative-machine-translation/writeups/32nd-byt5-base-fine-tuning-no-llms-no-synthet",
  "author_name": "",
  "post_date": "2026-03-26T12:56:38.260Z",
  "votes": 11,
  "comment_count": 5,
  "views": 0,
  "content": "<h1>[32nd] ByT5-base Fine-tuning | No LLMs, No Synthetic Data, No Ensembles</h1>\n<p><strong>Rank:</strong> 32 / 2674 teams | <strong>Public:</strong> 37.6 | <strong>Private:</strong> 38.1</p>\n<hr>\n<h2>Overview</h2>\n<p>No Gemini, no synthetic data, no large-scale PDF extraction. Our strategy was simpler: start from a strong base model, train carefully, iterate continuously, and use the leaderboard as the real validation signal.</p>\n<p>This writeup is for participants who want to understand what is achievable with only public data and a disciplined iterative process.</p>\n<hr>\n<h2>Two-Stage Training</h2>\n<p><strong>Stage 1: Akkademia Pre-training</strong></p>\n<p>ByT5-base was first fine-tuned on ~69k sentence pairs from the Akkademia corpus. Akkademia is not Old Assyrian — the relationship is similar to Portuguese vs Spanish. The goal was not to learn the competition domain directly, but to give the model familiarity with Akkadian grammar and morphology before seeing competition data. Without this stage, the model treats Old Assyrian as completely foreign.</p>\n<p><strong>Stage 2: Iterative Fine-tuning</strong></p>\n<p>Due to Kaggle runtime limits (~12h/session), we adopted a progressive fine-tuning loop in cycles of 3 epochs:</p>\n<ol>\n<li>Train 3 epochs from best checkpoint</li>\n<li>Save → create Kaggle dataset</li>\n<li>Run inference → submit</li>\n<li>Analyze score</li>\n<li>Continue or adjust</li>\n</ol>\n<p>We repeated this loop over nearly 3 months, reaching <strong>21 total epochs</strong>. Each iteration taught us which normalization rules helped, which hurt, and what decoding parameters worked best. The leaderboard became our continuous evaluation framework.</p>\n<hr>\n<h2>Data</h2>\n<p>Public data only:</p>\n<table>\n<thead>\n<tr>\n<th>Source</th>\n<th>Rows</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>train.csv</code></td>\n<td>1,561 documents</td>\n</tr>\n<tr>\n<td><code>published_texts.csv</code></td>\n<td>~199 recovered transliterations</td>\n</tr>\n<tr>\n<td><code>Sentences_Oare_FirstWord_LinNum.csv</code></td>\n<td>841 gold sentence pairs</td>\n</tr>\n<tr>\n<td><code>akkademia_train_CLEAN.csv</code></td>\n<td>~69k pre-training pairs</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<p>After splitting long documents: <strong>~2,800 sentence-level training samples</strong></p>\n<p>The <code>Sentences_Oare_FirstWord_LinNum.csv</code> file was a critical late discovery ; it contains gold sentence boundaries using <code>first_word_spelling</code> as anchor, which closely matches how the hidden test set was constructed.</p>\n<hr>\n<h2>Key Findings from Leaderboard Submissions</h2>\n<ul>\n<li><code>early_stopping=True</code> causes repetition artifacts → hurts score</li>\n<li><code>length_penalty=0.91</code> consistently outperforms lower values</li>\n<li>Complex postprocessing provides no benefit; the model already internalized normalizations during training</li>\n<li>Splitting documents to sentence level improves alignment with test distribution</li>\n</ul>\n<hr>\n<h2>Normalization</h2>\n<p>Applied to training data following host recommendations:</p>\n<ul>\n<li><code>ḫ/Ḫ → h/H</code> (confirmed absent from test set)</li>\n<li>Decimals → unicode fractions (<code>0.3333 → ⅓</code>)</li>\n<li><code>&lt;gap&gt;&lt;gap&gt;</code> / <code>&lt;big_gap&gt;</code> → single <code>&lt;gap&gt;</code></li>\n<li>Subscripts → integers (<code>₄ → 4</code>)</li>\n<li>Removed <code>fem.</code>, <code>pl.</code>, <code>(?)</code> annotations</li>\n<li><code>PN → &lt;gap&gt;</code></li>\n<li>Roman months → integers</li>\n</ul>\n<hr>\n<h2>Model &amp; Inference</h2>\n<p><strong>Model:</strong> <a href=\"https://www.kaggle.com/datasets/assiaazzouz/akk-v24-ep21\" target=\"_blank\">akk-v24-ep21 on Kaggle</a></p>\n<ul>\n<li>Base: <code>google/byt5-base</code></li>\n<li>Total epochs: 21</li>\n<li><code>num_beams=6</code>, <code>length_penalty=0.91</code>, <code>early_stopping=False</code></li>\n<li>No postprocessing</li>\n</ul>\n<h3>Inference : Less is More</h3>\n<p>Our final inference is intentionally minimal:</p>\n<pre><code>out = model.generate(\n    **enc,\n    max_new_tokens=300,\n    num_beams=6,\n    length_penalty=0.91,\n    # NO early_stopping\n)\npredictions = tokenizer.batch_decode(out, skip_special_tokens=True)\n# NO postprocessing applied\n</code></pre>\n<p><strong>No preprocessing of input. No postprocessing of output.</strong></p>\n<p>This was a late but important discovery. We spent months building a careful postprocessing pipeline; normalizing fractions, removing annotations, fixing gaps. Every rule was based on host-confirmed guidelines.</p>\n<p>Yet when we tested simple inference against our full pipeline, simple inference scored the same or higher.</p>\n<p><strong>Why?</strong> The model was trained on already-cleaned data. It learned to output correct fractions, correct quotes, correct gaps directly. Our postprocessing was correcting things that were already correct; and occasionally breaking things that were fine.</p>\n<p>The lesson: <strong>preprocess training data carefully, postprocess model output as little as possible.</strong> Interestingly, the 1st place team said exactly the same thing in their writeup.</p>\n<hr>\n<h2>What Limited Us</h2>\n<ul>\n<li>No ByT5-Large/XL (top teams used XL on 8×H20)</li>\n<li>No PDF extraction pipeline (top teams built 30k+ pairs with Gemini)</li>\n<li>No pseudo-labeling or synthetic data</li>\n<li>Kaggle runtime forced 3-epoch increments</li>\n</ul>\n<hr>\n<h2>Final Thoughts</h2>\n<p>The 1st place writeup says it best: <strong>\"Data quality dictates everything.\"</strong> Top teams had 30k+ clean sentence pairs. We had ~2,800. Despite this gap, the results show that careful iteration and data alignment can compensate for limited resources.</p>\n<p><strong>37.6 public → 38.1 private. Public data only. ByT5-base.</strong></p>\n<hr>",
  "messages": [
    {
      "id": "3429158",
      "postDate": "03/26/2026 12:56:16",
      "content": "<h1>[32nd] ByT5-base Fine-tuning | No LLMs, No Synthetic Data, No Ensembles</h1>\n<p><strong>Rank:</strong> 32 / 2674 teams | <strong>Public:</strong> 37.6 | <strong>Private:</strong> 38.1</p>\n<hr>\n<h2>Overview</h2>\n<p>No Gemini, no synthetic data, no large-scale PDF extraction. Our strategy was simpler: start from a strong base model, train carefully, iterate continuously, and use the leaderboard as the real validation signal.</p>\n<p>This writeup is for participants who want to understand what is achievable with only public data and a disciplined iterative process.</p>\n<hr>\n<h2>Two-Stage Training</h2>\n<p><strong>Stage 1: Akkademia Pre-training</strong></p>\n<p>ByT5-base was first fine-tuned on ~69k sentence pairs from the Akkademia corpus. Akkademia is not Old Assyrian — the relationship is similar to Portuguese vs Spanish. The goal was not to learn the competition domain directly, but to give the model familiarity with Akkadian grammar and morphology before seeing competition data. Without this stage, the model treats Old Assyrian as completely foreign.</p>\n<p><strong>Stage 2: Iterative Fine-tuning</strong></p>\n<p>Due to Kaggle runtime limits (~12h/session), we adopted a progressive fine-tuning loop in cycles of 3 epochs:</p>\n<ol>\n<li>Train 3 epochs from best checkpoint</li>\n<li>Save → create Kaggle dataset</li>\n<li>Run inference → submit</li>\n<li>Analyze score</li>\n<li>Continue or adjust</li>\n</ol>\n<p>We repeated this loop over nearly 3 months, reaching <strong>21 total epochs</strong>. Each iteration taught us which normalization rules helped, which hurt, and what decoding parameters worked best. The leaderboard became our continuous evaluation framework.</p>\n<hr>\n<h2>Data</h2>\n<p>Public data only:</p>\n<table>\n<thead>\n<tr>\n<th>Source</th>\n<th>Rows</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>train.csv</code></td>\n<td>1,561 documents</td>\n</tr>\n<tr>\n<td><code>published_texts.csv</code></td>\n<td>~199 recovered transliterations</td>\n</tr>\n<tr>\n<td><code>Sentences_Oare_FirstWord_LinNum.csv</code></td>\n<td>841 gold sentence pairs</td>\n</tr>\n<tr>\n<td><code>akkademia_train_CLEAN.csv</code></td>\n<td>~69k pre-training pairs</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<p>After splitting long documents: <strong>~2,800 sentence-level training samples</strong></p>\n<p>The <code>Sentences_Oare_FirstWord_LinNum.csv</code> file was a critical late discovery ; it contains gold sentence boundaries using <code>first_word_spelling</code> as anchor, which closely matches how the hidden test set was constructed.</p>\n<hr>\n<h2>Key Findings from Leaderboard Submissions</h2>\n<ul>\n<li><code>early_stopping=True</code> causes repetition artifacts → hurts score</li>\n<li><code>length_penalty=0.91</code> consistently outperforms lower values</li>\n<li>Complex postprocessing provides no benefit; the model already internalized normalizations during training</li>\n<li>Splitting documents to sentence level improves alignment with test distribution</li>\n</ul>\n<hr>\n<h2>Normalization</h2>\n<p>Applied to training data following host recommendations:</p>\n<ul>\n<li><code>ḫ/Ḫ → h/H</code> (confirmed absent from test set)</li>\n<li>Decimals → unicode fractions (<code>0.3333 → ⅓</code>)</li>\n<li><code>&lt;gap&gt;&lt;gap&gt;</code> / <code>&lt;big_gap&gt;</code> → single <code>&lt;gap&gt;</code></li>\n<li>Subscripts → integers (<code>₄ → 4</code>)</li>\n<li>Removed <code>fem.</code>, <code>pl.</code>, <code>(?)</code> annotations</li>\n<li><code>PN → &lt;gap&gt;</code></li>\n<li>Roman months → integers</li>\n</ul>\n<hr>\n<h2>Model &amp; Inference</h2>\n<p><strong>Model:</strong> <a href=\"https://www.kaggle.com/datasets/assiaazzouz/akk-v24-ep21\" target=\"_blank\">akk-v24-ep21 on Kaggle</a></p>\n<ul>\n<li>Base: <code>google/byt5-base</code></li>\n<li>Total epochs: 21</li>\n<li><code>num_beams=6</code>, <code>length_penalty=0.91</code>, <code>early_stopping=False</code></li>\n<li>No postprocessing</li>\n</ul>\n<h3>Inference : Less is More</h3>\n<p>Our final inference is intentionally minimal:</p>\n<pre><code>out = model.generate(\n    **enc,\n    max_new_tokens=300,\n    num_beams=6,\n    length_penalty=0.91,\n    # NO early_stopping\n)\npredictions = tokenizer.batch_decode(out, skip_special_tokens=True)\n# NO postprocessing applied\n</code></pre>\n<p><strong>No preprocessing of input. No postprocessing of output.</strong></p>\n<p>This was a late but important discovery. We spent months building a careful postprocessing pipeline; normalizing fractions, removing annotations, fixing gaps. Every rule was based on host-confirmed guidelines.</p>\n<p>Yet when we tested simple inference against our full pipeline, simple inference scored the same or higher.</p>\n<p><strong>Why?</strong> The model was trained on already-cleaned data. It learned to output correct fractions, correct quotes, correct gaps directly. Our postprocessing was correcting things that were already correct; and occasionally breaking things that were fine.</p>\n<p>The lesson: <strong>preprocess training data carefully, postprocess model output as little as possible.</strong> Interestingly, the 1st place team said exactly the same thing in their writeup.</p>\n<hr>\n<h2>What Limited Us</h2>\n<ul>\n<li>No ByT5-Large/XL (top teams used XL on 8×H20)</li>\n<li>No PDF extraction pipeline (top teams built 30k+ pairs with Gemini)</li>\n<li>No pseudo-labeling or synthetic data</li>\n<li>Kaggle runtime forced 3-epoch increments</li>\n</ul>\n<hr>\n<h2>Final Thoughts</h2>\n<p>The 1st place writeup says it best: <strong>\"Data quality dictates everything.\"</strong> Top teams had 30k+ clean sentence pairs. We had ~2,800. Despite this gap, the results show that careful iteration and data alignment can compensate for limited resources.</p>\n<p><strong>37.6 public → 38.1 private. Public data only. ByT5-base.</strong></p>\n<hr>",
      "rawMarkdown": "# [32nd] ByT5-base Fine-tuning | No LLMs, No Synthetic Data, No Ensembles\n\n**Rank:** 32 / 2674 teams | **Public:** 37.6 | **Private:** 38.1\n\n---\n\n## Overview\n\nNo Gemini, no synthetic data, no large-scale PDF extraction. Our strategy was simpler: start from a strong base model, train carefully, iterate continuously, and use the leaderboard as the real validation signal.\n\nThis writeup is for participants who want to understand what is achievable with only public data and a disciplined iterative process.\n\n---\n\n## Two-Stage Training\n\n**Stage 1: Akkademia Pre-training**\n\nByT5-base was first fine-tuned on ~69k sentence pairs from the Akkademia corpus. Akkademia is not Old Assyrian — the relationship is similar to Portuguese vs Spanish. The goal was not to learn the competition domain directly, but to give the model familiarity with Akkadian grammar and morphology before seeing competition data. Without this stage, the model treats Old Assyrian as completely foreign.\n\n**Stage 2: Iterative Fine-tuning**\n\nDue to Kaggle runtime limits (~12h/session), we adopted a progressive fine-tuning loop in cycles of 3 epochs:\n\n1. Train 3 epochs from best checkpoint\n2. Save → create Kaggle dataset\n3. Run inference → submit\n4. Analyze score\n5. Continue or adjust\n\nWe repeated this loop over nearly 3 months, reaching **21 total epochs**. Each iteration taught us which normalization rules helped, which hurt, and what decoding parameters worked best. The leaderboard became our continuous evaluation framework.\n\n---\n\n## Data\n\nPublic data only:\n\n| Source | Rows |\n|---|---|\n| `train.csv` | 1,561 documents |\n| `published_texts.csv` | ~199 recovered transliterations |\n| `Sentences_Oare_FirstWord_LinNum.csv` | 841 gold sentence pairs |\n| `akkademia_train_CLEAN.csv` | ~69k pre-training pairs |\n\n---\nAfter splitting long documents: **~2,800 sentence-level training samples**\n\nThe `Sentences_Oare_FirstWord_LinNum.csv` file was a critical late discovery ; it contains gold sentence boundaries using `first_word_spelling` as anchor, which closely matches how the hidden test set was constructed.\n\n---\n\n## Key Findings from Leaderboard Submissions\n\n- `early_stopping=True` causes repetition artifacts → hurts score\n- `length_penalty=0.91` consistently outperforms lower values\n- Complex postprocessing provides no benefit; the model already internalized normalizations during training\n- Splitting documents to sentence level improves alignment with test distribution\n\n---\n\n## Normalization\n\nApplied to training data following host recommendations:\n\n- `ḫ/Ḫ → h/H` (confirmed absent from test set)\n- Decimals → unicode fractions (`0.3333 → ⅓`)\n- `<gap><gap>` / `<big_gap>` → single `<gap>`\n- Subscripts → integers (`₄ → 4`)\n- Removed `fem.`, `pl.`, `(?)` annotations\n- `PN → <gap>`\n- Roman months → integers\n\n---\n\n## Model & Inference\n\n**Model:** [akk-v24-ep21 on Kaggle](https://www.kaggle.com/datasets/assiaazzouz/akk-v24-ep21)\n\n- Base: `google/byt5-base`\n- Total epochs: 21\n- `num_beams=6`, `length_penalty=0.91`, `early_stopping=False`\n- No postprocessing\n\n### Inference : Less is More\n\nOur final inference is intentionally minimal:\n\n```python\nout = model.generate(\n    **enc,\n    max_new_tokens=300,\n    num_beams=6,\n    length_penalty=0.91,\n    # NO early_stopping\n)\npredictions = tokenizer.batch_decode(out, skip_special_tokens=True)\n# NO postprocessing applied\n```\n\n**No preprocessing of input. No postprocessing of output.**\n\nThis was a late but important discovery. We spent months building a careful postprocessing pipeline; normalizing fractions, removing annotations, fixing gaps. Every rule was based on host-confirmed guidelines.\n\nYet when we tested simple inference against our full pipeline, simple inference scored the same or higher.\n\n**Why?** The model was trained on already-cleaned data. It learned to output correct fractions, correct quotes, correct gaps directly. Our postprocessing was correcting things that were already correct; and occasionally breaking things that were fine.\n\nThe lesson: **preprocess training data carefully, postprocess model output as little as possible.** Interestingly, the 1st place team said exactly the same thing in their writeup.\n\n\n---\n\n## What Limited Us\n\n- No ByT5-Large/XL (top teams used XL on 8×H20)\n- No PDF extraction pipeline (top teams built 30k+ pairs with Gemini)\n- No pseudo-labeling or synthetic data\n- Kaggle runtime forced 3-epoch increments\n\n---\n\n## Final Thoughts\n\nThe 1st place writeup says it best: **\"Data quality dictates everything.\"** Top teams had 30k+ clean sentence pairs. We had ~2,800. Despite this gap, the results show that careful iteration and data alignment can compensate for limited resources.\n\n**37.6 public → 38.1 private. Public data only. ByT5-base.**\n\n---",
      "votes": null
    },
    {
      "id": "3429161",
      "postDate": "03/26/2026 13:03:55",
      "content": "<p>Fantastic work team! 👏 Your disciplined iterative approach and careful data preprocessing clearly paid off, especially given the limited resources. I’m impressed by how you leveraged public data effectively and turned each leaderboard submission into a learning opportunity. This writeup is a great example of how strategy and consistency can sometimes outweigh sheer scale. Excited to see how we can apply these insights to our next challenge!</p>",
      "rawMarkdown": "Fantastic work team! 👏 Your disciplined iterative approach and careful data preprocessing clearly paid off, especially given the limited resources. I’m impressed by how you leveraged public data effectively and turned each leaderboard submission into a learning opportunity. This writeup is a great example of how strategy and consistency can sometimes outweigh sheer scale. Excited to see how we can apply these insights to our next challenge!",
      "votes": null
    },
    {
      "id": "3429255",
      "postDate": "03/26/2026 14:23:43",
      "content": "<p>Fantastic work.</p>",
      "rawMarkdown": "Fantastic work.",
      "votes": null
    },
    {
      "id": "3429286",
      "postDate": "03/26/2026 15:21:37",
      "content": "<p>Happy with our result and the journey! This competition pushed us to explore new ideas and improve our approach.</p>",
      "rawMarkdown": "Happy with our result and the journey! This competition pushed us to explore new ideas and improve our approach.",
      "votes": null
    },
    {
      "id": "3443570",
      "postDate": "04/16/2026 17:54:36",
      "content": "<p>This solution is fascinating - I am very impressed by your ability to get such a high score with such a low data input and lower computational cost. </p>",
      "rawMarkdown": "This solution is fascinating - I am very impressed by your ability to get such a high score with such a low data input and lower computational cost.",
      "votes": null
    },
    {
      "id": "3452351",
      "postDate": "05/03/2026 06:15:44",
      "content": "<p>This is impressive work. I genuinely appreciate the effort and clarity.</p>",
      "rawMarkdown": "This is impressive work. I genuinely appreciate the effort and clarity.",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 3429161,
      "author_name": "",
      "author_url": "",
      "post_date": "03/26/2026 13:03:55",
      "content": "<p>Fantastic work team! 👏 Your disciplined iterative approach and careful data preprocessing clearly paid off, especially given the limited resources. I’m impressed by how you leveraged public data effectively and turned each leaderboard submission into a learning opportunity. This writeup is a great example of how strategy and consistency can sometimes outweigh sheer scale. Excited to see how we can apply these insights to our next challenge!</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 3429255,
      "author_name": "",
      "author_url": "",
      "post_date": "03/26/2026 14:23:43",
      "content": "<p>Fantastic work.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 3429286,
      "author_name": "",
      "author_url": "",
      "post_date": "03/26/2026 15:21:37",
      "content": "<p>Happy with our result and the journey! This competition pushed us to explore new ideas and improve our approach.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 3443570,
      "author_name": "leedrake",
      "author_url": "",
      "post_date": "04/16/2026 17:54:36",
      "content": "<p>This solution is fascinating - I am very impressed by your ability to get such a high score with such a low data input and lower computational cost. </p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 3452351,
      "author_name": "",
      "author_url": "",
      "post_date": "05/03/2026 06:15:44",
      "content": "<p>This is impressive work. I genuinely appreciate the effort and clarity.</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "3429158": "# [32nd] ByT5-base Fine-tuning | No LLMs, No Synthetic Data, No Ensembles\n\n**Rank:** 32 / 2674 teams | **Public:** 37.6 | **Private:** 38.1\n\n---\n\n## Overview\n\nNo Gemini, no synthetic data, no large-scale PDF extraction. Our strategy was simpler: start from a strong base model, train carefully, iterate continuously, and use the leaderboard as the real validation signal.\n\nThis writeup is for participants who want to understand what is achievable with only public data and a disciplined iterative process.\n\n---\n\n## Two-Stage Training\n\n**Stage 1: Akkademia Pre-training**\n\nByT5-base was first fine-tuned on ~69k sentence pairs from the Akkademia corpus. Akkademia is not Old Assyrian — the relationship is similar to Portuguese vs Spanish. The goal was not to learn the competition domain directly, but to give the model familiarity with Akkadian grammar and morphology before seeing competition data. Without this stage, the model treats Old Assyrian as completely foreign.\n\n**Stage 2: Iterative Fine-tuning**\n\nDue to Kaggle runtime limits (~12h/session), we adopted a progressive fine-tuning loop in cycles of 3 epochs:\n\n1. Train 3 epochs from best checkpoint\n2. Save → create Kaggle dataset\n3. Run inference → submit\n4. Analyze score\n5. Continue or adjust\n\nWe repeated this loop over nearly 3 months, reaching **21 total epochs**. Each iteration taught us which normalization rules helped, which hurt, and what decoding parameters worked best. The leaderboard became our continuous evaluation framework.\n\n---\n\n## Data\n\nPublic data only:\n\n| Source | Rows |\n|---|---|\n| `train.csv` | 1,561 documents |\n| `published_texts.csv` | ~199 recovered transliterations |\n| `Sentences_Oare_FirstWord_LinNum.csv` | 841 gold sentence pairs |\n| `akkademia_train_CLEAN.csv` | ~69k pre-training pairs |\n\n---\nAfter splitting long documents: **~2,800 sentence-level training samples**\n\nThe `Sentences_Oare_FirstWord_LinNum.csv` file was a critical late discovery ; it contains gold sentence boundaries using `first_word_spelling` as anchor, which closely matches how the hidden test set was constructed.\n\n---\n\n## Key Findings from Leaderboard Submissions\n\n- `early_stopping=True` causes repetition artifacts → hurts score\n- `length_penalty=0.91` consistently outperforms lower values\n- Complex postprocessing provides no benefit; the model already internalized normalizations during training\n- Splitting documents to sentence level improves alignment with test distribution\n\n---\n\n## Normalization\n\nApplied to training data following host recommendations:\n\n- `ḫ/Ḫ → h/H` (confirmed absent from test set)\n- Decimals → unicode fractions (`0.3333 → ⅓`)\n- `<gap><gap>` / `<big_gap>` → single `<gap>`\n- Subscripts → integers (`₄ → 4`)\n- Removed `fem.`, `pl.`, `(?)` annotations\n- `PN → <gap>`\n- Roman months → integers\n\n---\n\n## Model & Inference\n\n**Model:** [akk-v24-ep21 on Kaggle](https://www.kaggle.com/datasets/assiaazzouz/akk-v24-ep21)\n\n- Base: `google/byt5-base`\n- Total epochs: 21\n- `num_beams=6`, `length_penalty=0.91`, `early_stopping=False`\n- No postprocessing\n\n### Inference : Less is More\n\nOur final inference is intentionally minimal:\n\n```python\nout = model.generate(\n    **enc,\n    max_new_tokens=300,\n    num_beams=6,\n    length_penalty=0.91,\n    # NO early_stopping\n)\npredictions = tokenizer.batch_decode(out, skip_special_tokens=True)\n# NO postprocessing applied\n```\n\n**No preprocessing of input. No postprocessing of output.**\n\nThis was a late but important discovery. We spent months building a careful postprocessing pipeline; normalizing fractions, removing annotations, fixing gaps. Every rule was based on host-confirmed guidelines.\n\nYet when we tested simple inference against our full pipeline, simple inference scored the same or higher.\n\n**Why?** The model was trained on already-cleaned data. It learned to output correct fractions, correct quotes, correct gaps directly. Our postprocessing was correcting things that were already correct; and occasionally breaking things that were fine.\n\nThe lesson: **preprocess training data carefully, postprocess model output as little as possible.** Interestingly, the 1st place team said exactly the same thing in their writeup.\n\n\n---\n\n## What Limited Us\n\n- No ByT5-Large/XL (top teams used XL on 8×H20)\n- No PDF extraction pipeline (top teams built 30k+ pairs with Gemini)\n- No pseudo-labeling or synthetic data\n- Kaggle runtime forced 3-epoch increments\n\n---\n\n## Final Thoughts\n\nThe 1st place writeup says it best: **\"Data quality dictates everything.\"** Top teams had 30k+ clean sentence pairs. We had ~2,800. Despite this gap, the results show that careful iteration and data alignment can compensate for limited resources.\n\n**37.6 public → 38.1 private. Public data only. ByT5-base.**\n\n---",
    "3429161": "Fantastic work team! 👏 Your disciplined iterative approach and careful data preprocessing clearly paid off, especially given the limited resources. I’m impressed by how you leveraged public data effectively and turned each leaderboard submission into a learning opportunity. This writeup is a great example of how strategy and consistency can sometimes outweigh sheer scale. Excited to see how we can apply these insights to our next challenge!",
    "3429255": "Fantastic work.",
    "3429286": "Happy with our result and the journey! This competition pushed us to explore new ideas and improve our approach.",
    "3443570": "This solution is fascinating - I am very impressed by your ability to get such a high score with such a low data input and lower computational cost.",
    "3452351": "This is impressive work. I genuinely appreciate the effort and clarity."
  },
  "source": "existing_discussion",
  "complete": true,
  "competition_id": 121150,
  "competition_slug": "deep-past-initiative-machine-translation",
  "team_id": 14984696,
  "solution_url": "/competitions/deep-past-initiative-machine-translation/writeups/32nd-byt5-base-fine-tuning-no-llms-no-synthet"
}