Skip to main content

🎯 A Thai Jev is here! OpenThai-SystemOne

Announced 20 September 2026

A Thai Jev is here: an open-source model by the OpenThai team, named OpenThai-SystemOne

0.8B parameters61.9 public benchFree, Apache-2.0Thai + English

Text + questions in → answers with a confidence score out, in a single pass.

Five days after TypeSafe launched Jev (a "System One model" that generates no text but answers decisions with probabilities in one pass), the OpenThai team has released an open-source version for Thai + English, named OpenThai-SystemOne.

  • 0.8B parameters, runs on a laptop
  • Qwen3.5-0.8B base, continued-pretrained on ~5B Thai tokens, with the 248k-word LM head replaced by a "256-slot decision head"
  • Feed it a state (text/JSON) + choice / score / yes-no questions → every question answered with confidence in one forward pass
  • On the same 13-subset public benchmark as Bespoke-Nimble-9B: ours 61.9 / Nimble-9B 74.8 / Jev 76.0 / raw Qwen3.5-0.8B 45.4 (ahead of the 9B on 4 of 13 subsets). Thai tasks: intent 86.4%, news topic 97.7%, XNLI-th 76.5%
  • Use it for: Text Classification, Sentiment Analysis, Agentic Computer Use (picking the action for an AI agent)
  • Apache-2.0, all of it open: weights, training scripts, configs and synthetic data

The API contract mirrors TypeSafe AI's POST /v1/systemone (Jev), so existing code can point at this model unchanged.

Try it in your browser

Play with OpenThai-SystemOne in your browser + API docsiapp.co.th/docs/llm/openthai-systemone

Download and install

OpenThai-SystemOne — weights and model card with benchmark tableshuggingface.co/iapp/OpenThai-SystemOne

Code, configs and every training script — GitHubgithub.com/iapp-technology/openthai-systemone

pip install "git+https://github.com/iapp-technology/openthai-systemone"

Try it

A real exchange with the model: one customer ticket, two questions, both answered in a single forward pass (91 input tokens, 0 output tokens).

curl -s https://api.iapp.co.th/v3/store/openthai/systemone -H "apikey: $IAPP_API_KEY" -H "content-type: application/json" -d '{
"state": {"ticket": "โดนหักเงินซ้ำสองครั้ง ขอเงินคืนด่วน"},
"questions": {
"department": {"type": "choice", "instructions": "ทีมใดควรรับผิดชอบ",
"criteria": {"billing": "การเงิน/คืนเงิน", "technical": "ระบบใช้งานไม่ได้", "sales": null}},
"refund": {"type": "noul", "instructions": "ลูกค้าขอเงินคืนหรือไม่"}
}}'
{"answers": {"department": {"choice": "billing", "probabilities": {"billing": 0.972, "technical": 0.009, "sales": 0.018}, "confidence": 0.87},
"refund": {"noul": 0.954}}, "usage": {"input_tokens": 91, "output_tokens": 0}}

🔑 Public API

The endpoint https://api.iapp.co.th/v3/store/openthai/systemone on the iApp AI Marketplace takes a free iApp API key. Details and a playground are at iapp.co.th/docs/llm/openthai-systemone, or run the model on your own machine as shown below.

Run it locally (CUDA, Apple MPS or CPU):

from openthai_systemone import SystemOneClient, Choice, Score, Noul

c = SystemOneClient("iapp/OpenThai-SystemOne")
r = c.system_one(
state={"ticket": "โดนหักเงินซ้ำสองครั้ง ขอเงินคืนด่วน โทรไปสามรอบแล้วไม่มีใครรับ"},
questions={
"department": Choice(instructions="ทีมใดควรรับผิดชอบ", criteria={"billing": "การเงิน/คืนเงิน", "technical": "ระบบใช้งานไม่ได้", "sales": None}),
"frustration": Score(instructions="ลูกค้าหงุดหงิดแค่ไหน", criteria=["ใจเย็น", "หงุดหงิดแต่สุภาพ", "โกรธมาก"]),
"refund": Noul(instructions="ลูกค้าขอเงินคืนอย่างชัดเจนหรือไม่"),
},
)
print(r.answers["department"].choice, r.answers["department"].probabilities)
print(r.answers["frustration"].score, r.answers["refund"].noul)

