Files
iolai26-solve/AGENTS.md
ModelHub XC 5b016c1af1 初始化项目,由ModelHub XC社区提供模型
Model: rpant/iolai26-solve
Source: Original Platform
2026-07-28 09:36:12 +08:00

10 KiB

IOL-AI 2026 Solver — Implementation Seed

Seed context and build plan for implementing a solver for International Linguistics Olympiad (IOL) style problems. Read this fully before writing code. Design principle: the structure of language does the reasoning; the LLM proposes hypotheses that a deterministic engine executes and a symbolic verifier selects. Do not outsource rule application to the LLM.

1. The task

Solve self-contained linguistic-reasoning puzzles over unseen, mostly low-resource languages. Each puzzle gives a small amount of bilingual/parallel data plus hints, and asks the solver to translate, fill blanks, match forms to meanings, or convert numerals. No prior knowledge of the language is needed or expected; everything must be induced from the given data.

Data (Linguini-style CSV)

Columns: id, context, query, work_lang, task_lang, task_type, eval_type.

  • One row = one complete problem. context holds the parallel data + hints. query holds numbered items sharing that context.
  • Read test set from /tmp/data/test.csv. Write submission.csv with a pred column: one JSON list of answers per row, one entry per numbered item, in order.

Task types (route on task_type)

  • translation (work->task and task->work): analysis one way, generation the other.
  • fill_blanks: complete a paradigm cell.
  • match_letters: match forms to meanings (assignment problem).
  • text_to_num / num_to_text: recover and apply a numeral system.
  • Others may appear (transliteration, glossing, error-correction, phonological rule application) — handle gracefully, fall back rather than crash.

Scoring (design to this)

Final score = geometric mean sqrt(EMw * chrFw), both points-weighted by official IOL point values.

  • Geometric mean => neither factor can be near zero. Never emit an empty or wildly-off answer; always produce a plausible string (chrF floor).
  • Need genuine exact hits (symbolic core) AND fuzzy overlap (fallback).
  • Generation into the unknown language is the hardest direction; invest there.

Submission and runtime constraints (hard)

  • Submit a public Hugging Face repo containing script.py + model weights. Load models from . (repo root). No internet in the eval sandbox — vendor every dependency and weight.
  • 30 minutes per run for the entire test set. Throughput is the real budget. Symbolic-first; batch all LLM calls; spend sampling on hard/high-point items only.
  • Greedy decoding for reproducibility. Up to 3 submissions/day; 2 count for the private leaderboard.
  • Compute at inference: single T4, 16 GB (Turing: fp16 yes, bf16 no). Use 4-bit AWQ/GPTQ + LoRA via vLLM.
  • Full repo is allowed: ship YAML configs, prompt libraries, DSL grammar files, multiple LoRA adapters, finetuned weights.
  • Finetuning (SFT or RL) is allowed; train offline on other hardware and upload weights. Only inference is T4-bound.

2. Core insight (why this architecture)

  1. LLMs (small ones especially) can propose linguistic rules but reliably fail to apply them consistently. => LLM proposes a grammar; a deterministic interpreter applies it.
  2. The given attested pairs are a free, exact verifier. Leave-one-out fit on them (points-weighted EM + chrF = the competition metric) selects among candidate grammars. No LLM judge needed for correctness. This makes the domain verifiable, which is what makes test-time scaling and RL-with-verifiable-rewards work.
  3. Explicit morpheme segmentation before anything else is a large, cheap win.
  4. Analogical exemplars (from a multilingual model) help the LLM propose better grammars, never to deduce.

3. Architecture

Router/typology scan  ->  Preprocess (normalize, segment, align, paradigm table)
   -> Symbolic-first solvers:  numeral CSP | matching (Hungarian) | concatenative morphology
   -> Program-synthesis subagent:  LLM proposes grammar in DSL  ->  interpreter runs it
                                    ->  CEGIS refine <= R rounds  (feed failing pairs back)
   -> Verifier: leave-one-out EM+chrF on attested pairs + MDL penalty; self-consistency on ties
   -> Select grammar (never empty; chrF-floor fallback = closest attested form / analogy)
   -> Apply selected grammar deterministically to query items  ->  answers
   -> (phase 5) Verbalizer LoRA: execution trace -> human explanation

Principles: segment first; symbolic-solved items cost ~0 LLM tokens; adaptive compute; guard against repetition loops (token cap + repetition penalty + loop detection).

The DSL (small, executable, verifiable)

Primitives for a puzzle grammar. Programs are tiny so execution/verification is effectively free.

  • LEXICON: morpheme -> gloss/feature
  • AFFIX(position, form, trigger)
  • REWRITE(pattern -> repl / context) (morphophonology: harmony, sandhi, elision)
  • ORDER(slot permutation) (source constituent order -> target)
  • AGREE(feature copy)
  • REDUP(template)
  • NUMERAL(base, digitmap, combine_op) Interpreter must run both directions (analyze and generate). Generation uses the grammar + proportional analogy for unseen stems; round-trip verify generated forms.

