26 KiB
Note
本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
English · 原始项目 · 上游 README
原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
Datalab
文档智能(Document Intelligence)领域的最先进模型
Surya
Surya 是一款 650M 参数的 OCR 模型,具备以下特性:
- 准确度 - 在 olmOCR-bench (top under 3B params) 上得分 83.3%
- 速度 - 在 RTX 5090 上吞吐量达 5 页/秒
- 多语言 - 在涵盖 91 种语言的内部基准测试集上得分 87.2%(更多内容见此处)
- 版面分析(表格、图片、页眉等)及阅读顺序
- 表格识别(行 + 列)
我们还提供用于行级文本检测和 OCR 错误检测的更小模型。它适用于多种文档(参见用法和基准测试)。
试用 Datalab 托管平台
我们的托管平台同时运行 Surya,以及我们最高精度模型 Chandra. 的变体
使用 $5 免费额度 即可开始 — 注册 (takes under 30 seconds) 或试用我们的免费公共 Playground.
模型信息
| 检测 | OCR |
|---|---|
![]() |
![]() |
| 版面 | 表格识别 |
|---|---|
![]() |
![]() |
Surya 得名于拥有全知之眼的印度教太阳神, who has universal vision.
示例
每一行链接到同一页面的五种标注视图:文本行检测、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 plus the NVIDIA Container Toolkit.
- CPU / Apple Silicon: 来自 llama.cpp 的
llama-server二进制文件:brew install llama.cpp # macOS # or grab a release from 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。同一管理器实例在LayoutPredictor、RecognitionPredictor、TableRecPredictor之间共享。- 输出模式已变更:请参阅下方各章节的 JSON 表格。要点 —
text_lines→blocks(含html);版面分析移除了top_k,新增了count;table_rec 从单元格中移除了is_header/colspan/rowspan。
用法
Surya 2 通过单一 VLM 运行版面分析、OCR 和表格识别。推理管理器会在首次使用时为你启动一个服务器;你也可以通过 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 将 keep-alive 设为默认行为。
交互式应用
我附带了一个 Streamlit 应用,可让你在图片或 PDF 文件上交互式试用 Surya。运行方式:
pip install streamlit pdftext
surya_gui
OCR(文本识别)
此命令会输出一个包含检测到的文本和边界框(bboxes)的 json 文件:
surya_ocr DATA_PATH
DATA_PATH可以是图片、PDF,或图片/PDF 文件夹--images会保存页面图像和检测到的区块图像(可选)--output_dir指定保存结果的目录,而非使用默认目录--page_range指定要处理的 PDF 页码范围,可以是单个数字、逗号分隔列表、范围,或逗号分隔的多个范围——示例:0,5-10,20。--keep_server会在命令退出后保持推理服务器运行,以便后续命令复用(参见 Server lifecycle)。所有命令均可用。
results.json 文件包含一个字典,以输入文件名(不含扩展名)为键。每个值是页面字典的列表。每个页面字典包含:
blocks- 按阅读顺序排列的逐块 OCR 结果label- 规范化后的版式标签(例如Text、SectionHeader、Table、Equation、Picture、Form、PageHeader、...)。详见surya/layout/label.py:LAYOUT_PRED_RELABEL获取完整规范化名称集合。raw_label- 模型输出的原始标签(规范化之前)reading_order- 在版式输出中的位置(从 0 开始索引)html- 区块内容的 HTML 表示(数学公式包裹在<math>...</math>中,表格为<table>...</table>等)。若区块被跳过则为""polygon- 四角多边形,按[[x0,y0],[x1,y0],[x1,y1],[x0,y1]]顺序排列bbox- 由多边形推导出的轴对齐[x0, y0, x1, y1]confidence- 该区块解码过程中各 token 的平均概率(0-1)skipped- 若该区块为视觉标签(例如 Picture)且未进行 OCR,则为 trueerror- 若该区块的 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 也会影响延迟/吞吐量——你可以在 settings 中调整 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 上的 VRAM 占用,并在更大显存的显卡上适当提高。
从 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- 规范化标签。取值为Caption、Footnote、Equation、ListGroup、PageHeader、PageFooter、Picture、SectionHeader、Table、Text、Figure、Code、Form、TableOfContents、ChemicalBlock、Diagram、Bibliography、BlankPage之一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)])
表格识别
此命令会输出一个包含检测到的表格单元格及行/列 ID,以及行/列边界框的 json 文件。若你需要获取单元格位置与文本,并获得良好格式,可查看 marker repo。可使用 TableConverter 在图片和 PDF 中检测并提取表格。支持以 json(含 bboxes)、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 文件包含一个以输入文件名(不含扩展名)为键的字典。每个值是每张表对应字典的列表。每个 table 字典包含:
rows- 按阅读顺序检测到的表格行polygon/bbox- 行几何信息(与项目中其他位置采用相同约定)row_id- 从 0 开始索引的行 ID
cols- 检测到的表格列polygon/bbox- 列几何信息col_id- 从 0 开始索引的列 ID
cells- 行 × 列的几何交叉点(简单模式)polygon/bbox- 单元格几何信息row_id,col_id,cell_id
html- 完整的<table>...</table>HTML(仅在使用predict_full时填充;处理跨单元格合并/表头行)。简单模式下为null。mode-"simple"或"full"image_bbox- 表格裁剪边界框(bbox)error- 若 table_rec 调用失败则为 trueraw- 原始模型输出,用于调试
性能提示
表格识别通过共享 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 过程中内联处理数学内容——识别出的公式会以 KaTeX 兼容的 LaTeX 形式,通过 <math>...</math> 标签返回,与周围正文位于同一份 HTML 输出中。无需单独的 LaTeX OCR 通道。
推理后端
Layout / 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 (vllm if NVIDIA, else llamacpp) | vllm | llamacpp | unset (auto) |
SURYA_INFERENCE_URL |
(auto-spawn) | 连接到已在运行的 OpenAI 兼容服务器 |
SURYA_INFERENCE_PARALLEL |
8 | 客户端对后端的并发数 |
SURYA_INFERENCE_KEEP_ALIVE |
false | 退出后保持已启动的服务器运行(参见 --keep_server) |
SURYA_GUIDED_LAYOUT |
true | 受 JSON schema 约束的布局解码 |
限制
- 本项目专为文档 OCR 设计。并非针对照片或自然场景优化性能。
- Layout / OCR / table_rec 均需要运行中的推理后端(vllm 或 llama.cpp)。Detection 纯基于 torch 运行,无需推理后端。
故障排除
若 OCR 效果不理想:
- 尝试提高图像分辨率,使文字更大。若分辨率已经很高,可尝试降低至不超过
2048px宽度。 - 对图像进行预处理(二值化、纠偏等)有助于处理非常陈旧/模糊的图像。
- 若效果不佳,可调整
DETECTOR_BLANK_THRESHOLD和DETECTOR_TEXT_THRESHOLD。DETECTOR_BLANK_THRESHOLD控制行间距——低于该阈值的预测将被视为空白。DETECTOR_TEXT_THRESHOLD控制文本拼接方式——高于该阈值的数值将被视为文本。DETECTOR_TEXT_THRESHOLD应始终大于DETECTOR_BLANK_THRESHOLD,且两者均应在 0–1 范围内。查看检测器调试输出中的热力图可帮助调整这些参数(若看到类似方框的 faint 痕迹,应降低阈值;若看到 bbox 被合并在一起,应提高阈值)。
手动安装
若要开发 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
在规模与得分权衡前沿上达到帕累托最优(Pareto-optimal),且在 3B 参数以下类别中表现最佳。
| Model | Params | Score |
|---|---|---|
| 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 |
多语言
我们还在涵盖 91 种语言的内部基准上评估 Surya 2,测试各语言文档的文本准确度、布局、表格、数学公式和阅读顺序。
总体通过率:91 种语言平均 87.2%。 91 种语言中有 38 种得分 ≥ 90%;76 种得分 ≥ 80%。
使用人数最多的 15 种语言:
| Code | Language | Score |
|---|---|---|
ar |
Arabic | 72.7% |
bn |
Bengali | 82.7% |
zh |
Chinese | 82.5% |
en |
English | 92.3% |
fr |
French | 89.3% |
de |
German | 89.7% |
hi |
Hindi | 82.2% |
it |
Italian | 93.0% |
ja |
Japanese | 86.2% |
ko |
Korean | 86.7% |
fa |
Persian | 82.3% |
pt |
Portuguese | 86.1% |
ru |
Russian | 88.8% |
es |
Spanish | 90.7% |
vi |
Vietnamese | 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)。
| Concurrency | Pages/s | Tokens/s | p50 (ms) | p95 (ms) | avg tok/page |
|---|---|---|---|---|---|
| 128 | 5.35 | 12,884 | 18,915 | 42,538 | 2,410 |
Apple Silicon (llama.cpp / Metal)
llama-server,使用 Metal 后端。
--parallel |
Pages/s | Tokens/s | p50 (ms) | p95 (ms) | avg tok/page | Power |
|---|---|---|---|---|---|---|
| 8 | 0.108 | 254 | 59,313 | 129,173 | 2,360 | ~30 W |
复现
我们使用 vllm(或 llama.cpp)部署模型,并运行来自 allenai/olmocr, 的 olmOCR-bench 测试框架,同时对输出 HTML 格式做了若干调整,以此在 olmOCR-bench 上为 Surya 2 打分。
训练
版面分析(Layout)、OCR 和表格识别均共用同一个视觉-语言模型(Qwen3.5 风格架构,约 650M 参数)。该模型在多样化的文档图像上进行训练,根据提示词(prompt)输出版面 JSON 或整页 HTML。文本行检测则是一个独立的小型 torch 模型——在文档行标注数据上从零训练的改良版 EfficientViT segformer。
若需在自己的数据上微调 Surya,或使用我们的托管训练栈,请通过 hi@datalab.to 联系我们。
致谢
若没有出色的开源 AI 工作,本项目不可能实现:
- Qwen3-VL,来自 Alibaba
- vllm 与 llama.cpp,用于推理
- Segformer,来自 NVIDIA
- EfficientViT,来自 MIT
- timm,来自 Ross Wightman
- transformers,来自 huggingface
- CRAFT,,出色的场景文本检测模型
感谢所有让开源 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},
}




