Docling มักถูกจับไปวางเทียบกับเว็บสแครปเปอร์อยู่บ่อย ๆ แต่จริง ๆ แล้วมันไม่ใช่แบบนั้นเลย นี่คือชุดเครื่องมือแปลงเอกสารจาก IBM Research — ตอนนี้เป็นโปรเจกต์ของ LF AI & Data Foundation — ที่รับไฟล์ที่คุณมีอยู่แล้ว เช่น PDF, DOCX, PPTX, XLSX, HTML และรูปภาพ แล้วแปลงออกมาเป็น Markdown หรือ JSON คำโปรยของมันก็พูดชัดอยู่แล้วว่า "เตรียมเอกสารของคุณให้พร้อมสำหรับ gen AI"
ดังนั้นรีวิวนี้จึงเป็นการทดสอบตัวแปลงเอกสารแบบลงมือจริง ไม่ใช่ตัวครอว์เลอร์ ผลทุกอย่างด้านล่างวัดบนเครื่อง CPU-only เครื่องเดียว (macOS arm64, Python 3.14.2, Docling 2.111.0) ให้คะแนนจากสคริปต์ และนับความล้มเหลวเป็นความล้มเหลวจริง ๆ โค้ดรีโปมีขนาดใหญ่มากและเปลี่ยนแทบทุกวัน — 63,069 stars, 4,449 forks และมีการ push ในวันเดียวกับที่ฉันดึง metadata — ดังนั้นตัวเลขเวอร์ชันหรือจำนวนปัญหาที่เห็นที่นี่ให้มองว่าเป็นภาพถ่าย ณ เวลานั้น ไม่ใช่ค่าคงที่
Docling คืออะไร และไม่ใช่อะไร
หัวใจหลักของ Docling คือ DoclingDocument: แปลงไฟล์เข้าไปเป็นโครงสร้างนี้ แล้วค่อยส่งออกเป็น Markdown, HTML, DocTags หรือ JSON แบบไม่สูญเสียข้อมูล โค้ดนี้ใช้ไลเซนส์ MIT (ไลเซนส์ของโมเดลแต่ละตัวอาจต่างกัน) มีจุดกำเนิดจาก IBM Research Zurich และ ณ วันที่เขียน เวอร์ชันล่าสุดคือ v2.112.0 ซึ่งเพิ่งปล่อยออกมาไม่กี่วันก่อนที่ฉันจะรันทดสอบนี้

ความสามารถเด่นที่สุดคือเส้นทาง PDF และภาพ และเส้นทางนี้ไม่ได้พึ่งการไล่สตริงแบบธรรมดา แต่ขับเคลื่อนด้วยสแต็กโมเดลแมชชีนเลิร์นนิง: โมเดลจัดวางหน้า RT-DETR, โมเดลโครงสร้างตาราง TableFormer, โมเดล vision-language แบบเลือกใช้ได้ และ RapidOCR สำหรับงานสแกน โมเดลเหล่านี้ช่วยกู้ layout ของหน้า ลำดับการอ่าน และโครงสร้างตาราง นี่แหละคือส่วนที่คุ้มค่าแก่การรีวิว และเป็นส่วนที่การทดสอบ HTML อย่างเดียวไม่มีทางเห็น
มีข้อแยกที่ต้องจำไว้ข้อหนึ่งซึ่งช่วยลดความสับสนไปได้หลายวัน Docling ไม่ได้ไปดึงข้อมูลจากที่ไหน มันไม่เรนเดอร์ JavaScript ไม่ฝ่ากำแพง anti-bot และไม่ครอว์ลเว็บ คุณเป็นคนส่งไฟล์ให้มัน แล้วมันจะแปลความไฟล์นั้น การครอว์ลเป็นหน้าที่ของอีกเครื่องมือหนึ่ง ซึ่งเรื่องนี้สำคัญมากเวลามีคนถามว่า Docling แทน Firecrawl ได้ไหม (คำตอบคือไม่ได้ — แต่ใช้เสริมกันได้ และเดี๋ยวฉันจะอธิบายว่าทำไม)
การรันครั้งแรกที่ไม่มีใครบอกคุณล่วงหน้า
pip install docling ติดตั้งได้ผ่านฉลุยบน Python 3.14.2 จากนั้นพอเปิดดูใน venv คุณจะพบว่ามันกินพื้นที่ถึง 1.3 GB Docling ดึงสแต็ก ML ทั้งก้อนมาเป็น hard dependency แม้ว่าคุณจะต้องแปลงแค่ไฟล์ HTML ก็ตาม:

