| --- |
| license: mit |
| language: |
| - en |
| - es |
| - fr |
| - de |
| library_name: onnx |
| tags: |
| - time |
| - temporal-parsing |
| - date-parsing |
| - nlp |
| - sql |
| - multilingual |
| - onnx |
| - sundial |
| --- |
| |
| # sundial-encoder-full |
|
|
| **Time expressions (en / es / fr / de) → a portable IR → SQL / JS date ranges.** A tiny (~14 MB) |
| multi-head classifier that runs in the browser or on the server in a single forward pass. |
|
|
| - 💻 **Code (MIT):** https://github.com/ceritium/sundial |
| - 🕹️ **Live demo:** https://sundial.onvibe.run/playground |
| - 📊 **Benchmarks:** https://github.com/ceritium/sundial/blob/master/BENCHMARKS.md |
|
|
| ## What it does |
|
|
| Given a phrase like `"last 7 days"`, `"último miércoles de 2027"`, `"first day of the month"` or |
| `"a fortnight ago"`, the model emits an **IR skeleton** — the *structure* only, no digits |
| (`last_n(N, day)`, `nth_weekday(last, wed, YEAR)`, `nth_day(1, month, this)`, `offset(-N, week)`, …). |
| A small **deterministic layer** (in the repo) then extracts the exact numbers, months and dates from |
| the input and materializes the full IR, which renders to a bound **SQLite / Postgres predicate** or a |
| JS `{start, end}` range. |
|
|
| > The model never generates a digit. Because the output space is a **finite set of skeletons**, this |
| > is **classification, not generation** — so a 14 M-parameter encoder with a few heads is enough, and |
| > it generalizes to years and phrasings it barely saw. |
|
|
| ## Model |
|
|
| - Base: `google/electra-small-discriminator` (~14 M params), fine-tuned as a **multi-head classifier** |
| with one head per IR slot: `op / unit / which / dow / ord / scope / sign / has_at`. |
| - Format: **int8 ONNX**, ~14 MB. Runtime: `onnxruntime` (WASM in the browser, single pass, ~1 ms/inf CPU). |
| - Trained on `en + es + fr + de`, basic + complex expressions, plus **LLM-distilled paraphrases** for |
| phrasing robustness. |
|
|
| **Files:** `model_int8.onnx`, the tokenizer, `heads.json` (the per-head label vocabulary). |
|
|
| ## Highlights |
|
|
| - Matches a T5 seq2seq (98.6% gold) at **14 MB** and ~30× faster per inference. |
| - One 14 MB English-vocab base handles **en/es/fr/de** at ~99% (a 135 MB multilingual base adds ~1%). |
| - vs rule engines: a *tie* with Duckling on the constructs it supports, but wins on **out-of-distribution |
| phrasing** (91.7% vs 38.9% on paraphrases) — the distilled model generalizes the long tail. |
|
|
| ## Usage |
|
|
| The model outputs the 8 head logits; you `argmax` them, compose the skeleton, then run the deterministic |
| `materialize` + renderers from the repo. The repo ships a ready-to-run script: |
|
|
| ```bash |
| git clone https://github.com/ceritium/sundial && cd sundial |
| uv run --project train python train/predict_onnx.py \ |
| --hf ceritium/sundial-encoder-full \ |
| --inputs data/gold/gold_complex_en.jsonl --out models/pred.jsonl |
| node eval/run_eval.mjs --gold data/gold/gold_complex_en.jsonl --predictions models/pred.jsonl --skeleton |
| # -> 26 examples · 100.0% (skeleton -> materialize -> execute vs gold) |
| ``` |
|
|
| Minimal inference (Python + onnxruntime): |
|
|
| ```python |
| import json, numpy as np, onnxruntime as ort |
| from huggingface_hub import hf_hub_download |
| from transformers import AutoTokenizer |
| |
| repo = "ceritium/sundial-encoder-full" |
| tok = AutoTokenizer.from_pretrained(repo) |
| heads = json.load(open(hf_hub_download(repo, "heads.json"))) |
| sess = ort.InferenceSession(hf_hub_download(repo, "model_int8.onnx")) |
| |
| enc = tok("last wednesday of 2027".lower(), return_tensors="np", truncation=True, max_length=32) |
| logits = sess.run(heads["head_names"], {"input_ids": enc["input_ids"].astype(np.int64), |
| "attention_mask": enc["attention_mask"].astype(np.int64)}) |
| slots = {n: heads["heads"][n][int(np.argmax(logits[i][0]))] for i, n in enumerate(heads["head_names"])} |
| print(slots) # -> {op: nth_weekday, ord: last, dow: wed, scope: year, ...} (compose + materialize in the repo) |
| ``` |
|
|
| ## License |
|
|
| MIT. Experimental research model — see the [repo](https://github.com/ceritium/sundial) for the full IR |
| grammar, renderers (validated by execution), training/distillation pipeline, and benchmarks. |
|
|