Darwin-180B-NL2SQL: BIRD Mini-Dev SQLite 83.80 EX predictions and scorer
Browse files- README.md +75 -0
- predict_mini_dev_darwin-180b-nl2sql_SQLite.json +0 -0
- predictions.jsonl +0 -0
- score_ex.py +56 -0
README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
tags:
|
| 6 |
+
- text-to-sql
|
| 7 |
+
- nl2sql
|
| 8 |
+
- bird
|
| 9 |
+
- sqlite
|
| 10 |
+
- darwin
|
| 11 |
+
pipeline_tag: text-generation
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# Darwin-180B-NL2SQL
|
| 15 |
+
|
| 16 |
+
<p align="center">
|
| 17 |
+
<img src="https://img.shields.io/badge/BIRD_Mini--Dev_SQLite-83.80_EX-gold?style=for-the-badge" alt="BIRD Mini-Dev SQLite 83.80">
|
| 18 |
+
<a href="https://huggingface.co/FINAL-Bench/Darwin-180B-RSI"><img src="https://img.shields.io/badge/Model-Darwin--180B--RSI-blue?style=for-the-badge" alt="Darwin-180B-RSI"></a>
|
| 19 |
+
<a href="https://huggingface.co/FINAL-Bench"><img src="https://img.shields.io/badge/Org-FINAL--Bench-black?style=for-the-badge" alt="FINAL-Bench"></a>
|
| 20 |
+
</p>
|
| 21 |
+
|
| 22 |
+
Darwin-180B-NL2SQL is VIDRAFT's text-to-SQL system built on [Darwin-180B-RSI](https://huggingface.co/FINAL-Bench/Darwin-180B-RSI). It turns a natural-language question into a SQLite query, runs it against the database and revises the query from what the execution shows, then returns one final query per question.
|
| 23 |
+
|
| 24 |
+
This repository holds the system's predictions on BIRD Mini-Dev (SQLite) and the script used to score them. The model weights are those of Darwin-180B-RSI; no weights were changed or trained for this result.
|
| 25 |
+
|
| 26 |
+
## Result
|
| 27 |
+
|
| 28 |
+
**BIRD Mini-Dev, SQLite, 500 questions: 83.80% execution accuracy (419 / 500).**
|
| 29 |
+
|
| 30 |
+
| Difficulty | Correct | Accuracy |
|
| 31 |
+
|---|---|---|
|
| 32 |
+
| Challenging | 384 / 460 | 83.5% |
|
| 33 |
+
| Moderate | 29 / 32 | 90.6% |
|
| 34 |
+
| Simple | 6 / 8 | 75.0% |
|
| 35 |
+
| **All** | **419 / 500** | **83.80%** |
|
| 36 |
+
|
| 37 |
+
- Data: the current canonical release on Hugging Face, [`birdsql/bird_mini_dev`](https://huggingface.co/datasets/birdsql/bird_mini_dev), release "Mini-Dev 1024", `data/mini_dev_sqlite.jsonl` (sha256 `926af2a0d1b47e5d0d15a7aa8a34d4721007f4550a881555b6a89496b54a2606`), with the SQLite databases from `minidev.zip`.
|
| 38 |
+
- Metric: strict execution accuracy. A prediction is correct when the set of rows it returns equals the set of rows the reference SQL returns. Each predicted query may run for 60 seconds.
|
| 39 |
+
- Measured on 29 October 2026 (KST). The score was computed twice on an idle machine and was identical both times.
|
| 40 |
+
|
| 41 |
+
## Evaluation conditions
|
| 42 |
+
|
| 43 |
+
| Condition | Setting |
|
| 44 |
+
|---|---|
|
| 45 |
+
| Reference (gold) SQL used at any stage of inference | **No** |
|
| 46 |
+
| Oracle knowledge beyond the question and evidence given | No |
|
| 47 |
+
| Fine-tuning on BIRD | No |
|
| 48 |
+
| Final candidates per question | 1 |
|
| 49 |
+
| Database access during inference | Read-only execution of the system's own queries |
|
| 50 |
+
|
| 51 |
+
The question and evidence in each item are the only task inputs. The reference SQL was used only to score the final predictions.
|
| 52 |
+
|
| 53 |
+
## Files
|
| 54 |
+
|
| 55 |
+
| File | Contents |
|
| 56 |
+
|---|---|
|
| 57 |
+
| `predict_mini_dev_darwin-180b-nl2sql_SQLite.json` | Predictions in the BIRD Mini-Dev submission format (`SQL\t----- bird -----\tdb_id`, keyed by question ID) |
|
| 58 |
+
| `predictions.jsonl` | The same predictions, one JSON object per line |
|
| 59 |
+
| `score_ex.py` | Strict execution-accuracy scorer used for the numbers above |
|
| 60 |
+
|
| 61 |
+
To reproduce the score, place `mini_dev_sqlite.jsonl` next to `score_ex.py` and run:
|
| 62 |
+
|
| 63 |
+
```bash
|
| 64 |
+
python score_ex.py predictions.jsonl path/to/MINIDEV/dev_databases
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
## About the system
|
| 68 |
+
|
| 69 |
+
The system pairs Darwin-180B-RSI with VIDRAFT's NL2SQL verification engine, which checks each generated query against the live database before an answer is returned. The engine is VIDRAFT's own implementation and is not released.
|
| 70 |
+
|
| 71 |
+
A public demo of VIDRAFT's NL2SQL engine (Korean and English, read-only, synthetic data) is available at [final-bench-nl2sql-demo.hf.space](https://final-bench-nl2sql-demo.hf.space/).
|
| 72 |
+
|
| 73 |
+
## Contact
|
| 74 |
+
|
| 75 |
+
VIDRAFT · [vidraft.net](https://vidraft.net) · vidraft@mail.vidraft.net
|
predict_mini_dev_darwin-180b-nl2sql_SQLite.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
predictions.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
score_ex.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Strict BIRD execution accuracy: set(pred rows) == set(gold rows). usage: python score.py preds.jsonl db_root
|
| 2 |
+
import json, os, sqlite3, sys, collections, time
|
| 3 |
+
from concurrent.futures import ProcessPoolExecutor, TimeoutError as TO
|
| 4 |
+
|
| 5 |
+
HERE = os.path.dirname(os.path.abspath(__file__))
|
| 6 |
+
preds_path, db_root = sys.argv[1], sys.argv[2]
|
| 7 |
+
gold = {d["question_id"]: d for d in (json.loads(l) for l in open(os.path.join(HERE, "mini_dev_sqlite.jsonl"), encoding="utf-8"))}
|
| 8 |
+
preds = {}
|
| 9 |
+
for l in open(preds_path, encoding="utf-8"):
|
| 10 |
+
p = json.loads(l); preds[p["question_id"]] = p
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def run(db, sql, limit=None):
|
| 14 |
+
con = sqlite3.connect(f"file:{db}?mode=ro", uri=True)
|
| 15 |
+
if limit: # abort runaway queries inside the worker; a pool timeout alone leaves them running
|
| 16 |
+
end = time.time() + limit
|
| 17 |
+
con.set_progress_handler(lambda: time.time() > end, 100000)
|
| 18 |
+
try:
|
| 19 |
+
return set(con.execute(sql).fetchall())
|
| 20 |
+
finally:
|
| 21 |
+
con.close()
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def judge(args):
|
| 25 |
+
db, psql, gsql = args
|
| 26 |
+
try:
|
| 27 |
+
g = run(db, gsql)
|
| 28 |
+
except Exception as e:
|
| 29 |
+
return "gold_error"
|
| 30 |
+
if not psql: return "no_sql"
|
| 31 |
+
try:
|
| 32 |
+
return "ok" if run(db, psql, 60) == g else "wrong"
|
| 33 |
+
except sqlite3.OperationalError as e:
|
| 34 |
+
return "timeout" if "interrupted" in str(e) else "exec_error"
|
| 35 |
+
except Exception:
|
| 36 |
+
return "exec_error"
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
if __name__ == "__main__":
|
| 40 |
+
jobs = []
|
| 41 |
+
for qid, g in gold.items():
|
| 42 |
+
db = os.path.join(db_root, g["db_id"], g["db_id"] + ".sqlite")
|
| 43 |
+
jobs.append((qid, (db, preds.get(qid, {}).get("sql", ""), g["SQL"])))
|
| 44 |
+
res = {}
|
| 45 |
+
with ProcessPoolExecutor(8) as ex:
|
| 46 |
+
futs = {qid: ex.submit(judge, a) for qid, a in jobs}
|
| 47 |
+
for qid, fu in futs.items():
|
| 48 |
+
try: res[qid] = fu.result(timeout=600) # the 60 s per-query limit is enforced inside the worker; this only guards a hung pool
|
| 49 |
+
except TO: res[qid] = "timeout"
|
| 50 |
+
c = collections.Counter(res.values())
|
| 51 |
+
by = collections.defaultdict(lambda: [0, 0])
|
| 52 |
+
for qid, v in res.items():
|
| 53 |
+
d = gold[qid]["difficulty"]; by[d][1] += 1; by[d][0] += v == "ok"
|
| 54 |
+
print(f"EX = {c['ok']}/{len(res)} = {100 * c['ok'] / len(res):.2f}% ", dict(c))
|
| 55 |
+
for d, (a, n) in sorted(by.items()): print(f" {d:12s} {a}/{n} = {100 * a / n:.1f}%")
|
| 56 |
+
json.dump(res, open(preds_path.replace(".jsonl", "_score.json"), "w"), indent=0)
|