| Dependency | On-disk size (MiB, du) |
|---|---|
| torch (2.13.0) | 536 |
| opencv (cv2) | 119 |
| transformers (5.8.1) | 101 |
| scipy | 99 |
| sympy | 76 |
| pandas | 72 |
| rapidocr (+ bundled models) | 72.1 |
| docling_parse | 30 |
และนี่ยังไม่รวมการแปลง PDF สักไฟล์ด้วยซ้ำ จุดที่แรงเสียดทานจริง ๆ เริ่มขึ้นคือการแปลง PDF ครั้งแรก เพราะตอนนั้นโมเดลจะถูกดาวน์โหลดใหม่ลงใน HuggingFace cache การแปลง PDF ครั้งแรกใช้เวลาประมาณ 224 วินาที — และเกือบทั้งหมดเป็นเวลาที่เสียไปกับการดาวน์โหลด ไม่ใช่การประมวลผล ตัวโมเดล layout และ TableFormer รวมกันกินพื้นที่บนดิสก์ประมาณ 506 MiB (TableFormer 342 MiB + layout 164 MiB, ตรวจด้วย du) และ RapidOCR จะดึง weights ของ PP-OCRv4 ขนาดราว 40 MB ลงไปไว้ใน site-packages แล้วการแปลงไฟล์เดิมรอบสองล่ะ? 0.55 วินาที โมเดลถูกแคชไว้แล้ว คุณจ่ายภาษีครั้งเดียวเท่านั้น

มีตัวเลขหนึ่งที่คุณควรมองข้าม: สคริปต์ coldstart พิมพ์ค่า model_download_mb เท่ากับ 1060.2 อย่าเอาตัวเลขนี้ไปอ้างเป็น footprint จริง เพราะมันมาจาก os.walk ที่ไล่ตาม symlink และ HuggingFace cache เก็บไฟล์โมเดลแต่ละไฟล์ไว้ครั้งเดียวใน blobs/ แล้วค่อย expose ออกมาอีกทีผ่าน symlink ใน snapshots/ — ดังนั้นการไล่ไฟล์จึงนับไฟล์โมเดล 14 ไฟล์ซ้ำสอง รอบ du ที่ตัด symlink ซ้ำออกแล้วได้ตัวเลข ประมาณ 506 MiB (เฉพาะ blobs คือ 505.4 MiB) บทสรุปสำหรับคนที่จะ benchmark Docling คือ ให้รายงานทั้งจำนวนที่ดาวน์โหลดและจำนวนที่อยู่บนดิสก์แยกกัน เพราะมันเป็นคนละเรื่องกัน
ยังมีอีกประเด็นหนึ่งที่มักเล่นงานคนที่กำลังสร้างคอนเทนเนอร์สำหรับ Docling น้ำหนักของ weights กระจายอยู่สองตำแหน่งและดาวน์โหลดคนละจังหวะ ส่วนของ layout กับ TableFormer จะเคารพ HF_HOME และดาวน์โหลดตอนแปลง PDF ครั้งแรก แต่ RapidOCR ไม่ได้ทำแบบนั้น — มันจะไปลงที่ …/site-packages/rapidocr/models/ โดยไม่สนค่า cache ของคุณเลย ถ้าคุณกำลัง pre-bake หรือทำ image แบบ air-gap คุณต้องจัดการทั้งสอง cache และไม่ว่าคุณจะตั้ง HF_HOME ยังไง มันก็ไม่ช่วยจับอีกจุดหนึ่งนี้
อย่างไรก็ตาม ต้องให้ความเป็นธรรมไว้ด้วย ตั้งแต่เวอร์ชันก่อน ๆ ของ Docling โปรเจกต์ได้ออก docling-slim มาแล้ว — core ขนาดราว 50 MB ที่ให้คุณ pip install docling-slim[format-html] สำหรับงาน HTML โดยไม่ต้องลาก torch เข้ามา ดังนั้นน้ำหนัก 1.3 GB ของแพ็กเกจ docling ค่าเริ่มต้นนั้นเป็นเรื่องจริง แต่ตอนนี้เลือกไม่ติดตั้งส่วนหนักได้แล้ว ฉันทดสอบแพ็กเกจค่าเริ่มต้นเพราะนั่นยังเป็นสิ่งที่ pip install docling ให้มาอยู่ดี แต่ความหนักไม่ได้เป็นข้อบกพร่องที่แก้ไม่ได้ — มีทางเลือกแบบโมดูลาร์แล้ว และมีการติดตามไว้ใน issue #2393
ระหว่างตั้งค่ายังเจอปัญหาจุกจิกเล็ก ๆ ที่ควรพูดถึง: import docling; docling.__version__ จะโยน AttributeError: module 'docling' has no attribute '__version__' โมดูลนี้ไม่ได้เปิดให้เรียกเวอร์ชันตรง ๆ วิธีที่ใช้ได้คือ importlib.metadata.version("docling") ซึ่งจะคืนค่า '2.111.0' นี่เป็นเรื่องเล็กในเชิง DX แต่ก็ยังมี issue ค้างอยู่ตั้งแต่กรกฎาคม 2026 ใน issue #3733
ความแม่นยำของตาราง: จุดที่ TableFormer คุ้มค่าจริง
ตารางคือเหตุผลที่คนหันมาใช้ Docling แทนการ dump PDF เป็นข้อความล้วน ๆ ฉันเลยสร้างไฟล์ PDF ตาราง 7 แบบที่มี ground truth แบบอ่านด้วยเครื่องได้ แล้วประเมินผลทีละเซลล์ สองเมตริกหลัก และมันไม่ใช่เรื่องเดียวกัน: cell recall คือสัดส่วนของค่าจาก ground truth ที่ปรากฏอยู่ที่ไหนสักแห่งในตารางที่ตรวจพบ; in-row rate คือสัดส่วนที่ลงไปอยู่ในแถวถูกต้อง การเอาสองค่านี้มาปนกันจะทำให้เครื่องมือดูดีเกินจริง ดังนั้นนี่คือทั้งสองค่า:

