surya:支持90+语言的文档OCR工具包,含布局分析、表格识别与LaTeX转换

OCR, layout analysis, reading order, table recognition in 90+ languages

Branch82Tags88
This repository is empty

Datalab Logo

Datalab

文档智能领域的顶尖模型

Code License Model License Discord

Homepage Docs Datalab Playground


Surya

Surya 是一个拥有 6.5 亿参数的 OCR 模型,具备以下特性:

  • 准确性——在 olmOCR-bench 上得分 83.3%(30 亿参数以下模型中的佼佼者)
  • 速度——在 RTX 5090 上的吞吐量为每秒 5 页
  • 多语言支持——在包含 91 种语言的内部基准测试集上得分 87.2%(更多信息见#多语言支持
  • 带阅读顺序的版面分析(表格、图像、标题等)
  • 表格识别(行 + 列)

我们还提供用于行级文本检测和 OCR 错误检测的小型模型。它适用于多种类型的文档(参见使用方法基准测试)。

试用 Datalab 托管平台

我们的托管平台同时运行 Surya 以及我们最高精度模型 Chandra 的变体。

立即开始使用5 美元免费额度——注册(不到 30 秒)或试用我们的免费公共演示平台

模型信息

检测 OCR
版面分析 表格识别

Surya 的命名源于印度教太阳神,象征其拥有全局视野。

示例

每行均链接至同一页面的五种标注视图:文本行检测、OCR、版面分析、阅读顺序以及(若存在)表格识别。

名称 检测 OCR 版面分析 阅读顺序 表格识别
报纸 图片 图片 图片 图片
教科书 图片 图片 图片 图片
税务表单 图片 图片 图片 图片 图片
手写笔记 图片 图片 图片 图片 图片
企业文档 图片 图片 图片 图片 图片

商业用途

Surya 代码基于 Apache 2.0 许可证授权。模型权重采用修改后的 AI Pubs Open Rail-M 许可证(免费用于研究、个人使用以及融资/收入低于 500 万美元的初创企业)。如需更广泛的模型权重商业授权,请访问我们的定价页面 此处

安装

通过以下方式安装:

pip install surya-ocr

推理后端前提条件

Surya 会在首次使用时自动启动服务器,您需要 vllm(适用于 NVIDIA GPU)或 llama.cpp(适用于 CPU / Apple Silicon):

  • NVIDIA GPU: 需安装 Docker 以及 NVIDIA Container Toolkit
  • CPU / Apple Silicon: 需从 llama.cpp 获取 llama-server 二进制文件:
    brew install llama.cpp     # macOS
    # 或从 https://github.com/ggml-org/llama.cpp/releases 下载发行版
    

从 Surya v1 升级

如果您使用的是 v1 版本代码,可按以下方式迁移至本版本:

# v2
from surya.inference import SuryaInferenceManager
from surya.recognition import RecognitionPredictor

manager = SuryaInferenceManager()              # auto-spawns vllm or llama-server
rec = RecognitionPredictor(manager)
predictions = rec([image])

有何不同:

  • SuryaInferenceManager 取代了 FoundationPredictor。同一个管理器实例可在 LayoutPredictorRecognitionPredictorTableRecPredictor 之间共享。
  • 输出架构已更改:详见下方各部分的 JSON 表格。重点变化 — text_linesblocks(新增 html);布局分析移除 top_k,新增 count;表格识别从单元格中移除 is_header / colspan / rowspan

用法

Surya 2 通过单个 VLM 运行布局分析、OCR 和表格识别。推理管理器会在首次使用时为您启动一个 VLM;您也可以通过 SURYA_INFERENCE_URL=http://host:port/v1 将其指向现有服务器。

  • 可在 surya/settings.py 中查看设置。您可以通过环境变量覆盖任何设置(例如 SURYA_INFERENCE_BACKEND=vllm)。
  • 文本检测和 OCR 错误是独立的模型。

服务器生命周期(--keep_server

默认情况下,每个命令在启动时启动 VLM 服务器,并在退出时将其关闭 — 因此连续运行多个命令时,每次都会产生启动(以及在 GPU 上的模型加载)成本。传递 --keep_server 可让服务器保持运行状态,以便后续命令连接到该服务器,而不是重新启动:

surya_ocr    DATA_PATH --keep_server   # spawns the server and leaves it up
surya_layout DATA_PATH                 # attaches to the running server
surya_table  DATA_PATH                 # ...and so on, no re-spawn

--keep_server 可用于所有命令。使用完毕后,请停止服务器(通过 docker stop 命令停止 surya-vllm-* 容器,或终止 llama-server 进程),或者设置 SURYA_INFERENCE_KEEP_ALIVE=1 以将保持连接设为默认状态。

交互式应用

我已内置一个 streamlit 应用,让您可以通过交互方式在图像或 PDF 文件上试用 Surya。运行命令如下:

pip install streamlit pdftext
surya_gui

OCR(文本识别)

此命令将输出一个包含检测到的文本和边界框的 json 文件:

surya_ocr DATA_PATH
  • DATA_PATH 可以是图片、PDF 或图片/PDF 文件夹
  • --images 会保存页面图像和检测到的区块图像(可选)
  • --output_dir 指定用于保存结果的目录,而非默认目录
  • --page_range 指定 PDF 中要处理的页面范围,可指定为单个数字、逗号分隔的列表、范围或逗号分隔的范围 - 例如:0,5-10,20
  • --keep_server 在命令退出后保持推理服务器运行,以便后续命令重用(参见 服务器生命周期)。适用于所有命令。

results.json 文件包含一个以输入文件名(无扩展名)为键的字典。每个值是一个页面字典列表。每个页面字典包含:

  • blocks - 按阅读顺序排列的每个区块的 OCR 结果
    • label - 规范化的布局标签(例如 TextSectionHeaderTableEquationPictureFormPageHeader 等)。完整的规范名称集参见 surya/layout/label.py:LAYOUT_PRED_RELABEL
    • raw_label - 模型输出的原始标签,未经规范化
    • reading_order - 布局输出中的 0 索引位置
    • html - 区块内容的 HTML 格式(数学公式包裹在 <math>...</math> 中,表格为 <table>...</table> 等)。如果区块被跳过,则为 ""
    • polygon - 4 角多边形,顺序为 [[x0,y0],[x1,y0],[x1,y1],[x0,y1]]
    • bbox - 从多边形导出的轴对齐边界框 [x0, y0, x1, y1]
    • confidence - 区块解码过程中每个 token 概率的平均值(0-1)
    • skipped - 如果区块是视觉标签(例如图片)且未进行 OCR,则为 true
    • error - 如果区块 OCR 调用失败,则为 true
  • image_bbox - 页面图像的 [0, 0, width, height]

性能提示

  • 吞吐量由推理后端决定。使用 vllm 时,提高 --max-num-seqs / --max-num-batched-tokens(或客户端的 SURYA_INFERENCE_PARALLEL)以保持更多页面在处理中。使用 llama.cpp 时,将 SURYA_INFERENCE_PARALLEL 设置为与 llama-server 上的 --parallel 相匹配。
  • DPI 也会显著影响吞吐量 - 您可以调整 DPI 设置,为您的用例做出合适的吞吐量/准确性权衡。尝试从 192 降至 96 以提高吞吐量。
  • MTP 也会影响延迟/吞吐量 - 您可以在设置中调整 vllm mtp 配置。

从 Python 开始

from PIL import Image
from surya.inference import SuryaInferenceManager
from surya.recognition import RecognitionPredictor

manager = SuryaInferenceManager()
recognition_predictor = RecognitionPredictor(manager)

# Default: full-page OCR. One VLM call per page. Returns one PageOCRResult per
# image: `.blocks` (each with label, html, polygon, bbox, confidence, ...) and
# `.image_bbox` — the same schema as block mode.
predictions = recognition_predictor([Image.open(IMAGE_PATH)])

# Block mode: pre-run layout, then per-block OCR. Same return schema as above.
# Auto-selected when `layout_results` is passed.
from surya.layout import LayoutPredictor
layout = LayoutPredictor(manager)
layouts = layout([Image.open(IMAGE_PATH)])
predictions = recognition_predictor([Image.open(IMAGE_PATH)], layouts)

文本行检测

此命令将输出一个包含检测到的边界框的 json 文件。

surya_detect DATA_PATH
  • DATA_PATH 可以是图片、PDF 或图片/PDF 文件夹
  • --images 将保存页面图像和检测到的文本行图像(可选)
  • --output_dir 指定用于保存结果的目录,而非默认目录
  • --page_range 指定 PDF 中要处理的页面范围,可指定为单个数字、逗号分隔的列表、范围或逗号分隔的范围 - 例如:0,5-10,20

results.json 文件将包含一个 JSON 字典,其中键是不带扩展名的输入文件名。每个值是一个字典列表,对应输入文档的每一页。每个页面字典包含:

  • bboxes - 检测到的文本边界框
    • bbox - 文本行的轴对齐矩形,格式为 (x1, y1, x2, y2)。(x1, y1) 是左上角,(x2, y2) 是右下角。
    • polygon - 文本行的多边形,格式为 (x1, y1), (x2, y2), (x3, y3), (x4, y4)。这些点按顺时针顺序从左上角开始排列。
    • confidence - 模型对检测到的文本的置信度(0-1)
  • vertical_lines - 文档中检测到的垂直线
    • bbox - 轴对齐的线坐标。
  • page - 文件中的页码
  • image_bbox - 图像的边界框,格式为 (x1, y1, x2, y2)。(x1, y1) 是左上角,(x2, y2) 是右下角。所有文本行边界框都将包含在此边界框内。

性能提示

检测模块是一个 torch 模型。DETECTOR_BATCH_SIZE 在运行时默认会自动选择一个值;可通过覆盖此环境变量来控制 GPU 上的显存使用,在显存更大的显卡上可适当提高该值。

从 Python 中使用

from PIL import Image
from surya.detection import DetectionPredictor

det_predictor = DetectionPredictor()
predictions = det_predictor([Image.open(IMAGE_PATH)])

版面与阅读顺序

此命令将输出一个包含检测到的版面和阅读顺序的 json 文件。

surya_layout DATA_PATH
  • DATA_PATH 可以是图片、PDF 或图片/PDF 文件夹
  • --images 将保存页面图像和检测到的文本行图像(可选)
  • --output_dir 指定用于保存结果的目录,而非默认目录
  • --page_range 指定 PDF 中要处理的页面范围,可指定为单个数字、逗号分隔的列表、范围或逗号分隔的范围 - 例如:0,5-10,20

results.json 文件包含一个以输入文件名(无扩展名)为键的字典。每个值是页面字典的列表。每个页面字典包含:

  • bboxes - 阅读顺序中的布局框
    • polygon - 四角多边形 [[x0,y0],[x1,y0],[x1,y1],[x0,y1]]
    • bbox - 从多边形导出的轴对齐 [x0, y0, x1, y1]
    • label - 规范化标签。为 CaptionFootnoteEquationListGroupPageHeaderPageFooterPictureSectionHeaderTableTextFigureCodeFormTableOfContentsChemicalBlockDiagramBibliographyBlankPage 中的一种
    • raw_label - 模型输出的原始标签
    • position - 从 0 开始的阅读顺序索引
    • count - 模型对该区块 OCR 的 token 估计值(四舍五入到 50 的倍数;用于确定每个区块的解码预算大小)
    • confidence - 布局解码过程中的平均每个 token 概率(0-1)
  • image_bbox - [0, 0, width, height]
  • raw - 布局模型输出的原始 JSON,用于调试
  • error - 若布局调用失败,则为 true

性能提示

布局通过共享推理后端运行。吞吐量调优与 OCR 相同——参见上文的性能提示。

从 Python 调用

from PIL import Image
from surya.inference import SuryaInferenceManager
from surya.layout import LayoutPredictor

layout_predictor = LayoutPredictor(SuryaInferenceManager())
layout_predictions = layout_predictor([Image.open(IMAGE_PATH)])

表格识别

此命令会输出一个 json 文件,其中包含检测到的表格单元格、行/列 ID 以及行/列边界框。如果您希望获取单元格位置和文本,并进行美观的格式化,请查看 marker 仓库。您可以使用 TableConverter 来检测和提取图像及 PDF 中的表格。它支持 json(带边界框)、markdown 和 html 格式的输出。

surya_table DATA_PATH
  • DATA_PATH 可以是图片、PDF 或图片/PDF 文件夹
  • --images 将在 json 文件旁保存带注释的行和列覆盖图(可选)
  • --output_dir 指定保存结果的目录,而非默认目录
  • --page_range 指定 PDF 中要处理的页面范围,可指定为单个数字、逗号分隔的列表、范围或逗号分隔的范围 - 例如:0,5-10,20
  • --skip_table_detection 告知表格识别不要先检测表格。如果您的图像已裁剪为表格,请使用此选项。

results.json 文件包含一个以输入文件名(无扩展名)为键的字典。每个值是一个表格字典列表。每个表格字典包含:

  • rows - 按阅读顺序检测到的表格行
    • polygon / bbox - 行几何形状(与其他地方的约定相同)
    • row_id - 0 索引的行 ID
  • cols - 检测到的表格列
    • polygon / bbox - 列几何形状
    • col_id - 0 索引的列 ID
  • cells - 几何行×列交叉区域(简单模式)
    • polygon / bbox - 单元格几何形状
    • row_idcol_idcell_id
  • html - 完整的 <table>...</table> HTML(仅在使用 predict_full 时填充;处理跨单元格/标题行)。在简单模式下为 null
  • mode - "simple""full"
  • image_bbox - 表格裁剪边框
  • error - 如果 table_rec 调用失败,则为 true
  • raw - 原始模型输出,用于调试

性能提示

表格识别通过共享的 VLM 进行。吞吐量调优与 OCR 相同。

从 Python 调用

from PIL import Image
from surya.inference import SuryaInferenceManager
from surya.table_rec import TableRecPredictor

table_rec_predictor = TableRecPredictor(SuryaInferenceManager())

# Default: rows + columns only, cells derived from intersections.
table_predictions = table_rec_predictor([Image.open(IMAGE_PATH)])

# Or full HTML output (better for spanning cells / headers):
# table_predictions = table_rec_predictor.predict_full([image])

数学/公式

Surya 2 将数学公式作为全页 OCR 的一部分进行内联处理——识别出的公式会以 <math>...</math> 标签的形式,与周围的文本内容一同出现在 HTML 输出中,其格式为兼容 KaTeX 的 LaTeX。无需单独的 LaTeX OCR 处理步骤。

推理后端

布局分析/OCR/表格识别(table_rec)均共享同一个 VLM,可通过 vllm(GPU)或 llama.cpp(CPU/Apple Silicon)提供服务。SuryaInferenceManager 会自动启动一个后端服务;您也可以将其指向一个已预先运行的服务器:

# Attach to an existing vllm
export SURYA_INFERENCE_BACKEND=vllm
export SURYA_INFERENCE_URL=http://localhost:8000/v1
设置项 默认值 说明
SURYA_INFERENCE_BACKEND auto (若为 NVIDIA 则使用 vllm,否则使用 llamacpp) vllm | llamacpp | 未设置(自动)
SURYA_INFERENCE_URL (自动启动) 连接到运行中的 OpenAI 兼容服务器
SURYA_INFERENCE_PARALLEL 8 客户端到后端的并发数
SURYA_INFERENCE_KEEP_ALIVE false 退出后保持启动的服务器运行(参见 --keep_server
SURYA_GUIDED_LAYOUT true JSON 模式约束的布局解码

局限性

  • 专为文档 OCR 设计。不针对照片或自然场景优化性能。
  • 布局分析、OCR、表格识别均需要运行中的推理后端(vllm 或 llama.cpp)。检测仅依赖 torch 运行,无需推理后端。

故障排除

如果 OCR 无法正常工作:

  • 尝试提高图像分辨率,使文本更大。如果分辨率已经很高,尝试将宽度降低到不超过 2048px
  • 对图像进行预处理(二值化、去歪斜等)有助于处理非常旧或模糊的图像。
  • 如果结果不理想,可以调整 DETECTOR_BLANK_THRESHOLDDETECTOR_TEXT_THRESHOLDDETECTOR_BLANK_THRESHOLD 控制行间距——任何低于此数值的预测都将被视为空白区域。DETECTOR_TEXT_THRESHOLD 控制文本的合并方式——任何高于此数值的都将被视为文本。DETECTOR_TEXT_THRESHOLD 应始终高于 DETECTOR_BLANK_THRESHOLD,且两者均应在 0-1 范围内。查看检测器调试输出中的热力图可以指导如何调整这些阈值(如果看到类似框的模糊区域,降低阈值;如果看到边界框被合并在一起,提高阈值)。

手动安装

如果您想要开发 surya,可以通过 uv 手动安装:

git clone https://github.com/datalab-to/surya.git
cd surya
uv sync --group dev      # installs runtime + dev deps
uv run surya_ocr ...     # or `source .venv/bin/activate` to enter the venv

基准测试

Surya 2 是一款单一视觉语言模型(VLM),可在一个模型中处理布局分析、光学字符识别(OCR,全页或按块)以及表格识别。我们在 olmOCR-bench 上进行端到端评估,该基准是文档解析器的标准质量基准。

olmOCR-bench

在模型大小与得分的权衡前沿上达到帕累托最优,且在 30 亿参数以下的模型中表现最佳。

模型 参数规模 得分
Infinity-Parser2-Pro 35.1B 87.6
Chandra OCR 2 (Datalab) 4.0B 85.9
dots.mocr 3.0B 83.9
Surya OCR 2 (Datalab) 0.65B 83.3
LightOnOCR 2-1B * 1.0B 83.2
Chandra OCR 1 (Datalab) 9.0B 83.1
olmOCR (anchored) 8.3B 77.4
GOT OCR 0.6B 48.3

* LightOnOCR 2-1B 采用的基准测试方法与其他条目不同(参见其 发布说明);此得分仅作参考,不具备直接可比性。

对比分数来源于 olmOCR-bench 数据集卡片

Surya 2 在 default 预设下各来源的通过率(共 8,413 项测试):

ArXiv Base Hdr/Ftr TinyTxt MultCol OldScan OldMath Tables
88.3 99.7 92.5 93.7 82.4 41.8 81.4 86.6

多语言能力

我们还针对 Surya 2 进行了一项涵盖 91 种语言的内部基准测试,评估内容包括每种语言文档中的文本准确性、布局、表格、数学公式以及阅读顺序。

总体通过率:91 种语言平均 87.2%。 其中 38 种语言得分 ≥ 90%;76 种语言得分 ≥ 80%。

使用最广泛的 15 种语言:

代码 语言 得分
ar 阿拉伯语 72.7%
bn 孟加拉语 82.7%
zh 中文 82.5%
en 英语 92.3%
fr 法语 89.3%
de 德语 89.7%
hi 印地语 82.2%
it 意大利语 93.0%
ja 日语 86.2%
ko 韩语 86.7%
fa 波斯语 82.3%
pt 葡萄牙语 86.1%
ru 俄语 88.8%
es 西班牙语 90.7%
vi 越南语 73.2%

完整的 91 种语言表格请参见 static/docs/multilingual.md

吞吐量

全页OCR,96 DPI输入(平均每页约2,400个输出token),在客户端针对运行中的推理服务器进行测量。

RTX 5090(vllm)

vllm/vllm-openai:v0.20.1,单块RTX 5090(32 GB)。

并发数 页数/秒 tokens/秒 p50(毫秒) p95(毫秒) 平均token/页
128 5.35 12,884 18,915 42,538 2,410

Apple Silicon(llama.cpp / Metal)

带有Metal后端的llama-server

--parallel 页数/秒 tokens/秒 p50(毫秒) p95(毫秒) 平均token/页 功耗
8 0.108 254 59,313 129,173 2,360 ~30 W

复现方法

我们通过使用vllm(或llama.cpp)部署模型,并运行来自allenai/olmocr的olmOCR-bench测试工具,对Surya 2在olmOCR-bench上进行评分。我们对测试工具做了一些调整,以适应我们的HTML输出格式。

训练

布局分析、OCR和表格识别共享一个单一的视觉语言模型(Qwen3.5风格架构,约6.5亿参数)。该模型在多样化的文档图像上进行训练,可根据提示输出布局JSON或全页HTML。文本行检测是一个独立的小型torch模型——基于EfficientViT segformer修改而来,使用文档行注释数据从头开始训练。

如果您需要帮助使用自己的数据微调Surya,或希望使用我们的托管训练栈,请通过hi@datalab.to与我们联系。

致谢

这项工作的完成离不开众多出色的开源AI项目:

感谢所有为开源AI做出贡献的人们。

引用说明

如果您在工作或研究中使用 surya(或相关模型),请考虑使用以下 BibTeX 条目引用我们:

@misc{paruchuri2025surya,
  author       = {Vikas Paruchuri and Datalab Team},
  title        = {Surya: A lightweight document OCR and analysis toolkit},
  year         = {2025},
  howpublished = {\url{https://github.com/datalab-to/surya}},
  note         = {GitHub repository},
}



Introduction

光学字符识别、版面分析以及在90多种语言中的行检测【此简介由AI生成】

Customize your domain
12821.36 K1.54 KVisit GitHub