OCRFlux是一款轻量的多模态工具包,擅长处理PDF文件中复杂布局、解析复杂表格以及合并跨页内容,OCRFlux基于30亿参数的视觉语言模型(VLM)构建,能在GTX 3090 GPU上运行。
OCRFlux单页处理功能,能在多列布局、图表和插图的情况下,将内容转换为符合自然阅读顺序的文本,支持复杂表格和公式能自动移除页眉页脚,支持跨页表格合并和跨页段落合并。
在发布的基准测试OCRFlux-bench-single上,编辑距离相似度(EDS)分别比基线模型olmOCR-7B-0225-preview高0.095(从0.872提升至0.967)、比Nanonets-OCR-s高0.109(从0.858提升至0.967)、比MonkeyOCR高0.187(从0.780提升至0.967)
为衡量OCR系统的单页解析性能,我们推出了两个全面的基准测试:
OCRFlux-bench-single:包含2000个PDF页面(1000个英文页面和1000个中文页面)及其人工多轮校验的真实Markdown标注。
OCRFlux-pubtabnet-single:基于公开的PubTabNet基准改造,包含9064个HTML表格样本,根据是否包含跨行跨列单元格,分为简单表格和复杂表格。
以上基准测试均未纳入训练和评估数据,主要结果如下:
在OCRFlux-bench-single中,通过生成的Markdown与真实Markdown的编辑距离相似度(EDS)进行评估:
语言 | 模型 | 平均EDS(越高越好) |
---|---|---|
英文 | olmOCR-7B-0225-preview | 0.885 |
Nanonets-OCR-s | 0.870 | |
MonkeyOCR | 0.828 | |
OCRFlux-3B | 0.971 | |
中文 | olmOCR-7B-0225-preview | 0.859 |
Nanonets-OCR-s | 0.846 | |
MonkeyOCR | 0.731 | |
OCRFlux-3B | 0.962 | |
总计 | olmOCR-7B-0225-preview | 0.872 |
Nanonets-OCR-s | 0.858 | |
MonkeyOCR | 0.780 | |
OCRFlux-3B | 0.967 |
在OCRFlux-pubtabnet-single中,通过生成的HTML表格与真实HTML表格的树编辑距离相似度(TEDS)进行评估:
类型 | 模型 | 平均TEDS(越高越好) |
---|---|---|
简单 | olmOCR-7B-0225-preview | 0.810 |
Nanonets-OCR-s | 0.882 | |
MonkeyOCR | 0.880 | |
OCRFlux-3B | 0.912 | |
复杂 | olmOCR-7B-0225-preview | 0.676 |
Nanonets-OCR-s | 0.772 | |
MonkeyOCR | 0.826 | |
OCRFlux-3B | 0.807 | |
总计 | olmOCR-7B-0225-preview | 0.744 |
Nanonets-OCR-s | 0.828 | |
MonkeyOCR | 0.853 | |
OCRFlux-3B | 0.861 |
PDF文档通常分页显示,这会导致表格或段落被拆分到连续页面中。准确检测并合并这些跨页结构,能避免生成不完整或碎片化的内容。
检测任务:给定连续两页的Markdown元素列表(如段落、表格),识别需要跨页合并的元素索引。
合并任务:段落合并可直接拼接;表格合并更复杂(如跨页表格可能重复首页表头、单元格内容跨页拆分、多列表格垂直拆分等)。为此,专门开发了用于跨页表格合并的LLM模型,输入两个拆分的表格片段,输出完整、结构清晰的表格。
OCRFlux-bench-cross:包含1000个样本(500个英文样本和500个中文样本),每个样本含连续两页的Markdown元素列表及需合并元素的人工标注索引(无合并需求则索引为空)。
OCRFlux-pubtabnet-cross:包含9064对拆分的表格片段及对应的真实合并版本。
以上基准测试同样未纳入训练和评估数据,主要结果如下:
在OCRFlux-bench-cross中,评估指标为准确率、精确率、召回率和F1分数(检测结果需准确判断是否有跨页合并元素及对应索引):
语言 | 精确率(越高越好) | 召回率(越高越好) | F1分数(越高越好) | 准确率(越高越好) |
---|---|---|---|---|
英文 | 0.992 | 0.964 | 0.978 | 0.978 |
中文 | 1.000 | 0.988 | 0.994 | 0.994 |
总计 | 0.996 | 0.976 | 0.986 | 0.986 |
在OCRFlux-pubtabnet-cross中,通过生成的合并表格与真实合并表格的树编辑距离相似度(TEDS)评估:
表格类型 | 平均TEDS(越高越好) |
---|---|
简单 | 0.965 |
复杂 | 0.935 |
总计 | 0.950 |
• 较新的NVIDIA GPU(已在RTX 3090、4090、L40S、A100、H100上测试),至少12GB GPU内存
• 20GB可用磁盘空间
• 需要安装poppler-utils和额外字体用于PDF图像渲染
sudo apt-get update
sudo apt-get install poppler-utils poppler-data ttf-mscorefonts-installer msttcorefonts fonts-crosextra-caladea fonts-crosextra-carlito gsfonts lcdf-typetools
OCRFlux的依赖在现有Python环境中较难安装,建议创建干净的Python环境:
conda create -n ocrflux python=3.11
conda activate ocrflux
git clone https://github.com/chatdoc-com/OCRFlux.git
cd ocrflux
pip install -e . --find-links https://flashinfer.ai/whl/cu124/torch2.5/flashinfer/
快速测试可尝试网页演示。本地运行需要GPU(推理基于vllm)。
python -m ocrflux.pipeline ./localworkspace --data test.pdf --model /model_dir/OCRFlux-3B
python -m ocrflux.pipeline ./localworkspace --data test_page.png --model /model_dir/OCRFlux-3B
python -m ocrflux.pipeline ./localworkspace --data test_pdf_dir/* --model /model_dir/OCRFlux-3B
可设置--skip_cross_page_merge
跳过跨页合并以加速处理,直接拼接每页解析结果生成最终Markdown。
结果以JSONL文件形式保存在./localworkspace/results
目录,每行JSON对象包含以下字段:
{
"orig_path": "str", // 原始pdf或图片文件路径
"num_pages": "int", // pdf文件的页数
"document_text": "str", // 转换后的Markdown文本
"page_texts": "dict", // 每页的Markdown文本,键为页码索引,值为对应页文本
"fallback_pages": "[int]", // 转换失败的页码索引
}
无需使用在线vllm服务器,可在代码中使用推理API直接调用OCRFlux:
from vllm import LLM
from ocrflux.inference import parse
file_path = 'test.pdf'
# file_path = 'test.png'
llm = LLM(model="model_dir/OCRFlux-3B",gpu_memory_utilization=0.8,max_model_len=8192)
result = parse(llm,file_path)
if result != None:
document_markdown = result['document_text']
print(document_markdown)
with open('test.md','w') as f:
f.write(document_markdown)
else:
print("解析失败。")
若解析失败或结果中有转换失败的页面,可在parse
函数中设置max_page_retries
参数(正整数)以获取更好结果,但可能会延长推理时间。
• 支持GPU的Docker(NVIDIA Toolkit) • 预下载模型:OCRFlux-3B
docker run -it --gpus all \
-v /path/to/localworkspace:/localworkspace \
-v /path/to/test_pdf_dir:/test_pdf_dir/ \
-v /path/to/OCRFlux-3B:/OCRFlux-3B \
chatdoc/ocrflux:latest /localworkspace --data /test_pdf_dir/* --model /OCRFlux-3B/
运行以下命令生成最终Markdown文件,生成的文件位于./localworkspace/markdowns/DOCUMENT_NAME
目录:
python -m ocrflux.jsonl_to_markdown ./localworkspace
python -m ocrflux.pipeline --help
usage: pipeline.py [-h] [--task {pdf2markdown,merge_pages,merge_tables}] [--data [DATA ...]] [--pages_per_group PAGES_PER_GROUP] [--max_page_retries MAX_PAGE_RETRIES]
[--max_page_error_rate MAX_PAGE_ERROR_RATE] [--workers WORKERS] [--model MODEL] [--model_max_context MODEL_MAX_CONTEXT] [--model_chat_template MODEL_CHAT_TEMPLATE]
[--target_longest_image_dim TARGET_LONGEST_IMAGE_DIM] [--skip_cross_page_merge] [--port PORT]
workspace
用于批量处理数百万PDF的管道管理器
positional arguments:
workspace 工作存储的文件系统路径,可以是本地文件夹
options:
-h, --help 显示帮助信息并退出
--data [DATA ...] 待处理文件的路径列表
--pages_per_group PAGES_PER_GROUP
每个工作项组的目标PDF页数
--max_page_retries MAX_PAGE_RETRIES
页面渲染的最大重试次数
--max_page_error_rate MAX_PAGE_ERROR_RATE
文档中允许的失败页面比例,默认1/250
--workers WORKERS 同时运行的工作进程数
--model MODEL 模型路径
--model_max_context MODEL_MAX_CONTEXT
模型微调时的最大上下文长度
--model_chat_template MODEL_CHAT_TEMPLATE
传递给vllm服务器的聊天模板
--target_longest_image_dim TARGET_LONGEST_IMAGE_DIM
渲染PDF页面时最长边的尺寸
--skip_cross_page_merge
是否跳过跨页合并
--port PORT VLLM服务器使用的端口
代码中部分可复用模块可能对其他项目有帮助: • 使用VLLM通过已发布模型处理数百万PDF——pipeline.py • 从jsonl文件生成最终Markdown——jsonl_to_markdown.py • 评估模型单页解析任务——eval_page_to_markdown.py • 评估模型表格解析任务——eval_table_to_html.py • 评估模型段落/表格合并检测任务——eval_element_merge_detect.py • 评估模型表格合并任务——eval_html_table_merge.py