Show HN: ตัวแยกวิเคราะห์ PDF แบบโอเพนซอร์สที่อิงกฎสำหรับ RAG
(github.com/nlmatics)- nlm-ingestor เป็นโค้ดบริการที่ API ของ llmsherpa ใช้เชื่อมต่อ และมีตัวแยกวิเคราะห์เอกสารสำหรับ PDF·HTML·Text·DOCX·PPTX และรูปแบบอื่น ๆ ที่ปรับให้เหมาะกับ RAG
- ตัวแยกวิเคราะห์ PDF ใช้ข้อมูล พิกัดข้อความ, กราฟิก และฟอนต์ที่ได้จาก Tika ฉบับดัดแปลงของ nlmatics และหากมีหน้าที่เป็นสแกนอยู่ก็สามารถใช้ OCR อัตโนมัติได้ด้วยตัวเลือก
apply_ocr - ความสามารถในการประมวลผล PDF ครอบคลุมระดับเซ็กชัน·เซ็กชันย่อย, การรวมย่อหน้า, การเชื่อมโยงเซ็กชัน-ย่อหน้า, ตาราง, รายการซ้อนกัน, การรวมเนื้อหาข้ามหน้า, การลบ header·footer ที่ซ้ำ, การลบลายน้ำ, และ bounding box ของ OCR
- เมื่อเทียบกับตัวแยกวิเคราะห์ภาพที่ใช้โมเดล ตัวแยกวิเคราะห์แบบอิงกฎไม่จำเป็นต้องสร้างภาพจากหน้า PDF จึงอธิบายว่า เร็วกว่า 100 เท่า และมองว่าใช้งานได้จริงกว่าสำหรับ PDF ที่มี text layer แทน OCR และเอกสารที่ยาวหลายร้อยหน้า
- เซิร์ฟเวอร์สำหรับพัฒนาสามารถรันได้ด้วย Docker หรือรันโดยตรง และในสภาพแวดล้อม production แนะนำให้รันหลัง security gateway อย่าง nginx หรือ cloud gateway
ตัวแยกวิเคราะห์เอกสารที่ nlm-ingestor มีให้
- nlm-ingestor เป็นรีโพซิทอรีโค้ดบริการที่ API ของ llmsherpa สามารถเชื่อมต่อได้
- มี custom parser สำหรับหลายรูปแบบไฟล์ที่ปรับให้เหมาะกับ RAG (retrieval augmented generation)
-
PDF
-
HTML
-
Text
- DOCX, PPTX และรูปแบบอื่น ๆ ที่ Apache Tika รองรับ
-
วิธีทำงานและความสามารถของตัวแยกวิเคราะห์ PDF
- ตัวแยกวิเคราะห์ PDF เป็นแบบอิงกฎ และใช้ข้อมูล พิกัดข้อความ, กราฟิก และฟอนต์ที่ได้จาก nlm-tika ฉบับดัดแปลงของ nlmatics
- ทำงานโดยอิงกับ PDF text layer และสามารถใช้ OCR อัตโนมัติได้ผ่านตัวเลือก
apply_ocrหากใน PDF มีหน้าที่เป็นสแกน - ฟังก์ชัน OCR อิงจาก Tika ฉบับดัดแปลงของ nlmatics ที่ใช้ tesseract ภายใน
- มีโน้ตบุ๊ก pdf_visual_ingestor_step_by_step ให้ทดลองตัวแยกวิเคราะห์ PDF ได้โดยตรง
- ความสามารถของตัวแยกวิเคราะห์ PDF มีดังนี้
- ระบุเซ็กชัน เซ็กชันย่อย และ ระดับ ของแต่ละส่วน
- รวมหลายบรรทัดให้เป็น ย่อหน้า
- สร้างความเชื่อมโยงระหว่างเซ็กชันกับย่อหน้า
- ระบุตารางและเซ็กชันที่พบตาราง
- จัดการรายการและรายการซ้อนกัน
- รวมเนื้อหาที่ต่อเนื่องข้ามหน้า
- ลบ header และ footer ที่ซ้ำกัน
- ลบลายน้ำ
- ให้ bounding box สำหรับผลลัพธ์ OCR
การประมวลผล HTML·Text·เอกสาร Office
- ตัวแยกวิเคราะห์ HTML สร้าง บล็อกที่รับรู้เลย์เอาต์ เพื่อสร้าง chunk ที่มีคุณภาพดีกว่าสำหรับเพิ่มประสิทธิภาพ RAG
- ตัวแยกวิเคราะห์ Text จะดูจากข้อความเพียงอย่างเดียวโดยไม่มีข้อมูลภาพ ข้อมูลฟอนต์ หรือ bounding box เพื่อคาดเดารายการ ตาราง header เป็นต้น
- DOCX, PPTX และรูปแบบอื่น ๆ ที่ Apache Tika รองรับ จะใช้ ผลลัพธ์ HTML ของ Tika ก่อนแล้วจึงประมวลผลด้วยตัวแยกวิเคราะห์ HTML
การรันและการใช้งาน API
- ขั้นตอนการรันโดยตรงประกอบด้วยการติดตั้ง Java, รันเซิร์ฟเวอร์ Tika, ติดตั้ง
nlm-ingestorและรัน ingestor- รันเซิร์ฟเวอร์ Tika:
java -jar <path_to_nlm_ingestor>/jars/tika-server-standard-nlm-modified-2.9.2_v2.jar - ติดตั้ง:
pip install nlm-ingestor - รัน:
python -m nlm_ingestor.ingestion_daemon
- รันเซิร์ฟเวอร์ Tika:
- มี Docker image ให้ผ่าน GitHub Container Registry สาธารณะ
- ดึง image:
docker pull ghcr.io/nlmatics/nlm-ingestor:latest - ตัวอย่างการรัน:
docker run -p 5010:5001 ghcr.io/nlmatics/nlm-ingestor:latest-<version>
- ดึง image:
- หลังจากรันเซิร์ฟเวอร์แล้ว สามารถใช้ไลบรารี API ของ llmsherpa เพื่อรับ chunk ไปใช้ในโปรเจกต์ LLM ได้
- ตัวอย่าง
llmsherpa_urlคือhttp://localhost:5010/api/parseDocument?renderFormat=all- ใช้ OCR:
&applyOcr=yes - ใช้ indent parser ใหม่ที่ใช้อัลกอริทึมอื่นในการกำหนดระดับ header:
&useNewIndentParser=yes
- ใช้ OCR:
- แม้จะใช้เป็นเซิร์ฟเวอร์สำหรับพัฒนาได้ แต่ในสภาพแวดล้อม production แนะนำให้รันหลัง security gateway อย่าง nginx หรือ cloud gateway
- โค้ดตัวอย่างสำหรับทดสอบเซิร์ฟเวอร์ด้วย llmsherpa parser อยู่ในโน้ตบุ๊ก test_llmsherpa_api
เหตุผลที่เลือกตัวแยกวิเคราะห์แบบอิงกฎ
- ทีม nlmatics ประเมินหลายทางเลือกตลอด 4 ปี รวมถึงตัวแยกวิเคราะห์ภาพแบบ YOLO ที่ Tom Liu และ Yi Zhang พัฒนา ก่อนจะเลือก ตัวแยกวิเคราะห์แบบอิงกฎ
- ตัวแยกวิเคราะห์แบบอิงกฎเร็วกว่าตัวแยกวิเคราะห์ภาพใด ๆ อย่างมาก โดยคำอธิบายในรีโพซิทอรีระบุว่า เร็วกว่า 100 เท่า
- ตัวแยกวิเคราะห์ภาพต้องสร้างภาพของทุกหน้า แม้แต่สำหรับ PDF ที่มี text layer อยู่แล้ว
- ตัวแยกวิเคราะห์ภาพอาจเป็นตัวเลือกที่ดีกว่าสำหรับ OCR PDF ที่ไม่มี text layer หรือ PDF ขนาดเล็กที่ประกอบด้วยข้อมูลแบบฟอร์ม
- สำหรับ PDF ขนาดใหญ่ที่มี text layer และยาวหลายร้อยหน้า มองว่าตัวแยกวิเคราะห์แบบอิงกฎใช้งานได้จริงกว่า
- หากไม่ใช้ฟังก์ชัน PDF OCR ก็ไม่ต้องการฮาร์ดแวร์พิเศษ
- คำอธิบายในรีโพซิทอรีระบุว่าสามารถรันได้แม้บนฮาร์ดแวร์ต้นยุค 2000
- ตัวแยกวิเคราะห์ทุกแบบรวมถึงตัวแยกวิเคราะห์ภาพอาจเกิดข้อผิดพลาดได้ และอธิบายว่าวิธีแก้ข้อผิดพลาดของตัวแยกวิเคราะห์ที่ใช้โมเดลนั้นไม่น่าพอใจ
- เมื่อเพิ่มตัวอย่างลงในชุดฝึก ความแม่นยำของการฝึกก่อนหน้าอาจลดลง และโค้ดเดิมที่เคยทำงานได้อาจไม่แน่นอน
- หากแก้ปัญหาของตัวแยกวิเคราะห์ที่ใช้โมเดลด้วยแนวคิดแบบอิงกฎ สุดท้ายก็ต้องเขียนกฎจำนวนมากอีกครั้ง
Tika ฉบับดัดแปลงของ nlmatics
- Tika ฉบับดัดแปลงของ nlmatics อยู่ที่ สาขา 2.4.1-nlm
- เพื่อความสะดวก มีไฟล์ jar ที่คอมไพล์แล้วรวมอยู่ในโฟลเดอร์
jars/ของรีโพซิทอรี - PDF บางไฟล์อาจเกิดข้อผิดพลาดในเซิร์ฟเวอร์ Java และในกรณีนั้นต้องแก้โค้ดส่วนนั้นแล้วคอมไพล์ไฟล์ jar ใหม่
- ไฟล์ที่แก้ไขแล้วจะเพิ่ม ฟอนต์และพิกัด ให้กับแต่ละองค์ประกอบข้อความใน PDF และลบลายน้ำ
PDF2XHTML.javaAbstractPDF2XHTML.java
- การเปลี่ยนแปลงใน
GraphicsStreamProcessor.javaมีไว้เพื่อเพิ่ม เส้นและสี่เหลี่ยม ที่อาจช่วยในการตรวจจับตาราง - ดูผลกระทบของการเปลี่ยนแปลงได้จากช่วงต้นของโน้ตบุ๊ก pdf_visual_ingestor_step_by_step
- แนวคิดสำหรับงานในอนาคตมีดังนี้
- เขียน wrapper ของตัวเองบน pdfbox เพื่อลดการพึ่งพาการแก้ไข Tika
- อัปเกรดเป็น Tika เวอร์ชันล่าสุด
- จัดรูปแบบ HTML ที่ส่งกลับมาให้เป็นมิตรกับ CSS มากขึ้น
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ถ้าต้องจัดการกับงานวิจัยทางวิทยาศาสตร์ ก็น่าจะเพิ่ม GROBID ไว้ด้วย: https://github.com/kermitt2/grobid
ผมใช้งานร่วมกับ paperetl(https://github.com/neuml/paperetl)
โปรเจ็กต์ดีมาก สำหรับการพาร์สเอกสาร ผมใช้ Tika มานานเพราะมีความเสถียรและรองรับฟอร์แมตกว้าง และ ผลลัพธ์แบบ XHTML ช่วยกับการแบ่งชิ้นเอกสารสำหรับ RAG ได้
ดูตัวอย่างได้ที่ https://neuml.hashnode.dev/build-rag-pipelines-with-txtai และ https://neuml.hashnode.dev/extract-text-from-documents
อ้อ ผมเป็นผู้เขียนหลักของ txtai(https://github.com/neuml/txtai)
pdfminer.six (ที่ unstructured ใช้) ทำการตรวจจับเลย์เอาต์ได้ค่อนข้างพื้นฐานจนพาร์สข้อความหลายคอลัมน์ไม่สำเร็จ ซึ่งน่าผิดหวัง ขณะที่ MuPDF ทำได้สมบูรณ์
ตอนนี้ผมใช้ MuPDF + AWS Textract ผสมกัน (ส่วนใหญ่ใช้กับตาราง) แต่อยากรู้ว่าคนอื่นใช้ตัวไหนกัน
น่าจะมีประโยชน์มาก บริษัทที่ผมทำงานอยู่มีเครื่องมือเทียบ PDF ชื่อ “PDFC” ที่อ่าน PDF แล้วเปรียบเทียบ ความแตกต่างเชิงความหมาย: https://www.inetsoftware.de/products/pdf-content-comparer
ฟอร์แมต PDF ซับซ้อนมากจนการพาร์สอาจปวดหัวพอสมควร เรารองรับความสามารถส่วนใหญ่พวกนี้อยู่แล้ว แต่เคสขอบยังมีเยอะมาก ดังนั้นแนวทางเพิ่มเติมอาจช่วยได้
Tesseract OCR fallback ดูดีมาก
ตอนนี้มี file loader สำหรับ RAG เยอะมากจาก langchain, LLMindex, unstructured ฯลฯ เลยสงสัยว่ามีเหตุผลอะไรให้เลือกตัวนี้ เช่น มีหลักฐานอย่างคะแนน benchmark ที่ดีกว่าหรือไม่
แต่ผมเคยใช้เครื่องมือ RAG พวกนั้นกับงานพาร์ส PDF แล้วคุณภาพผลลัพธ์ค่อนข้างต่ำ LLM ช่วยกลบปัญหาได้ระดับหนึ่งเลยยังพอใช้กับ RAG ได้ แต่ถ้าต้องการคำตอบคุณภาพสูงกว่าพร้อมการอ้างอิงที่ถูกต้อง ผมคิดว่าการใช้ rule-based parser โดยตรงดีที่สุด สุดท้ายผมก็ทำแบบนั้นเหมือนกัน เพียงแต่ใช้ MuPDF แทน Tika
ผู้เขียนเครื่องมือนี้ก็น่าจะคิดคล้ายกัน
มันพอสำหรับรัน RAG prototype แต่ยังไม่พอสำหรับทำของที่เชื่อถือได้ โปรเจ็กต์นี้ดูเหมือน implementation ที่ผ่านการใช้งานจริงมากกว่ามาก
งานยอดเยี่ยมและน่าสนใจมาก แต่พอเข้าไปดู GitHub แล้วขึ้นว่า “This organization has no public members” ทำให้ไม่รู้เลยว่าพวกคุณคือใคร และไม่รู้ว่าภายในนี้อาจมีอะไรที่ไม่ได้เปิดเผยอีกบ้าง
โดยรวมแล้ว ผมคิดว่าระหว่าง “กลุ่มนิรนามที่ไม่มีตัวตนโพสต์อะไรบางอย่างบนเว็บไซต์ความปลอดภัยของ $CORP” กับวิธีแนะนำตัวและสร้างความน่าเชื่อถือแบบดั้งเดิม น่าจะต้องมีจุดกึ่งกลางที่ช่วยสะสม ตัวตนและความน่าเชื่อถือ ได้เมื่อเวลาผ่านไป
ถ้าต้องการได้ chunk ที่เหมาะที่สุดในโปรเจ็กต์ LLM/RAG ก็ใช้เซิร์ฟเวอร์นี้ร่วมกับ llmsherpa LayoutPDFReader ได้เลย: https://github.com/nlmatics/llmsherpa
ดูตัวอย่างและโน้ตบุ๊กในรีโพซิทอรีได้
สงสัยว่ามีตัวอย่างคู่ input-output อยู่ที่ไหนสักแห่งไหม
ตัวอย่างพร้อมโน้ตบุ๊กอยู่ที่นี่: https://github.com/nlmatics/llmsherpa
และอีกตัวอย่างโน้ตบุ๊กในรีโพซิทอรีอยู่ที่นี่: https://github.com/nlmatics/nlm-ingestor/blob/main/notebooks...
ผมลองใช้ตัวนี้พาร์ส PDF ไปหลายร้อยไฟล์แล้ว ผลลัพธ์ค่อนข้างดี ถ้าพัฒนาด้วย Julia น่าจะเร็วขึ้นอย่างน้อย 10 เท่า
สงสัยว่าสิ่งนี้ต่างจาก Azure Document Intelligence อย่างไร หรือจริง ๆ แล้วแทบจะเหมือนกัน
ถ้าใช้เซิร์ฟเวอร์นี้ร่วมกับไลบรารี llmsherpa(https://github.com/nlmatics/llmsherpa) ก็จะได้ chunk ที่คำนึงถึงเลย์เอาต์และเหมาะกับโปรเจ็กต์ LLM/RAG
ไลบรารีนี้และเครื่องมืออย่าง fitz/pymupdf สามารถดึงข้อความจาก PDF โดยตรง แล้วค่อยใช้กฎในการพาร์สและจัดโครงสร้างได้ PDF สมัยใหม่ส่วนใหญ่ดึงข้อความได้โดยไม่ต้อง OCR
แน่นอนว่าถูกกว่ามาก แต่ก็ขยายไปครอบคลุมเลย์เอาต์แบบไดนามิกทุกแบบได้ไม่ดีนัก ดังนั้นมักใช้เมื่อสามารถปรับให้เข้ากับโครงสร้างมาตรฐานได้ ถึงอย่างนั้นกับงานอย่างบทความวิทยาศาสตร์ ผมเห็นว่า การดึงข้อความแบบอิงกฎ ก็รับมือกับความไดนามิกได้ดีพอสมควร
แค่กังวลว่า Tesseract OCR อาจเป็นข้อจำกัดแฝง เพราะผมเห็นมันพลาดบ่อยมาก
สงสัยว่ามีตัวอย่างไหม ในรีโพซิทอรีดูเหมือนไม่มีไฟล์ PDF เลยสักไฟล์
โปรเจ็กต์ nlm-ingestor นี้ให้ backend ที่ทำงานร่วมกับ llmsherpa ส่วนไลบรารี llmsherpa สะดวกมากสำหรับการดึง chunk ที่ดีสำหรับโปรเจ็กต์ LLM/RAG