{
  "id": 672511,
  "title": "Akkadian Translation Competition - Community Knowledge Synthesis",
  "url": "/competitions/deep-past-initiative-machine-translation/discussion/672511",
  "author_name": "Prayag Patel",
  "post_date": "2026-02-08T19:51:26.816000",
  "votes": 45,
  "comment_count": 14,
  "views": 0,
  "content": "<h2>⚠️ Important Context</h2>\n<p><strong>Transparency:</strong> This is a synthesis of community discussions and public notebooks, not original research. I'm currently ranked at 35.1 score and learning from the community myself.</p>\n<p><strong>Timing Note:</strong> Many insights here are from early-to-mid January discussions. \nThe community's understanding has evolved since then. <strong>If you're in the top 50, you probably know more than what's written here.</strong></p>\n<p><strong>Target Audience:</strong> This consolidation is aimed at competitors who are:</p>\n<ul>\n<li>New to the competition</li>\n<li>Stuck at baseline scores (30-35)</li>\n<li>Looking for a starting point before diving deeper</li>\n</ul>\n<p><strong>What I HAVE tested personally:</strong> AKK-300m failure, bucket batching, length penalty variations, the 35.1 optimization stack.</p>\n<p><strong>What I'm synthesizing from others:</strong> Training recipes, data quality insights, overfitting analysis.</p>\n<p><strong>Request to Top Competitors:</strong> If anything here is outdated or wrong, please comment! I want this to be accurate and helpful, not misleading.</p>\n<p><strong>Purpose of This Post</strong></p>\n<p>After weeks of testing, collaboration, and learning from the community, I wanted to consolidate what's actually working (and what's not) to help everyone still pushing for improvements. This is a synthesis of public discussions, shared notebooks, and systematic testing.</p>\n<p><strong>TL;DR:</strong> We're at an interesting inflection point. The public model ceiling is ~35.1, and breaking past it requires either custom training data, novel techniques, or collaboration. Here's what we know.</p>\n<p>Current State of the Leaderboard</p>\n<p><strong>The 35.1 Plateau:</strong></p>\n<ul>\n<li>100s of competitors clustered at exactly 35.1</li>\n<li><strong>Why:</strong> Everyone using the same model (Assia Benkedia's <code>byt5-akkadian-optimized-34x</code>) with minor variations</li>\n<li><strong>Implication:</strong> To break 35.5+, you need something different</li>\n</ul>\n<p><strong>Score Distribution:</strong></p>\n<ul>\n<li>Top tier (36.5-38.1): Likely custom training on private Old Assyrian data</li>\n<li>Competitive cluster (35.1-36.4): Public model + optimizations  </li>\n<li>Copy-paste crowd (34.9-35.0): Direct Assia model usage</li>\n<li>Baseline methods (&lt;34.9): Older approaches</li>\n</ul>\n<p><strong>Critical Insight from Aaron Bornstein:</strong></p>\n<blockquote>\n  <p>\"High scores on the visible 33% of the test set are likely to degrade significantly on the hidden 67% if they are out of domain\"</p>\n</blockquote>\n<p>Public LB (34% of test) ≠ Private LB (66% of test). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.</p>\n<p>Proven Optimization Stack (34.9 → 35.1)</p>\n<h3>1. Base \"Model\": Assia Benkedia's <code>byt5-akkadian-optimized-34x</code> (34.9)</h3>\n<p><strong>IMPORTANT CORRECTION</strong> (Thanks to Musa Peker for catching this):</p>\n<p>This is actually an <strong>ENSEMBLE</strong> of three models, not a single model:</p>\n<ul>\n<li><code>/kaggle/input/byt5-akk-gap-sentence-v4-cp-final</code> (likely Assia's)</li>\n<li><code>/kaggle/input/byt5-akkadian-model</code></li>\n<li><code>/kaggle/input/byt5-base-big-data2</code></li>\n</ul>\n<p><strong>Implication:</strong> The 34.9 baseline is achieved through ensemble combination, not a \nsingle checkpoint. This means:</p>\n<ul>\n<li>Single model ceiling is probably ~33-34</li>\n<li>To beat 35.5, you need either a better base model OR different ensemble components</li>\n<li>The 35.1 \"plateau\" makes sense - everyone using the same 3-model ensemble + minor optimizations</li>\n</ul>\n<p><strong>Credit:</strong> Assia Benkedia for the ensemble approach, plus the contributors of the \nthree base models\n<strong>Availability:</strong> Kaggle dataset <code>final-byt5</code></p>\n<h3>2. Bucket Batching (+0.1)</h3>\n<ul>\n<li><strong>Credit:</strong> Sera Ria Gomes  </li>\n<li><strong>What it does:</strong> Groups similar-length samples together in batches</li>\n<li><strong>Why it works:</strong> Reduces padding waste by 20-40% → model sees less noise</li>\n<li><strong>Implementation:</strong></li>\n</ul>\n<pre><code>class BucketBatchSampler(Sampler):\n    \"\"\"Groups samples by similar length to minimize padding\"\"\"\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n\n        # Sort indices by length\n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n\n        # Divide into buckets\n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i &lt; num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n\n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n\n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n</code></pre>\n<h3>3. Length Penalty = 1.3-1.5 (+0.1)</h3>\n<ul>\n<li><strong>Credit:</strong> manwithacat (discovered optimal range)</li>\n<li><strong>Why it works:</strong> Encourages longer, more complete translations</li>\n<li><strong>Testing results:</strong><ul>\n<li>1.3: 35.1 ✅ (conservative)</li>\n<li>1.5: 35.1 ✅ (also works)  </li>\n<li>1.7: 35.0 ❌ (too aggressive)</li></ul></li>\n</ul>\n<h3>4. Optimal Configuration</h3>\n<pre><code>CONFIG = {\n    \"model\": \"byt5-akkadian-optimized-34x\",\n    \"num_beams\": 8,\n    \"max_new_tokens\": 512,\n    \"length_penalty\": 1.3,  # or 1.5\n    \"early_stopping\": True,\n    \"batch_size\": 8,\n    \"use_bucket_batching\": True,\n    \"num_buckets\": 4\n}\n</code></pre>\n<hr>\n<h2>Novel Technique: MBR Decoding (Untested Potential)</h2>\n<ul>\n<li><strong>Credit:</strong> Hikari_30  </li>\n<li><strong>What it does:</strong> Minimum Bayes Risk - generates 20 diverse candidates, scores each against all others using chrF++, selects consensus winner</li>\n<li><strong>Why it could help:</strong> <ul>\n<li>Reduces hallucination risk (single beam search can hallucinate)</li>\n<li>Combines diversity (sampling) + quality (beam search)</li>\n<li>No training required - pure inference technique</li>\n<li>Validated in NMT research literature</li></ul></li>\n<li><strong>Cost:</strong> ~3-4x slower inference</li>\n<li><strong>Status:</strong> Only 1 person testing it publicly - could improve private LB robustness</li>\n</ul>\n<p><strong>Implementation outline:</strong></p>\n<pre><code># Generate 15 diverse candidates (temperature=0.7)\n# Generate 5 beam search candidates\n# Score each candidate against all others using chrF++\n# Select candidate with highest average similarity\n</code></pre>\n<hr>\n<h2>❌ Failed Optimizations (Save Your Time!)</h2>\n<h3>1. Onomasticon Name Replacement (0.0 gain)</h3>\n<ul>\n<li>5,973 Akkadian→English name mappings</li>\n<li>Expected: +0.5 to +1.0 (host claimed \"biggest single improvement\")</li>\n<li><strong>Actual: 34.9 → 34.9</strong> (no change)</li>\n<li>Why: Model already outputs English names correctly</li>\n</ul>\n<h3>2. Submission Blending (0.0 gain)</h3>\n<ul>\n<li>Attempted: Blend Assia's 34.9 with older 34.6 ensemble</li>\n<li>Result: Assia's model dominated 100%</li>\n<li>Conclusion: Need equal-quality models to blend effectively</li>\n</ul>\n<h3>3. Hyperparameter Tuning via Optuna (Minimal Impact)</h3>\n<ul>\n<li><strong>Credit:</strong> HARUKI HARADA</li>\n<li>Tested 20 combinations on validation set</li>\n<li>Best found: <code>length_penalty=1.788, beams=6</code> → validation score 25.97</li>\n<li>Baseline: <code>length_penalty=1.5, beams=8</code> → validation score 25.58</li>\n<li><strong>BUT:</strong> They still used baseline for submission (didn't trust Optuna)</li>\n<li>Conclusion: Limited impact (~0.4 max), not worth compute time</li>\n</ul>\n<h3>4. AKK-300m Model (Complete Failure - AVOID!)</h3>\n<ul>\n<li><strong>Credit:</strong> Thalesian/Akkademia Project  </li>\n<li>Tested Feb 8, 2026</li>\n<li><strong>Result:</strong> Outputs only <code>&lt;big_gap&gt;</code> tokens (complete garbage)</li>\n<li><strong>Why it failed:</strong><ul>\n<li>Wrong dialect mix (all Akkadian periods, not Old Assyrian specific)</li>\n<li>Context window only 64 tokens (vs ByT5's 512)</li>\n<li>Multi-task confusion (7+ different tasks)</li>\n<li><strong>Cannot submit:</strong> Requires internet to download, not in Kaggle datasets</li></ul></li>\n<li><strong>Downloads:</strong> 744 in 2 days, but ZERO public successes &gt;35.1</li>\n<li><strong>Recommendation:</strong> Skip this entirely</li>\n</ul>\n<h3>5. BetterTransformer</h3>\n<ul>\n<li>Not accessible in Kaggle environment (deprecated in newer optimum versions)</li>\n<li>Multiple workaround attempts failed</li>\n<li>Stop pursuing</li>\n</ul>\n<hr>\n<h2>Critical Warnings &amp; Insights</h2>\n<h3>Data Quality Issues</h3>\n<p><strong>From Angantyr:</strong></p>\n<ul>\n<li>163/1,561 training samples (~10%) have incomplete translations</li>\n<li>Pattern: Long Akkadian → First item only, then \"…\"</li>\n<li>Example: 66 tokens → \"1 talent … …\" (3 words)</li>\n</ul>\n<p><strong>Host Confirmation:</strong></p>\n<blockquote>\n  <p>\"By no means an error-free dataset. Many of these databases are worked on by students with little oversight\"</p>\n</blockquote>\n<h3>The Overfitting Crisis</h3>\n<p><strong>From Aaron Bornstein's Systematic Perturbation Testing:</strong></p>\n<ul>\n<li>Top models (34-38 scores) are ~40% pattern matchers, not true translators</li>\n<li>They hallucinate generic trade sentences from corpus templates</li>\n<li>Public LB (34%) ≠ Private LB (67%)</li>\n<li><strong>Implication:</strong> Conservative, semantically-accurate models may rank higher on private LB</li>\n</ul>\n<h3>The Metric Trap</h3>\n<p><strong>From Musa Peker:</strong></p>\n<ul>\n<li>Compared two models:<ul>\n<li>\"The Parrot\" (pattern matcher): 34.2 score, complete nonsense</li>\n<li>\"The Domain Expert\" (semantic translator): 11.8 score, accurate translations</li></ul></li>\n<li><strong>Key insight:</strong> BLEU/chrF++ rewards n-gram overlap, NOT semantic accuracy</li>\n<li>Quote: <em>\"We are optimizing for a metric that measures 'Vibes' rather than 'Translation'\"</em></li>\n</ul>\n<h3>Domain Mismatch: EvaCun = ORACC Data</h3>\n<p><strong>CRITICAL FINDING:</strong></p>\n<ul>\n<li>EvaCun corpus IS the ORACC dataset</li>\n<li><strong>Time Period:</strong> Neo-Assyrian (~911-539 BCE)  </li>\n<li><strong>Competition:</strong> Old Assyrian (~1950-1750 BCE)</li>\n<li><strong>Gap:</strong> 1,000 years wrong!</li>\n<li><strong>Host Quote:</strong> <em>\"Would you include Middle English to train modern English? Probably not.\"</em></li>\n<li><strong>Recommendation:</strong> ❌ DO NOT USE for training</li>\n</ul>\n<hr>\n<h2>💻 Working Code: Complete Inference Pipeline</h2>\n<pre><code>\"\"\"\nASSIA'S MODEL + BUCKET BATCHING + OPTIMAL LENGTH PENALTY\nExpected Score: 35.1\n\nNOTEBOOK SETUP:\n- Accelerator: GPU T4 x2\n- Internet: OFF  \n- Datasets: deep-past-initiative-machine-translation, final-byt5\n\"\"\"\n\nimport re\nimport pandas as pd\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, Sampler\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n\n# ============================================================\n# CONFIGURATION\n# ============================================================\nCONFIG = {\n    \"test_path\": \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\",\n    \"model_path\": \"/kaggle/input/final-byt5/byt5-akkadian-optimized-34x\",\n    \"device\": torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\"),\n    \"max_length\": 512,\n    \"batch_size\": 8,\n    \"num_buckets\": 4,\n\n    \"generation\": {\n        \"num_beams\": 8,\n        \"max_new_tokens\": 512,\n        \"length_penalty\": 1.3,  # or 1.5\n        \"early_stopping\": True\n    }\n}\n\n# ============================================================\n# BUCKET BATCH SAMPLER (SERA'S OPTIMIZATION)\n# ============================================================\nclass BucketBatchSampler(Sampler):\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n\n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n\n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i &lt; num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n\n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n\n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n\n# ============================================================\n# PREPROCESSING &amp; POSTPROCESSING\n# ============================================================\ndef preprocess_input(text):\n    \"\"\"Minimal preprocessing for test data\"\"\"\n    if pd.isna(text):\n        return \"\"\n    text = str(text)\n    text = re.sub(r'(\\.{3,}|…+)', '&lt;big_gap&gt;', text)\n    text = re.sub(r'(xx+|\\s+x\\s+)', '&lt;gap&gt;', text)\n    return text\n\ndef postprocess_output(text):\n    \"\"\"Clean model output - proven effective stack\"\"\"\n    if not isinstance(text, str) or not text.strip():\n        return \"\"\n\n    # 1. Normalize ḫ/Ḫ → h/H (test set uses h)\n    text = text.replace('ḫ', 'h').replace('Ḫ', 'H')\n\n    # 2. Subscript numbers → regular\n    subscript_map = str.maketrans(\"₀₁₂₃₄₅₆₇₈₉\", \"0123456789\")\n    text = text.translate(subscript_map)\n\n    # 3. Normalize gaps in output\n    text = re.sub(r'(\\[x\\]|\\(x\\)|\\bx\\b)', '&lt;gap&gt;', text, flags=re.I)\n    text = re.sub(r'(\\.{3,}|…)', '&lt;big_gap&gt;', text)\n\n    # 4. Remove scribal annotations\n    text = re.sub(r'\\((fem|plur|pl|sing|\\?|!)\\.?\\)', '', text, flags=re.I)\n\n    # 5. Protect gap markers, remove forbidden chars\n    text = text.replace('&lt;gap&gt;', '\\x00GAP\\x00')\n    text = text.replace('&lt;big_gap&gt;', '\\x00BIG\\x00')\n    forbidden = '!?()\"—–&lt;&gt;⌈⌋⌊[]+ʾ/;'\n    text = text.translate(str.maketrans('', '', forbidden))\n    text = text.replace('\\x00GAP\\x00', ' &lt;gap&gt; ')\n    text = text.replace('\\x00BIG\\x00', ' &lt;big_gap&gt; ')\n\n    # 6. Unicode fractions\n    text = re.sub(r'(\\d+)\\.5\\b', r'\\1 ½', text)\n    text = re.sub(r'(\\d+)\\.25\\b', r'\\1 ¼', text)\n    text = re.sub(r'(\\d+)\\.75\\b', r'\\1 ¾', text)\n\n    # 7. Remove word repetitions\n    text = re.sub(r'\\b(\\w+)(?:\\s+\\1\\b)+', r'\\1', text)\n\n    # 8. Final cleanup\n    text = re.sub(r'\\s+', ' ', text).strip()\n\n    return text\n\n# ============================================================\n# DATASET CLASS\n# ============================================================\nclass AkkadianDataset(Dataset):\n    def __init__(self, df):\n        self.ids = df['id'].tolist()\n        self.texts = [\n            \"translate Akkadian to English: \" + str(t) \n            for t in df['transliteration']\n        ]\n        self.lengths = [len(t.split()) for t in self.texts]\n\n    def __len__(self):\n        return len(self.ids)\n\n    def __getitem__(self, idx):\n        return self.ids[idx], self.texts[idx]\n\n# ============================================================\n# MAIN INFERENCE\n# ============================================================\nprint(\"Loading test data...\")\ntest_df = pd.read_csv(CONFIG['test_path'])\ntest_df['transliteration'] = test_df['transliteration'].apply(preprocess_input)\n\nprint(\"Loading model...\")\nmodel = AutoModelForSeq2SeqLM.from_pretrained(CONFIG['model_path']).to(CONFIG['device']).eval()\ntokenizer = AutoTokenizer.from_pretrained(CONFIG['model_path'])\n\nprint(\"Creating dataset with bucket sampling...\")\ndataset = AkkadianDataset(test_df)\nsampler = BucketBatchSampler(dataset.lengths, CONFIG['batch_size'], CONFIG['num_buckets'])\n\ndef collate_fn(batch):\n    ids = [item[0] for item in batch]\n    texts = [item[1] for item in batch]\n    encoded = tokenizer(texts, max_length=CONFIG['max_length'], \n                       padding=True, truncation=True, return_tensors=\"pt\")\n    return ids, encoded\n\ndataloader = DataLoader(dataset, batch_sampler=sampler, collate_fn=collate_fn, num_workers=2)\n\nprint(\"Running inference...\")\npredictions = []\nwith torch.inference_mode():\n    for batch_ids, encoded_inputs in dataloader:\n        outputs = model.generate(\n            input_ids=encoded_inputs.input_ids.to(CONFIG['device']),\n            attention_mask=encoded_inputs.attention_mask.to(CONFIG['device']),\n            **CONFIG['generation']\n        )\n        decoded = tokenizer.batch_decode(outputs, skip_special_tokens=True)\n        cleaned = [postprocess_output(text) for text in decoded]\n        predictions.extend(zip(batch_ids, cleaned))\n\n# Create submission\nsubmission = pd.DataFrame(predictions, columns=['id', 'translation'])\nsubmission.to_csv('submission.csv', index=False)\nprint(f\"Done! Saved {len(submission)} translations. Expected score: 35.1\")\n</code></pre>\n<hr>\n<h2>🎯 Strategic Insights</h2>\n<h3>For Breaking Past 35.1</h3>\n<p>You need ONE of these:</p>\n<ol>\n<li><p><strong>Custom Training Data</strong> (3,000-5,000 clean Old Assyrian sentence pairs)</p>\n<ul>\n<li>Top scorers manually extracted from PDFs (40-100+ hours of work)</li>\n<li>Could potentially automate with LLM-assisted extraction</li></ul></li>\n<li><p><strong>Novel Inference Techniques</strong></p>\n<ul>\n<li>MBR decoding (Hikari_30's approach - untested by most)</li>\n<li>Ensemble of equal-quality models (not just Assia + older models)</li></ul></li>\n<li><p><strong>Collaboration</strong></p>\n<ul>\n<li>Aaron Bornstein climbed from #48 → #24 (his methods work!)</li>\n<li>Combine complementary skills: data processing + inference optimization</li></ul></li>\n</ol>\n<h3>Training Insights (If You Go That Route)</h3>\n<p><strong>From Jean-Louis Roy (#5) - Validated Recipe:</strong></p>\n<pre><code>EPOCHS = 10-15  # NOT 26+\nMAX_LENGTH = 512  # NOT 256\nBATCH_SIZE = 4\nGRADIENT_ACCUMULATION_STEPS = 4\nLEARNING_RATE = 5e-5\nFP16 = False  # Critical - prevents NaN errors\n</code></pre>\n<p>From Jack (#2) - <strong>CORRECTED</strong> (Thanks to hongan for catching this):</p>\n<p><strong>What I originally wrote was WRONG.</strong> Jack clarified his actual approach:</p>\n<p>✅ <strong>What Jack actually does:</strong></p>\n<ul>\n<li>\"95% is preprocessing/formatting\" - BUT this means CAREFUL MANUAL REVIEW</li>\n<li>Manually reviewed EVERY document in train.csv (where he gained most score)</li>\n<li>Follows recommended formatting guidelines</li>\n<li>Tests different approaches on training data</li>\n<li>Ensures <strong>meaning alignment</strong> in samples</li>\n</ul>\n<p>❌ <strong>What Jack does NOT do:</strong></p>\n<ul>\n<li>Keep training data \"as is\" without review</li>\n<li>Avoid cleaning training data</li>\n<li>Only preprocess test data</li>\n</ul>\n<p><strong>Key quote (Feb 2026):</strong>\n\"I really started to gain in score when I manually reviewed (briefly - still \nfinding things I've missed) each and every document in the train.csv.\"</p>\n<p><strong>About sentence alignment:</strong>\n\"Sentence alignment didn't work for me because my sentences sucked 😭\" \n(This was about HIS implementation, not the approach itself)</p>\n<p><strong>Critical insight:</strong>\n\"If your formatting is off, especially on translations, nothing else you do \nwill matter since your model isn't matching the desired output format.\"</p>\n<p><strong>From 耶✌ :</strong></p>\n<ul>\n<li>Gap preprocessing applied to BOTH columns (transliteration AND translation)</li>\n<li>Sentence alignment from <code>Sentences_Oare_FirstWord_LinNum.csv</code> improved score +0.5</li>\n<li>MAX_LENGTH progression validated: 385 → 475 → 512 (each step +0.2-0.3)</li>\n</ul>\n<hr>\n<h2>Safe Data Sources</h2>\n<h3>✅ SAFE TO USE</h3>\n<ul>\n<li><code>train.csv</code> (1,561 samples) - Original competition data</li>\n<li><code>Sentences_Oare_FirstWord_LinNum.csv</code> (9,782 alignments) - If verified against first_word matching</li>\n</ul>\n<h3>⚠️ USE WITH CAUTION</h3>\n<ul>\n<li><code>published_texts.csv</code> (7,953 samples) - Transliterations only, unknown time period mix</li>\n</ul>\n<h3>❌ DO NOT USE</h3>\n<ul>\n<li><strong>EvaCun Corpus / ORACC Data</strong> - Neo-Assyrian (911-539 BCE), 1,000 years wrong!</li>\n</ul>\n<hr>\n<h2>Medal Zone Strategy</h2>\n<p><strong>Gold (Top 15):</strong> Requires custom data OR collaboration OR breakthrough technique</p>\n<p><strong>Silver (Top 50):</strong> Achievable with proven optimization stack (35.1-35.3)</p>\n<p><strong>(Top 200):</strong> Public model baseline (34.9-35.0)</p>\n<p><strong>Key Decision:</strong> Private LB shake-up probability ~60% (per Aaron Bornstein's analysis). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.</p>\n<hr>\n<h2>🙏 Credits &amp; Acknowledgments</h2>\n<p><strong>Major Contributors (in alphabetical order):</strong></p>\n<ul>\n<li><strong>Aaron Bornstein</strong> - Overfitting analysis, perturbation testing</li>\n<li><strong>Angantyr</strong> - Incomplete translation analysis  </li>\n<li><strong>Assia Benkedia</strong> - byt5-akkadian-optimized-34x model (publicly released)</li>\n<li><strong>HARUKI HARADA</strong> - Optuna hyperparameter tuning, chunked beam search</li>\n<li><strong>Hikari_30</strong> - MBR decoding technique</li>\n<li><strong>Jack</strong> - Preprocessing insights (\"95% is preprocessing\")</li>\n<li><strong>Jean-Louis Roy</strong> - Validated training recipe</li>\n<li><strong>manwithacat</strong> - Length penalty optimization discovery</li>\n<li><strong>MPWARE</strong> - ḫ/h issue discovery, determinative inconsistency</li>\n<li><strong>Musa Peker</strong> - Metric trap analysis  </li>\n<li><strong>Sera Ria Gomes</strong> - Bucket batching optimization</li>\n<li><strong>Thalesian/Akkademia</strong> - AKK-300m model (tested and documented as failed)</li>\n<li><strong>耶✌</strong> - Gap preprocessing methodology, sentence alignment</li>\n</ul>\n<p><strong>Host (DeepPast Initiative)</strong> - For hosting this fascinating competition and providing clarifications throughout</p>\n<h2>Apologies</h2>\n<p>If I missed giving proper credit to anyone or misattributed any techniques, please let me know in the comments and I'll update immediately. This synthesis is based on public discussions and notebooks—if you contributed something I didn't mention, that's my oversight, not intentional!</p>\n<p><strong>Good luck to everyone in the final push! 51 days to go.</strong></p>",
  "messages": [
    {
      "id": 3403575,
      "postDate": "2026-02-08T19:51:26.817Z",
      "content": "<h2>⚠️ Important Context</h2>\n<p><strong>Transparency:</strong> This is a synthesis of community discussions and public notebooks, not original research. I'm currently ranked at 35.1 score and learning from the community myself.</p>\n<p><strong>Timing Note:</strong> Many insights here are from early-to-mid January discussions. \nThe community's understanding has evolved since then. <strong>If you're in the top 50, you probably know more than what's written here.</strong></p>\n<p><strong>Target Audience:</strong> This consolidation is aimed at competitors who are:</p>\n<ul>\n<li>New to the competition</li>\n<li>Stuck at baseline scores (30-35)</li>\n<li>Looking for a starting point before diving deeper</li>\n</ul>\n<p><strong>What I HAVE tested personally:</strong> AKK-300m failure, bucket batching, length penalty variations, the 35.1 optimization stack.</p>\n<p><strong>What I'm synthesizing from others:</strong> Training recipes, data quality insights, overfitting analysis.</p>\n<p><strong>Request to Top Competitors:</strong> If anything here is outdated or wrong, please comment! I want this to be accurate and helpful, not misleading.</p>\n<p><strong>Purpose of This Post</strong></p>\n<p>After weeks of testing, collaboration, and learning from the community, I wanted to consolidate what's actually working (and what's not) to help everyone still pushing for improvements. This is a synthesis of public discussions, shared notebooks, and systematic testing.</p>\n<p><strong>TL;DR:</strong> We're at an interesting inflection point. The public model ceiling is ~35.1, and breaking past it requires either custom training data, novel techniques, or collaboration. Here's what we know.</p>\n<p>Current State of the Leaderboard</p>\n<p><strong>The 35.1 Plateau:</strong></p>\n<ul>\n<li>100s of competitors clustered at exactly 35.1</li>\n<li><strong>Why:</strong> Everyone using the same model (Assia Benkedia's <code>byt5-akkadian-optimized-34x</code>) with minor variations</li>\n<li><strong>Implication:</strong> To break 35.5+, you need something different</li>\n</ul>\n<p><strong>Score Distribution:</strong></p>\n<ul>\n<li>Top tier (36.5-38.1): Likely custom training on private Old Assyrian data</li>\n<li>Competitive cluster (35.1-36.4): Public model + optimizations  </li>\n<li>Copy-paste crowd (34.9-35.0): Direct Assia model usage</li>\n<li>Baseline methods (&lt;34.9): Older approaches</li>\n</ul>\n<p><strong>Critical Insight from Aaron Bornstein:</strong></p>\n<blockquote>\n  <p>\"High scores on the visible 33% of the test set are likely to degrade significantly on the hidden 67% if they are out of domain\"</p>\n</blockquote>\n<p>Public LB (34% of test) ≠ Private LB (66% of test). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.</p>\n<p>Proven Optimization Stack (34.9 → 35.1)</p>\n<h3>1. Base \"Model\": Assia Benkedia's <code>byt5-akkadian-optimized-34x</code> (34.9)</h3>\n<p><strong>IMPORTANT CORRECTION</strong> (Thanks to Musa Peker for catching this):</p>\n<p>This is actually an <strong>ENSEMBLE</strong> of three models, not a single model:</p>\n<ul>\n<li><code>/kaggle/input/byt5-akk-gap-sentence-v4-cp-final</code> (likely Assia's)</li>\n<li><code>/kaggle/input/byt5-akkadian-model</code></li>\n<li><code>/kaggle/input/byt5-base-big-data2</code></li>\n</ul>\n<p><strong>Implication:</strong> The 34.9 baseline is achieved through ensemble combination, not a \nsingle checkpoint. This means:</p>\n<ul>\n<li>Single model ceiling is probably ~33-34</li>\n<li>To beat 35.5, you need either a better base model OR different ensemble components</li>\n<li>The 35.1 \"plateau\" makes sense - everyone using the same 3-model ensemble + minor optimizations</li>\n</ul>\n<p><strong>Credit:</strong> Assia Benkedia for the ensemble approach, plus the contributors of the \nthree base models\n<strong>Availability:</strong> Kaggle dataset <code>final-byt5</code></p>\n<h3>2. Bucket Batching (+0.1)</h3>\n<ul>\n<li><strong>Credit:</strong> Sera Ria Gomes  </li>\n<li><strong>What it does:</strong> Groups similar-length samples together in batches</li>\n<li><strong>Why it works:</strong> Reduces padding waste by 20-40% → model sees less noise</li>\n<li><strong>Implementation:</strong></li>\n</ul>\n<pre><code>class BucketBatchSampler(Sampler):\n    \"\"\"Groups samples by similar length to minimize padding\"\"\"\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n\n        # Sort indices by length\n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n\n        # Divide into buckets\n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i &lt; num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n\n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n\n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n</code></pre>\n<h3>3. Length Penalty = 1.3-1.5 (+0.1)</h3>\n<ul>\n<li><strong>Credit:</strong> manwithacat (discovered optimal range)</li>\n<li><strong>Why it works:</strong> Encourages longer, more complete translations</li>\n<li><strong>Testing results:</strong><ul>\n<li>1.3: 35.1 ✅ (conservative)</li>\n<li>1.5: 35.1 ✅ (also works)  </li>\n<li>1.7: 35.0 ❌ (too aggressive)</li></ul></li>\n</ul>\n<h3>4. Optimal Configuration</h3>\n<pre><code>CONFIG = {\n    \"model\": \"byt5-akkadian-optimized-34x\",\n    \"num_beams\": 8,\n    \"max_new_tokens\": 512,\n    \"length_penalty\": 1.3,  # or 1.5\n    \"early_stopping\": True,\n    \"batch_size\": 8,\n    \"use_bucket_batching\": True,\n    \"num_buckets\": 4\n}\n</code></pre>\n<hr>\n<h2>Novel Technique: MBR Decoding (Untested Potential)</h2>\n<ul>\n<li><strong>Credit:</strong> Hikari_30  </li>\n<li><strong>What it does:</strong> Minimum Bayes Risk - generates 20 diverse candidates, scores each against all others using chrF++, selects consensus winner</li>\n<li><strong>Why it could help:</strong> <ul>\n<li>Reduces hallucination risk (single beam search can hallucinate)</li>\n<li>Combines diversity (sampling) + quality (beam search)</li>\n<li>No training required - pure inference technique</li>\n<li>Validated in NMT research literature</li></ul></li>\n<li><strong>Cost:</strong> ~3-4x slower inference</li>\n<li><strong>Status:</strong> Only 1 person testing it publicly - could improve private LB robustness</li>\n</ul>\n<p><strong>Implementation outline:</strong></p>\n<pre><code># Generate 15 diverse candidates (temperature=0.7)\n# Generate 5 beam search candidates\n# Score each candidate against all others using chrF++\n# Select candidate with highest average similarity\n</code></pre>\n<hr>\n<h2>❌ Failed Optimizations (Save Your Time!)</h2>\n<h3>1. Onomasticon Name Replacement (0.0 gain)</h3>\n<ul>\n<li>5,973 Akkadian→English name mappings</li>\n<li>Expected: +0.5 to +1.0 (host claimed \"biggest single improvement\")</li>\n<li><strong>Actual: 34.9 → 34.9</strong> (no change)</li>\n<li>Why: Model already outputs English names correctly</li>\n</ul>\n<h3>2. Submission Blending (0.0 gain)</h3>\n<ul>\n<li>Attempted: Blend Assia's 34.9 with older 34.6 ensemble</li>\n<li>Result: Assia's model dominated 100%</li>\n<li>Conclusion: Need equal-quality models to blend effectively</li>\n</ul>\n<h3>3. Hyperparameter Tuning via Optuna (Minimal Impact)</h3>\n<ul>\n<li><strong>Credit:</strong> HARUKI HARADA</li>\n<li>Tested 20 combinations on validation set</li>\n<li>Best found: <code>length_penalty=1.788, beams=6</code> → validation score 25.97</li>\n<li>Baseline: <code>length_penalty=1.5, beams=8</code> → validation score 25.58</li>\n<li><strong>BUT:</strong> They still used baseline for submission (didn't trust Optuna)</li>\n<li>Conclusion: Limited impact (~0.4 max), not worth compute time</li>\n</ul>\n<h3>4. AKK-300m Model (Complete Failure - AVOID!)</h3>\n<ul>\n<li><strong>Credit:</strong> Thalesian/Akkademia Project  </li>\n<li>Tested Feb 8, 2026</li>\n<li><strong>Result:</strong> Outputs only <code>&lt;big_gap&gt;</code> tokens (complete garbage)</li>\n<li><strong>Why it failed:</strong><ul>\n<li>Wrong dialect mix (all Akkadian periods, not Old Assyrian specific)</li>\n<li>Context window only 64 tokens (vs ByT5's 512)</li>\n<li>Multi-task confusion (7+ different tasks)</li>\n<li><strong>Cannot submit:</strong> Requires internet to download, not in Kaggle datasets</li></ul></li>\n<li><strong>Downloads:</strong> 744 in 2 days, but ZERO public successes &gt;35.1</li>\n<li><strong>Recommendation:</strong> Skip this entirely</li>\n</ul>\n<h3>5. BetterTransformer</h3>\n<ul>\n<li>Not accessible in Kaggle environment (deprecated in newer optimum versions)</li>\n<li>Multiple workaround attempts failed</li>\n<li>Stop pursuing</li>\n</ul>\n<hr>\n<h2>Critical Warnings &amp; Insights</h2>\n<h3>Data Quality Issues</h3>\n<p><strong>From Angantyr:</strong></p>\n<ul>\n<li>163/1,561 training samples (~10%) have incomplete translations</li>\n<li>Pattern: Long Akkadian → First item only, then \"…\"</li>\n<li>Example: 66 tokens → \"1 talent … …\" (3 words)</li>\n</ul>\n<p><strong>Host Confirmation:</strong></p>\n<blockquote>\n  <p>\"By no means an error-free dataset. Many of these databases are worked on by students with little oversight\"</p>\n</blockquote>\n<h3>The Overfitting Crisis</h3>\n<p><strong>From Aaron Bornstein's Systematic Perturbation Testing:</strong></p>\n<ul>\n<li>Top models (34-38 scores) are ~40% pattern matchers, not true translators</li>\n<li>They hallucinate generic trade sentences from corpus templates</li>\n<li>Public LB (34%) ≠ Private LB (67%)</li>\n<li><strong>Implication:</strong> Conservative, semantically-accurate models may rank higher on private LB</li>\n</ul>\n<h3>The Metric Trap</h3>\n<p><strong>From Musa Peker:</strong></p>\n<ul>\n<li>Compared two models:<ul>\n<li>\"The Parrot\" (pattern matcher): 34.2 score, complete nonsense</li>\n<li>\"The Domain Expert\" (semantic translator): 11.8 score, accurate translations</li></ul></li>\n<li><strong>Key insight:</strong> BLEU/chrF++ rewards n-gram overlap, NOT semantic accuracy</li>\n<li>Quote: <em>\"We are optimizing for a metric that measures 'Vibes' rather than 'Translation'\"</em></li>\n</ul>\n<h3>Domain Mismatch: EvaCun = ORACC Data</h3>\n<p><strong>CRITICAL FINDING:</strong></p>\n<ul>\n<li>EvaCun corpus IS the ORACC dataset</li>\n<li><strong>Time Period:</strong> Neo-Assyrian (~911-539 BCE)  </li>\n<li><strong>Competition:</strong> Old Assyrian (~1950-1750 BCE)</li>\n<li><strong>Gap:</strong> 1,000 years wrong!</li>\n<li><strong>Host Quote:</strong> <em>\"Would you include Middle English to train modern English? Probably not.\"</em></li>\n<li><strong>Recommendation:</strong> ❌ DO NOT USE for training</li>\n</ul>\n<hr>\n<h2>💻 Working Code: Complete Inference Pipeline</h2>\n<pre><code>\"\"\"\nASSIA'S MODEL + BUCKET BATCHING + OPTIMAL LENGTH PENALTY\nExpected Score: 35.1\n\nNOTEBOOK SETUP:\n- Accelerator: GPU T4 x2\n- Internet: OFF  \n- Datasets: deep-past-initiative-machine-translation, final-byt5\n\"\"\"\n\nimport re\nimport pandas as pd\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, Sampler\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n\n# ============================================================\n# CONFIGURATION\n# ============================================================\nCONFIG = {\n    \"test_path\": \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\",\n    \"model_path\": \"/kaggle/input/final-byt5/byt5-akkadian-optimized-34x\",\n    \"device\": torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\"),\n    \"max_length\": 512,\n    \"batch_size\": 8,\n    \"num_buckets\": 4,\n\n    \"generation\": {\n        \"num_beams\": 8,\n        \"max_new_tokens\": 512,\n        \"length_penalty\": 1.3,  # or 1.5\n        \"early_stopping\": True\n    }\n}\n\n# ============================================================\n# BUCKET BATCH SAMPLER (SERA'S OPTIMIZATION)\n# ============================================================\nclass BucketBatchSampler(Sampler):\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n\n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n\n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i &lt; num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n\n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n\n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n\n# ============================================================\n# PREPROCESSING &amp; POSTPROCESSING\n# ============================================================\ndef preprocess_input(text):\n    \"\"\"Minimal preprocessing for test data\"\"\"\n    if pd.isna(text):\n        return \"\"\n    text = str(text)\n    text = re.sub(r'(\\.{3,}|…+)', '&lt;big_gap&gt;', text)\n    text = re.sub(r'(xx+|\\s+x\\s+)', '&lt;gap&gt;', text)\n    return text\n\ndef postprocess_output(text):\n    \"\"\"Clean model output - proven effective stack\"\"\"\n    if not isinstance(text, str) or not text.strip():\n        return \"\"\n\n    # 1. Normalize ḫ/Ḫ → h/H (test set uses h)\n    text = text.replace('ḫ', 'h').replace('Ḫ', 'H')\n\n    # 2. Subscript numbers → regular\n    subscript_map = str.maketrans(\"₀₁₂₃₄₅₆₇₈₉\", \"0123456789\")\n    text = text.translate(subscript_map)\n\n    # 3. Normalize gaps in output\n    text = re.sub(r'(\\[x\\]|\\(x\\)|\\bx\\b)', '&lt;gap&gt;', text, flags=re.I)\n    text = re.sub(r'(\\.{3,}|…)', '&lt;big_gap&gt;', text)\n\n    # 4. Remove scribal annotations\n    text = re.sub(r'\\((fem|plur|pl|sing|\\?|!)\\.?\\)', '', text, flags=re.I)\n\n    # 5. Protect gap markers, remove forbidden chars\n    text = text.replace('&lt;gap&gt;', '\\x00GAP\\x00')\n    text = text.replace('&lt;big_gap&gt;', '\\x00BIG\\x00')\n    forbidden = '!?()\"—–&lt;&gt;⌈⌋⌊[]+ʾ/;'\n    text = text.translate(str.maketrans('', '', forbidden))\n    text = text.replace('\\x00GAP\\x00', ' &lt;gap&gt; ')\n    text = text.replace('\\x00BIG\\x00', ' &lt;big_gap&gt; ')\n\n    # 6. Unicode fractions\n    text = re.sub(r'(\\d+)\\.5\\b', r'\\1 ½', text)\n    text = re.sub(r'(\\d+)\\.25\\b', r'\\1 ¼', text)\n    text = re.sub(r'(\\d+)\\.75\\b', r'\\1 ¾', text)\n\n    # 7. Remove word repetitions\n    text = re.sub(r'\\b(\\w+)(?:\\s+\\1\\b)+', r'\\1', text)\n\n    # 8. Final cleanup\n    text = re.sub(r'\\s+', ' ', text).strip()\n\n    return text\n\n# ============================================================\n# DATASET CLASS\n# ============================================================\nclass AkkadianDataset(Dataset):\n    def __init__(self, df):\n        self.ids = df['id'].tolist()\n        self.texts = [\n            \"translate Akkadian to English: \" + str(t) \n            for t in df['transliteration']\n        ]\n        self.lengths = [len(t.split()) for t in self.texts]\n\n    def __len__(self):\n        return len(self.ids)\n\n    def __getitem__(self, idx):\n        return self.ids[idx], self.texts[idx]\n\n# ============================================================\n# MAIN INFERENCE\n# ============================================================\nprint(\"Loading test data...\")\ntest_df = pd.read_csv(CONFIG['test_path'])\ntest_df['transliteration'] = test_df['transliteration'].apply(preprocess_input)\n\nprint(\"Loading model...\")\nmodel = AutoModelForSeq2SeqLM.from_pretrained(CONFIG['model_path']).to(CONFIG['device']).eval()\ntokenizer = AutoTokenizer.from_pretrained(CONFIG['model_path'])\n\nprint(\"Creating dataset with bucket sampling...\")\ndataset = AkkadianDataset(test_df)\nsampler = BucketBatchSampler(dataset.lengths, CONFIG['batch_size'], CONFIG['num_buckets'])\n\ndef collate_fn(batch):\n    ids = [item[0] for item in batch]\n    texts = [item[1] for item in batch]\n    encoded = tokenizer(texts, max_length=CONFIG['max_length'], \n                       padding=True, truncation=True, return_tensors=\"pt\")\n    return ids, encoded\n\ndataloader = DataLoader(dataset, batch_sampler=sampler, collate_fn=collate_fn, num_workers=2)\n\nprint(\"Running inference...\")\npredictions = []\nwith torch.inference_mode():\n    for batch_ids, encoded_inputs in dataloader:\n        outputs = model.generate(\n            input_ids=encoded_inputs.input_ids.to(CONFIG['device']),\n            attention_mask=encoded_inputs.attention_mask.to(CONFIG['device']),\n            **CONFIG['generation']\n        )\n        decoded = tokenizer.batch_decode(outputs, skip_special_tokens=True)\n        cleaned = [postprocess_output(text) for text in decoded]\n        predictions.extend(zip(batch_ids, cleaned))\n\n# Create submission\nsubmission = pd.DataFrame(predictions, columns=['id', 'translation'])\nsubmission.to_csv('submission.csv', index=False)\nprint(f\"Done! Saved {len(submission)} translations. Expected score: 35.1\")\n</code></pre>\n<hr>\n<h2>🎯 Strategic Insights</h2>\n<h3>For Breaking Past 35.1</h3>\n<p>You need ONE of these:</p>\n<ol>\n<li><p><strong>Custom Training Data</strong> (3,000-5,000 clean Old Assyrian sentence pairs)</p>\n<ul>\n<li>Top scorers manually extracted from PDFs (40-100+ hours of work)</li>\n<li>Could potentially automate with LLM-assisted extraction</li></ul></li>\n<li><p><strong>Novel Inference Techniques</strong></p>\n<ul>\n<li>MBR decoding (Hikari_30's approach - untested by most)</li>\n<li>Ensemble of equal-quality models (not just Assia + older models)</li></ul></li>\n<li><p><strong>Collaboration</strong></p>\n<ul>\n<li>Aaron Bornstein climbed from #48 → #24 (his methods work!)</li>\n<li>Combine complementary skills: data processing + inference optimization</li></ul></li>\n</ol>\n<h3>Training Insights (If You Go That Route)</h3>\n<p><strong>From Jean-Louis Roy (#5) - Validated Recipe:</strong></p>\n<pre><code>EPOCHS = 10-15  # NOT 26+\nMAX_LENGTH = 512  # NOT 256\nBATCH_SIZE = 4\nGRADIENT_ACCUMULATION_STEPS = 4\nLEARNING_RATE = 5e-5\nFP16 = False  # Critical - prevents NaN errors\n</code></pre>\n<p>From Jack (#2) - <strong>CORRECTED</strong> (Thanks to hongan for catching this):</p>\n<p><strong>What I originally wrote was WRONG.</strong> Jack clarified his actual approach:</p>\n<p>✅ <strong>What Jack actually does:</strong></p>\n<ul>\n<li>\"95% is preprocessing/formatting\" - BUT this means CAREFUL MANUAL REVIEW</li>\n<li>Manually reviewed EVERY document in train.csv (where he gained most score)</li>\n<li>Follows recommended formatting guidelines</li>\n<li>Tests different approaches on training data</li>\n<li>Ensures <strong>meaning alignment</strong> in samples</li>\n</ul>\n<p>❌ <strong>What Jack does NOT do:</strong></p>\n<ul>\n<li>Keep training data \"as is\" without review</li>\n<li>Avoid cleaning training data</li>\n<li>Only preprocess test data</li>\n</ul>\n<p><strong>Key quote (Feb 2026):</strong>\n\"I really started to gain in score when I manually reviewed (briefly - still \nfinding things I've missed) each and every document in the train.csv.\"</p>\n<p><strong>About sentence alignment:</strong>\n\"Sentence alignment didn't work for me because my sentences sucked 😭\" \n(This was about HIS implementation, not the approach itself)</p>\n<p><strong>Critical insight:</strong>\n\"If your formatting is off, especially on translations, nothing else you do \nwill matter since your model isn't matching the desired output format.\"</p>\n<p><strong>From 耶✌ :</strong></p>\n<ul>\n<li>Gap preprocessing applied to BOTH columns (transliteration AND translation)</li>\n<li>Sentence alignment from <code>Sentences_Oare_FirstWord_LinNum.csv</code> improved score +0.5</li>\n<li>MAX_LENGTH progression validated: 385 → 475 → 512 (each step +0.2-0.3)</li>\n</ul>\n<hr>\n<h2>Safe Data Sources</h2>\n<h3>✅ SAFE TO USE</h3>\n<ul>\n<li><code>train.csv</code> (1,561 samples) - Original competition data</li>\n<li><code>Sentences_Oare_FirstWord_LinNum.csv</code> (9,782 alignments) - If verified against first_word matching</li>\n</ul>\n<h3>⚠️ USE WITH CAUTION</h3>\n<ul>\n<li><code>published_texts.csv</code> (7,953 samples) - Transliterations only, unknown time period mix</li>\n</ul>\n<h3>❌ DO NOT USE</h3>\n<ul>\n<li><strong>EvaCun Corpus / ORACC Data</strong> - Neo-Assyrian (911-539 BCE), 1,000 years wrong!</li>\n</ul>\n<hr>\n<h2>Medal Zone Strategy</h2>\n<p><strong>Gold (Top 15):</strong> Requires custom data OR collaboration OR breakthrough technique</p>\n<p><strong>Silver (Top 50):</strong> Achievable with proven optimization stack (35.1-35.3)</p>\n<p><strong>(Top 200):</strong> Public model baseline (34.9-35.0)</p>\n<p><strong>Key Decision:</strong> Private LB shake-up probability ~60% (per Aaron Bornstein's analysis). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.</p>\n<hr>\n<h2>🙏 Credits &amp; Acknowledgments</h2>\n<p><strong>Major Contributors (in alphabetical order):</strong></p>\n<ul>\n<li><strong>Aaron Bornstein</strong> - Overfitting analysis, perturbation testing</li>\n<li><strong>Angantyr</strong> - Incomplete translation analysis  </li>\n<li><strong>Assia Benkedia</strong> - byt5-akkadian-optimized-34x model (publicly released)</li>\n<li><strong>HARUKI HARADA</strong> - Optuna hyperparameter tuning, chunked beam search</li>\n<li><strong>Hikari_30</strong> - MBR decoding technique</li>\n<li><strong>Jack</strong> - Preprocessing insights (\"95% is preprocessing\")</li>\n<li><strong>Jean-Louis Roy</strong> - Validated training recipe</li>\n<li><strong>manwithacat</strong> - Length penalty optimization discovery</li>\n<li><strong>MPWARE</strong> - ḫ/h issue discovery, determinative inconsistency</li>\n<li><strong>Musa Peker</strong> - Metric trap analysis  </li>\n<li><strong>Sera Ria Gomes</strong> - Bucket batching optimization</li>\n<li><strong>Thalesian/Akkademia</strong> - AKK-300m model (tested and documented as failed)</li>\n<li><strong>耶✌</strong> - Gap preprocessing methodology, sentence alignment</li>\n</ul>\n<p><strong>Host (DeepPast Initiative)</strong> - For hosting this fascinating competition and providing clarifications throughout</p>\n<h2>Apologies</h2>\n<p>If I missed giving proper credit to anyone or misattributed any techniques, please let me know in the comments and I'll update immediately. This synthesis is based on public discussions and notebooks—if you contributed something I didn't mention, that's my oversight, not intentional!</p>\n<p><strong>Good luck to everyone in the final push! 51 days to go.</strong></p>",
      "rawMarkdown": "## ⚠️ Important Context\n\n**Transparency:** This is a synthesis of community discussions and public notebooks, not original research. I'm currently ranked at 35.1 score and learning from the community myself.\n\n**Timing Note:** Many insights here are from early-to-mid January discussions. \nThe community's understanding has evolved since then. **If you're in the top 50, you probably know more than what's written here.**\n\n**Target Audience:** This consolidation is aimed at competitors who are:\n- New to the competition\n- Stuck at baseline scores (30-35)\n- Looking for a starting point before diving deeper\n\n**What I HAVE tested personally:** AKK-300m failure, bucket batching, length penalty variations, the 35.1 optimization stack.\n\n**What I'm synthesizing from others:** Training recipes, data quality insights, overfitting analysis.\n\n**Request to Top Competitors:** If anything here is outdated or wrong, please comment! I want this to be accurate and helpful, not misleading.\n\n**Purpose of This Post**\n\nAfter weeks of testing, collaboration, and learning from the community, I wanted to consolidate what's actually working (and what's not) to help everyone still pushing for improvements. This is a synthesis of public discussions, shared notebooks, and systematic testing.\n\n**TL;DR:** We're at an interesting inflection point. The public model ceiling is ~35.1, and breaking past it requires either custom training data, novel techniques, or collaboration. Here's what we know.\n\n\nCurrent State of the Leaderboard\n\n**The 35.1 Plateau:**\n- 100s of competitors clustered at exactly 35.1\n- **Why:** Everyone using the same model (Assia Benkedia's `byt5-akkadian-optimized-34x`) with minor variations\n- **Implication:** To break 35.5+, you need something different\n\n**Score Distribution:**\n- Top tier (36.5-38.1): Likely custom training on private Old Assyrian data\n- Competitive cluster (35.1-36.4): Public model + optimizations  \n- Copy-paste crowd (34.9-35.0): Direct Assia model usage\n- Baseline methods (<34.9): Older approaches\n\n**Critical Insight from Aaron Bornstein:**\n> \"High scores on the visible 33% of the test set are likely to degrade significantly on the hidden 67% if they are out of domain\"\n\nPublic LB (34% of test) ≠ Private LB (66% of test). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.\n\nProven Optimization Stack (34.9 → 35.1)\n\n### 1. Base \"Model\": Assia Benkedia's `byt5-akkadian-optimized-34x` (34.9)\n\n**IMPORTANT CORRECTION** (Thanks to Musa Peker for catching this):\n\nThis is actually an **ENSEMBLE** of three models, not a single model:\n- `/kaggle/input/byt5-akk-gap-sentence-v4-cp-final` (likely Assia's)\n- `/kaggle/input/byt5-akkadian-model`\n- `/kaggle/input/byt5-base-big-data2`\n\n**Implication:** The 34.9 baseline is achieved through ensemble combination, not a \nsingle checkpoint. This means:\n- Single model ceiling is probably ~33-34\n- To beat 35.5, you need either a better base model OR different ensemble components\n- The 35.1 \"plateau\" makes sense - everyone using the same 3-model ensemble + minor optimizations\n\n**Credit:** Assia Benkedia for the ensemble approach, plus the contributors of the \nthree base models\n**Availability:** Kaggle dataset `final-byt5`\n\n### 2. Bucket Batching (+0.1) \n- **Credit:** Sera Ria Gomes  \n- **What it does:** Groups similar-length samples together in batches\n- **Why it works:** Reduces padding waste by 20-40% → model sees less noise\n- **Implementation:**\n\n```python\nclass BucketBatchSampler(Sampler):\n    \"\"\"Groups samples by similar length to minimize padding\"\"\"\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n        \n        # Sort indices by length\n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n        \n        # Divide into buckets\n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i < num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n    \n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n    \n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n```\n\n### 3. Length Penalty = 1.3-1.5 (+0.1)\n- **Credit:** manwithacat (discovered optimal range)\n- **Why it works:** Encourages longer, more complete translations\n- **Testing results:**\n  - 1.3: 35.1 ✅ (conservative)\n  - 1.5: 35.1 ✅ (also works)  \n  - 1.7: 35.0 ❌ (too aggressive)\n\n### 4. Optimal Configuration\n\n```python\nCONFIG = {\n    \"model\": \"byt5-akkadian-optimized-34x\",\n    \"num_beams\": 8,\n    \"max_new_tokens\": 512,\n    \"length_penalty\": 1.3,  # or 1.5\n    \"early_stopping\": True,\n    \"batch_size\": 8,\n    \"use_bucket_batching\": True,\n    \"num_buckets\": 4\n}\n```\n\n---\n\n## Novel Technique: MBR Decoding (Untested Potential)\n\n- **Credit:** Hikari_30  \n- **What it does:** Minimum Bayes Risk - generates 20 diverse candidates, scores each against all others using chrF++, selects consensus winner\n- **Why it could help:** \n  - Reduces hallucination risk (single beam search can hallucinate)\n  - Combines diversity (sampling) + quality (beam search)\n  - No training required - pure inference technique\n  - Validated in NMT research literature\n- **Cost:** ~3-4x slower inference\n- **Status:** Only 1 person testing it publicly - could improve private LB robustness\n\n**Implementation outline:**\n```python\n# Generate 15 diverse candidates (temperature=0.7)\n# Generate 5 beam search candidates\n# Score each candidate against all others using chrF++\n# Select candidate with highest average similarity\n```\n\n---\n\n## ❌ Failed Optimizations (Save Your Time!)\n\n### 1. Onomasticon Name Replacement (0.0 gain)\n- 5,973 Akkadian→English name mappings\n- Expected: +0.5 to +1.0 (host claimed \"biggest single improvement\")\n- **Actual: 34.9 → 34.9** (no change)\n- Why: Model already outputs English names correctly\n\n### 2. Submission Blending (0.0 gain)  \n- Attempted: Blend Assia's 34.9 with older 34.6 ensemble\n- Result: Assia's model dominated 100%\n- Conclusion: Need equal-quality models to blend effectively\n\n### 3. Hyperparameter Tuning via Optuna (Minimal Impact)\n- **Credit:** HARUKI HARADA\n- Tested 20 combinations on validation set\n- Best found: `length_penalty=1.788, beams=6` → validation score 25.97\n- Baseline: `length_penalty=1.5, beams=8` → validation score 25.58\n- **BUT:** They still used baseline for submission (didn't trust Optuna)\n- Conclusion: Limited impact (~0.4 max), not worth compute time\n\n### 4. AKK-300m Model (Complete Failure - AVOID!)\n- **Credit:** Thalesian/Akkademia Project  \n- Tested Feb 8, 2026\n- **Result:** Outputs only `<big_gap>` tokens (complete garbage)\n- **Why it failed:**\n  - Wrong dialect mix (all Akkadian periods, not Old Assyrian specific)\n  - Context window only 64 tokens (vs ByT5's 512)\n  - Multi-task confusion (7+ different tasks)\n  - **Cannot submit:** Requires internet to download, not in Kaggle datasets\n- **Downloads:** 744 in 2 days, but ZERO public successes >35.1\n- **Recommendation:** Skip this entirely\n\n### 5. BetterTransformer\n- Not accessible in Kaggle environment (deprecated in newer optimum versions)\n- Multiple workaround attempts failed\n- Stop pursuing\n\n---\n\n## Critical Warnings & Insights\n\n### Data Quality Issues\n\n**From Angantyr:**\n- 163/1,561 training samples (~10%) have incomplete translations\n- Pattern: Long Akkadian → First item only, then \"...\"\n- Example: 66 tokens → \"1 talent ... ...\" (3 words)\n\n**Host Confirmation:**\n> \"By no means an error-free dataset. Many of these databases are worked on by students with little oversight\"\n\n### The Overfitting Crisis\n\n**From Aaron Bornstein's Systematic Perturbation Testing:**\n- Top models (34-38 scores) are ~40% pattern matchers, not true translators\n- They hallucinate generic trade sentences from corpus templates\n- Public LB (34%) ≠ Private LB (67%)\n- **Implication:** Conservative, semantically-accurate models may rank higher on private LB\n\n### The Metric Trap\n\n**From Musa Peker:**\n- Compared two models:\n  - \"The Parrot\" (pattern matcher): 34.2 score, complete nonsense\n  - \"The Domain Expert\" (semantic translator): 11.8 score, accurate translations\n- **Key insight:** BLEU/chrF++ rewards n-gram overlap, NOT semantic accuracy\n- Quote: *\"We are optimizing for a metric that measures 'Vibes' rather than 'Translation'\"*\n\n### Domain Mismatch: EvaCun = ORACC Data\n\n**CRITICAL FINDING:**\n- EvaCun corpus IS the ORACC dataset\n- **Time Period:** Neo-Assyrian (~911-539 BCE)  \n- **Competition:** Old Assyrian (~1950-1750 BCE)\n- **Gap:** 1,000 years wrong!\n- **Host Quote:** *\"Would you include Middle English to train modern English? Probably not.\"*\n- **Recommendation:** ❌ DO NOT USE for training\n\n---\n\n## 💻 Working Code: Complete Inference Pipeline\n\n```python\n\"\"\"\nASSIA'S MODEL + BUCKET BATCHING + OPTIMAL LENGTH PENALTY\nExpected Score: 35.1\n\nNOTEBOOK SETUP:\n- Accelerator: GPU T4 x2\n- Internet: OFF  \n- Datasets: deep-past-initiative-machine-translation, final-byt5\n\"\"\"\n\nimport re\nimport pandas as pd\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, Sampler\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n\n# ============================================================\n# CONFIGURATION\n# ============================================================\nCONFIG = {\n    \"test_path\": \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\",\n    \"model_path\": \"/kaggle/input/final-byt5/byt5-akkadian-optimized-34x\",\n    \"device\": torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\"),\n    \"max_length\": 512,\n    \"batch_size\": 8,\n    \"num_buckets\": 4,\n    \n    \"generation\": {\n        \"num_beams\": 8,\n        \"max_new_tokens\": 512,\n        \"length_penalty\": 1.3,  # or 1.5\n        \"early_stopping\": True\n    }\n}\n\n# ============================================================\n# BUCKET BATCH SAMPLER (SERA'S OPTIMIZATION)\n# ============================================================\nclass BucketBatchSampler(Sampler):\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n        \n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n        \n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i < num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n    \n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n    \n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n\n# ============================================================\n# PREPROCESSING & POSTPROCESSING\n# ============================================================\ndef preprocess_input(text):\n    \"\"\"Minimal preprocessing for test data\"\"\"\n    if pd.isna(text):\n        return \"\"\n    text = str(text)\n    text = re.sub(r'(\\.{3,}|…+)', '<big_gap>', text)\n    text = re.sub(r'(xx+|\\s+x\\s+)', '<gap>', text)\n    return text\n\ndef postprocess_output(text):\n    \"\"\"Clean model output - proven effective stack\"\"\"\n    if not isinstance(text, str) or not text.strip():\n        return \"\"\n    \n    # 1. Normalize ḫ/Ḫ → h/H (test set uses h)\n    text = text.replace('ḫ', 'h').replace('Ḫ', 'H')\n    \n    # 2. Subscript numbers → regular\n    subscript_map = str.maketrans(\"₀₁₂₃₄₅₆₇₈₉\", \"0123456789\")\n    text = text.translate(subscript_map)\n    \n    # 3. Normalize gaps in output\n    text = re.sub(r'(\\[x\\]|\\(x\\)|\\bx\\b)', '<gap>', text, flags=re.I)\n    text = re.sub(r'(\\.{3,}|…)', '<big_gap>', text)\n    \n    # 4. Remove scribal annotations\n    text = re.sub(r'\\((fem|plur|pl|sing|\\?|!)\\.?\\)', '', text, flags=re.I)\n    \n    # 5. Protect gap markers, remove forbidden chars\n    text = text.replace('<gap>', '\\x00GAP\\x00')\n    text = text.replace('<big_gap>', '\\x00BIG\\x00')\n    forbidden = '!?()\"—–<>⌈⌋⌊[]+ʾ/;'\n    text = text.translate(str.maketrans('', '', forbidden))\n    text = text.replace('\\x00GAP\\x00', ' <gap> ')\n    text = text.replace('\\x00BIG\\x00', ' <big_gap> ')\n    \n    # 6. Unicode fractions\n    text = re.sub(r'(\\d+)\\.5\\b', r'\\1 ½', text)\n    text = re.sub(r'(\\d+)\\.25\\b', r'\\1 ¼', text)\n    text = re.sub(r'(\\d+)\\.75\\b', r'\\1 ¾', text)\n    \n    # 7. Remove word repetitions\n    text = re.sub(r'\\b(\\w+)(?:\\s+\\1\\b)+', r'\\1', text)\n    \n    # 8. Final cleanup\n    text = re.sub(r'\\s+', ' ', text).strip()\n    \n    return text\n\n# ============================================================\n# DATASET CLASS\n# ============================================================\nclass AkkadianDataset(Dataset):\n    def __init__(self, df):\n        self.ids = df['id'].tolist()\n        self.texts = [\n            \"translate Akkadian to English: \" + str(t) \n            for t in df['transliteration']\n        ]\n        self.lengths = [len(t.split()) for t in self.texts]\n    \n    def __len__(self):\n        return len(self.ids)\n    \n    def __getitem__(self, idx):\n        return self.ids[idx], self.texts[idx]\n\n# ============================================================\n# MAIN INFERENCE\n# ============================================================\nprint(\"Loading test data...\")\ntest_df = pd.read_csv(CONFIG['test_path'])\ntest_df['transliteration'] = test_df['transliteration'].apply(preprocess_input)\n\nprint(\"Loading model...\")\nmodel = AutoModelForSeq2SeqLM.from_pretrained(CONFIG['model_path']).to(CONFIG['device']).eval()\ntokenizer = AutoTokenizer.from_pretrained(CONFIG['model_path'])\n\nprint(\"Creating dataset with bucket sampling...\")\ndataset = AkkadianDataset(test_df)\nsampler = BucketBatchSampler(dataset.lengths, CONFIG['batch_size'], CONFIG['num_buckets'])\n\ndef collate_fn(batch):\n    ids = [item[0] for item in batch]\n    texts = [item[1] for item in batch]\n    encoded = tokenizer(texts, max_length=CONFIG['max_length'], \n                       padding=True, truncation=True, return_tensors=\"pt\")\n    return ids, encoded\n\ndataloader = DataLoader(dataset, batch_sampler=sampler, collate_fn=collate_fn, num_workers=2)\n\nprint(\"Running inference...\")\npredictions = []\nwith torch.inference_mode():\n    for batch_ids, encoded_inputs in dataloader:\n        outputs = model.generate(\n            input_ids=encoded_inputs.input_ids.to(CONFIG['device']),\n            attention_mask=encoded_inputs.attention_mask.to(CONFIG['device']),\n            **CONFIG['generation']\n        )\n        decoded = tokenizer.batch_decode(outputs, skip_special_tokens=True)\n        cleaned = [postprocess_output(text) for text in decoded]\n        predictions.extend(zip(batch_ids, cleaned))\n\n# Create submission\nsubmission = pd.DataFrame(predictions, columns=['id', 'translation'])\nsubmission.to_csv('submission.csv', index=False)\nprint(f\"Done! Saved {len(submission)} translations. Expected score: 35.1\")\n```\n\n---\n\n## 🎯 Strategic Insights\n\n### For Breaking Past 35.1\n\nYou need ONE of these:\n\n1. **Custom Training Data** (3,000-5,000 clean Old Assyrian sentence pairs)\n   - Top scorers manually extracted from PDFs (40-100+ hours of work)\n   - Could potentially automate with LLM-assisted extraction\n\n2. **Novel Inference Techniques**\n   - MBR decoding (Hikari_30's approach - untested by most)\n   - Ensemble of equal-quality models (not just Assia + older models)\n\n3. **Collaboration**\n   - Aaron Bornstein climbed from #48 → #24 (his methods work!)\n   - Combine complementary skills: data processing + inference optimization\n\n### Training Insights (If You Go That Route)\n\n**From Jean-Louis Roy (#5) - Validated Recipe:**\n```python\nEPOCHS = 10-15  # NOT 26+\nMAX_LENGTH = 512  # NOT 256\nBATCH_SIZE = 4\nGRADIENT_ACCUMULATION_STEPS = 4\nLEARNING_RATE = 5e-5\nFP16 = False  # Critical - prevents NaN errors\n```\n\nFrom Jack (#2) - **CORRECTED** (Thanks to hongan for catching this):\n\n**What I originally wrote was WRONG.** Jack clarified his actual approach:\n\n✅ **What Jack actually does:**\n- \"95% is preprocessing/formatting\" - BUT this means CAREFUL MANUAL REVIEW\n- Manually reviewed EVERY document in train.csv (where he gained most score)\n- Follows recommended formatting guidelines\n- Tests different approaches on training data\n- Ensures **meaning alignment** in samples\n\n❌ **What Jack does NOT do:**\n- Keep training data \"as is\" without review\n- Avoid cleaning training data\n- Only preprocess test data\n\n**Key quote (Feb 2026):**\n\"I really started to gain in score when I manually reviewed (briefly - still \nfinding things I've missed) each and every document in the train.csv.\"\n\n**About sentence alignment:**\n\"Sentence alignment didn't work for me because my sentences sucked 😭\" \n(This was about HIS implementation, not the approach itself)\n\n**Critical insight:**\n\"If your formatting is off, especially on translations, nothing else you do \nwill matter since your model isn't matching the desired output format.\"\n\n**From 耶✌ :**\n- Gap preprocessing applied to BOTH columns (transliteration AND translation)\n- Sentence alignment from `Sentences_Oare_FirstWord_LinNum.csv` improved score +0.5\n- MAX_LENGTH progression validated: 385 → 475 → 512 (each step +0.2-0.3)\n\n---\n\n## Safe Data Sources\n\n### ✅ SAFE TO USE\n- `train.csv` (1,561 samples) - Original competition data\n- `Sentences_Oare_FirstWord_LinNum.csv` (9,782 alignments) - If verified against first_word matching\n\n### ⚠️ USE WITH CAUTION  \n- `published_texts.csv` (7,953 samples) - Transliterations only, unknown time period mix\n\n### ❌ DO NOT USE\n- **EvaCun Corpus / ORACC Data** - Neo-Assyrian (911-539 BCE), 1,000 years wrong!\n\n---\n\n## Medal Zone Strategy\n\n**Gold (Top 15):** Requires custom data OR collaboration OR breakthrough technique\n\n**Silver (Top 50):** Achievable with proven optimization stack (35.1-35.3)\n\n**(Top 200):** Public model baseline (34.9-35.0)\n\n**Key Decision:** Private LB shake-up probability ~60% (per Aaron Bornstein's analysis). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.\n\n---\n\n## 🙏 Credits & Acknowledgments\n\n**Major Contributors (in alphabetical order):**\n- **Aaron Bornstein** - Overfitting analysis, perturbation testing\n- **Angantyr** - Incomplete translation analysis  \n- **Assia Benkedia** - byt5-akkadian-optimized-34x model (publicly released)\n- **HARUKI HARADA** - Optuna hyperparameter tuning, chunked beam search\n- **Hikari_30** - MBR decoding technique\n- **Jack** - Preprocessing insights (\"95% is preprocessing\")\n- **Jean-Louis Roy** - Validated training recipe\n- **manwithacat** - Length penalty optimization discovery\n- **MPWARE** - ḫ/h issue discovery, determinative inconsistency\n- **Musa Peker** - Metric trap analysis  \n- **Sera Ria Gomes** - Bucket batching optimization\n- **Thalesian/Akkademia** - AKK-300m model (tested and documented as failed)\n- **耶✌** - Gap preprocessing methodology, sentence alignment\n\n**Host (DeepPast Initiative)** - For hosting this fascinating competition and providing clarifications throughout\n\n## Apologies\n\nIf I missed giving proper credit to anyone or misattributed any techniques, please let me know in the comments and I'll update immediately. This synthesis is based on public discussions and notebooks—if you contributed something I didn't mention, that's my oversight, not intentional!\n\n**Good luck to everyone in the final push! 51 days to go.**",
      "votes": 45
    },
    {
      "id": 3403657,
      "postDate": "2026-02-09T02:34:55.993Z",
      "content": "<p>I made a lot of mistakes in my preprocessing early on.. I’m not totally sure when that quote is from but it was probably early.</p>\n<p>I’d still argue 95% of this will be preprocessing/formatting your transliterations/translations.. but, I’d follow the recommended guidelines. Also, sentence alignment didn’t work for me because my sentences sucked 😂 </p>\n<p>If your formatting is off, especially on translations, nothing else you do will matter since your model isn’t matching the desired output format. </p>\n<p>I would start off with minimal changes to the train.csv but you should 100% test different things and ensure meaning is aligned in your samples as well. I really started to gain in score when I manually reviewed (briefly - still finding things I’ve missed) each and every document in the train.csv. </p>",
      "rawMarkdown": "I made a lot of mistakes in my preprocessing early on.. I’m not totally sure when that quote is from but it was probably early.\n\nI’d still argue 95% of this will be preprocessing/formatting your transliterations/translations.. but, I’d follow the recommended guidelines. Also, sentence alignment didn’t work for me because my sentences sucked 😂 \n\nIf your formatting is off, especially on translations, nothing else you do will matter since your model isn’t matching the desired output format. \n\nI would start off with minimal changes to the train.csv but you should 100% test different things and ensure meaning is aligned in your samples as well. I really started to gain in score when I manually reviewed (briefly - still finding things I’ve missed) each and every document in the train.csv. ",
      "votes": 5
    },
    {
      "id": 3403583,
      "postDate": "2026-02-08T20:31:11.240Z",
      "content": "<p>Great synthesis! This is a very comprehensive summary of the current state of the competition. Thanks for putting this together.</p>\n<p>I just wanted to add a small technical correction regarding the \"Base Model\" section (Assia Benkedia's byt5-akkadian-optimized-34x). Upon inspecting the model files and configuration, it appears this is actually an ensemble technique rather than a single model.</p>\n<p>The code references a list of BASE_MODELS that includes:</p>\n<p>/kaggle/input/byt5-akk-gap-sentence-v4-cp-final (Likely Assia's)\n/kaggle/input/byt5-akkadian-model\n/kaggle/input/byt5-base-big-data2</p>\n<p>So, the 34.9+ baseline is achieved by ensembling these public models. It’s worth acknowledging that the performance comes from combining the work of multiple contributors/models, not just a single checkpoint.</p>\n<p>Thanks again for the great overview!</p>",
      "rawMarkdown": "Great synthesis! This is a very comprehensive summary of the current state of the competition. Thanks for putting this together.\n\nI just wanted to add a small technical correction regarding the \"Base Model\" section (Assia Benkedia's byt5-akkadian-optimized-34x). Upon inspecting the model files and configuration, it appears this is actually an ensemble technique rather than a single model.\n\nThe code references a list of BASE_MODELS that includes:\n\n/kaggle/input/byt5-akk-gap-sentence-v4-cp-final (Likely Assia's)\n/kaggle/input/byt5-akkadian-model\n/kaggle/input/byt5-base-big-data2\n\nSo, the 34.9+ baseline is achieved by ensembling these public models. It’s worth acknowledging that the performance comes from combining the work of multiple contributors/models, not just a single checkpoint.\n\nThanks again for the great overview!",
      "votes": 3,
      "replies": [
        {
          "id": 3403590,
          "postDate": "2026-02-08T20:41:47.077Z",
          "content": "<p>Thank you for the correction. </p>\n<p>This is a great info! This also explains why submission blending didn't work for me (I was trying to blend an ensemble with another ensemble)</p>\n<p>Quick clarifications:</p>\n<ol>\n<li>Is the ensemble using simple averaging, or weighted voting?</li>\n<li>Do you know if the 3 base models were trained on different data splits, or different approaches?</li>\n<li>Does this mean a well-trained single model could potentially reach around 34 on its own?</li>\n</ol>\n<p>Updated the post with this info. Really appreciate this technical detail!</p>",
          "rawMarkdown": "Thank you for the correction. \n\nThis is a great info! This also explains why submission blending didn't work for me (I was trying to blend an ensemble with another ensemble)\n\nQuick clarifications:\n1. Is the ensemble using simple averaging, or weighted voting?\n2. Do you know if the 3 base models were trained on different data splits, or different approaches?\n3. Does this mean a well-trained single model could potentially reach around 34 on its own?\n\nUpdated the post with this info. Really appreciate this technical detail!",
          "votes": 1,
          "replies": [
            {
              "id": 3403592,
              "postDate": "2026-02-08T20:48:14.643Z",
              "content": "<p>This is not a classic inference-time ensemble; instead, it merges the model weights.\nThe parameters of three different ByT5 checkpoints were averaged using Weighted Parameter Averaging with predefined ratios, producing a single new model.</p>",
              "rawMarkdown": "This is not a classic inference-time ensemble; instead, it merges the model weights.\nThe parameters of three different ByT5 checkpoints were averaged using Weighted Parameter Averaging with predefined ratios, producing a single new model.",
              "votes": 1
            },
            {
              "id": 3404133,
              "postDate": "2026-02-09T23:20:45.603Z",
              "content": "<p>Thanks so much for the technical details about the ensemble! I updated my post to mention it's weighted parameter averaging(without specific weights or code though).</p>\n<p>This explains why submission blending didn't work for me(I  was trying to ensemble an already-ensembled model with another ensemble). </p>\n<p>One question if you don't mind: do you know if the 3 base models were trained on different data or just different hyperparameters/random seeds? Trying to figure out if I should be aiming for diversity in training data or diversity in model architecture for my own attempts.</p>",
              "rawMarkdown": "Thanks so much for the technical details about the ensemble! I updated my post to mention it's weighted parameter averaging(without specific weights or code though).\n\nThis explains why submission blending didn't work for me(I  was trying to ensemble an already-ensembled model with another ensemble). \n\nOne question if you don't mind: do you know if the 3 base models were trained on different data or just different hyperparameters/random seeds? Trying to figure out if I should be aiming for diversity in training data or diversity in model architecture for my own attempts."
            },
            {
              "id": 3406687,
              "postDate": "2026-02-16T10:59:31.230Z",
              "content": "<p>I don’t have definitive information on whether these models were trained on different datasets or whether the differences arise from architectural choices, hyperparameters, or random seeds.</p>",
              "rawMarkdown": "I don’t have definitive information on whether these models were trained on different datasets or whether the differences arise from architectural choices, hyperparameters, or random seeds."
            }
          ]
        }
      ]
    },
    {
      "id": 3403581,
      "postDate": "2026-02-08T20:22:37.560Z",
      "content": "<p>respect the effort. However, I believe many of your quotes and suggestions are not entirely accurate, mainly because they are comments made 2 months ago (!) and I believe we, as a community, have gained a better understanding of the data since then…  IMO you need to be prepared to spend many more hours on this task in order to beat the public model and understand why you are doing better, but i could be wrong😀 And until you have gone through the train data at least once, i would refrain from giving any advice to other people…</p>",
      "rawMarkdown": "respect the effort. However, I believe many of your quotes and suggestions are not entirely accurate, mainly because they are comments made 2 months ago (!) and I believe we, as a community, have gained a better understanding of the data since then...  IMO you need to be prepared to spend many more hours on this task in order to beat the public model and understand why you are doing better, but i could be wrong😀 And until you have gone through the train data at least once, i would refrain from giving any advice to other people...",
      "votes": 3,
      "replies": [
        {
          "id": 3403585,
          "postDate": "2026-02-08T20:32:55.077Z",
          "content": "<p>Really appreciate the feedback! You're absolutely right that:</p>\n<ol>\n<li>I haven't yet gone through the training data line-by-line myself</li>\n<li>many of these insights are from early jan discussions (2 months old)</li>\n<li>im synthesizing community knowledge, not presenting original research\nMy intent was to consolidate scattered information(added additional context to the post) for people entering the competition now, but I should have been clearer about what I've personally tested vs. what I'm reporting from others.</li>\n</ol>\n<p>Quick question, what have you learned in the past 2 months that contradicts or updates the insights here? I'm genuinely curious what the top competitors know now that we didn't know in January. \nHappy to update the post with newer findings!</p>",
          "rawMarkdown": "Really appreciate the feedback! You're absolutely right that:\n\n1. I haven't yet gone through the training data line-by-line myself\n2. many of these insights are from early jan discussions (2 months old)\n3. im synthesizing community knowledge, not presenting original research\nMy intent was to consolidate scattered information(added additional context to the post) for people entering the competition now, but I should have been clearer about what I've personally tested vs. what I'm reporting from others.\n\nQuick question, what have you learned in the past 2 months that contradicts or updates the insights here? I'm genuinely curious what the top competitors know now that we didn't know in January. \nHappy to update the post with newer findings!",
          "replies": [
            {
              "id": 3403591,
              "postDate": "2026-02-08T20:44:07.267Z",
              "content": "<p>for example, i believe the \"insight\" you are giving here is very far from being true:</p>\n<blockquote>\n  <p>\"95% is preprocessing. Every attempt to follow instructions for cleaning data led to worse performance.\"\n  Keep training data as close to original as possible\n  Heavy preprocessing ONLY for test/inference data\n  Adding sentence-level data from published_texts.csv made his model WORSE</p>\n</blockquote>",
              "rawMarkdown": "for example, i believe the \"insight\" you are giving here is very far from being true:\n>\"95% is preprocessing. Every attempt to follow instructions for cleaning data led to worse performance.\"\nKeep training data as close to original as possible\nHeavy preprocessing ONLY for test/inference data\nAdding sentence-level data from published_texts.csv made his model WORSE"
            },
            {
              "id": 3403658,
              "postDate": "2026-02-09T02:35:20.423Z",
              "content": "<p>Yes, this is off. I was goin through it at the time. </p>",
              "rawMarkdown": "Yes, this is off. I was goin through it at the time. "
            },
            {
              "id": 3404132,
              "postDate": "2026-02-09T23:17:17.263Z",
              "content": "<p>Yeah, good catch on that one.</p>\n<p>Turns out I completely misread what Jack meant. Pretty much the opposite of what I wrote lol.</p>\n<p>Updated the post with the correction. </p>",
              "rawMarkdown": "Yeah, good catch on that one.\n\nTurns out I completely misread what Jack meant. Pretty much the opposite of what I wrote lol.\n\nUpdated the post with the correction. "
            }
          ]
        }
      ]
    },
    {
      "id": 3403740,
      "postDate": "2026-02-09T07:21:50.197Z",
      "content": "<p>I unintentionally made one of my notebooks public. While it wasn't my initial intention, I would be happy if it could contribute to the community's learning and discussion.</p>\n<p>Currently, I suspect that the top scores on the Public LB might be overfitting. Therefore, I believe the key to success in this competition—beyond just improving raw model performance—is focusing on robustness. In other words, our goal should be to minimize the \"shake\" and ensure the model generalizes well to the private data.</p>\n<p>P.S. We are looking for teammates! If you are passionate about LLMs or interested in translation tasks, let’s team up! Please feel free to reach out.</p>\n<p>Happy Kaggling!</p>",
      "rawMarkdown": "I unintentionally made one of my notebooks public. While it wasn't my initial intention, I would be happy if it could contribute to the community's learning and discussion.\n\nCurrently, I suspect that the top scores on the Public LB might be overfitting. Therefore, I believe the key to success in this competition—beyond just improving raw model performance—is focusing on robustness. In other words, our goal should be to minimize the \"shake\" and ensure the model generalizes well to the private data.\n\nP.S. We are looking for teammates! If you are passionate about LLMs or interested in translation tasks, let’s team up! Please feel free to reach out.\n\nHappy Kaggling!",
      "votes": 2,
      "replies": [
        {
          "id": 3403818,
          "postDate": "2026-02-09T10:36:01.090Z",
          "rawMarkdown": "",
          "isDeleted": true
        },
        {
          "id": 3403897,
          "postDate": "2026-02-09T13:52:49.133Z",
          "content": "<p>Currently, I suspect that your scores on the Public LB might be underfitting.</p>",
          "rawMarkdown": "Currently, I suspect that your scores on the Public LB might be underfitting.",
          "votes": 2
        }
      ]
    }
  ],
  "comments": [
    {
      "id": 3403657,
      "author_name": "Jack",
      "author_url": "",
      "post_date": "2026-02-09T02:34:55.993000",
      "content": "<p>I made a lot of mistakes in my preprocessing early on.. I’m not totally sure when that quote is from but it was probably early.</p>\n<p>I’d still argue 95% of this will be preprocessing/formatting your transliterations/translations.. but, I’d follow the recommended guidelines. Also, sentence alignment didn’t work for me because my sentences sucked 😂 </p>\n<p>If your formatting is off, especially on translations, nothing else you do will matter since your model isn’t matching the desired output format. </p>\n<p>I would start off with minimal changes to the train.csv but you should 100% test different things and ensure meaning is aligned in your samples as well. I really started to gain in score when I manually reviewed (briefly - still finding things I’ve missed) each and every document in the train.csv. </p>",
      "votes": 5,
      "replies": []
    },
    {
      "id": 3403583,
      "author_name": "Musa Peker",
      "author_url": "",
      "post_date": "2026-02-08T20:31:11.240000",
      "content": "<p>Great synthesis! This is a very comprehensive summary of the current state of the competition. Thanks for putting this together.</p>\n<p>I just wanted to add a small technical correction regarding the \"Base Model\" section (Assia Benkedia's byt5-akkadian-optimized-34x). Upon inspecting the model files and configuration, it appears this is actually an ensemble technique rather than a single model.</p>\n<p>The code references a list of BASE_MODELS that includes:</p>\n<p>/kaggle/input/byt5-akk-gap-sentence-v4-cp-final (Likely Assia's)\n/kaggle/input/byt5-akkadian-model\n/kaggle/input/byt5-base-big-data2</p>\n<p>So, the 34.9+ baseline is achieved by ensembling these public models. It’s worth acknowledging that the performance comes from combining the work of multiple contributors/models, not just a single checkpoint.</p>\n<p>Thanks again for the great overview!</p>",
      "votes": 3,
      "replies": [
        {
          "id": 3403590,
          "author_name": "Prayag Patel",
          "author_url": "",
          "post_date": "2026-02-08T20:41:47.077000",
          "content": "<p>Thank you for the correction. </p>\n<p>This is a great info! This also explains why submission blending didn't work for me (I was trying to blend an ensemble with another ensemble)</p>\n<p>Quick clarifications:</p>\n<ol>\n<li>Is the ensemble using simple averaging, or weighted voting?</li>\n<li>Do you know if the 3 base models were trained on different data splits, or different approaches?</li>\n<li>Does this mean a well-trained single model could potentially reach around 34 on its own?</li>\n</ol>\n<p>Updated the post with this info. Really appreciate this technical detail!</p>",
          "votes": 1,
          "replies": [
            {
              "id": 3403592,
              "author_name": "Musa Peker",
              "author_url": "",
              "post_date": "2026-02-08T20:48:14.643000",
              "content": "<p>This is not a classic inference-time ensemble; instead, it merges the model weights.\nThe parameters of three different ByT5 checkpoints were averaged using Weighted Parameter Averaging with predefined ratios, producing a single new model.</p>",
              "votes": 1,
              "replies": []
            },
            {
              "id": 3404133,
              "author_name": "Prayag Patel",
              "author_url": "",
              "post_date": "2026-02-09T23:20:45.603000",
              "content": "<p>Thanks so much for the technical details about the ensemble! I updated my post to mention it's weighted parameter averaging(without specific weights or code though).</p>\n<p>This explains why submission blending didn't work for me(I  was trying to ensemble an already-ensembled model with another ensemble). </p>\n<p>One question if you don't mind: do you know if the 3 base models were trained on different data or just different hyperparameters/random seeds? Trying to figure out if I should be aiming for diversity in training data or diversity in model architecture for my own attempts.</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3406687,
              "author_name": "Musa Peker",
              "author_url": "",
              "post_date": "2026-02-16T10:59:31.230000",
              "content": "<p>I don’t have definitive information on whether these models were trained on different datasets or whether the differences arise from architectural choices, hyperparameters, or random seeds.</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3403581,
      "author_name": "hongan",
      "author_url": "",
      "post_date": "2026-02-08T20:22:37.560000",
      "content": "<p>respect the effort. However, I believe many of your quotes and suggestions are not entirely accurate, mainly because they are comments made 2 months ago (!) and I believe we, as a community, have gained a better understanding of the data since then…  IMO you need to be prepared to spend many more hours on this task in order to beat the public model and understand why you are doing better, but i could be wrong😀 And until you have gone through the train data at least once, i would refrain from giving any advice to other people…</p>",
      "votes": 3,
      "replies": [
        {
          "id": 3403585,
          "author_name": "Prayag Patel",
          "author_url": "",
          "post_date": "2026-02-08T20:32:55.077000",
          "content": "<p>Really appreciate the feedback! You're absolutely right that:</p>\n<ol>\n<li>I haven't yet gone through the training data line-by-line myself</li>\n<li>many of these insights are from early jan discussions (2 months old)</li>\n<li>im synthesizing community knowledge, not presenting original research\nMy intent was to consolidate scattered information(added additional context to the post) for people entering the competition now, but I should have been clearer about what I've personally tested vs. what I'm reporting from others.</li>\n</ol>\n<p>Quick question, what have you learned in the past 2 months that contradicts or updates the insights here? I'm genuinely curious what the top competitors know now that we didn't know in January. \nHappy to update the post with newer findings!</p>",
          "votes": 0,
          "replies": [
            {
              "id": 3403591,
              "author_name": "hongan",
              "author_url": "",
              "post_date": "2026-02-08T20:44:07.267000",
              "content": "<p>for example, i believe the \"insight\" you are giving here is very far from being true:</p>\n<blockquote>\n  <p>\"95% is preprocessing. Every attempt to follow instructions for cleaning data led to worse performance.\"\n  Keep training data as close to original as possible\n  Heavy preprocessing ONLY for test/inference data\n  Adding sentence-level data from published_texts.csv made his model WORSE</p>\n</blockquote>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3403658,
              "author_name": "Jack",
              "author_url": "",
              "post_date": "2026-02-09T02:35:20.423000",
              "content": "<p>Yes, this is off. I was goin through it at the time. </p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3404132,
              "author_name": "Prayag Patel",
              "author_url": "",
              "post_date": "2026-02-09T23:17:17.263000",
              "content": "<p>Yeah, good catch on that one.</p>\n<p>Turns out I completely misread what Jack meant. Pretty much the opposite of what I wrote lol.</p>\n<p>Updated the post with the correction. </p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3403740,
      "author_name": "Hikari_30",
      "author_url": "",
      "post_date": "2026-02-09T07:21:50.197000",
      "content": "<p>I unintentionally made one of my notebooks public. While it wasn't my initial intention, I would be happy if it could contribute to the community's learning and discussion.</p>\n<p>Currently, I suspect that the top scores on the Public LB might be overfitting. Therefore, I believe the key to success in this competition—beyond just improving raw model performance—is focusing on robustness. In other words, our goal should be to minimize the \"shake\" and ensure the model generalizes well to the private data.</p>\n<p>P.S. We are looking for teammates! If you are passionate about LLMs or interested in translation tasks, let’s team up! Please feel free to reach out.</p>\n<p>Happy Kaggling!</p>",
      "votes": 2,
      "replies": [
        {
          "id": 3403818,
          "author_name": "",
          "author_url": "",
          "post_date": "2026-02-09T10:36:01.090000",
          "content": "",
          "votes": 0,
          "replies": []
        },
        {
          "id": 3403897,
          "author_name": "Jack",
          "author_url": "",
          "post_date": "2026-02-09T13:52:49.133000",
          "content": "<p>Currently, I suspect that your scores on the Public LB might be underfitting.</p>",
          "votes": 2,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "3403575": "## ⚠️ Important Context\n\n**Transparency:** This is a synthesis of community discussions and public notebooks, not original research. I'm currently ranked at 35.1 score and learning from the community myself.\n\n**Timing Note:** Many insights here are from early-to-mid January discussions. \nThe community's understanding has evolved since then. **If you're in the top 50, you probably know more than what's written here.**\n\n**Target Audience:** This consolidation is aimed at competitors who are:\n- New to the competition\n- Stuck at baseline scores (30-35)\n- Looking for a starting point before diving deeper\n\n**What I HAVE tested personally:** AKK-300m failure, bucket batching, length penalty variations, the 35.1 optimization stack.\n\n**What I'm synthesizing from others:** Training recipes, data quality insights, overfitting analysis.\n\n**Request to Top Competitors:** If anything here is outdated or wrong, please comment! I want this to be accurate and helpful, not misleading.\n\n**Purpose of This Post**\n\nAfter weeks of testing, collaboration, and learning from the community, I wanted to consolidate what's actually working (and what's not) to help everyone still pushing for improvements. This is a synthesis of public discussions, shared notebooks, and systematic testing.\n\n**TL;DR:** We're at an interesting inflection point. The public model ceiling is ~35.1, and breaking past it requires either custom training data, novel techniques, or collaboration. Here's what we know.\n\n\nCurrent State of the Leaderboard\n\n**The 35.1 Plateau:**\n- 100s of competitors clustered at exactly 35.1\n- **Why:** Everyone using the same model (Assia Benkedia's `byt5-akkadian-optimized-34x`) with minor variations\n- **Implication:** To break 35.5+, you need something different\n\n**Score Distribution:**\n- Top tier (36.5-38.1): Likely custom training on private Old Assyrian data\n- Competitive cluster (35.1-36.4): Public model + optimizations  \n- Copy-paste crowd (34.9-35.0): Direct Assia model usage\n- Baseline methods (<34.9): Older approaches\n\n**Critical Insight from Aaron Bornstein:**\n> \"High scores on the visible 33% of the test set are likely to degrade significantly on the hidden 67% if they are out of domain\"\n\nPublic LB (34% of test) ≠ Private LB (66% of test). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.\n\nProven Optimization Stack (34.9 → 35.1)\n\n### 1. Base \"Model\": Assia Benkedia's `byt5-akkadian-optimized-34x` (34.9)\n\n**IMPORTANT CORRECTION** (Thanks to Musa Peker for catching this):\n\nThis is actually an **ENSEMBLE** of three models, not a single model:\n- `/kaggle/input/byt5-akk-gap-sentence-v4-cp-final` (likely Assia's)\n- `/kaggle/input/byt5-akkadian-model`\n- `/kaggle/input/byt5-base-big-data2`\n\n**Implication:** The 34.9 baseline is achieved through ensemble combination, not a \nsingle checkpoint. This means:\n- Single model ceiling is probably ~33-34\n- To beat 35.5, you need either a better base model OR different ensemble components\n- The 35.1 \"plateau\" makes sense - everyone using the same 3-model ensemble + minor optimizations\n\n**Credit:** Assia Benkedia for the ensemble approach, plus the contributors of the \nthree base models\n**Availability:** Kaggle dataset `final-byt5`\n\n### 2. Bucket Batching (+0.1) \n- **Credit:** Sera Ria Gomes  \n- **What it does:** Groups similar-length samples together in batches\n- **Why it works:** Reduces padding waste by 20-40% → model sees less noise\n- **Implementation:**\n\n```python\nclass BucketBatchSampler(Sampler):\n    \"\"\"Groups samples by similar length to minimize padding\"\"\"\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n        \n        # Sort indices by length\n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n        \n        # Divide into buckets\n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i < num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n    \n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n    \n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n```\n\n### 3. Length Penalty = 1.3-1.5 (+0.1)\n- **Credit:** manwithacat (discovered optimal range)\n- **Why it works:** Encourages longer, more complete translations\n- **Testing results:**\n  - 1.3: 35.1 ✅ (conservative)\n  - 1.5: 35.1 ✅ (also works)  \n  - 1.7: 35.0 ❌ (too aggressive)\n\n### 4. Optimal Configuration\n\n```python\nCONFIG = {\n    \"model\": \"byt5-akkadian-optimized-34x\",\n    \"num_beams\": 8,\n    \"max_new_tokens\": 512,\n    \"length_penalty\": 1.3,  # or 1.5\n    \"early_stopping\": True,\n    \"batch_size\": 8,\n    \"use_bucket_batching\": True,\n    \"num_buckets\": 4\n}\n```\n\n---\n\n## Novel Technique: MBR Decoding (Untested Potential)\n\n- **Credit:** Hikari_30  \n- **What it does:** Minimum Bayes Risk - generates 20 diverse candidates, scores each against all others using chrF++, selects consensus winner\n- **Why it could help:** \n  - Reduces hallucination risk (single beam search can hallucinate)\n  - Combines diversity (sampling) + quality (beam search)\n  - No training required - pure inference technique\n  - Validated in NMT research literature\n- **Cost:** ~3-4x slower inference\n- **Status:** Only 1 person testing it publicly - could improve private LB robustness\n\n**Implementation outline:**\n```python\n# Generate 15 diverse candidates (temperature=0.7)\n# Generate 5 beam search candidates\n# Score each candidate against all others using chrF++\n# Select candidate with highest average similarity\n```\n\n---\n\n## ❌ Failed Optimizations (Save Your Time!)\n\n### 1. Onomasticon Name Replacement (0.0 gain)\n- 5,973 Akkadian→English name mappings\n- Expected: +0.5 to +1.0 (host claimed \"biggest single improvement\")\n- **Actual: 34.9 → 34.9** (no change)\n- Why: Model already outputs English names correctly\n\n### 2. Submission Blending (0.0 gain)  \n- Attempted: Blend Assia's 34.9 with older 34.6 ensemble\n- Result: Assia's model dominated 100%\n- Conclusion: Need equal-quality models to blend effectively\n\n### 3. Hyperparameter Tuning via Optuna (Minimal Impact)\n- **Credit:** HARUKI HARADA\n- Tested 20 combinations on validation set\n- Best found: `length_penalty=1.788, beams=6` → validation score 25.97\n- Baseline: `length_penalty=1.5, beams=8` → validation score 25.58\n- **BUT:** They still used baseline for submission (didn't trust Optuna)\n- Conclusion: Limited impact (~0.4 max), not worth compute time\n\n### 4. AKK-300m Model (Complete Failure - AVOID!)\n- **Credit:** Thalesian/Akkademia Project  \n- Tested Feb 8, 2026\n- **Result:** Outputs only `<big_gap>` tokens (complete garbage)\n- **Why it failed:**\n  - Wrong dialect mix (all Akkadian periods, not Old Assyrian specific)\n  - Context window only 64 tokens (vs ByT5's 512)\n  - Multi-task confusion (7+ different tasks)\n  - **Cannot submit:** Requires internet to download, not in Kaggle datasets\n- **Downloads:** 744 in 2 days, but ZERO public successes >35.1\n- **Recommendation:** Skip this entirely\n\n### 5. BetterTransformer\n- Not accessible in Kaggle environment (deprecated in newer optimum versions)\n- Multiple workaround attempts failed\n- Stop pursuing\n\n---\n\n## Critical Warnings & Insights\n\n### Data Quality Issues\n\n**From Angantyr:**\n- 163/1,561 training samples (~10%) have incomplete translations\n- Pattern: Long Akkadian → First item only, then \"...\"\n- Example: 66 tokens → \"1 talent ... ...\" (3 words)\n\n**Host Confirmation:**\n> \"By no means an error-free dataset. Many of these databases are worked on by students with little oversight\"\n\n### The Overfitting Crisis\n\n**From Aaron Bornstein's Systematic Perturbation Testing:**\n- Top models (34-38 scores) are ~40% pattern matchers, not true translators\n- They hallucinate generic trade sentences from corpus templates\n- Public LB (34%) ≠ Private LB (67%)\n- **Implication:** Conservative, semantically-accurate models may rank higher on private LB\n\n### The Metric Trap\n\n**From Musa Peker:**\n- Compared two models:\n  - \"The Parrot\" (pattern matcher): 34.2 score, complete nonsense\n  - \"The Domain Expert\" (semantic translator): 11.8 score, accurate translations\n- **Key insight:** BLEU/chrF++ rewards n-gram overlap, NOT semantic accuracy\n- Quote: *\"We are optimizing for a metric that measures 'Vibes' rather than 'Translation'\"*\n\n### Domain Mismatch: EvaCun = ORACC Data\n\n**CRITICAL FINDING:**\n- EvaCun corpus IS the ORACC dataset\n- **Time Period:** Neo-Assyrian (~911-539 BCE)  \n- **Competition:** Old Assyrian (~1950-1750 BCE)\n- **Gap:** 1,000 years wrong!\n- **Host Quote:** *\"Would you include Middle English to train modern English? Probably not.\"*\n- **Recommendation:** ❌ DO NOT USE for training\n\n---\n\n## 💻 Working Code: Complete Inference Pipeline\n\n```python\n\"\"\"\nASSIA'S MODEL + BUCKET BATCHING + OPTIMAL LENGTH PENALTY\nExpected Score: 35.1\n\nNOTEBOOK SETUP:\n- Accelerator: GPU T4 x2\n- Internet: OFF  \n- Datasets: deep-past-initiative-machine-translation, final-byt5\n\"\"\"\n\nimport re\nimport pandas as pd\nimport torch\nfrom torch.utils.data import Dataset, DataLoader, Sampler\nfrom transformers import AutoTokenizer, AutoModelForSeq2SeqLM\n\n# ============================================================\n# CONFIGURATION\n# ============================================================\nCONFIG = {\n    \"test_path\": \"/kaggle/input/deep-past-initiative-machine-translation/test.csv\",\n    \"model_path\": \"/kaggle/input/final-byt5/byt5-akkadian-optimized-34x\",\n    \"device\": torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\"),\n    \"max_length\": 512,\n    \"batch_size\": 8,\n    \"num_buckets\": 4,\n    \n    \"generation\": {\n        \"num_beams\": 8,\n        \"max_new_tokens\": 512,\n        \"length_penalty\": 1.3,  # or 1.5\n        \"early_stopping\": True\n    }\n}\n\n# ============================================================\n# BUCKET BATCH SAMPLER (SERA'S OPTIMIZATION)\n# ============================================================\nclass BucketBatchSampler(Sampler):\n    def __init__(self, lengths, batch_size, num_buckets=4):\n        self.lengths = lengths\n        self.batch_size = batch_size\n        self.num_buckets = num_buckets\n        \n        sorted_indices = sorted(range(len(lengths)), key=lambda i: lengths[i])\n        \n        bucket_size = len(sorted_indices) // num_buckets\n        self.buckets = []\n        for i in range(num_buckets):\n            start = i * bucket_size\n            end = start + bucket_size if i < num_buckets - 1 else len(sorted_indices)\n            self.buckets.append(sorted_indices[start:end])\n    \n    def __iter__(self):\n        for bucket in self.buckets:\n            indices = bucket.copy()\n            for i in range(0, len(indices), self.batch_size):\n                yield indices[i:i + self.batch_size]\n    \n    def __len__(self):\n        return sum(len(bucket) // self.batch_size for bucket in self.buckets)\n\n# ============================================================\n# PREPROCESSING & POSTPROCESSING\n# ============================================================\ndef preprocess_input(text):\n    \"\"\"Minimal preprocessing for test data\"\"\"\n    if pd.isna(text):\n        return \"\"\n    text = str(text)\n    text = re.sub(r'(\\.{3,}|…+)', '<big_gap>', text)\n    text = re.sub(r'(xx+|\\s+x\\s+)', '<gap>', text)\n    return text\n\ndef postprocess_output(text):\n    \"\"\"Clean model output - proven effective stack\"\"\"\n    if not isinstance(text, str) or not text.strip():\n        return \"\"\n    \n    # 1. Normalize ḫ/Ḫ → h/H (test set uses h)\n    text = text.replace('ḫ', 'h').replace('Ḫ', 'H')\n    \n    # 2. Subscript numbers → regular\n    subscript_map = str.maketrans(\"₀₁₂₃₄₅₆₇₈₉\", \"0123456789\")\n    text = text.translate(subscript_map)\n    \n    # 3. Normalize gaps in output\n    text = re.sub(r'(\\[x\\]|\\(x\\)|\\bx\\b)', '<gap>', text, flags=re.I)\n    text = re.sub(r'(\\.{3,}|…)', '<big_gap>', text)\n    \n    # 4. Remove scribal annotations\n    text = re.sub(r'\\((fem|plur|pl|sing|\\?|!)\\.?\\)', '', text, flags=re.I)\n    \n    # 5. Protect gap markers, remove forbidden chars\n    text = text.replace('<gap>', '\\x00GAP\\x00')\n    text = text.replace('<big_gap>', '\\x00BIG\\x00')\n    forbidden = '!?()\"—–<>⌈⌋⌊[]+ʾ/;'\n    text = text.translate(str.maketrans('', '', forbidden))\n    text = text.replace('\\x00GAP\\x00', ' <gap> ')\n    text = text.replace('\\x00BIG\\x00', ' <big_gap> ')\n    \n    # 6. Unicode fractions\n    text = re.sub(r'(\\d+)\\.5\\b', r'\\1 ½', text)\n    text = re.sub(r'(\\d+)\\.25\\b', r'\\1 ¼', text)\n    text = re.sub(r'(\\d+)\\.75\\b', r'\\1 ¾', text)\n    \n    # 7. Remove word repetitions\n    text = re.sub(r'\\b(\\w+)(?:\\s+\\1\\b)+', r'\\1', text)\n    \n    # 8. Final cleanup\n    text = re.sub(r'\\s+', ' ', text).strip()\n    \n    return text\n\n# ============================================================\n# DATASET CLASS\n# ============================================================\nclass AkkadianDataset(Dataset):\n    def __init__(self, df):\n        self.ids = df['id'].tolist()\n        self.texts = [\n            \"translate Akkadian to English: \" + str(t) \n            for t in df['transliteration']\n        ]\n        self.lengths = [len(t.split()) for t in self.texts]\n    \n    def __len__(self):\n        return len(self.ids)\n    \n    def __getitem__(self, idx):\n        return self.ids[idx], self.texts[idx]\n\n# ============================================================\n# MAIN INFERENCE\n# ============================================================\nprint(\"Loading test data...\")\ntest_df = pd.read_csv(CONFIG['test_path'])\ntest_df['transliteration'] = test_df['transliteration'].apply(preprocess_input)\n\nprint(\"Loading model...\")\nmodel = AutoModelForSeq2SeqLM.from_pretrained(CONFIG['model_path']).to(CONFIG['device']).eval()\ntokenizer = AutoTokenizer.from_pretrained(CONFIG['model_path'])\n\nprint(\"Creating dataset with bucket sampling...\")\ndataset = AkkadianDataset(test_df)\nsampler = BucketBatchSampler(dataset.lengths, CONFIG['batch_size'], CONFIG['num_buckets'])\n\ndef collate_fn(batch):\n    ids = [item[0] for item in batch]\n    texts = [item[1] for item in batch]\n    encoded = tokenizer(texts, max_length=CONFIG['max_length'], \n                       padding=True, truncation=True, return_tensors=\"pt\")\n    return ids, encoded\n\ndataloader = DataLoader(dataset, batch_sampler=sampler, collate_fn=collate_fn, num_workers=2)\n\nprint(\"Running inference...\")\npredictions = []\nwith torch.inference_mode():\n    for batch_ids, encoded_inputs in dataloader:\n        outputs = model.generate(\n            input_ids=encoded_inputs.input_ids.to(CONFIG['device']),\n            attention_mask=encoded_inputs.attention_mask.to(CONFIG['device']),\n            **CONFIG['generation']\n        )\n        decoded = tokenizer.batch_decode(outputs, skip_special_tokens=True)\n        cleaned = [postprocess_output(text) for text in decoded]\n        predictions.extend(zip(batch_ids, cleaned))\n\n# Create submission\nsubmission = pd.DataFrame(predictions, columns=['id', 'translation'])\nsubmission.to_csv('submission.csv', index=False)\nprint(f\"Done! Saved {len(submission)} translations. Expected score: 35.1\")\n```\n\n---\n\n## 🎯 Strategic Insights\n\n### For Breaking Past 35.1\n\nYou need ONE of these:\n\n1. **Custom Training Data** (3,000-5,000 clean Old Assyrian sentence pairs)\n   - Top scorers manually extracted from PDFs (40-100+ hours of work)\n   - Could potentially automate with LLM-assisted extraction\n\n2. **Novel Inference Techniques**\n   - MBR decoding (Hikari_30's approach - untested by most)\n   - Ensemble of equal-quality models (not just Assia + older models)\n\n3. **Collaboration**\n   - Aaron Bornstein climbed from #48 → #24 (his methods work!)\n   - Combine complementary skills: data processing + inference optimization\n\n### Training Insights (If You Go That Route)\n\n**From Jean-Louis Roy (#5) - Validated Recipe:**\n```python\nEPOCHS = 10-15  # NOT 26+\nMAX_LENGTH = 512  # NOT 256\nBATCH_SIZE = 4\nGRADIENT_ACCUMULATION_STEPS = 4\nLEARNING_RATE = 5e-5\nFP16 = False  # Critical - prevents NaN errors\n```\n\nFrom Jack (#2) - **CORRECTED** (Thanks to hongan for catching this):\n\n**What I originally wrote was WRONG.** Jack clarified his actual approach:\n\n✅ **What Jack actually does:**\n- \"95% is preprocessing/formatting\" - BUT this means CAREFUL MANUAL REVIEW\n- Manually reviewed EVERY document in train.csv (where he gained most score)\n- Follows recommended formatting guidelines\n- Tests different approaches on training data\n- Ensures **meaning alignment** in samples\n\n❌ **What Jack does NOT do:**\n- Keep training data \"as is\" without review\n- Avoid cleaning training data\n- Only preprocess test data\n\n**Key quote (Feb 2026):**\n\"I really started to gain in score when I manually reviewed (briefly - still \nfinding things I've missed) each and every document in the train.csv.\"\n\n**About sentence alignment:**\n\"Sentence alignment didn't work for me because my sentences sucked 😭\" \n(This was about HIS implementation, not the approach itself)\n\n**Critical insight:**\n\"If your formatting is off, especially on translations, nothing else you do \nwill matter since your model isn't matching the desired output format.\"\n\n**From 耶✌ :**\n- Gap preprocessing applied to BOTH columns (transliteration AND translation)\n- Sentence alignment from `Sentences_Oare_FirstWord_LinNum.csv` improved score +0.5\n- MAX_LENGTH progression validated: 385 → 475 → 512 (each step +0.2-0.3)\n\n---\n\n## Safe Data Sources\n\n### ✅ SAFE TO USE\n- `train.csv` (1,561 samples) - Original competition data\n- `Sentences_Oare_FirstWord_LinNum.csv` (9,782 alignments) - If verified against first_word matching\n\n### ⚠️ USE WITH CAUTION  \n- `published_texts.csv` (7,953 samples) - Transliterations only, unknown time period mix\n\n### ❌ DO NOT USE\n- **EvaCun Corpus / ORACC Data** - Neo-Assyrian (911-539 BCE), 1,000 years wrong!\n\n---\n\n## Medal Zone Strategy\n\n**Gold (Top 15):** Requires custom data OR collaboration OR breakthrough technique\n\n**Silver (Top 50):** Achievable with proven optimization stack (35.1-35.3)\n\n**(Top 200):** Public model baseline (34.9-35.0)\n\n**Key Decision:** Private LB shake-up probability ~60% (per Aaron Bornstein's analysis). Conservative, semantically-accurate approaches may outperform pattern-matching models on final evaluation.\n\n---\n\n## 🙏 Credits & Acknowledgments\n\n**Major Contributors (in alphabetical order):**\n- **Aaron Bornstein** - Overfitting analysis, perturbation testing\n- **Angantyr** - Incomplete translation analysis  \n- **Assia Benkedia** - byt5-akkadian-optimized-34x model (publicly released)\n- **HARUKI HARADA** - Optuna hyperparameter tuning, chunked beam search\n- **Hikari_30** - MBR decoding technique\n- **Jack** - Preprocessing insights (\"95% is preprocessing\")\n- **Jean-Louis Roy** - Validated training recipe\n- **manwithacat** - Length penalty optimization discovery\n- **MPWARE** - ḫ/h issue discovery, determinative inconsistency\n- **Musa Peker** - Metric trap analysis  \n- **Sera Ria Gomes** - Bucket batching optimization\n- **Thalesian/Akkademia** - AKK-300m model (tested and documented as failed)\n- **耶✌** - Gap preprocessing methodology, sentence alignment\n\n**Host (DeepPast Initiative)** - For hosting this fascinating competition and providing clarifications throughout\n\n## Apologies\n\nIf I missed giving proper credit to anyone or misattributed any techniques, please let me know in the comments and I'll update immediately. This synthesis is based on public discussions and notebooks—if you contributed something I didn't mention, that's my oversight, not intentional!\n\n**Good luck to everyone in the final push! 51 days to go.**",
    "3403657": "I made a lot of mistakes in my preprocessing early on.. I’m not totally sure when that quote is from but it was probably early.\n\nI’d still argue 95% of this will be preprocessing/formatting your transliterations/translations.. but, I’d follow the recommended guidelines. Also, sentence alignment didn’t work for me because my sentences sucked 😂 \n\nIf your formatting is off, especially on translations, nothing else you do will matter since your model isn’t matching the desired output format. \n\nI would start off with minimal changes to the train.csv but you should 100% test different things and ensure meaning is aligned in your samples as well. I really started to gain in score when I manually reviewed (briefly - still finding things I’ve missed) each and every document in the train.csv. ",
    "3403583": "Great synthesis! This is a very comprehensive summary of the current state of the competition. Thanks for putting this together.\n\nI just wanted to add a small technical correction regarding the \"Base Model\" section (Assia Benkedia's byt5-akkadian-optimized-34x). Upon inspecting the model files and configuration, it appears this is actually an ensemble technique rather than a single model.\n\nThe code references a list of BASE_MODELS that includes:\n\n/kaggle/input/byt5-akk-gap-sentence-v4-cp-final (Likely Assia's)\n/kaggle/input/byt5-akkadian-model\n/kaggle/input/byt5-base-big-data2\n\nSo, the 34.9+ baseline is achieved by ensembling these public models. It’s worth acknowledging that the performance comes from combining the work of multiple contributors/models, not just a single checkpoint.\n\nThanks again for the great overview!",
    "3403581": "respect the effort. However, I believe many of your quotes and suggestions are not entirely accurate, mainly because they are comments made 2 months ago (!) and I believe we, as a community, have gained a better understanding of the data since then...  IMO you need to be prepared to spend many more hours on this task in order to beat the public model and understand why you are doing better, but i could be wrong😀 And until you have gone through the train data at least once, i would refrain from giving any advice to other people...",
    "3403740": "I unintentionally made one of my notebooks public. While it wasn't my initial intention, I would be happy if it could contribute to the community's learning and discussion.\n\nCurrently, I suspect that the top scores on the Public LB might be overfitting. Therefore, I believe the key to success in this competition—beyond just improving raw model performance—is focusing on robustness. In other words, our goal should be to minimize the \"shake\" and ensure the model generalizes well to the private data.\n\nP.S. We are looking for teammates! If you are passionate about LLMs or interested in translation tasks, let’s team up! Please feel free to reach out.\n\nHappy Kaggling!"
  }
}