Dolphin是字节跳动于2025年5月在Hugging Face等平台低调发布并开源的一款新型多模态文档图像解析模型。它并非简单地堆砌参数,而是通过精巧的架构设计,以约322M的参数量,在文档解析领域实现了令人瞩目的性能突破。本文将在项目源码的基础上,通过Docker部署Dolphin API可供dify平台调用。
Dolphin基本原理
概述
Dolphin的核心特点在于其创新的“先分析后解析”的两阶段范式。在第一阶段,模型对整个文档图像进行页面级布局分析,识别出其中包含的各种元素,并生成一个按照人类自然阅读顺序排列的元素序列。在第二阶段,这些被识别出的“异构元素”将作为“锚点”,模型会结合针对不同元素类型的特定任务提示,对这些锚点所对应的图像区域进行并行化的内容解析。这种设计使得Dolphin能够高效且准确地处理包含文本段落、复杂表格、数学公式、插图等多种交织元素的文档图像。该模型目前主要支持中英文文档的解析,并将最终的解析结果输出为结构化的Markdown或JSON等易于后续处理的格式。
核心组件
视觉编码器: Swin Transformer
视觉编码器负责从输入的文档图像中提取丰富的、深层次的视觉特征。Dolphin采用Swin Transformer 作为其视觉主干网络。Swin Transformer以其层级化的特征表示和高效的移位窗口自注意力机制著称,能够同时捕捉图像的全局布局信息和局部细节特征。在输入前,图像会经过精心预处理,例如将长边缩放到特定尺寸然后填充为正方形,同时保持原始宽高比,以避免文本失真,最大化信息保留。
文本解码器: 基于MBart架构
文本解码器接收来自视觉编码器的图像特征以及特定任务的文本提示,通过自回归的方式生成结构化的文本序列,如段落内容、表格的Markdown表示、公式的LaTeX代码等。Dolphin的文本解码器基于MBart架构进行修改,使其作为解码器专用模型。它通过交叉注意力机制有效融合Swin Transformer提取的视觉特征和输入的文本提示,将视觉信息“翻译”成相应的语言描述。解码器包含多个Transformer层,隐藏层维度为1024。
核心模型: NougatModel
NougatModel整合Swin Transformer视觉编码器和BART文本解码器的核心模块,构成了Dolphin的视觉-语言模型主体。它负责执行实际的“看图说话”或“看图生成结构”任务。NougatModel在Dolphin的两个解析阶段均被调用。在布局分析阶段,它接收完整的页面图像和用于布局识别的提示,输出页面元素的序列和位置。在第内容解析阶段,它接收裁剪后的元素图像块以及针对该元素类型的特定内容解析提示,输出该元素的具体文本内容。通过这种方式,一个统一的模型架构能够借助不同的输入粒度和提示策略,高效地完成多样化的解析子任务。
文档解析性能对比
类别 | 方法 | 模型大小 | 平均ED | FPS |
---|---|---|---|---|
集成式方法 | MinerU | 1.2B | 0.1732 | 0.0350 |
Mathpix | – | 0.0924 | 0.0944 | |
专业VLM | Nougat | 250M | 0.6131 | 0.0673 |
Kosmos-2.5 | 1.3B | 0.2691 | 0.0841 | |
Vary | 7B | – | – | |
Fox | 1.8B | – | – | |
GOT | 580M | 0.1411 | 0.0604 | |
olmOCR | 7B | 0.1148 | 0.0427 | |
SmolDocling | 256M | 0.4636 | 0.0140 | |
Mistral-OCR | – | 0.0737 | 0.0996 | |
通用VLM | InternVL-2.5 | 8B | 0.4037 | 0.0444 |
InternVL-3 | 8B | 0.2089 | 0.0431 | |
MiniCPM-o 2.6 | 8B | 0.2882 | 0.0494 | |
GLM4v-plus | 9B | 0.2481 | 0.0427 | |
Gemini-1.5 pro | – | 0.1348 | 0.0376 | |
Gemini-2.5 pro | – | 0.1432 | 0.0231 | |
Claude3.5-Sonnet | – | 0.1358 | 0.0320 | |
GPT-4o-202408 | – | 0.2453 | 0.0368 | |
GPT-4.1-250414 | – | 0.2133 | 0.0337 | |
Step-1v-8k | – | 0.1227 | 0.0417 | |
Qwen2-VL | 7B | 0.2550 | 0.0315 | |
Qwen2.5-VL | 7B | 0.1112 | 0.0343 | |
Dolphin | Dolphin | 322M | 0.0575 | 0.1729 |
-
ED (编辑距离):数值越低越好 -
FPS (每秒帧数):数值越高越好
Dolphin-API接口改造
FastAPI改写API接口
在Dolphin源码的基础上,基于FastAPI框架,构造Dolphie-API接口。
app = FastAPI(
title="DOLPHIN API",
description="API for document layout analysis and text recognition",
version="1.0.0"
)
@app.post("/analyze")
asyncdef analyze_document(file: UploadFile = File(...)):
"""
分析文档图片并返回结果
参数:
- file: 上传的图片文件
返回:
- JSON格式的分析结果
"""
try:
# 直接从上传的文件内容创建图像对象
content = await file.read()
image = Image.open(io.BytesIO(content)).convert("RGB")
# 创建临时目录保存结果
with tempfile.TemporaryDirectory() as temp_dir:
# 确保必要的子目录存在
setup_output_dirs(temp_dir)
# 使用prepare_image函数处理图像
padded_image, dimensions = prepare_image(image)
try:
# 将处理后的图像保存到临时文件(因为process_page需要文件路径)
temp_image_path = os.path.join(temp_dir, "temp_image.png")
cv2.imwrite(temp_image_path, padded_image)
# 处理图片
json_path, recognition_results = process_page(
image_path=temp_image_path,
model=model,
save_dir=temp_dir,
max_batch_size=16
)
return JSONResponse(content=recognition_results)
finally:
# 确保临时图片文件被删除
if os.path.exists(temp_image_path):
try:
os.remove(temp_image_path)
except Exception as e:
print(f"Warning: Failed to delete temporary file {temp_image_path}: {e}")
except Exception as e:
return JSONResponse(
status_code=500,
content={"error": f"处理图像时出错: {str(e)}"}
)
Docker镜像构建及部署
编写Dockerfile
# 安装系统依赖
RUN apt-get update && apt-get install -y
libgl1-mesa-glx
libglib2.0-0
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件并安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
# 安装FastAPI、uvicorn和huggingface_hub
RUN pip install --no-cache-dir fastapi uvicorn python-multipart huggingface_hub -i https://mirrors.aliyun.com/pypi/simple/
# 复制项目文件
COPY . .
# 设置环境变量使用镜像站
ENV HF_ENDPOINT=https://hf-mirror.com
# 下载模型
RUN python -c "from huggingface_hub import snapshot_download; snapshot_download(repo_id='ByteDance/Dolphin', local_dir='./hf_model')"
构建镜像并启动服务
## 构建镜像
docker build -t dolphin-api:0.1 .
## 启动服务(对外暴露端口)
docker run -d --gpus all -p 6500:6500 --ipc=host --name dolphin-api dolphin-api:0.1
## 启动服务(仅对本机Dify暴露端口)
docker run -d --gpus all --network docker_ssrf_proxy_network --name dolphin-api dolphin-api:0.1
Swagger UI界面测试接口
目前API仅支持图片格式,我们上传一张截图进行测试。


Dify工作流集成
先在Dify中创建一个Chatflow,编排如下的对话流。可以参考MinerU的文章《MinerU-API | 支持多格式解析,进一步提升Dify文档能力》

Dolphin-API为节点我们通过python脚本来执行
headers = {
'accept': 'application/json',
}
files = {
'file': (file_name, open(file_path, 'rb'), mime_type),
}
response = requests.post('http://dolphin-api:6500/analyze', headers=headers, files=files)
在页面上进行测试