| Table (stress) | Detected | Cell recall | In-row rate | Note |
|---|---|---|---|---|
| T1 simple bordered grid (8 rows × 5 cols), alone on page | No | 0.0 | — | classified as <!-- image -->, all cells dropped |
| T2 borderless (only a header rule) | Yes | 1.00 | 1.00 | perfect, exact grid |
| T3 merged 2-level colspan header | Yes | 1.00 | 0.97 | all values found; one header value shifts a row |
| T4 merged rowspan row-label, alone on page | No | 0.0 | — | classified as <!-- image --> |
| T5 colspan header + borderless | Yes | 1.00 | 0.97 | all values found; same header-row shift as T3 |
| T6 financials, blank column, right-aligned | Yes | 1.00 | 1.00 | blank column preserved, not shifted |
| T7 wide 12-column grid | Yes | 1.00 | 1.00 | no column shift on a wide table |
ในตาราง 5 แบบที่ Docling ตรวจพบ ค่าจาก ground truth ทุกตัวถูกดึงออกมาครบ — cell recall 1.00 ทุกกรณี ใน 3 จาก 5 ตารางนั้น ทุกค่าก็ยังลงแถวถูกต้องด้วย ส่วนในกรณีที่มี multi-level header สองชุด (T3 และ T5) มีค่าหัวตารางหนึ่งตัวเลื่อนออกจากแถวเดิม ทำให้ in-row ลงมาเหลือ 0.97 — ข้อมูลยังอยู่ครบ แต่การจับคู่แถวสั่นคลอนเล็กน้อยเมื่อเจอ header ซ้อนกัน
กรณีโครงสร้างยาก ๆ ก็ยังรับมือได้ดีกว่าที่คาดไว้ ตารางหัวเรื่องแบบ colspan สองชั้นถูก flatten ออกมาเป็น GitHub-flavored Markdown ได้ถูกต้อง (ป้าย "Q1 2026" ถูกทำซ้ำเหนือสองคอลัมน์ที่ครอบอยู่ ซึ่งเป็นวิธีที่ถูกต้องในการยุบ colspan ลงเป็น GFM) ตารางแบบไม่มีเส้นขอบที่มีเพียง header rule (T2) ออกมาเป๊ะ ตารางกว้าง 12 คอลัมน์ (T7) ก็ไม่เลื่อนไปไหน และคอลัมน์การเงินที่ว่างเปล่า (T6) ก็ยังถูกเก็บเป็นเซลล์ว่าง ไม่ได้หายไปหรือถูกรวมทับ ผลนี้สอดคล้องกับ คะแนน TEDS อย่างเป็นทางการของ TableFormer — simple 95.4, complex 90.1, all-tables 93.6 — ซึ่งบน model card ทำคะแนนสูงกว่า Camelot (73.0) และ EDD (88.3) ชัดเจน
ขอเตือนเรื่อง merged cells ไว้สักนิด เพราะมี issue ที่เล่าอีกแบบหนึ่ง issue #3698 รายงานว่า V1 และ V2 จัดการ merged rows และ columns ได้ไม่ดี ใน fixture ของฉัน colspan แบบง่าย (T3/T5) และค่า rowspan ถูก flatten ได้ถูกต้อง มีเพียงการเลื่อนแถวของ multi-level header ที่กล่าวไปแล้วเท่านั้น แต่เคสที่ล้มใน #3698 คือการ merge หลายแถวหลายคอลัมน์แบบไม่สม่ำเสมอ และ ตารางหลายหน้า — ซึ่งเป็นปลายทางของความป่วนแบบ pathological ไฟล์ของฉันเป็นกรณีง่ายกว่า ดังนั้นถ้าจะพูดให้แม่นยำก็คือ: colspan และ rowspan แบบง่ายในที่นี้ถูกกู้คืนได้ (แต่ multi-level header อาจเลื่อนหนึ่งแถว) ส่วนการ merge ที่ซับซ้อนและผิดปกติยังเป็นปัญหาที่เปิดอยู่ ไม่ใช่ "merged cells ใช้ได้หมด" และก็ไม่ใช่ "merged cells ใช้ไม่ได้"
กับดัก: ตารางที่อยู่ลอย ๆ บนหน้าเดียวอาจหายไปเฉย ๆ
ย้อนดูตารางอีกครั้ง — T1 และ T4 ไม่ได้ถูกตรวจพบเลย Docling ส่งออก <!-- image --> แล้วทิ้งทุกเซลล์ โดยไม่แจ้ง error ใด ๆ T1 เป็นกริด 8 แถว 5 คอลัมน์ที่ปกติทุกประการ ปัญหานี้น่ากังวลพอให้ฉันยังไม่กล้าสรุปว่าเป็นจุดอ่อนของตัว parser ตาราง จนกว่าจะรู้ว่ามันถูกกระตุ้นด้วยอะไรแน่ ๆ ฉันเลยทำ A/B แบบสคริปต์ขึ้นมา

