Skip to content

About

No description, website, or topics provided.

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

gazet-tutorial

Fine-tune a small language model to do natural-language geocoding, in two Colab notebooks and about two hours. This is a teaching-sized reproduction of gazet: one country (Ecuador), one table (Overture administrative divisions), eight query templates, a 0.8B model with a LoRA adapter trained on a free T4.

"which cantons border Cuenca?"
   -> model extracts ["Cuenca"]
   -> fuzzy search returns 10 candidate rows (Cuenca, Cuenca?, Cumandá, ...)
   -> model writes DuckDB spatial SQL using the right id
   -> SQL runs, polygons come back as GeoJSON
Notebook Runtime Time What you do
1 Open In Colab 01_data_and_dataset CPU ~25 min Pull Ecuador's boundaries from Overture, compute spatial relations, write SQL templates, generate ~3,000 verified training examples for two tasks
2 Open In Colab 02_train_eval_inference T4 GPU ~60 min LoRA fine-tune Qwen3.5-0.8B with Unsloth, score it by executing the SQL it writes, compare with the base model, run the geocoder on a map

No accounts needed. No Hugging Face token, no Drive mount. The dataset produced by notebook 1 is bundled with the package, so notebook 2 runs on its own; a trained adapter can be downloaded (SKIP_TRAINING = True) if you only want the evaluation and demo.

What the model learns

Training data is entirely synthetic and never touches an LLM. Each SQL template comes with a list of question phrasings; a sampled place fills both, the SQL is executed against the real table, and only queries that return rows are kept.

family template example question
direct_lookup lookup_01 where is Latacunga?
disambiguation disambiguate_01 Bolívar, Carchi (there are three Bolívars)
adjacency adj_01, adj_02 which provinces border Pichincha?
containment contain_01, contain_02 cantons of Azuay / which province is Baños in?
buffer buffer_01 cantons within 25 km of Guayaquil
aggregation agg_01 3 largest cantons in Loja

One model is trained on two tasks at once, distinguished by the system prompt: extract place names as JSON, and write SQL given a candidate table plus the question. The evaluation metric is execution accuracy: predicted and reference SQL are both run, and the sets of returned feature ids must match.

Suggested 2-hour agenda

time block
0:00–0:10 What gazet does; why synthetic data; what we simplify
0:10–0:45 Notebook 1 live: data, relations, templates, generation, export
0:45–1:15 Notebook 2: install, LoRA, masking check, start training; discuss the eval while it runs
1:15–1:40 Results: base vs fine-tuned, error gallery
1:40–1:55 Live geocoding on maps; how it ships (GGUF, llama-server)
1:55–2:00 Homework: 2 epochs, unseen-canton holdout, add a template, change country

Repository layout

notebooks/            the two .ipynb files Colab opens (generated from notebooks/src/*.py)
notebooks/src/        percent-format sources; edit these, then scripts/build_notebooks.sh
src/gazet_tutorial/   helper package: DuckDB/Overture access, fuzzy search, SQL utils, eval, maps
artifacts/            bundled output of notebook 1 (dataset, prompts, relation tables)
tests/                pytest suite (synthetic square polygons, no downloads)
scripts/              build_notebooks.sh, run_nb1.sh (regenerates artifacts/ via papermill)

The learner-facing logic (templates, generation loop, prompts, training config, metrics, the geocode() function) lives in notebook cells. The package holds only boilerplate so that pip install is the entire setup.

Local development

uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -e ".[dev]"
.venv/bin/python -m pytest
scripts/run_nb1.sh                # executes notebook 1 (downloads ~10 MB from Overture S3)
scripts/run_nb1.sh "/path/to/overture/divisions_area/*.parquet"   # or from a local copy

Notebook 2 needs a CUDA GPU (Unsloth does not run on Apple Silicon); run it in Colab.

Fallback artifacts

  • artifacts/dataset/ is produced by scripts/run_nb1.sh with fixed seeds; regenerate it whenever templates or prompts change.
  • The trained adapter for SKIP_TRAINING is attached to the GitHub release v1 as adapter.zip (produced by notebook 2 with default settings).

Data and licenses

Code is MIT licensed. Boundary data comes from the Overture Maps Foundation divisions theme, which is derived from OpenStreetMap and distributed under the ODbL; the bundled dataset contains feature ids and names from that data and inherits its terms. Model weights: Qwen3.5 (Apache 2.0), via Unsloth.

About

No description, website, or topics provided.

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages