ข้ามไปยังเนื้อหาหลัก

วิธีใช้ OpenThai 2.0 OCR Text และ OCR Markdown บน Windows, Mac และ Linux

· อ่าน 11 นาที
Kobkrit Viriyayudhakorn
CEO @ iApp Technology

วันนี้เราเปิดให้ดาวน์โหลดโมเดล OCR ภาษาไทยฟรีสองตัว คือ OpenThai 2.0 OCR Text และ OpenThai 2.0 OCR Markdown คู่มือนี้แสดงวิธีรันทั้งสองตัวบนเครื่องของคุณเอง ทั้ง Windows, macOS และ Linux ตั้งแต่ติดตั้ง Python จนแปลง PDF เป็นข้อความหรือ Markdown ได้ เอกสารของคุณไม่ออกจากเครื่อง

เลือกใช้โมเดลไหน​

OpenThai 2.0 OCR TextOpenThai 2.0 OCR Markdown
ผลที่ได้ข้อความของหน้าตามลำดับการอ่าน พร้อมกรอบและค่าความมั่นใจของทุกบรรทัดMarkdown โดยเขียนตารางเป็น HTML (rowspan และ colspan) พร้อมกรอบและประเภทของทุกบล็อก
ขนาดดาวน์โหลด4 MB2.5 GB
รันบนCPU ใดก็ได้ ไม่ต้องใช้ GPUGPU ของ NVIDIA (เร็วที่สุด), Mac ชิป Apple silicon หรือ CPU
ความเร็วราว 0.5 วินาทีต่อหน้าบน Mac ชิป M3 Max1.6 วินาทีต่อหน้าบน NVIDIA H100 หนึ่งใบ, 15 ถึง 27 วินาทีต่อหน้าบน Mac ชิป M3 Max
สัญญาอนุญาตApache-2.0OpenMDW-1.1

ใช้ OCR Text เมื่อต้องการตัวหนังสือ เช่น ค้นหา ดึงข้อความจากเอกสารสแกน หรือส่งต่อให้แชตบอต ใช้ OCR Markdown เมื่อรูปแบบหน้าสำคัญ โดยเฉพาะตาราง ที่ตัวเลขต้องอยู่ในแถวและคอลัมน์เดิม

ตัวเลขบน Mac วัดสำหรับคู่มือนี้บน MacBook Pro ชิป M3 Max กับหนังสือราชการไทยหนึ่งหน้าและหน้าตารางหนึ่งหน้า ส่วนตัวเลขบน H100 มาจากการ์ดโมเดล

ไม่ต้องเขียนโค้ด: Chinda Bot​

Chinda Bot ผู้ช่วยบนเดสก์ท็อปที่ใช้ได้ฟรีของเรา มี OCR Text อยู่ในตัวแล้ว แนบไฟล์ PDF ด้วยปุ่มคลิปหนีบหรือลากมาวางในแชต ทุกหน้าจะถูกอ่านบนเครื่องของคุณ คลิกที่ชื่อไฟล์เพื่อดูและคัดลอกข้อความที่อ่านได้ Chinda Bot ใช้ได้บน Mac ชิป Apple silicon, เครื่อง Windows (Intel หรือ AMD และ Windows on Arm) และ Linux arm64

Chinda Bot อ่านเป็นบรรทัดข้อความเท่านั้น ถ้าต้องการให้ตารางยังเป็นตาราง ให้ใช้ OCR Markdown ตามขั้นตอนด้านล่าง

ก่อนเริ่ม: ติดตั้ง Python​

ทั้งสองโมเดลรันด้วย Python 3.10 ขึ้นไป เราทดสอบคู่มือนี้ด้วย Python 3.13 บน macOS และ Python 3.12 บน Ubuntu 24.04

ดาวน์โหลด Python 3.13 จาก python.org แล้วรันตัวติดตั้ง ในหน้าแรกให้ติ๊ก Add python.exe to PATH จากนั้นเปิด Command Prompt (กดปุ่ม Windows แล้วพิมพ์ cmd) คำสั่งสำหรับ Windows ทั้งหมดในหน้านี้ใช้ใน Command Prompt

OpenThai 2.0 OCR Text ใช้ได้กับทุกเครื่อง​

1. สร้างโฟลเดอร์และสภาพแวดล้อม Python​

mkdir thai-ocr
cd thai-ocr
py -m venv .venv
.venv\Scripts\activate

สภาพแวดล้อมนี้แยกแพ็กเกจที่ติดตั้งออกจากส่วนอื่นของเครื่อง เมื่อเปิดหน้าต่างใหม่ ให้รันบรรทัดสุดท้ายเพื่อเปิดใช้อีกครั้ง

2. ติดตั้งแพ็กเกจและดาวน์โหลดโมเดล​

ใช้สองคำสั่งเดียวกันในทุกระบบ:

pip install onnxruntime opencv-python-headless pyclipper numpy pillow pypdfium2 huggingface_hub
hf download iapp/OpenThai2.0-OCR-Text --local-dir OpenThai2.0-OCR-Text

โมเดลมีสองไฟล์ ขนาด 1.8 MB และ 2.4 MB พร้อมโค้ดสำหรับอ่าน อยู่ในโฟลเดอร์ OpenThai2.0-OCR-Text

Windows on Arm (RTX Spark และเครื่อง Arm อื่น): แพ็กเกจ opencv-python-headless และ pyclipper ยังไม่มีรุ่นสำหรับ Windows on Arm คำสั่ง pip install จึงไม่ผ่านบนเครื่องเหล่านี้ ทางเลือกคือติดตั้ง Python รุ่น x64 จาก python.org ซึ่ง Windows จะรันแบบจำลอง (emulation) และช้ากว่า หรือใช้ Chinda Bot ที่รัน OCR Text บน Windows on Arm ได้โดยตรง

3. บันทึกสคริปต์​

บันทึกโค้ดนี้เป็นไฟล์ ocr_text.py ในโฟลเดอร์ thai-ocr:

ocr_text.py
"""Read Thai and English text from pictures and PDFs with OpenThai 2.0 OCR Text.

Usage: python ocr_text.py document.pdf [more files ...]
Prints the text and saves it next to each file as <file>.txt.
"""
import sys
import time
from pathlib import Path

MODEL_DIR = Path(__file__).resolve().parent / "OpenThai2.0-OCR-Text"
sys.path.insert(0, str(MODEL_DIR))
from runtime.line_engine import LineOCR # noqa: E402


def pages(path):
"""Each page of a PDF as a picture (drawn at 200 dpi), or the picture itself."""
if path.suffix.lower() == ".pdf":
import pypdfium2 as pdfium
pdf = pdfium.PdfDocument(str(path))
for i in range(len(pdf)):
yield pdf[i].render(scale=200 / 72).to_pil()
else:
yield str(path)


ocr = LineOCR(str(MODEL_DIR), threads=2)
for name in sys.argv[1:]:
path = Path(name)
texts = []
for number, page in enumerate(pages(path), start=1):
start = time.perf_counter()
result = ocr.read(page)
seconds = time.perf_counter() - start
print(f"{path.name} page {number}: {len(result['lines'])} lines in {seconds:.2f} s", file=sys.stderr)
texts.append(result["text"])
text = "\n\n".join(texts)
path.with_name(path.name + ".txt").write_text(text, encoding="utf-8")
print(text)

4. อ่านเอกสาร​

python ocr_text.py document.pdf

สคริปต์จะแสดงข้อความและบันทึกเป็นไฟล์ document.pdf.txt อ่าน PDF ทีละหน้า และอ่านรูปภาพ (PNG, JPG และรูปแบบทั่วไปอื่น) ได้โดยตรง ใส่หลายไฟล์พร้อมกันก็ได้ เครื่องรุ่นใหม่ใช้เวลาราวครึ่งวินาทีต่อหน้า

หมายเหตุสองข้อ:

  • ใช้ได้ทั้ง PDF จากการสแกนและ PDF ที่มีข้อความ เพราะทุกหน้าถูกวาดเป็นรูปแล้วอ่าน
  • ถ้ามีหลายพันหน้า ให้เปลี่ยน threads=2 เป็น threads=1 แล้วรันสคริปต์หนึ่งชุดต่อหนึ่งคอร์ของ CPU โดยแบ่งไฟล์กันไป ในโปรเซสเดียว การเพิ่มเธรดเร็วขึ้นได้แค่ราวสองคอร์ การ์ดโมเดลวัดไว้ราว 950 หน้าต่อนาทีบนเซิร์ฟเวอร์ 8 คอร์

OpenThai 2.0 OCR Markdown​

โมเดลนี้มีขนาด 2.5 GB จึงเหมาะกับ GPU เรารันบน Linux ด้วย GPU NVIDIA H100 และทดสอบคู่มือนี้บน Mac ชิป M3 Max เลือกระบบของคุณ:

ถ้ามี GPU ของ NVIDIA: ใช้ WSL 2 ซึ่งรัน Ubuntu ภายใน Windows และให้ Ubuntu ใช้ GPU ผ่านไดรเวอร์ NVIDIA ที่ติดตั้งอยู่แล้ว เปิด PowerShell แบบ administrator แล้วรัน:

wsl --install -d Ubuntu-24.04

รีสตาร์ตเมื่อระบบขอ เปิด Ubuntu จากเมนู Start แล้วทำตามขั้นตอนของ Linux ในหน้านี้ภายใน Ubuntu เรายังไม่ได้ทดสอบ OCR Markdown บน Windows ด้วยตัวเอง

ถ้าไม่มี GPU ของ NVIDIA: ใช้ OCR Markdown API ด้านล่าง หรือใช้ Chinda Bot สำหรับข้อความล้วน

บันทึกโค้ดนี้เป็นไฟล์ ocr_markdown.py ในโฟลเดอร์ที่มี OpenThai2.0-OCR-Markdown อยู่:

ocr_markdown.py
"""Read pictures and PDFs into Markdown with OpenThai 2.0 OCR Markdown.

python ocr_markdown.py document.pdf
runs the model on this computer: an NVIDIA GPU, a Mac's GPU, or the CPU
python ocr_markdown.py document.pdf --server http://localhost:8000/v1
sends the pages to a vLLM server instead (the fastest way)

Saves the Markdown next to each file as <file>.md. Tables come out as HTML.
"""
import argparse
import sys
import time
from pathlib import Path

from PIL import Image
from nemotron_parse.inference import DocumentParser, GenerationError, GenerationSettings, TransformersBackend

MODEL_DIR = Path(__file__).resolve().parent / "OpenThai2.0-OCR-Markdown"


def pages(path):
"""Each page of a PDF as a picture (drawn at 200 dpi), or the picture itself."""
if path.suffix.lower() == ".pdf":
import pypdfium2 as pdfium
pdf = pdfium.PdfDocument(str(path))
for i in range(len(pdf)):
yield pdf[i].render(scale=200 / 72).to_pil()
else:
yield Image.open(path)


def local_parser():
import torch
from transformers import AutoModel, AutoProcessor

if torch.cuda.is_available():
device, dtype = "cuda", torch.bfloat16
elif torch.backends.mps.is_available():
device, dtype = "mps", torch.float32
else:
device, dtype = "cpu", torch.float32
model = AutoModel.from_pretrained(MODEL_DIR, trust_remote_code=True, dtype=dtype).to(device).eval()
processor = AutoProcessor.from_pretrained(MODEL_DIR, trust_remote_code=True)

class Backend(TransformersBackend):
# a vLLM server reads the prompt after a new line; send the same tokens here
def __call__(self, image, *, prompt, **kwargs):
return super().__call__(image, prompt="\n" + prompt, **kwargs)

print(f"Running the model on {device}", file=sys.stderr)
# read greedily (temperature 0); with sampling, a Mac's GPU garbled pages in our test
return DocumentParser(backend=Backend(model, processor), fullpage=GenerationSettings(temperature=0))


args = argparse.ArgumentParser()
args.add_argument("files", nargs="+")
args.add_argument("--server", help="a vLLM server, for example http://localhost:8000/v1")
args = args.parse_args()

parser = DocumentParser(base_url=args.server, model="nemotron-parse") if args.server else local_parser()
with parser:
for name in args.files:
path = Path(name)
parts = []
for number, page in enumerate(pages(path), start=1):
start = time.perf_counter()
try:
parts.append(parser.parse(page, mode="single")["markdown"])
except GenerationError:
parts.append(f"<!-- page {number} could not be read completely -->")
print(f"{path.name} page {number}: {time.perf_counter() - start:.1f} s", file=sys.stderr)
markdown = "\n\n".join(parts)
path.with_name(path.name + ".md").write_text(markdown, encoding="utf-8")
print(markdown)

สคริปต์จะเขียนไฟล์ document.pdf.md โดยแต่ละตารางเป็น HTML <table> ซึ่งโปรแกรมแสดง Markdown และโมเดลภาษาส่วนใหญ่อ่านได้ทันที ถ้ามีหน้าใดถูกตัดเพราะยาวเกินขีดจำกัด สคริปต์จะบันทึกหมายเหตุไว้ในไฟล์แล้วอ่านหน้าถัดไปต่อ

ไม่มี GPU? ใช้ API​

ทั้งสองโมเดลมีให้ใช้เป็น API ด้วย ไม่ต้องติดตั้งอะไร:

  • OpenThai 2.0 OCR Markdown API: ส่ง PDF หรือรูปภาพ ได้ Markdown และตารางกลับมา 0.15 IC ต่อหน้า
  • OpenThai 2.0 OCR Text API: ข้อความล้วน Word, PowerPoint, Excel หรือ PDF ที่ค้นหาข้อความได้ เริ่มต้น 0.049 IC ต่อหน้า

ลิงก์​

ถ้าเอกสารภาษาไทยฉบับไหนอ่านได้ไม่ดี ส่งตัวอย่างที่ไม่มีข้อมูลส่วนบุคคลมาที่ sale@iapp.co.th ได้ หน้าเหล่านั้นช่วยให้เราปรับปรุงรุ่นถัดไป