開源PDF解析工具Marker深度解析
檢索增強生成(RAG)系統的第一步就是做 pdf 解析,從復雜多樣的 pdf 中提取出干凈準確的文本內容。現有的最優秀的開源工具有兩個:Marker 和 MinerU。因為 Marker 是個人開發者做的,文檔不完善,所以這里基于我個人的理解對它的代碼進行解析。
深度學習模型
在marker/models.py
中可以看到,marker 用到了如下的深度學習模型:
def create_model_dict(device=None, dtype=None) -> dict:return {"layout_model": LayoutPredictor(device=device, dtype=dtype),"texify_model": TexifyPredictor(device=device, dtype=dtype),"recognition_model": RecognitionPredictor(device=device, dtype=dtype),"table_rec_model": TableRecPredictor(device=device, dtype=dtype),"detection_model": DetectionPredictor(device=device, dtype=dtype),"inline_detection_model": InlineDetectionPredictor(device=device, dtype=dtype),"ocr_error_model": OCRErrorPredictor(device=device, dtype=dtype)}
這些模型都來自surya,作者沒有直接介紹這些模型的原理,但可推測
像檢測相關的 DetectionPredictor
和 InlineDetectionPredictor
可能用 Faster R - CNN、YOLO 系列等目標檢測模型;
-
LayoutPredictor
或采用 Mask R - CNN 、LayoutLM 等進行布局分析; -
OCRErrorPredictor
或許借助 RNN 變體或 BERT 類模型處理 OCR 錯誤; -
RecognitionPredictor
可能使用 CRNN 等做字符識別; -
TableRecPredictor
會用到基于 GNN 的模型處理表格; -
TexifyPredictor
可能采用 Seq2Seq 或 Transformer - based 的 Seq2Seq 模型來生成 LaTeX 代碼。
代碼使用 PyTorch 框架,可指定設備和數據類型。
解析流程
因為其它數據類型(docx,pptx,xlsx)都可以轉成pdf,所以 pdf 是 marker 處理的主要對象。從marker/converters/pdf.py
可以看到處理pdf 的所有流程如下。marker 先通過以下流程,把pdf 解析為 document(抽象語法樹),然后將document 渲染為json,html 或者markdown 格式。
default_processors: Tuple[BaseProcessor, ...] = (OrderProcessor,LineMergeProcessor,BlockquoteProcessor,CodeProcessor,DocumentTOCProcessor,EquationProcessor,FootnoteProcessor,IgnoreTextProcessor,LineNumbersProcessor,ListProcessor,PageHeaderProcessor,SectionHeaderProcessor,TableProcessor,LLMTableProcessor,LLMTableMergeProcessor,LLMFormProcessor,TextProcessor,LLMInlineMathLinesProcessor,LLMComplexRegionProcessor,LLMImageDescriptionProcessor,LLMEquationProcessor,LLMHandwritingProcessor,LLMMathBlockProcessor,ReferenceProcessor,DebugProcessor,)
通用格式處理
OrderProcessor
- 用于處理文檔中元素的順序,確保各部分內容按照正確的邏輯順序排列,比如調整段落、列表項等的先后順序。LineMergeProcessor
- 對分割的行進行合并操作。在OCR處理或文檔解析過程中,文本可能會被錯誤地分割成多行,該處理器會將相關的行合并成合理的段落或語句。LineNumbersProcessor
- 處理文檔中的行號信息。它可以識別、提取或添加行號,也可能對行號的格式和編號規則進行調整,以符合特定的輸出要求。
特定元素處理
BlockquoteProcessor
- 專門處理文檔中的塊引用內容。它會識別塊引用的起始和結束位置,對其進行格式化,例如添加特定的縮進或標記來區分塊引用與普通文本。CodeProcessor
- 處理代碼塊。會識別代碼塊的邊界,對代碼進行語法高亮處理(如果需要),并確保代碼的格式在轉換過程中保持正確,例如保留縮進、換行等。ListProcessor
- 處理列表元素,包括有序列表和無序列表。它會識別列表項的格式,確保列表的編號或標記正確顯示,并且處理列表嵌套等復雜情況。PageHeaderProcessor
- 處理文檔頁面的頁眉部分。可以識別頁眉內容,對其進行提取、格式化或去除不必要的信息,以保證頁眉內容在輸出中正確顯示。SectionHeaderProcessor
- 處理文檔中的章節標題。它會識別不同級別的章節標題,根據標題的層次結構進行相應的格式化,例如設置不同的字體大小、加粗等,以體現章節的主次關系。TableProcessor
- 處理文檔中的表格。會識別表格的結構,包括表頭、表體、單元格等,對表格進行格式化,確保表格的布局和內容在轉換后正確顯示,可能還會處理表格的合并單元格等情況。
特定內容處理
DocumentTOCProcessor
- 生成文檔的目錄(TOC)。它會分析文檔中的章節標題,根據標題的層次結構生成目錄,并為每個目錄項添加對應的頁碼或鏈接,方便讀者快速定位文檔內容。EquationProcessor
- 處理文檔中的數學公式。會識別公式的格式,可能會將公式轉換為特定的表示形式,如LaTeX代碼,以便在后續的渲染中正確顯示數學內容。FootnoteProcessor
- 處理文檔中的腳注。它會識別腳注的引用標記和腳注內容,將腳注正確地放置在頁面底部或文檔末尾,并處理腳注與正文的關聯。TextProcessor
- 對普通文本進行處理,包括文本的清理、替換、大小寫轉換等操作,以確保文本的質量和一致性。ReferenceProcessor
- 處理文檔中的參考文獻。它會識別參考文獻的格式,對其進行整理和格式化,使其符合特定的引用規范,如APA、MLA等。
基于大語言模型(LLM)的處理LLMTableProcessor
- 利用大語言模型對表格進行處理。可以對表格內容進行語義分析、補充缺失信息、優化表格結構等,以提高表格處理的質量和智能化程度。LLMTableMergeProcessor
- 使用大語言模型來處理表格合并的情況。當文檔中有多個相關表格需要合并時,該處理器借助大語言模型的理解能力,合理地合并表格內容,確保合并后的表格邏輯清晰。LLMFormProcessor
- 利用大語言模型處理文檔中的表單。可以識別表單的字段、填寫要求,甚至可以根據上下文對表單內容進行自動填充或驗證。LLMInlineMathLinesProcessor
- 借助大語言模型處理行內數學公式。它可以對行內數學公式進行更準確的識別和轉換,提高公式處理的準確性和可讀性。LLMComplexRegionProcessor
- 處理文檔中的復雜區域,這些區域可能包含多種類型的元素,如文本、圖像、表格等。大語言模型可以幫助理解這些復雜區域的結構和語義,進行更合理的處理和轉換。LLMImageDescriptionProcessor
- 利用大語言模型為文檔中的圖像生成描述信息。可以根據圖像的內容、上下文等生成準確的圖像描述,提高文檔的可訪問性和信息完整性。LLMEquationProcessor
- 結合大語言模型處理數學公式。與普通的EquationProcessor
相比,它可以利用大語言模型的語義理解能力,對公式進行更深入的分析和處理,例如對公式進行解釋、推導等。LLMHandwritingProcessor
- 使用大語言模型處理手寫內容。可以識別手寫文字,將其轉換為可編輯的文本,并對識別結果進行優化和糾錯,提高手寫內容處理的準確性。LLMMathBlockProcessor
- 借助大語言模型處理獨立的數學塊。它可以對數學塊進行更細致的分析和處理,確保數學塊的內容和格式在轉換后正確顯示,同時可能會對數學塊進行語義解釋等操作。
調試相關
DebugProcessor
- 主要用于調試目的。它可以輸出一些調試信息,幫助開發者檢查文檔處理過程中的中間結果、變量值等,以便發現和解決問題。 這些處理器共同作用,對PDF文檔進行全面、細致的解析和處理,以實現將PDF轉換為其他格式(如Markdown)的功能。
其它類型的文件處理方式:
-
對于docx,marker使用mammoth庫把docx轉換成HTML,然后再用weasyprint庫把HTML轉成PDF。中間隔了一個HTML,效果很差,親測不如用 wps 把docx 轉pdf。
-
對于pptx,使用python-pptx庫解析pptx元素,然后轉化成HTML,再用weasyprint 將 HTML 渲染為 PDF。
-
對于xlsx,使用openpyxl庫的 load_workbook 加載 XLSX 文件,將每個工作表轉換為包含合并單元格處理的 HTML 表格。通過weasyprint 轉成pdf。
Renderers
marker 提供了三種格式的輸出:json、html、markdown,它們的代碼都在marker/renderers
。這三種格式包含的信息不是相同的,以下是分析:
- 因為 document 最容易轉化為 json(都是樹結構可以直接轉),所以 json 包含的信息最多(比如包含了caption 的分類結果,還有目標檢測bbox 框),但因為過于復雜所以一般用不上。
- html 是可視化效果最好的,尤其是表格,marker 對表格的解析非常驚艷,不僅文本精確識別,而且能識別出復雜的表結構(比如合并單元格),這些都能用 html 很好的渲染。
- markdown 包含的信息量最少,但是勝在簡單,在 RAG 任務中適合作為下游 LLM 模型的輸入。注意markdown 是從html 轉換過來的而不是document,所以一些復雜結構(比如表格)會有失真。
renderers 中的代碼可讀性不錯,可以自己修改得到想要的輸出。比如我就修改過 markdown 的輸出,讓它包含頁碼、bbox、table html 等信息。
總結
marker 是一個非常優秀的基于深度學習的 pdf 解析工具,它可以在大部分場景下得到完美的解析結果,代碼可讀性和拓展性也很不錯,很難想象這是一個人獨自開發出來的。
marker 項目地址:https://github.com/VikParuchuri/marker