Serve it over HTTP with the same contract as POST /v1/systemone:

OPENTHAI_SYSTEMONE_MODEL=iapp/OpenThai-SystemOne uvicorn openthai_systemone.server:app --port 8000

Or load it with plain transformers (the remote code ships in the model repo):

from transformers import AutoModel
model = AutoModel.from_pretrained("iapp/OpenThai-SystemOne", trust_remote_code=True)

Three question types

TypeYou giveYou get
choiceinstructions + up to 255 options (name → description or null)choice, probabilities for every option, confidence
scoreinstructions + 2–10 ordered level descriptionsscore (probability-weighted, can be fractional), probabilities, confidence
noula yes/no questionnoul = p(yes)

Every question in a request is answered together in one forward pass. confidence is 1 − normalised entropy, and abstain is the probability that none of the offered options fits.

📊 Numbers

All numbers are zero-shot: the model sees only the state, the instructions and the option names and descriptions. They are for the calibrated v0.1 release.

Bespoke Labs' 13-subset public benchmark (same sources, splits, instructions and sampler used to compare against Jev), macro average:

ModelSizeAverage
OpenThai-SystemOne0.8B61.9
Bespoke-Nimble-9B9B74.8
Jev (TypeSafe AI, closed)76.0
Raw Qwen3.5-0.8B0.8B45.4

Honest reading: the 0.8B model is ahead of the 9B on 4 of 13 subsets (MultiNLI 85.6, SummEval-consistency 84.0, HelpSteer2 42.8, Civil Comments 78.0) and clearly behind on reading-comprehension style yes/no tasks (squad2 at chance, boolq, pubmedqa) and on summary relevance scoring, the one subset where the score head is badly miscalibrated (ECE 0.79). Nimble-9B and Jev numbers are as published by Bespoke Labs (18 September 2026); ours are measured with scripts/06_eval.py on scripts/06b_public_benchmarks.py rebuilds of the same subsets. The per-dataset table with ECE is in the model card.

Thai held-out sets (full eval sets; sets marked * were held out as whole datasets; lower ECE means confidence is more trustworthy):

SetTaskAccuracyECE
Prachathai67knews topic (choice)97.70.005
Prachathai67kper-topic yes/no (noul)94.10.008
MASSIVE-th60-way intent (choice)86.40.048
XNLI-thnatural language inference (choice)76.50.028
XNLI-thentailment yes/no (noul)84.30.042
SIB-200 Thai*7-way topic (choice)77.50.074
Thai contrastive pairs (one-fact flips)choice / noul / score78.7 / 82.3 / 73.20.105 / 0.088 / 0.133
Wongnaireview stars 1–5 (score)63.3 exact (MAE 0.44)0.010
xLAM tool selection (English)tool choice (choice)99.40.007
Wisesight*4-class social sentiment (choice)38.7 (known weak spot, v0.2 targets it)0.341
banking77* (English)77-way intent (choice)32.7 (weak)0.165

Calibration helps where the model is already competent (Thai topic and NLI, Wongnai scoring, MultiNLI: ECE at or below 0.05) and does not rescue sets where accuracy itself is low, because a temperature cannot fix a wrong ranking. On the English public bench the median ECE is 0.15, so treat confidence as reliable on the Thai sets and on NLI and topic tasks, and route low-confidence English yes/no decisions to a bigger model.

Latency — a 3-question request takes about 40 ms on an H100 and 154 ms on a MacBook M3 Max (Apple GPU via MPS). A 255-option question takes 44 ms on an H100 and 1.5 s on the MacBook. Pure CPU is still slow (about 4.6 s), so use a GPU or MPS.

⚙️ How it works

Architecture: state and questions → Qwen3.5-0.8B text tower → hidden state at each ts_answer token → 256-slot decision head → masked softmax → choice / score / noul

  • Backbone — the text tower of Qwen3.5-0.8B-Base (24 layers, hybrid Gated-DeltaNet / attention, 262k context) with the vision encoder removed, then continued-pretrained on ~5B tokens of Thai (web, Wikipedia, parallel Thai↔English, and machine-state text such as accessibility trees and JSON).
  • Decision head — the 248k-token LM head is replaced by a 256-way slot head. Options are introduced by control tokens <|ts_opt_0|> … <|ts_opt_254|>; the hidden state at each question's <|ts_answer|> token is projected to 256 logits, slots beyond the number of options are masked, and a softmax gives the distribution. Slot 255 is abstain (none of the options fits).
  • Reading the answerchoice = argmax, score = Σ pᵢ·i over the ordered levels, noul = p(yes).
  • No position bias — option order is shuffled in training and abstain examples are mixed in, so this is an architecture, not a trick of reading logprobs over the letters A/B/C.

