Text Generation
Transformers
ONNX
Safetensors
English
qwen2
information-extraction
structured-output
json
maintenance
edge
conversational
text-generation-inference
Instructions to use thinkingdbx/FIELDNOTEx-500M with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use thinkingdbx/FIELDNOTEx-500M with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="thinkingdbx/FIELDNOTEx-500M") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("thinkingdbx/FIELDNOTEx-500M") model = AutoModelForCausalLM.from_pretrained("thinkingdbx/FIELDNOTEx-500M", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use thinkingdbx/FIELDNOTEx-500M with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "thinkingdbx/FIELDNOTEx-500M" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "thinkingdbx/FIELDNOTEx-500M", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/thinkingdbx/FIELDNOTEx-500M
- SGLang
How to use thinkingdbx/FIELDNOTEx-500M with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "thinkingdbx/FIELDNOTEx-500M" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "thinkingdbx/FIELDNOTEx-500M", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "thinkingdbx/FIELDNOTEx-500M" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "thinkingdbx/FIELDNOTEx-500M", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use thinkingdbx/FIELDNOTEx-500M with Docker Model Runner:
docker model run hf.co/thinkingdbx/FIELDNOTEx-500M
|
Download README.md from thinkingdbx/FIELDNOTEx-500M: direct link, hf CLI and curl.
- Browser
- Download file 7.93 kB
-
https://huggingface.co/thinkingdbx/FIELDNOTEx-500M/resolve/main/README.md
- Command line
-
hf download hf://thinkingdbx/FIELDNOTEx-500M/README.md
-
curl -L -o README.md https://huggingface.co/thinkingdbx/FIELDNOTEx-500M/resolve/main/README.md
7.93 kB
| license: apache-2.0 | |
| base_model: Qwen/Qwen2.5-0.5B-Instruct | |
| language: | |
| - en | |
| pipeline_tag: text-generation | |
| library_name: transformers | |
| tags: | |
| - information-extraction | |
| - structured-output | |
| - json | |
| - maintenance | |
| - onnx | |
| - edge | |
| # FIELDNOTEx-500M | |
| Turns a technician's maintenance note into one JSON record that a | |
| maintenance system can file. It is small enough to run on a Raspberry Pi 5 | |
| with no network. | |
| ``` | |
| P-104 leaking at the seal, replaced 2x seal, pressure back to 3.2 bar, recheck in 2 weeks | |
| ``` | |
| ```json | |
| {"asset_id": "P-104", "asset_type": "pump", "issue": "leak", "severity": null, | |
| "action": "replaced_part", "parts": [{"part": "seal", "qty": 2}], | |
| "reading": {"value": 3.2, "unit": "bar"}, "follow_up": true, "due_days": 14} | |
| ``` | |
| It is a full fine-tune of Qwen2.5-0.5B-Instruct. It comes as transformers | |
| weights and as two ONNX exports, INT4 (452 MB) and INT8 (1,051 MB). | |
| ## The record | |
| | Field | Values | | |
| |---|---| | |
| | `asset_id` | the tag, upper case with a hyphen: `P-104`, `PR-15` | | |
| | `asset_type` | pump, compressor, conveyor, motor, valve, boiler, chiller, fan, generator, press | | |
| | `issue` | leak, vibration, overheating, noise, pressure_drop, electrical_fault, wear, blockage, corrosion, none | | |
| | `severity` | low, medium, high, critical, or `null` when the note does not say | | |
| | `action` | inspected, repaired, replaced_part, adjusted, cleaned, lubricated, shut_down, none | | |
| | `parts` | `[{"part": "seal", "qty": 2}]`, or `[]` | | |
| | `reading` | `{"value": 3.2, "unit": "bar"}` with unit C, bar, mm/s, A or rpm, or `null` | | |
| | `follow_up` | `true` when the note asks for another visit | | |
| | `due_days` | days until that visit ("2 weeks" is 14), or `null` | | |
| The lists are fixed. The model has not learnt any value outside them, though | |
| it can still write one (see below). Check every value against the lists before | |
| you file the record. | |
| ## Results | |
| Exact match means every field of the record is right. The base model scores | |
| 0% on both test sets. | |
| | | Held-out phrasings (300) | Hand-written (40) | | |
| |---|---|---| | |
| | Full precision | 71.7% | 80.0% | | |
| | ONNX INT8, 1,051 MB | 71.7% | 80.0% | | |
| | ONNX INT4, 452 MB | 72.0% | 77.5% | | |
| - **Held-out phrasings:** generated notes whose wording and layouts never | |
| appear in training. They test whether the model learnt the task or the | |
| sentences. | |
| - **Hand-written:** 40 notes written by a person, outside any template. With 40 | |
| cases, one note is 2.5 points. | |
| - **INT8 against full precision:** the same answer on every one of the 340 | |
| notes. | |
| - **INT4 against full precision:** 5 notes broken and 6 mended on held-out, | |
| and 1 broken on hand-written. That is within chance. | |
| **Speed.** Decode speed on 4 threads of an x86 cloud host was 29 tok/s for INT4 | |
| and 30 tok/s for INT8. A record is about 70 tokens, after a prompt of about | |
| 270. **It has not been timed on a Raspberry Pi yet.** The memory-bandwidth | |
| ceiling for a Pi 5 is about 45 tok/s for INT4 and 30 for INT8. | |
| ## Use | |
| The model was trained on one exact instruction, in `prompt.txt`, with the | |
| note appended after `Field note: `. Use that prompt word for word and decode | |
| greedily. Another prompt, or sampling, gives worse records. | |
| ### transformers | |
| ```python | |
| import json | |
| from huggingface_hub import hf_hub_download | |
| from transformers import AutoModelForCausalLM, AutoTokenizer | |
| repo = "thinkingdbx/FIELDNOTEx-500M" | |
| prompt = open(hf_hub_download(repo, "prompt.txt")).read() | |
| tok = AutoTokenizer.from_pretrained(repo) | |
| model = AutoModelForCausalLM.from_pretrained(repo) | |
| note = "P-104 leaking at the seal, replaced 2x seal, pressure back to 3.2 bar, recheck in 2 weeks" | |
| ids = tok.apply_chat_template([{"role": "user", "content": prompt + note}], | |
| add_generation_prompt=True, return_tensors="pt", return_dict=True) | |
| out = model.generate(**ids, max_new_tokens=200, do_sample=False) | |
| record = json.loads(tok.decode(out[0][ids["input_ids"].shape[1]:], skip_special_tokens=True)) | |
| ``` | |
| ### ONNX Runtime (INT4 or INT8) | |
| The exports were made with optimum-onnx 0.1.0 and onnxruntime 1.31.0. The | |
| INT4 export uses `MatMulNBits`, which needs a recent ONNX Runtime. | |
| ```python | |
| import json | |
| from huggingface_hub import snapshot_download | |
| from optimum.onnxruntime import ORTModelForCausalLM | |
| from transformers import AutoTokenizer | |
| path = snapshot_download("thinkingdbx/FIELDNOTEx-500M", allow_patterns=["onnx/int4/*", "prompt.txt"]) | |
| prompt = open(f"{path}/prompt.txt").read() | |
| tok = AutoTokenizer.from_pretrained(f"{path}/onnx/int4") | |
| model = ORTModelForCausalLM.from_pretrained(f"{path}/onnx/int4") | |
| note = "compressor C-7 overheating again, 104C at the discharge. shut it down until we get parts. urgent - critical" | |
| ids = tok.apply_chat_template([{"role": "user", "content": prompt + note}], | |
| add_generation_prompt=True, return_tensors="pt", return_dict=True) | |
| out = model.generate(**ids, max_new_tokens=200, do_sample=False) | |
| record = json.loads(tok.decode(out[0][ids["input_ids"].shape[1]:], skip_special_tokens=True)) | |
| ``` | |
| Every one of the 340 test answers parsed as JSON. Still validate the record, | |
| values included, before you file it. | |
| ## Files | |
| | Path | What | Size | | |
| |---|---|---| | |
| | `model.safetensors` | full-precision weights (fp32) | 1.98 GB | | |
| | `onnx/int4/` | 4-bit weights in blocks of 16, symmetric; embedding table quantised too | 452 MB | | |
| | `onnx/int8/` | 8-bit weight-only in blocks of 32; embedding table kept at fp32 | 1,051 MB | | |
| | `prompt.txt` | the instruction the model was trained on | | | |
| ## What it gets wrong | |
| Most misses on held-out notes are in `issue` (43–46 of 300 notes) and `action` | |
| (26). They cluster on wording the model never saw: | |
| - **"sorted it out"** comes out as `"action": "sorted"`, which is not a value | |
| in the list, on all 26 held-out notes. It should be `repaired`. Words copied | |
| from the note are the commonest way the model leaves its lists. | |
| - **"running rough"** gives `vibration` in 4 notes of 16, and `none` in the | |
| other 12. | |
| - **"keeps tripping out"** (an electrical fault) is read as `vibration` in 33 | |
| held-out notes of 34, and on the hand-written note too. | |
| - **Counts in words**, as in "replaced the seals, 3 of them", can come out as | |
| `qty: 1`. | |
| - **The asset tag is not used** to infer the asset type. A note that says only | |
| "F-9" with no other word for fan relies on the wording. | |
| How well the model reads one particular phrasing also moved between two | |
| training runs that differed only in the random draw of training notes. Treat | |
| any single phrasing in the lists above as an example, not a guarantee. | |
| ## Training | |
| - **Data:** 8,000 synthetic notes from a deterministic generator. The | |
| generator computes every label. A language model never wrote or checked a | |
| record. | |
| - **Phrasing:** each field drew its wording from pools of hand-written | |
| phrasings, 6 to 8 per value. On top of those, Qwen2.5-7B-Instruct proposed | |
| 364 phrasings, which a person reviewed one by one. Any proposed phrasing | |
| that appeared in a test note, or contained one, was removed before review. | |
| - **Run:** full fine-tune, 500 steps at an effective batch of 32, learning rate | |
| 2e-5 with cosine decay, sequence length 512, on one NVIDIA L4. | |
| - **Exports:** made after training, then scored again on both test sets with | |
| ONNX Runtime. An export would have been refused if it had lost more than 2 | |
| points on either set, with more answers broken than chance allows. | |
| Trained with Foundry by thinkingdbx. | |
| ## Limitations | |
| - **English only.** The training notes use industrial maintenance language, | |
| and only that. | |
| - **One note, one record.** A note covering two assets gets one record. | |
| - **Synthetic training data.** The hand-written set is the best guide to real | |
| notes, and it has only 40 notes. Test it on your own notes before relying on | |
| it. | |
| - **Fixed lists.** Assets, issues and units outside the table are not | |
| covered. Expect a wrong value, or a word copied from the note. | |
| ## License | |
| Apache 2.0, as for the base model, Qwen2.5-0.5B-Instruct. | |