เริ่มจากตัดคำอธิบายง่าย ๆ ที่คิดได้ทิ้งก่อน ชั้นข้อความบนไฟล์ยังอยู่ครบ — pypdfium2 อ่านตัวอักษรได้ 327 ตัวจาก T1 และ 221 ตัวจาก T4 ดังนั้นนี่คือ PDF ดิจิทัลจริง ไม่ใช่ภาพสแกน การปิด OCR (do_ocr=False) ก็ไม่ช่วย ตารางยังคงหายไป และเมื่อดู DoclingDocument โดยตรง len(doc.tables) == 0 ในขณะที่ len(doc.pictures) == 1 — โมเดล layout มองบริเวณทั้งตารางเป็น Picture ไปแล้ว
จากนั้นจึงทดสอบตัวชี้ขาด ฉันเรนเดอร์ตาราง T1 และ T4 แบบเดิมอีกครั้ง แต่คราวนี้ใส่ย่อหน้าข้อความธรรมดา ๆ ล้อมรอบ แล้วค่อยแปลงใหม่ คราวนี้ทั้งสองอันมาแบบสมบูรณ์: len(doc.tables) == 1 ตาราง GFM ถูกสร้างออกมาถูกต้อง และป้าย rowspan "North" ของ T4b ถูกทำซ้ำครอบทั้งสามแถวเหมาะสม ตารางเดียวกันทุกอย่าง ตัวแปรที่เปลี่ยนมีแค่ว่ามันอยู่เดี่ยว ๆ บนหน้าที่เบาบาง หรือถูกฝังอยู่ในเนื้อความ
ดังนั้นข้อควรระวังที่แท้จริงไม่ใช่ TableFormer เปราะบาง แต่เป็นว่าโมเดล RT-DETR ด้าน layout ของ Docling ใช้บริบทของหน้า และตารางขนาดเล็กที่อยู่เดี่ยว ๆ บนหน้าที่แทบไม่มีอะไรเลยมีโอกาสสูงที่จะถูกอ่านเป็น Picture แล้วถูกทิ้งไปแบบไม่มีเสียงเตือน เรื่องนี้เจอได้ง่ายในงานจริง เพราะเอกสารอย่างใบแจ้งหนี้ สเปกชีต และไฟล์ export แบบครอปมักมีลักษณะนี้อยู่แล้ว: หนึ่งตารางต่อหนึ่งหน้า ไม่มีเนื้อความล้อมรอบ วิธีแก้ที่ตรงไปตรงมาและได้ผลคือ ให้บริบทของหน้าแก่โมเดล layout หรือไม่ก็ตรวจ doc.tables หลังแปลงทุกครั้งแล้วแจ้งเตือนหน้าที่นับได้เป็นศูนย์ เรื่องนี้ใกล้เคียงกับ issue #3495 (ตรวจพบตารางเป็นทั้ง Table และ Picture) แต่ตัวทริกเกอร์จากความ sparse ของหน้า — ตารางเดียวกัน หายเมื่ออยู่เดี่ยว ๆ แต่ออกมาถูกเมื่อมีข้อความล้อม — ฉันยังไม่พบว่าใครเขียนไว้ก่อนหน้า วัดมาเอง ไม่ใช่บั๊กที่ไม่มีใครรู้
OCR กับสแกนจริง: RapidOCR ไม่ใช่ EasyOCR
ไฟล์ PDF ที่สแกนมาเป็นสนามที่ตัวแปลงหลายตัวมักพลาดเงียบ ๆ ฉันเลยป้อนสแกนจริง 2 ไฟล์ให้ Docling โดยทั้งคู่มี text layer เป็น 0 ตัวอักษรตามที่วัดได้ — pypdfium2 รายงานว่าไม่มีตัวอักษรที่กู้คืนได้เลย จึงยืนยันว่าผลลัพธ์ใด ๆ ที่ได้ต้องมาจาก OCR ไม่ใช่ text layer ที่ซ่อนอยู่ในไฟล์
ไฟล์หน้าเดียว ocr_test.pdf กลับมาสะอาดใน 14.3 วินาทีบน CPU: "Docling bundles PDF document conversion to JSON and Markdown in an easy self contained package," ถูกกู้คืนมาแบบตรงตัว ส่วน nemotron_multipage.pdf ที่มี 4 หน้า ยิง OCR ครบทั้ง 4 หน้า ใช้เวลารวม 70.1 วินาที (17.5 วินาที/หน้า) และพ่นประโยคทดสอบเดิมซ้ำในแต่ละหน้า OCR ทำงานอัตโนมัติเลย — ไม่ต้องตั้ง flag ไม่ต้องตั้งค่าอะไร
รายละเอียดที่บทความหลายชิ้นมักเขียนผิดคือ เอนจิน OCR ค่าเริ่มต้นคือ RapidOCR ไม่ใช่ EasyOCR ฉันยืนยันได้จากการเห็น weights .pth ของ PP-OCRv4 ถูกดาวน์โหลดตอนรันครั้งแรก บล็อกจำนวนมากและ FAQ รุ่นเก่าของ Docling ยังบอกว่า EasyOCR เป็นค่าเริ่มต้น ซึ่งล้าสมัยไปแล้ว ตอนนี้ EasyOCR กลายเป็นตัวเลือกเสริมที่ต้อง opt in สิ่งที่ยังจริงอยู่คือ OCR เป็นเส้นทางที่ช้าที่สุดเมื่อสเกลใหญ่ และตัวเลขทั้งหมดที่เห็นที่นี่เป็นเพดานของ CPU-only ถ้ามี GPU เวลาก็จะลดลงมาก
PDF จริง, ลำดับการอ่าน, และเวลาต่อหน้า
ไฟล์จำลองช่วยพิสูจน์พฤติกรรมเฉพาะจุด ส่วน PDF จริงช่วยพิสูจน์ว่ามันใช้งานได้จริง ฉันจึงลองกับบทความวิชาการที่เป็น born-digital สองฉบับ — รายงานเทคนิคของ Docling 9 หน้า และ "Attention Is All You Need" 15 หน้า ทั้งคู่เป็นเอกสารสองคอลัมน์ที่มีตารางและสูตร
ในบทความ Attention 15 หน้า เครื่องหมายของแต่ละส่วนทั้งห้าจุด — Abstract, Introduction, Background, Conclusion, References — ปรากฏ ตามลำดับของเอกสาร ใน Markdown ที่แปลงแล้ว แม้จะเป็นเลย์เอาต์สองคอลัมน์ก็ตาม ทุกจุดตรวจเนื้อหา (Transformer, encoder, BLEU, multi-head) ก็มีครบ และตารางผลลัพธ์หลายคอลัมน์อันโด่งดังก็ถูกตรวจพบเป็น 4 ตาราง นี่คือการกู้คืนทั้ง reading order และการรวมคอลัมน์จริง ๆ ซึ่งเป็นคุณค่าหลักสำหรับการ chunk เอกสารไปใช้กับ RAG — คุณจะแบ่งเอกสารอย่างมีความหมายไม่ได้ ถ้าตัว linearizer ทำให้หน้าสองคอลัมน์กลายเป็นข้อความสลับมั่วไปหมด
เวลาในการรันสอนบทเรียนที่ค่อนข้างสวนทางสัญชาตญาณอยู่ข้อหนึ่ง: เวลาต่อหน้าไม่ได้ขึ้นกับจำนวนหน้าโดยตรง แต่วัดจากปริมาณโครงสร้างในแต่ละหน้า เอกสาร 9 หน้าที่หนาแน่นกว่ารันที่ 14.95 วินาทีต่อหน้า — ช้ากว่าบทความ 15 หน้าที่ 5.99 วินาทีต่อหน้า — เพราะในแต่ละหน้ามีตารางและรูปจำนวนมากกว่า — 3 ตารางใน 9 หน้า เทียบกับ 4 ตารางใน 15 หน้า — และแต่ละชิ้นทำให้ inference ของ layout และ TableFormer ทำงานเพิ่มขึ้น นี่คือส่วนต่างที่เล็ก และถ้าพูดในเชิงจำนวนจริง เอกสารที่หนาแน่นกว่ากลับมีตารางน้อยกว่า ไม่ใช่มากกว่า ดังนั้น "วินาทีต่อหน้า" บน CPU จึงเป็นฟังก์ชันของความหนาแน่นเชิงโครงสร้าง ไม่ใช่ความยาวไฟล์ และนี่เป็นการรันบน CPU-only เพียงครั้งเดียว จึงเป็นเพดาน ไม่ใช่ตัวเลขสำหรับ production
รองรับหลายฟอร์แมต และคำอ้างว่า JSON ไม่สูญเสียข้อมูล
Docling โฆษณาว่ารองรับการ parse หลายฟอร์แมตในแบบรวมศูนย์ ฉันจึงสร้าง DOCX, XLSX และ PPTX ที่มีเนื้อหาและจุดตรวจแบบรู้ค่าล่วงหน้า แล้วตรวจสองเรื่อง: จุดตรวจเหล่านั้นปรากฏใน Markdown หรือไม่ และยังอยู่ครบเมื่อ round-trip ผ่าน JSON ด้วย export_to_dict() หรือไม่
| File | Convert s | MD probes found | Tables in MD | Probes survive JSON |
|---|---|---|---|---|
report.docx (headings + merged-"Total" table + bullets) | 0.137 | 7/7 | 1 | Yes |
workbook.xlsx (2 sheets, blank column) | 0.016 | 6/6 | 2 | Yes |
deck.pptx (3 slides, bullets + table) | 0.038 | 6/6 | 1 | Yes |
จุดตรวจทุกตัวถูกดึงเข้า Markdown ครบ ตารางก็ถูกกู้คืนมาได้ รวมถึงแถว "Total" แบบ merged ใน DOCX และทั้งสองชีตของ XLSX และจุดตรวจทุกตัวก็ยังอยู่ครบหลัง export_to_dict() เป็นหลักฐานที่สำคัญต่อคำอ้างว่า DoclingDocument แบบไม่สูญเสียข้อมูล อย่างน้อยบนไฟล์ที่สะอาดแล้ว ไฟล์เหล่านี้ผ่าน backend เฉพาะฟอร์แมต ไม่ได้ผ่านโมเดล ML จึงทำงานในระดับเพียงไม่กี่สิบมิลลิวินาทีและใช้งานออฟไลน์ได้เต็มรูปแบบ ขอบเขตนี้พูดตรง ๆ คือ ไฟล์สะอาดฟอร์แมตละหนึ่งไฟล์ ยืนยันความกว้างของการรองรับได้ แต่ยังไม่ใช่การ stress test ไฟล์ Office ที่มีความผิดปกติ
HTML: ซื่อสัตย์ แต่ยังไม่สะอาด
นี่คือข้อควรระวังที่เป็นตัวตัดสินว่า Docling เหมาะจะอยู่ใน RAG pipeline ของคุณหรือไม่ ดังนั้นอ่านให้ดี Docling แปลง HTML ทั้งหน้า มันไม่ได้ทำ main-content extraction แบบสาย readability ฉันวัดว่าของตกแต่งของเว็บยังหลงเหลืออยู่มากแค่ไหน โดยนับบรรทัด nav, TOC, cookie และ footer ใน output ของ Docling เอง
| Page | Non-blank MD lines | Boilerplate lines | % boilerplate | Article starts at line |
|---|---|---|---|---|
| Wikipedia "Web scraping" | 255 | 34 | 13.3% | 28 |
| scrapethissite/forms | 63 | 1 | 1.6% | — |
| books.toscrape | 65 | 0 | 0.0% | — |
| quotes.toscrape | 35 | 0 | 0.0% | — |
ในหน้าเว็บที่มี chrome หนาแน่นอย่าง Wikipedia ประมาณ 13% ของบรรทัด Markdown คือ nav/TOC/footer boilerplate และบทความจริงเพิ่งเริ่มที่บรรทัด 28 — output เปิดมาด้วย "move to sidebar / Contents / Toggle the table of contents" และปิดด้วย "CS1 maint… / Search Wikipedia" ส่วนในหน้าที่มีเนื้อหาสะอาด (books, quotes) จะอยู่ที่ประมาณ 0% ดังนั้นนี่คือปัญหา template chrome ไม่ใช่ค่าธรรมเนียมต่อหน้าทุกครั้ง Docling ให้ Markdown แบบซื่อสัตย์ทั้งเอกสาร ไม่ใช่การดึงเฉพาะเนื้อหาหลักอย่างสะอาด ปัญหา HTML furniture นี้ถูกติดตามไว้ใน issue #1865 (ปิดแล้ว) และ #1930 (ยังเปิดอยู่)
แต่มีสองอย่างที่ทำให้คำนี้ยุติธรรมขึ้น อย่างแรก บน HTML โดยเฉพาะ Docling ไม่ได้ใช้โมเดล ML ใด ๆ เลย — มันเป็น backend ของ BeautifulSoup ใน pipeline ง่าย ๆ เรื่องเล่าว่า "vision models อ่านหน้าเว็บของคุณ" ใช้ได้กับ PDF และรูปภาพเท่านั้น ถ้าส่ง HTML ให้ Docling โมเดล layout หรือ TableFormer จะไม่ทำงานเลย อย่างที่สอง เส้นทาง PDF ยังพยายามจำแนก header/footer furniture อยู่ ดังนั้นถ้าจะบอกว่า "ไม่มีการลบ boilerplate เลย" ก็แรงเกินไป — ที่ปล่อย chrome กลับมาคือ backend HTML โดยเฉพาะ
เทียบกับเครื่องมืออื่น และ Thunderbit อยู่ตรงไหน
ลองใช้ Thunderbit สำหรับการดึงข้อมูลเว็บ
เครื่องมือที่คนชอบเอามาเทียบกับ Docling มากที่สุดคือ Firecrawl ดังนั้นขอสรุปเป็นตาราง positioning ไว้ก่อน มีข้อควรระวังตั้งแต่ต้น เพราะสำคัญ: นี่คือการเทียบระดับเอกสาร ไม่ใช่ benchmark เครื่องเดียวกัน ฉันไม่ได้รัน Firecrawl กับ fixture เหล่านี้ คอลัมน์ Docling เท่านั้นที่วัดจริง ส่วนคอลัมน์ Firecrawl มาจากเอกสารสาธารณะของมัน
| Axis | Firecrawl (per its docs) | Docling (measured here) |
|---|---|---|
| Core job | Crawl + scrape the live web → Markdown | Convert a document you already have → Markdown/JSON |
| Fetching / JS render / anti-bot | Yes (hosted browser) | No — you supply the file |
| Main-content extraction | Yes | No — faithful full-document (~13% chrome on Wikipedia) |
| PDF table structure (ML) | limited | Yes — TableFormer (TEDS 93.6 official; cell recall 1.00, in-row 0.97–1.00 on detected fixtures) |
| Scanned PDF / OCR | limited | Yes — RapidOCR by default (recovered a 0-text-layer scan) |
| Format breadth | web pages | PDF/DOCX/PPTX/XLSX/HTML/EPUB/images |
| Deployment | hosted API (+ self-host) | local pip library, offline, no API key |
| Setup weight | API key / light client | 1.3 GB default install + ~506 MiB models (or docling-slim) |
| License | commercial / source-available | MIT |
สรุปสั้น ๆ คือ Firecrawl คือเครื่องมือที่ใช้เมื่อข้อมูลของคุณอยู่บนเว็บสด และต้องครอว์ล เรนเดอร์ JS และล้างเนื้อหาหลัก ส่วน Docling คือเครื่องมือที่ใช้เมื่อคุณมีเอกสารอยู่แล้ว โดยเฉพาะ PDF, สแกน และไฟล์ Office ที่เน้นตาราง และต้องการการแปลงแบบออฟไลน์ที่รักษาโครงสร้างจริง พร้อมความเข้าใจตารางและ OCR ที่แท้จริง ทั้งสองตัวเสริมกันได้ ถ้าทำ pipeline แบบสมจริง มักจะใช้ตัวหนึ่งครอว์ล อีกตัวแปลงเอกสาร
และตรงนี้ฉันจะพูดตรง ๆ เรื่อง Thunderbit เพราะฉันทำงานที่นี่ คุณก็คงสงสัยถ้าฉันทำเป็นไม่เกี่ยว Thunderbit กับ Docling ไม่ได้ทำงานเดียวกัน และฉันจะไม่ฝืนบอกว่ามันเทียบกันตรง ๆ สำหรับนักพัฒนา Thunderbit คือ AI scraping API + MCP server + CLI และหน้าที่ของมันคือ หน้าเว็บสด: POST /distill แปลง URL เป็น Markdown ที่พร้อมให้ LLM ใช้ (จัดการ JS rendering, anti-bot และ CAPTCHA ที่ Docling ไม่แตะต้อง) ส่วน POST /extract จะคืน JSON ที่ตรงตามสคีมาด้วย JSON Schema ที่คุณกำหนดไว้ นี่คือส่วน fetch-and-clean ของ RAG pipeline ขณะที่ Docling คือฝั่งเอกสารในเครื่อง — PDF, สแกน, สเปรดชีตที่อยู่บนดิสก์ของคุณแล้ว ถ้าคอร์ปัสของคุณเป็นหน้าเว็บ ให้เลือก Thunderbit API, เครื่องมือ MCP (thunderbit_suggest_fields, thunderbit_distill, thunderbit_extract) หรือ CLI (npx @thunderbit/thunderbit-cli) ถ้าเป็น PDF และสแกน ให้เลือก Docling ถ้ามีทั้งสองแบบ — ซึ่งเป็นสถานการณ์จริงส่วนใหญ่ — ก็ใช้คู่กัน และไม่มีตัวไหนพยายามเป็นอีกตัว
ข้อสรุป: ยังเป็นข้อสรุปชั่วคราว และยังมีการบ้านต่อ
ฉันจะไม่ให้คะแนนรวม 0–100 เพียงตัวเดียว เพราะถ้าคิดแบบถ่วงน้ำหนัก มันจะเอาโทษจากสิ่งที่ Docling ไม่เคยอ้างว่าจะทำอยู่แล้ว (อย่างเช่นการครอว์ล) มาปนกัน และทำเหมือนมันเทียบกันได้ ในแต่ละด้าน จาก fixture ที่ฉันทดสอบ:
- การติดตั้ง / การรันครั้งแรก: หนัก — venv 1.3 GB, โมเดล ~506 MiB, PDF แรก ~224 วินาที, warm run ~0.55 วินาที — แต่
docling-slimช่วยให้หลีกเลี่ยงน้ำหนักส่วนนี้ได้ - ความแม่นยำของตาราง: แข็งแรงเมื่อตรวจพบตารางแล้ว (cell recall 1.00 ใน 5/5, in-row 0.97–1.00) สอดคล้องกับภาพรวม TEDS ทางการบน fixture เหล่านี้
- ความทนทานในการตรวจตาราง: มีหลุมพรางเรื่อง sparse-page — ตารางที่อยู่โดดเดี่ยวอาจถูกมองเป็น Picture ตรวจ
doc.tablesหลังแปลงเสมอ - สแกน / OCR: ใช้ได้ RapidOCR เป็นค่าเริ่มต้น แต่ช้าเมื่อสเกลใหญ่
- หลายฟอร์แมต: ใช้ได้ดี และ round-trip JSON ยังสมบูรณ์
- HTML: ซื่อสัตย์ แต่ไม่สะอาด — ไม่มี main-content extraction
- ประสบการณ์นักพัฒนา: API เรียบง่าย 3 บรรทัด และ
DoclingDocumentจัดระเบียบดี ยกเว้นการไม่มี__version__
เหมาะกับใคร: ทีมที่สร้าง RAG หรือ data pipeline บน PDF, สแกน และไฟล์ Office ที่ต้องการการแปลงแบบออฟไลน์ รักษาโครงสร้าง และเข้าใจตารางกับ OCR จริง ๆ ไม่เหมาะกับใคร: คนที่ต้องการ live-web crawling หรือการดึงเฉพาะเนื้อหาหลักจาก HTML แบบสะอาด — นั่นคืองานของอีกเครื่องมือหนึ่ง
และเพราะนี่คือรีวิว ไม่ใช่ press release ข้อจำกัดต่าง ๆ จึงต้องอยู่บนป้ายชัดเจน นี่คือการทดสอบแบบเจาะจง — ตารางสังเคราะห์ 7 แบบ + PDF จริง 2 ไฟล์ บนเครื่อง CPU-only เครื่องเดียว — ไม่ใช่ benchmark ความแม่นยำระดับ TEDS มีหลายเรื่องที่ฉันไม่ได้ทดสอบ และคุณควรทดสอบก่อนจะฝาก pipeline ไว้กับ Docling ได้แก่ เส้นทาง VLM เสริม (GraniteDocling), footprint ของ docling-slim จริง ๆ, การรันบน GPU, merged cells แบบซับซ้อนและผิดปกติรวมถึงตารางหลายหน้า, ความแม่นยำของการแปลงสูตรเป็น LaTeX และ — ที่มีโอกาสทำให้คุณแปลกใจที่สุดใน production — ความทนทานของ batch memory growth, การสเกลด้วย thread/GIL และ lifecycle ของ object ตลอดการแปลงนับพันครั้ง Doclingแข็งแรงในสิ่งที่มันอ้าง และวัดได้จริงมากกว่าที่โฆษณาไว้ แต่ก็ยังมีขอบที่คุณควรทำแผนที่ให้ชัดก่อนเชื่อมันกับทั้งคอร์ปัส รู้ข้อควรระวังเรื่อง sparse-page ไว้ จัดงบสำหรับการดาวน์โหลดครั้งแรก และทดสอบพฤติกรรมเมื่อใช้งานจริงด้วยตัวเอง
ลองใช้ Thunderbit สำหรับการดึงข้อมูลเว็บ Get Started Free
คำถามที่พบบ่อย
Docling เป็นเว็บสแครปเปอร์หรือครอว์เลอร์ไหม? ไม่ใช่ Docling แปลงเอกสารที่คุณมีอยู่แล้ว — PDF, DOCX, PPTX, XLSX, HTML, รูปภาพ — ให้เป็น Markdown หรือ JSON มันไม่ได้ดึง URL, ไม่เรนเดอร์ JavaScript และไม่จัดการ anti-bot การครอว์ลเว็บสดเป็นงานคนละส่วน ซึ่งเครื่องมืออย่าง Firecrawl หรือ Thunderbit web API จะรับหน้าที่นั้น ส่วน Docling เริ่มจากไฟล์ที่คุณส่งให้
การติดตั้ง Docling และดาวน์โหลดตอนรันครั้งแรกใหญ่แค่ไหน?
แพ็กเกจ docling ค่าเริ่มต้นจะทำให้ venv มีขนาดราว 1.3 GB เพราะดึงสแต็ก ML ทั้งชุดเข้ามา (แค่ torch ก็ 536 MiB แล้ว) เป็น hard dependency การแปลง PDF ครั้งแรกจะดาวน์โหลดโมเดล layout และ TableFormer ประมาณ 506 MiB ลงดิสก์ รวมกับ weights ของ RapidOCR อีกประมาณ 40 MB และใช้เวลาประมาณ 224 วินาที — เกือบทั้งหมดคือเวลาที่เสียกับการดาวน์โหลด การแปลงครั้งที่สองจะเหลือราว 0.55 วินาที ถ้าคุณต้องการแค่ฟอร์แมตเบา ๆ docling-slim (core ราว 50 MB) จะตัดเส้นทางหนักทิ้งไป
Docling ทำ OCR ไหม และใช้เอนจินอะไร? ทำ และทำอัตโนมัติด้วย บน PDF ที่สแกนมาและไม่มี text layer Docling จะเรียก OCR เอง และในทดสอบของฉันมันกู้ข้อความได้อย่างสะอาด เอนจินค่าเริ่มต้นคือ RapidOCR ไม่ใช่ EasyOCR ซึ่งมักถูกเขียนผิดในบทความเก่า ๆ ตอนนี้ EasyOCR เป็นตัวเลือกเสริมที่ต้องเปิดใช้เอง OCR เป็นเส้นทางที่ช้าเมื่อสเกลใหญ่ โดยเฉพาะบน CPU
ทำไม Docling แปลงตารางของฉันเป็นรูปภาพ หรือไม่ก็หายไปเลย?
สาเหตุที่เป็นไปได้มากที่สุดคือผลของ sparse-page Docling ใช้โมเดล RT-DETR สำหรับ layout ซึ่งอาศัยบริบทของหน้า และตารางขนาดเล็กที่อยู่โดดเดี่ยวบนหน้าที่แทบว่างเปล่าอาจถูกจัดเป็น Picture แล้วหายไปแบบไม่มี error ตารางเดียวกันนี้ถ้าใส่ข้อความล้อมรอบจะถูกแปลงได้ปกติ วิธีแก้คือให้บริบทของหน้ากับโมเดล layout หรือไม่ก็ตรวจ doc.tables หลังแปลงแล้วแจ้งเตือนทุกหน้าที่นับได้เป็นศูนย์
Docling กับ Firecrawl ควรใช้ตัวไหน? เป็นคนละงานกัน ส่วนใหญ่จึงไม่ใช่เรื่องเลือกอย่างใดอย่างหนึ่ง Firecrawl ใช้ครอว์ลเว็บสด เรนเดอร์ JavaScript และดึง main content ส่วน Docling ใช้แปลงเอกสารที่คุณมีอยู่แล้ว พร้อมความเข้าใจโครงสร้างตารางใน PDF และ OCR แบบออฟไลน์เต็มรูปแบบ ถ้าแหล่งข้อมูลคือหน้าเว็บ ให้ใช้เครื่องมือเว็บ (Firecrawl หรือ Thunderbit API/MCP/CLI) ถ้าเป็น PDF, สแกน หรือไฟล์ Office ให้ใช้ Docling งานจริงส่วนใหญ่มักใช้ทั้งคู่