🔬 Training recipe

Every stage is in the GitHub repo, one script per stage, reproducible on a single H100.

  1. scripts/00_prepare_base.py — drop Qwen3.5-0.8B's vision encoder, keep the text tower (752M parameters).
  2. scripts/01_cpt_data.py + scripts/02_cpt_train.py — Thai-heavy continued pretraining (filtered FineWeb-2 Thai, Thai Wikipedia, Thai instruction and summary text, OPUS Thai↔English, FineWeb-Edu replay, synthetic accessibility trees and JSON). One H100, about 40 hours. Held-out perplexity 31.4 → 5.38.
  3. scripts/03_decision_data.py — 1.81M decision records converted from 21 public datasets (Thai: wisesight*, wongnai, prachathai, XNLI-th, MASSIVE-th, SIB-200*, ThaiExam, iapp_wiki_qa, Thai toxicity; English: MNLI, MMLU, ARC, HelpSteer2, AG News, DBpedia, CLINC, banking77*, Mind2Web, xLAM tools). Sets marked * were held out entirely for evaluation.
  4. scripts/03b_synth_generate.py — about 100k synthetic Thai/English decision tasks generated with Qwen3.6-35B-A3B, each blind-relabelled and filtered for answer leakage (dataset iapp/openthai2.0-systemone-synth).
  5. scripts/04_decision_train.py — head swap + 12k-step SFT, then a calibration stage (Brier loss + per-type temperature) so that higher confidence really means higher accuracy.
  6. scripts/06b_public_benchmarks.py — rebuilds Bespoke Nimble's 13-subset public benchmark for a like-for-like comparison.

👨‍👩‍👧 The OpenThai 2.0 family

ModelWhatSizeStatus
OpenThai 2.0Thai chat and reasoning LLM, reads images27Breleased
OpenThai 2.0 LegalThai law model for RAG30B-A3Breleased
OpenThai-SystemOneThai + English decision model (no text generation)0.8Breleased
OpenThai-SystemOne CPTthe Thai-pretrained base underneath (research use)0.8Bprivate for now

⚠️ Limits

  • Version 0.1 — a 0.8B model is not a reasoning model. It will not do multi-step verification or arithmetic.
  • It can only answer with the options you give, but it can still be wrong — it cannot emit an invalid option, but it can pick the wrong one. Use the confidence field and route low-confidence cases to a bigger model or a human.
  • Text only — no images. Up to 255 options per question (bucket into groups for more) and 64k tokens per request.
  • Pure CPU is still slow — use a GPU or Apple MPS.
  • Known v0.1 weak spots — Thai social-media sentiment (Wisesight 38.7), fine-grained 77-way English intents (banking77 32.7), extractive-QA style yes/no (squad2 at chance), and summary relevance scoring. v0.2 adds a synthetic Thai sentiment set and a second SFT round; expect the first to move, not the others.
  • English calibration is weaker than Thai — median ECE 0.15 versus 0.05 or below, because the training mix is Thai-heavy by design.

🤝 Help us build it

  • More Thai test sets — especially tasks with many options and UI/agent tasks. Open an issue on GitHub.
  • GGUF / ONNX / MLX — the head is a plain Linear layer, so conversions are straightforward if you know the toolchain.
  • Domain LoRA adapters — share yours; the plan is "one base, N adapters".
  • Talk to us on the OpenThaiGPT Discord and the Facebook group.

📄 Licence and credits

Apache-2.0. Built by iApp Technology / OpenThaiGPT on Qwen3.5-0.8B-Base (Apache-2.0). Inspired by TypeSafe AI's System One models (Jev); this is an independent open re-implementation and is not affiliated with TypeSafe AI.

🙏 Thank you, Siam AI

Siam AI Corporation

The Thai continued pretraining, SFT and every evaluation ran on NVIDIA H100 GPUs generously provided by Siam AI Corporation. Thank you for your continued support of open Thai AI.