Downloads · 30 days
781
19% of all-time downloads
iapp/openthai2.0-qwen3.8-27b
openthai2.0-qwen3.8-27b is a image-text-to-text model from iapp. Use it for the image-text-to-text task on the model card, and read the license before you ship it in a product. The card lists the license as apache-2.0.
Release notes - v2.0.3 (1 Sep 2026) — Thai factual recall repaired: the freerecall training data carried a phantom-citation register ("บทความระบุ...") and single-shape questions; cleaned and re-drilled with model-writ…
Downloads · 30 days
781
19% of all-time downloads
All-time downloads
4.2K
Public
Parameters
27.8B
317 GB on disk
Likes
14
Public
Click a slice to open those files.
.safetensors56.5 GB · 100%
From the Hugging Face model README
Release notes
- v2.0.3 (1 Sep 2026) — Thai factual recall repaired: the freerecall training data carried a phantom-citation register ("บทความระบุ...") and single-shape questions; cleaned and re-drilled with model-written paraphrases. Paraphrase battery 85/104 (from 79), Thai knowledge battery 21/21, OCR-Eval-104 CER 0.084 (from 0.093), HumanEval 0.982, IFEval-TH 0.837. Known residual: some numeric facts still scatter at temperature 0.7 — use low temperature for factual queries.
- v2.0.2 (31 Aug 2026) — identifies as OpenThai 2.0 (iApp Technology + AIEAT) and adds a Thai-language safety guardrail; stock chat template. Printed-OCR CER about +0.02 vs v2.0.1, other benchmarks unchanged.
- v2.0.1 (30 Aug 2026) — restores closed-book Thai knowledge lost in v2.0.0 (thanks to Dr. Panutat Tejasen's ThaiEval-2026 v3).
- v2.0.0 — initial release. Earlier builds: revision tags
v2.0.1,v2.0.0.Per-version benchmark tables: CHANGELOGS.md.

โมเดล AI โอเพนซอร์ส ด้านความรู้ภาษาไทย เอกสารไทย และงานเอเจนต์ · เปิดตัวโดย iApp Technology ร่วมกับ สมาคมผู้ประกอบการปัญญาประดิษฐ์ประเทศไทย (AIEAT) · Apache 2.0
An open all-in-one Thai AI: reads Thai documents and handwriting at specialist level, answers with Thai knowledge in natural, explanatory Thai, leads its base model and Typhoon on agentic tool use (BFCL) — and keeps its base model's general intelligence.
🌐 Try it FREE right now — no install: chinda3.iapp.co.th 🦙 Or one command on your own machine: ollama.com/openthai/openthai2.0-qwen3.8-27b
ollama run openthai/openthai2.0-qwen3.8-27b
Or serve the full bf16 weights with vLLM:
vllm serve iapp/openthai2.0-qwen3.8-27b \
--max-model-len 32768 --gpu-memory-utilization 0.85 \
--max-num-seqs 128 --reasoning-parser qwen3 --trust-remote-code
One 80 GB GPU (~56 GB bf16). The LoRA adapter alone (7 GB, rank 64) is in adapter/ for
serving on top of Qwen/Qwen3.8-27B with dynamic LoRA.
| Format | Repo | Runs on |
|---|---|---|
| bf16 (this repo) | iapp/openthai2.0-qwen3.8-27b | vLLM / transformers · 1× 80 GB GPU |
| GGUF Q4_K_M / Q8_0 + vision mmproj | iapp/openthai2.0-qwen3.8-27b-GGUF | llama.cpp · CPU or consumer GPU (17 / 29 GB) |
| GGUF IQ2_M (2-bit, 9.8 GB, imatrix) | same repo | recommended 2-bit — importance-matrix calibrated (Thai+EN), passes factual sanity where plain Q2_K slips; still prefer Q4_K_M when it fits |
| MLX 4-bit | iapp/openthai2.0-qwen3.8-27b-MLX-4bit | Apple silicon, 24 GB+ unified memory (~16 GB) |
| MLX 4-bit via TensorFold | iapp/openthai2.0-qwen3.8-27b-MLX-4bit | TensorFold · Apple silicon 48 GB+ or NVIDIA (DGX Spark, RTX 40/50, Hopper, Blackwell) · OpenAI API with DFlash2 drafts |
| INT8 W8A8 | iapp/openthai2.0-qwen3.8-27b-INT8-W8A8 | vLLM · ~40 GB-class GPUs |
| NVFP4 | iapp/openthai2.0-qwen3.8-27b-NVFP4 | vLLM · NVIDIA Blackwell |
| Ollama | openthai/openthai2.0-qwen3.8-27b | ollama run openthai/openthai2.0-qwen3.8-27b — one command, vision + thinking included |
The checkpoint ships the Qwen3.8 MTP draft head (mtp.* tensors,
text_config.mtp_num_hidden_layers: 1), so vLLM can run self-speculative decoding:
vllm serve iapp/openthai2.0-qwen3.8-27b \
--max-model-len 32768 --max-num-seqs 128 --reasoning-parser qwen3 \
--speculative-config '{"method":"qwen3_5_mtp","num_speculative_tokens":2}' \
--trust-remote-code
Speculative decoding is verified token-by-token by the main model, so outputs are identical
with or without it — the draft head only accelerates decoding. Measured: 75.2 tok/s with MTP
vs 50.1 tok/s without (+50%, single-stream, H100, identical prompts, all outputs clean).
Without the flag the head is simply skipped (no overhead). Per format: GGUF exports the head as nextn layers (llama.cpp);
INT8/NVFP4 keep it in bf16; the MLX build omits it (mlx-vlm has no drafter support for this
architecture yet).
INT8-W8A8 / NVFP4 before 2026-08-31 had no draft head. The quantisation export dropped the
mtp.*tensors while the config still advertised them, so--speculative-configran a draft head with no weights: every draft rejected (mean acceptance length 1.00) and decoding ~1.6× slower. Found by Dr. Panutat Tejasen. The repaired repos carry the head in bf16 (model-mtp.safetensors,re:.*mtp.*in the quantisation ignore list) and were verified under vLLM speculative decoding. If your INT8/NVFP4 download predates that, re-download — or serve it without--speculative-config. bf16 weights were never affected.
🇹🇭 Thai knowledge & instruction-following
📄 Thai documents
🤖 Agentic
⚙️ In practice
(The tables in this section were measured on v2.0.0. For the v2.0.1 numbers see the changelog table at the top of this card.)

All numbers measured under identical serving conditions, with the same answer-unwrap scoring pass applied to every model (verified: unwrapping changes OpenThai 2.0's scores by ≤0.001 on every track — it already answers OCR prompts cleanly).
| Benchmark | OpenThai 2.0 (27B) | Qwen3.8-27B (base) | Typhoon 2.5 (30B-A3B) | Pathumma think 3.0 (8B) |
|---|---|---|---|---|
| OpenThaiEval (Thai national exams) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.842</span> | 0.820 | 0.742 | 0.660 |
| Code-switching (TH↔EN)<br><sub>0.985 vs 0.990 = one sample on n=200 — a statistical tie</sub> | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.985</span> | 0.895 | 0.940 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.990</span> |
| HumanEval (coding) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.957</span> | 0.939 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.957</span> | 0.805 |
| MMLU-Redux (5.7k, world knowledge) | 0.916 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.924</span> | 0.884 | 0.762 |
| IFEval-TH (Thai instruction-following) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.795</span> | 0.772 | 0.749 | 0.498 |
| IFEval (EN instruction-following) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.914</span> | 0.902 | 0.846 | 0.630 |
| Benchmark | OpenThai 2.0 (27B) | Qwen3.8-27B (base) | Typhoon-OCR 1.5 (2B) | Pathumma-vision 2.0 (7B) |
|---|---|---|---|---|
| Wikisource TH — books/gazette (n=608) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.126</span> | 0.370 | 0.271 | 0.931 |
| DocBench — government docs (n=906) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.327</span> | 0.530 | 0.551 | 0.691 |
| SEA-DocBench-TH (n=1,499) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.497</span> | 0.559 | 0.575 | 0.832 |
| ThaiOCRBench (n=2,808) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.743</span> | 0.750 | 0.793 | 0.894 |
| MTVQA-TH — scene text (n=231) | 0.819 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.737</span> | 1.000 | 0.905 |
| Thai handwriting — text-disjoint (n=916) | 0.261 | 0.649 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.054</span> | 0.821 |
| OCR-Eval-104 — printed (n=104) | 0.077 | 0.103 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.014</span> | 0.352 |
All four models measured by us on the same suite, each with its own recommended prompts/parameters (Typhoon-OCR via its exact model-card protocol), so the experiment can be repeated with the linked checkpoints above. Read it honestly: Typhoon-OCR 1.5 is an excellent transcription specialist — on clean printed lines and isolated handwriting it beats every model here, including this one. It is also only a transcriber: it accepts a single fixed OCR prompt, so document Q&A and scene-text questions score at or near total error (MTVQA 1.000), and it has no knowledge or assistant ability. OpenThai 2.0 leads on books/gazette reading and on Thai knowledge and instruction-following — the only Thai open model in these tables that reads documents at specialist level and answers questions about them in the same model. Scene text (MTVQA) is its weakest reading track.
English retention: Benchmarking (previous build: 0.333 CER) on a held-out CoSyn-400K English document set. English document reading is functional but is not this model's focus; for EN-primary workloads prefer the base model.
Official Berkeley Function-Calling Leaderboard harness (bfcl-eval 2026.3.23):
3,841 cases across 14 categories, identical OpenAI-function-calling protocol for every model
(tool parser qwen3_xml for the Qwen3.8 family, hermes for Typhoon, per each family's spec).

| Benchmark | OpenThai 2.0 (27B) | Qwen3.8-27B (base) | Typhoon 2.5 (30B-A3B) |
|---|---|---|---|
| BFCL overall — weighted (n=3,841) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.820</span> | 0.811 | 0.792 |
| Multi-turn agentic episodes (n=200) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.775</span> | 0.750 | 0.550 |
| Irrelevance detection — knowing when not to call a tool (n=1,124) | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.779</span> | 0.763 | 0.726 |
Thai-document fine-tuning did not tax tool use: OpenThai 2.0 leads every summary row, with the
largest gap on multi-turn agentic episodes (+22.5 points over Typhoon 2.5). Typhoon is stronger
on several single-turn AST categories; full per-category
results ship in the repo (results/agentic-2026-08/).
| Mode | What it tests | Setup |
|---|---|---|
| Transcription | reading accuracy | image + fixed OCR prompt, thinking disabled, raw CER vs human-verified ground truth |
| Knowledge (MCQ) | Thai/world knowledge | OpenThaiEval / MMLU-Redux via EvalScope, temperature 0 |
| Instruction-following | arbitrary format constraints | IFEval / IFEval-TH |
| Style canary | keeps the explanatory voice | verbosity ratio vs base, terse-on-request rate, OCR-preamble rate |
Benchmark sets are held out from training by an n-gram leakage guard run on every corpus change. Handwriting uses a text-disjoint split: no transcription string in training appears in the test set.
The exact prompts our benchmark numbers were measured with. Where the template is "—", no special prompt is needed — ask naturally in Thai.
| Use case | Prompt template | Thinking |
|---|---|---|
| Full-page transcription (Markdown) | Extract all text from this image as Markdown.<br>- Preserve the reading order and all information on the page.<br>- Render tables as HTML <table> blocks; equations as LaTeX ($...$ inline, $$...$$ block).<br>- Keep the original language of the text (Thai stays Thai, English stays English).<br>- Return only the Markdown, no explanations. | off (enable_thinking: false, image attached) |
| Plain-text transcription | Extract all text from this image as plain text in natural reading order.<br>- Keep the original language of the text.<br>- No markup, no formatting symbols, no explanations — text content only. | off |
| JSON layout extraction | Extract the full content and layout of this document image as JSON with this schema:<br>{"blocks": [{"type": "title|heading|paragraph|table|figure|list|page_number|other", "reading_order": <int>, "content": "..."}]}<br>- Return only valid JSON, no explanations. | off |
| Document Q&A | — (image + natural Thai question) | on (default) |
| Thai knowledge / general assistant | — (plain question; leave max_tokens unset or ≥ 8k) | on (default) |
| Terse / machine-parsed answers | append ตอบสั้นๆ or ตอบเป็น JSON เท่านั้น | on |
| Agentic tool use | standard OpenAI tools=[...] — no prompt template needed | on |
Verbatim model outputs on held-out benchmark items, same image and prompt for both models — all five use the Full-page transcription (Markdown) template above with thinking off.
Case 1 — Thai handwriting (hw_disjoint/48)
Case 2 — Thai handwriting (CPE-OPH) (hw_cpeoph/20)
Case 3 — Book / Royal Gazette page (wikisource_l4/ws4_53969)
Case 4 — Government document (parliament budget) (docbench/parliament_year_60_00000903_p0181)
Case 5 — Thai national exam (OpenThaiEval item 200)
คำถาม: ท่านมีความเห็นอย่างไรต่อแพทย์ที่สั่งยาจากบริษัทที่มักพาแพทย์ไปเที่ยวต่างประเทศ (ข้อสอบจริยธรรมแพทย์ ปี 65) Choice: (1) เป็นการตอบแทนเล็กน้อยมิใช่หรือ (2) ถ้ายาดีจริง ก็เป็นสิ่งที่ทําได้มิใช่หรือ (3) แพทย์คนนี้เห็นแก่ประโยชน์ส่วนตัวใช่หรือไม่ (4) หากแพทย์สั่งยาจากบริษัทนี้อีก เท่ากับว่าแพทย์สนับสนุนการกระทําในสิ่งที่ไม่ถูกต้อง ใช่หรือไม่ (5) เป็นการกระทําที่ดูถูกศักดิ์ศรีความเป็นแพทย์ใช่หรือไม่
Three stages of LoRA fine-tuning (r=64, α=64, all-linear) on ~143k verified rows:
Every stage used a verify-everything pipeline: answers checked against human-confirmed ground truth by n-gram containment; images the model could not read were routed away from explanatory training (anti-hallucination); malformed-Thai, scaffolding-leak, and markup filters on every row; benchmark-leakage guard on the whole corpus.
| Property | Value |
|---|---|
| Base model | Qwen/Qwen3.8-27B (dense VLM, hybrid Mamba-attention) |
| Parameters | 27B |
| Context length | 262,144 tokens (max_position_embeddings); production API serves 131,072; benchmarks run at 16k |
| Modality | image + text → text |
| Languages | Thai (primary), English |
| Precision | bfloat16 safetensors (~52 GB incl. MTP shard) + LoRA adapter (7 GB) |
| MTP draft head | included (1 layer) — self-speculative decoding via qwen3_5_mtp |
| Knowledge cutoff | Inherited from Qwen3.8-27B — Qwen publishes no exact date for this release (≈ early 2026 per third-party tracking; model self-reports are unreliable). OpenThai fine-tuning (to Sep 2026) adds Thai skills, not world events. For anything time-sensitive, pair the model with web search. |
| Training stack | ms-swift 4.3 · LoRA r64/α64 all-linear · 3× H100 |
| Serving | vLLM ≥ 0.19 (verified), OpenAI-compatible |
| License | Apache 2.0 |
--max-num-seqs 128 is required: the hybrid architecture allocates one Mamba cache
block per decode sequence; vLLM's default (1024) aborts engine startup.--reasoning-parser qwen3 and leave thinking ON for all text-only requests.
Measured (QA 2026-08-24, 36 prompts/config): thinking on with max_tokens unset gives 94%
usable answers and 0% reasoning leakage; sending enable_thinking:false on text-only requests
degrades to 42% usable.enable_thinking:false is for image-attached OCR/transcription requests only (measured
safe there: 0% leakage across 84 image requests) — it keeps reasoning text out of
transcriptions.max_tokens unset, or set it ≥ 8192. Small caps starve generation: at 1024 roughly
a third of replies come back empty (finish_reason=length); unset brings this to ~6% (base
model behaves the same). Budget ~3.5k output tokens per long answer.repetition_penalty: 1.05 for long-form Thai generation, and trim the
leading blank line some responses start with (content.lstrip()).Inherited from the base Qwen3.8-27B recommendations, with one OpenThai-specific change:
repetition_penalty 1.05 in non-thinking mode (measured: prevents rare long-form Thai
repetition collapse; short OCR outputs are unaffected).
| Parameter | Thinking mode (assistant work) | Non-thinking mode (image-attached OCR/extraction only) |
|---|---|---|
| Temperature | 1.0 | 0.7 — or <span class="text-xl font-bold text-blue-600 dark:text-blue-400">0.0</span> for deterministic OCR/extraction |
| Top-P | 0.95 | 0.80 |
| Top-K | 20 | 20 |
| Repetition penalty | 1.0 | <span class="text-xl font-bold text-blue-600 dark:text-blue-400">1.05</span> |
| Presence penalty | — | 1.5 |
{"temperature": 0.0, "top_p": 0.8, "top_k": 20, "repetition_penalty": 1.05, "max_tokens": 8192}
All benchmark numbers in this card were measured in non-thinking mode at temperature 0.
Tested configuration: vLLM 0.19, single H100 80GB, --max-model-len 16384–32768,
--gpu-memory-utilization 0.85. All benchmark numbers in this card were produced under
this configuration.
import base64
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="none")
img = base64.b64encode(open("thai_document.jpg", "rb").read()).decode()
r = client.chat.completions.create(
model="iapp/openthai2.0-qwen3.8-27b",
messages=[{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img}"}},
{"type": "text", "text": "อ่านข้อความในเอกสารนี้ทั้งหมด"},
]}],
temperature=0.0,
extra_body={"repetition_penalty": 1.05,
"chat_template_kwargs": {"enable_thinking": False}},
)
print(r.choices[0].message.content)
Ask in natural Thai and it explains; add "ตอบสั้น ๆ" or "ตอบเป็น JSON เท่านั้น" for terse or structured output.
⚠️ Give it room to generate — this is the #1 setup mistake. The model reasons before it answers, so a short context window or a small
max_tokenscap gets eaten by reasoning and the reply comes back empty. Serve with--max-model-len 32768(or more) and leavemax_tokensunset, or set it ≥ 8192. Measured:max_tokens 1024→ ~33% empty replies; unset → ~6%.
TensorFold serves the MLX 4-bit checkpoint
iapp/openthai2.0-qwen3.8-27b-MLX-4bit through an
OpenAI-compatible API on Apple Silicon and on NVIDIA GPUs. It speeds up decoding with speculative drafts, and every
drafted token is checked against the model, so replies are the same as TensorFold decoding this checkpoint one
token at a time. The same checkpoint runs on both backends, with image input.
These instructions are written for TensorFold v0.6.5.
Needs compute capability 8.9 or newer: RTX 40 / 50 series, Hopper, Blackwell, including the DGX Spark (GB10).
docker run -it --gpus all --ipc=host --network host \
-v ~/.cache/huggingface:/root/.cache/huggingface \
nvcr.io/nvidia/pytorch:26.07-py3
# inside the container
python -m pip install "tensorfold[vision] @ git+https://github.com/ashhart/[email protected]"
tensorfold pull iapp/openthai2.0-qwen3.8-27b-MLX-4bit z-lab/Qwen3.8-27B-DFlash2
tensorfold serve iapp/openthai2.0-qwen3.8-27b-MLX-4bit \
--name openthai2.0 --host 0.0.0.0 --port 8080 --vision
The first start compiles CUDA kernels for your GPU, which takes a few minutes once. Add --parallel 4 to decode up to
four requests together. On CUDA the draft model is required: pull it as above, or serve with --no-drafts.
48 GB of unified memory or more is recommended. On a 32 GB Mac the model does not fit TensorFold's default budget
(70% of RAM); raise it with TENSORFOLD_MEMORY_LIMIT_GB, leaving little memory for other apps.
python -m pip install "tensorfold[vision] @ git+https://github.com/ashhart/[email protected]"
tensorfold pull iapp/openthai2.0-qwen3.8-27b-MLX-4bit z-lab/Qwen3.8-27B-DFlash2
tensorfold serve iapp/openthai2.0-qwen3.8-27b-MLX-4bit --name openthai2.0 --vision
Any OpenAI client works with base URL http://<host>:8080/v1 and model openthai2.0.
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="none")
# Text
r = client.chat.completions.create(
model="openthai2.0",
messages=[{"role": "user", "content": "สรุปสาระสำคัญของ พ.ร.บ. คุ้มครองข้อมูลส่วนบุคคล ใน 3 ข้อ"}],
max_tokens=4096,
)
print(r.choices[0].message.content)
# Thai document image (data URL; start the server with --vision-urls to accept public HTTPS links)
import base64
img = base64.b64encode(open("document.png", "rb").read()).decode()
r = client.chat.completions.create(
model="openthai2.0",
messages=[{"role": "user", "content": [
{"type": "text", "text": "อ่านข้อความทั้งหมดในเอกสารนี้"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}},
]}],
max_tokens=4096,
)
print(r.choices[0].message.content)
The model thinks before it answers by default; the reasoning arrives in reasoning_content and the answer in
content, so leave enough max_tokens. Start the server with --no-thinking to answer directly.
z-lab/Qwen3.8-27B-DFlash2 (Apache-2.0) was
trained on base Qwen3.8-27B, not on OpenThai 2.0. It accepts fewer drafted tokens on Thai replies, so the speedup
is smaller than on the base model; the replies themselves are unaffected. Send "draft": false in a request to get
the one-token-at-a-time reference.This model is strongest at reading, explaining, and answering over documents you give it. For tax, legal, medical, or any compliance-sensitive work, we recommend running it with retrieval-augmented generation (RAG) over authoritative sources — e.g. current statutes, official announcements, or your organization's verified knowledge base — plus human review, rather than relying on closed-book statutory recall.
For the legal domain specifically, use our purpose-built Thai legal model:
iapp/openthai2.0-legal-thaillm-nemotron-3-nano-30b-a3b.

@misc{openthai2_2026,
title = {OpenThai 2.0: An Open Thai Knowledge and Document AI},
author = {iApp Technology and Artificial Intelligence Entrepreneur Association of Thailand},
year = {2026},
url = {https://openthai.aieat.or.th}
}
Built by iApp Technology, launched jointly with AIEAT. Base model: Qwen/Qwen3.8-27B (Apache 2.0).

<a href="https://siam.ai"><img src="assets/siamai-logo.png" alt="Siam AI Corporation" width="120"/></a>
ได้รับการสนับสนุน GPU NVIDIA H100 × 8 ใบ จาก บริษัท สยาม เอไอ คอร์เปอเรชั่น จำกัด — ขอขอบคุณเป็นอย่างยิ่งสำหรับการสนับสนุนโครงสร้างพื้นฐานการประมวลผลตลอดโครงการ · siam.ai
Training and evaluation for this model ran on 8× NVIDIA H100 GPUs generously provided by Siam AI Corporation — thank you for supporting open Thai AI.