OCR, layout analysis, reading order, table recognition in 90+ languages
Datalab
文档智能领域的顶尖模型
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。同一个管理器实例可在LayoutPredictor、RecognitionPredictor、TableRecPredictor之间共享。- 输出架构已更改:详见下方各部分的 JSON 表格。重点变化 —
text_lines→blocks(新增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- 规范化的布局标签(例如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- 4 角多边形,顺序为[[x0,y0],[x1,y0],[x1,y1],[x0,y1]]bbox- 从多边形导出的轴对齐边界框[x0, y0, x1, y1]confidence- 区块解码过程中每个 token 概率的平均值(0-1)skipped- 如果区块是视觉标签(例如图片)且未进行 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 也会影响延迟/吞吐量 - 您可以在设置中调整 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- 规范化标签。为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)])
表格识别
此命令会输出一个 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_id、col_id、cell_id
html- 完整的<table>...</table>HTML(仅在使用predict_full时填充;处理跨单元格/标题行)。在简单模式下为null。mode-"simple"或"full"image_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 的一部分进行内联处理——识别出的公式会以 <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_THRESHOLD和DETECTOR_TEXT_THRESHOLD。DETECTOR_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项目:
- 阿里巴巴的Qwen3-VL
- 用于推理的vllm和llama.cpp
- NVIDIA的Segformer
- MIT的EfficientViT
- Ross Wightman的timm
- Hugging Face的transformers
- 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},
}



