agentbyumer's picture
Update README.md
3889c70 verified
|
Raw History Blame Contribute Delete
4.79 kB
---
base_model: unsloth/gemma-4-e2b-it-unsloth-bnb-4bit
tags:
- text-generation-inference
- transformers
- gemma4
- trl
- structured-output
- json
- function-calling
- agentic-ai
license: apache-2.0
language:
- en
datasets:
- interstellarninja/json-mode-agentic
---
# Gemma 4 E2B — Structured Output
A QLoRA fine-tune of Google's Gemma 4 E2B, trained to convert natural-language text into
valid, schema-conforming JSON. Built for use cases where an LLM needs to reliably hand off
structured data to downstream code — agent tool calls, form extraction, data pipelines,
and anywhere else "give me clean JSON, not prose" actually matters.
## Why this model exists
Most instruction-tuned models *can* produce JSON when asked, but they tend to wrap it in
explanation, second-guess the schema, or take an unnecessarily long reasoning path to get
there. This fine-tune trains that overhead away, so the model goes straight from a schema
and a block of text to a clean, parseable JSON object.
## Training details
| | |
|---|---|
| Base model | unsloth/gemma-4-e2b-it-unsloth-bnb-4bit |
| Method | QLoRA |
| Dataset | [interstellarninja/json-mode-agentic](https://huggingface.co/datasets/interstellarninja/json-mode-agentic) |
| Task | Schema-guided JSON extraction from natural language |
| License | apache-2.0 |
## Evaluation
Tested informally against the base model on a set of hand-written extraction tasks,
covering simple schemas, nested/typed schemas, and — most importantly — cases where the
input text is missing information the schema asks for.
**Speed.** On every test, the fine-tuned model produced output immediately, with no visible
reasoning phase. The base model consistently reasoned through a multi-step "analyze, map,
construct, review" process first, taking 30+ seconds before reaching the same answer.
**Accuracy on typed schemas.** On a schema mixing strings, numbers, booleans, and arrays
(e.g. `price: number`, `in_stock: boolean`, `tags: [string]`), the fine-tuned model matched
every field type correctly, including nested arrays and decimal numbers. On a separate,
simpler test, it returned one field (`age`) as a string instead of the integer the schema
specified — the base model got this particular field right. Across the full test set this
looked like an isolated slip rather than a systematic pattern, but it's a real, observed
behavior worth knowing about if your use case depends on strict type fidelity.
**Handling missing data.** This was the most important test. When a required field wasn't
present anywhere in the input text, the fine-tuned model correctly returned `null` for that
field instead of inventing a plausible-looking value to fill the schema. This matters more
than it might sound — a structured-output model that fabricates missing fields to "complete"
a schema is a real liability in any pipeline that trusts its output, and this model didn't
do that in testing.
**Bottom line:** significantly faster and more direct than the base model on structured
extraction tasks, with strong type accuracy on complex schemas and correct, honest behavior
on missing data. The one observed weak spot — an occasional type mismatch on simpler
schemas — is worth validating against your own schema and data before relying on it in
production.
This isn't a formal benchmark result, and it's a small test set. If you run it against
something more rigorous (JSON-mode-eval, a custom test suite, or your own production data),
I'd genuinely like to hear how it does — open an issue or start a discussion on this repo.
## How to use
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained(
"agentbyumer/gemma4-e2b-structured-output",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("agentbyumer/gemma4-e2b-structured-output")
prompt = """Schema: {"name": "string", "age": "integer", "email": "string"}
Text: "Hi, I'm Sarah Ahmed, I'm 29 years old, you can reach me at sarah.ahmed@email.com"
Task: Extract the information into the given JSON schema."""
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
```
A GGUF-quantized version for local/CPU inference is planned — check back or watch this repo
for updates.
## Part of an ongoing series
This is one of several small, task-focused fine-tunes I'm building and evaluating as part
of exploring what narrow specialization can (and can't) improve in sub-5B parameter models —
covering function-calling, math reasoning, code generation, and structured output so far.
More context on the approach and results across the series.