Verifier (single object, reused everywhere)

score(grammar, held_out_pairs) -> points_weighted_EM, chrF. Used as: test-time selector, CEGIS signal, and (later) RL reward. Add MDL penalty L(grammar)+L(data|grammar) to prefer the simplest adequate grammar.

4. Suggested repo layout

script.py                 # entrypoint: read /tmp/data/test.csv -> write submission.csv
solver/
  router.py               # task typing + typology scan + budget tier
  preprocess.py           # unicode NFC (keep tone/diacritics), tokenize, align, segment
  align.py                # minimal-pair set-difference aligner (pure python)
  segment.py              # MDL-guided segmentation conditioned on alignment
  analogy.py              # proportional analogy (a:b::c:d), analogical grids
  numerals.py             # base detection + CSP/algebraic solve
  matching.py             # scipy Hungarian over alignment-consistency scores
  dsl/
    grammar.py            # DSL datatypes
    interpreter.py        # analyze() and generate(), both directions
  synth.py                # program-synthesis subagent + CEGIS loop
  verifier.py             # leave-one-out EM+chrF + MDL; selection + self-consistency
  llm.py                  # vLLM wrapper, 4-bit base + LoRA adapter swap, batching, guards
  fallback.py             # chrF-floor: never return empty
  budget.py               # adaptive compute allocation under 30-min cap
prompts/                  # YAML prompt library (proposer, analogical generator, critic)
weights/                  # 4-bit base + LoRA adapters (proposer/deducer/verbalizer/critic)
eval/
  scorer.py               # reimplement official geomean scorer
  dev_harness.py          # run + score on public dev puzzles
data/dev/                 # public IOL/Linguini/PuzzLing/modeLing/LINGOLY (validation ONLY)

5. Build order (do in this sequence; each has a gate)

  1. Harness first. eval/scorer.py (points-weighted EM + chrF geomean) and verifier.py leave-one-out. Assemble data/dev/ from public puzzles (respect CC-BY-SA / IOL copyright; validation only). Baselines: analogy-only floor, small-LLM few-shot. Gate: scorer matches hand-computed values.
  2. Cheap symbolic points. numerals.py, matching.py, align.py, segment.py, analogy.py. Gate: numerals/matching beat LLM baseline; segmentation shows a positive downstream delta (replicate the known morpheme-boundary gain). If segmentation does not help, the aligner is mis-conditioned.
  3. Synthesis core. DSL + interpreter + synth.py CEGIS with proposer LLM. Ablate: direct-LLM vs synthesis+verifier vs +segmentation vs +analogical exemplars; vary CEGIS rounds. Gate: synthesis+verifier clearly beats direct-LLM on translation/fill_blanks at fixed budget.
  4. Verifier-gated test-time scaling. Best-of-N grammar sampling ranked by verifier; self-consistency; adaptive budget. Gate: monotone accuracy gain that still fits 30 min; pick operating N from the compute-accuracy curve.
  5. Finetuning (offline, highest ceiling). Procedurally generate synthetic puzzles with gold grammar/segmentation/derivation. SFT the proposer/deducer for DSL emission + reliable rule application; then GRPO/RLVR with the verifier as reward. Validate on real public puzzles (guard the synthetic-real gap). Gate: finetuned small model >= best prompt-only config on real held-out puzzles at equal/lower cost.
  6. Explanation track (later). Verbalizer LoRA: execution trace -> prose; narrow LLM critic checks faithfulness to the trace. The automated solver's trace is the explanation substrate.

6. Stack and risks

Models (T4, 4-bit + LoRA, vLLM): base = Qwen2.5-7B-Instruct; try a Coder variant for DSL emission; optional Aya-Expanse-8B as multilingual analogical generator. Role specialization via hot-swapped LoRA adapters over one base (stay in 16 GB).

Libraries (vendor all, offline): unicodedata/regex; pure-python aligner + MDL segmenter (avoid native pynini/hfst; implement rewrite-rule + analogy engine in python); scipy (Hungarian); hand-rolled CSP for numerals (spaces are tiny) or z3-solver if redistributable; sacrebleu (chrF); vllm; peft.

Risks: throughput vs 30 min (symbolic-first, batch, adaptive budget, cap N); small-model deduction leakage (always execute rules deterministically); DSL coverage of hard phenomena — tone, reduplication, circumfixes, harmony, ergativity, suppletion (grow primitives from failure analysis; keep an LLM fallback so nothing is empty); synthetic-real gap (validate on real puzzles only); repetition collapse (token caps + penalties); quantization hurting multilingual quality (compare AWQ/GPTQ/fp16 on dev before committing).

7. Non-negotiables

  • Read /tmp/data/test.csv; write submission.csv with pred as a JSON list per row. Load all models/deps from repo root; assume no network.
  • Never return empty for any item. Stay within 30 minutes for the whole set. Greedy decoding.
  • LLM proposes; symbolic engine applies and verifies. Segment before reasoning. Keep tone/diacritics.