senthil090's picture
Update README.md
5aaf6c0 verified
|
Raw
History Blame
7.58 kB
---
language:
- en
library_name: transformers
base_model: LiquidAI/LFM2.5-350M
tags:
- schema-extraction
- json-extraction
- structured-output
- information-extraction
- lora
- edge-ai
- schemalm
---
# SchemaLM v2 β€” LFM2.5 350M
A 350M parameter model fine-tuned for **JSON-schema-conditioned information extraction**.
Give it a JSON Schema and any unstructured text β€” it returns a JSON object that matches the schema exactly.
**Base model:** [`LiquidAI/LFM2.5-350M`](https://huggingface.co/LiquidAI/LFM2.5-350M) (SSM hybrid, ideal for edge/CPU deployment)
---
## Benchmark Results
| Metric | Score |
|---|---|
| Overall score (v2 training benchmark) | **97.7%** |
| JSON validity | **100%** |
| Schema conformance | **100%** |
| Field extraction accuracy | **97.6%** |
| Internal benchmark cases | **96.2%** |
Evaluated on a 25-case internal benchmark covering easy/medium/hard extraction across 7 domains.
| Domain | Avg Accuracy |
|---|---|
| Software Projects | ~74% |
| Governance / Compliance | ~75% |
| HR | ~85% |
| Education | ~81% |
| Sales | ~55% |
| Healthcare | ~53% |
| Support (phone) | ~61% |
---
## Training
- **Dataset:** 49K synthetic schema-extraction examples (93 schemas, 29 domains, nested object/array coverage)
- **Method:** PEFT/LoRA SFT β€” rank 32, alpha 64, ~2% trainable parameters
- **Epochs:** 5 | **LR:** 2e-4 (cosine) | **Max seq:** 768 tokens
- **Precision:** bf16 on Ampere/Hopper, fp16 otherwise
---
## Usage
The model follows the **ChatML format**: system message = JSON Schema, user message = unstructured text, assistant response = JSON.
### Basic (Transformers)
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch, json
model_id = "senthil090/schemalm-v2-lfm2-350m"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id, torch_dtype=torch.bfloat16, device_map="auto"
)
model.eval()
def extract(schema: dict, text: str, max_new_tokens: int = 256) -> dict:
messages = [
{"role": "system", "content": json.dumps(schema)},
{"role": "user", "content": text},
]
prompt = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
out = model.generate(
**inputs,
max_new_tokens=max_new_tokens,
do_sample=False,
repetition_penalty=1.08,
)
raw = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
return json.loads(raw.strip())
```
---
### Example 1 β€” Sprint planning note β†’ structured task
```python
schema = {
"type": "object",
"properties": {
"task_title": {"type": "string"},
"assignee": {"type": "string"},
"priority": {"type": "string", "enum": ["critical", "high", "medium", "low"]},
"story_points": {"type": "integer"},
"status": {"type": "string", "enum": ["todo", "in_progress", "done"]},
"epic": {"type": "string"},
},
"required": ["task_title", "assignee", "priority"],
}
text = (
"Assign the Redis caching implementation to Priya for Sprint 14. "
"It's high priority under the Performance epic, estimated 5 story points. "
"Mark it as in progress since she already started."
)
result = extract(schema, text)
# β†’ {
# "task_title": "Redis caching implementation",
# "assignee": "Priya",
# "priority": "high",
# "story_points": 5,
# "status": "in_progress",
# "epic": "Performance"
# }
```
---
### Example 2 β€” Nested support ticket (nested objects + arrays)
```python
schema = {
"type": "object",
"properties": {
"customer": {
"type": "object",
"properties": {
"name": {"type": "string"},
"company": {"type": "string"},
"email": {"type": "string", "format": "email"},
},
"required": ["name", "company"],
},
"issue": {
"type": "object",
"properties": {
"summary": {"type": "string"},
"severity": {"type": "string", "enum": ["low", "medium", "high", "critical"]},
},
"required": ["summary", "severity"],
},
"actions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"owner": {"type": "string"},
"task": {"type": "string"},
},
"required": ["owner", "task"],
},
},
},
"required": ["customer", "issue"],
}
text = (
"Support note: customer Priya Shah from Velocity Corp, email priya@velocity.io. "
"Dashboard charts won't load β€” severity high. "
"Action: Sarah to open an engineering ticket. Marcus to send ETA to customer."
)
result = extract(schema, text)
# β†’ {
# "customer": {"name": "Priya Shah", "company": "Velocity Corp", "email": "priya@velocity.io"},
# "issue": {"summary": "Dashboard charts won't load", "severity": "high"},
# "actions": [
# {"owner": "Sarah", "task": "open an engineering ticket"},
# {"owner": "Marcus", "task": "send ETA to customer"}
# ]
# }
```
---
### Example 3 β€” Compliance finding with date and enum fields
```python
schema = {
"type": "object",
"properties": {
"finding_id": {"type": "string"},
"standard": {"type": "string", "enum": ["ISO27001", "SOC2", "HIPAA", "GDPR", "PCI-DSS"]},
"clause": {"type": "string"},
"severity": {"type": "string", "enum": ["critical", "major", "minor", "observation"]},
"description": {"type": "string"},
"due_date": {"type": "string", "format": "date"},
"owner": {"type": "string"},
"status": {"type": "string", "enum": ["open", "in_remediation", "closed"]},
},
"required": ["standard", "severity", "description", "due_date"],
}
text = (
"Audit finding AF-2024-089: ISO27001 clause A.9.4.2 violation β€” "
"privileged accounts are not protected with MFA. Severity: major. "
"Remediation owner: Chen, due by 2024-09-30. Status: in_remediation."
)
result = extract(schema, text)
# β†’ {
# "finding_id": "AF-2024-089",
# "standard": "ISO27001",
# "clause": "A.9.4.2",
# "severity": "major",
# "description": "Privileged accounts are not protected with MFA",
# "due_date": "2024-09-30",
# "owner": "Chen",
# "status": "in_remediation"
# }
```
---
### Example 4 β€” CPU inference (no GPU)
```python
model = AutoModelForCausalLM.from_pretrained(
"senthil090/schemalm-v2-lfm2-350m",
torch_dtype=torch.float32, # fp32 for CPU
)
model.eval()
# Same extract() function as above β€” just slower (~5–15s per call on a modern CPU)
```
---
## Limitations
- Best on extraction tasks (reading text and pulling fields) β€” not a general-purpose chat model
- Weaker on very long schemas (>50 fields) or schemas with complex `pattern`/`format` constraints
- Sales numeric extraction and phone-call transcripts have lower accuracy (~50–60%) β€” targeted in v2.1 hardcase training
- Not suitable for code generation, reasoning, or creative tasks
## Citation
```
@misc{schemalm-v2,
title = {SchemaLM v2 β€” JSON Schema-Conditioned Information Extraction},
author = {Senthil},
year = {2025},
url = {https://huggingface.co/senthil090/schemalm-v2-lfm2-350m}
}
```