前言
文件分割是一項具有挑戰性的任務,它是任何知識庫問答系統的基礎。高質量的文件分割結果對於顯著提升問答效果至關重要,但是目前大多數開源庫的處理能力有限。
這些開源的庫或者方法缺點大致可以羅列如下:
- 只能處理文字,無法提取表格中的內容
- 缺乏有效的分割策略,要麼是一整個文件全部提取,要麼是詞粒度的獲取
對於第一點,一般是把表格中的內容識別成文字,這樣餵給大模型的時候就會出現一連串數字或者字母,這無疑會增大模型的理解難度;對於第二點,則是需要按照指定的長度對文件進行切分,或者把詞按照一定的規則拼接到一塊,這同樣會損失到文字自身的上下文資訊。
而本文接下來介紹的Open-parse這個庫可以直接從文字中提取出多個節點,每個節點就是一個chunk,已經分好了,因此無需再按照長度進行split,這樣同時也比單獨提取一個詞再進行合併又簡化了不少操作;同時還支援同時提取表格和文字,無需分開提取。
快速開始
安裝
pip install openparse
使用pip
進行安裝,同時這個庫依賴Pymupdf
、pdfminer
等其他庫,也會同時安裝。
識別文字
pdf = "c:\\人口.pdf"
parser = openparse.DocumentParser()
parsed_basic_doc = parser.parse(pdf)
for node in parsed_basic_doc.nodes:
node
print('\n--------------------\n')
可以看到每一頁的pdf被分成多個chunk,且還能保留原始文字中的加粗、斜體等資訊。
print(parsed_basic_doc.nodes[0])
elements=(TextElement(text='Aging Research老齡化研究, 2022, 9(3), 26-34\nPublished Online September 2022 in Hans. http://www.hanspub.org/journal/ar \nhttps://doi.org/10.12677/ar.2022.93004 ', lines=(LineElement(bbox=(56.64, 739.57, 232.44, 750.01), spans=(TextSpan(text='Aging Research ', is_bold=True, is_italic=False, size=9.0), TextSpan(text='老齡化研究', is_bold=False, is_italic=False, size=9.0), TextSpan(text=', 2022, 9(3), 26-34 ', is_bold=True, is_italic=False, size=9.0)), style=None, text='Aging Research老齡化研究, 2022, 9(3), 26-34'), LineElement(bbox=(56.65, 728.28, 348.95, 737.28), spans=(TextSpan(text='Published Online September 2022 in Hans. http://www.hanspub.org/journal/ar ', is_bold=False, is_italic=False, size=9.0),), style=None, text='Published Online September 2022 in Hans. http://www.hanspub.org/journal/ar '), LineElement(bbox=(56.64, 717.36, 225.23, 726.36), spans=(TextSpan(text='https://doi.org/10.12677/ar.2022.93004 ', is_bold=False, is_italic=False, size=9.0),), style=None, text='https://doi.org/10.12677/ar.2022.93004 ')), bbox=Bbox(page=0, page_height=807.96, page_width=595.32, x0=56.64, y0=717.36, x1=348.95, y1=750.01), variant=<NodeVariant.TEXT: 'text'>, embed_text='Aging Research老齡化研究, 2022, 9(3), 26-34\nPublished Online September 2022 in Hans. http://www.hanspub.org/journal/ar \nhttps://doi.org/10.12677/ar.2022.93004 '),) variant={'text'} tokens=66 bbox=[Bbox(page=0, page_height=807.96, page_width=595.32, x0=56.64, y0=717.36, x1=348.95, y1=750.01)] text='Aging Research老齡化研究, 2022, 9(3), 26-34\nPublished Online September 2022 in Hans. http://www.hanspub.org/journal/ar \nhttps://doi.org/10.12677/ar.2022.93004 '
透過列印出node,可以看出這種結構包含了原始文字中的元資訊,包含文字的座標、大小、是否加粗、是否斜體等。
識別表格內容
- Pymupdf
- Unitable
- Table Transformer
openparse
提供了三個方法來識別和提取表格中的內容,方法1是直接使用Pymupdf
這個庫的表格識別模組,因此準確率最差,但對硬體要求不高;其他的2個都是100mb左右的模型,如果用cpu來推理會比較耗時。
# defining the parser (table_args is a dict)
parser = openparse.DocumentParser(
table_args={
"parsing_algorithm": "table-transformers", # 或者其他兩個方法
"table_output_format": "html" # 以html格式返回表格內容,也可以選擇md
}
)
與前面直接識別文字類似,只需要加入table_args
引數即可。
可以看到表格中的內容被很好的還原了
使用表格提取除了返回表格內容外,還會把正常的文字返回,這與
Pymupdf
等庫只能選擇返回文字還是隻返回已有的表格不同。因此在不確定文字中含有什麼內容時用這個方法會更加保險一點,對硬體的計算要求也不高。
語義相似
from openparse import processing, DocumentParser
semantic_pipeline = processing.SemanticIngestionPipeline(
openai_api_key=OPEN_AI_KEY,
model="text-embedding-3-large",
min_tokens=64,
max_tokens=1024,
)
parser = DocumentParser(
processing_pipeline=semantic_pipeline,
)
openparse
還支援端到端的方式對node資料進行向量化並聚類,只需要指定processing_pipeline
為相應的embedding模型即可。但是目前僅支援OpenAI的模型,需要OPEN_AI_KEY才可以使用。雖然後續會更新其他模型,但目前想用的話需要自己修改這段程式碼的實現。
combine_parser = DocumentParser(
processing_pipeline=semantic_pipeline,
table_args={
"parsing_algorithm": "table-transformers",
"table_output_format": "html"
}
)
同時,還能把語義相似和表格內容提取組合到一起使用,實現對錶格內容提取的同時還能融合相似的片段。
總結
openparse
這個庫算是目前開源社群中比較優秀的文件分割處理庫了,功能雖然全面,還是還有不少可以最佳化的地方,後續也會支援其他向量化模型,並且可以跟Llamaindex
、Langchain
等框架無縫銜接,應該值得持續關注。