DeepSeek-OCR 架构详解
论文链接:DeepSeek-OCR: 上下文光学压缩 | GitHub DeepSeek-AI 在 2025 年提出的革命性视觉-语言模型,专注于通过视觉模态实现高效的文本信息压缩。DeepSeek-OCR 在 OCR 任务上实现了 10× 的视觉-文本压缩比,在保持 97% 解码精度的同时,大幅减少了视觉 token 数量,为长上下文处理和 LLM 训练数据生成提供了高效解决方案。
DeepSeek-OCR 的核心创新:通过分层视觉编码架构(DeepEncoder)和混合专家解码器(MoE),实现了高分辨率图像下的低激活内存和高效视觉 token 压缩。核心创新包括:1) SAM-base 窗口注意力 + 16× 卷积压缩器 + CLIP-large 全局注意力的串联设计;2) 在 10× 压缩比下达到 97% OCR 精度,证明了视觉-文本压缩的可行性;3) 多分辨率支持(Tiny/Small/Base/Large/Gundam 模式),灵活适配不同场景。
本文内容:本文详细解析 DeepSeek-OCR 的架构组成和工作流程,包括:
-
模型发展历程:从传统 OCR 到端到端 VLM 的演进路径
-
模型构成与网络结构:组件参数分布和整体架构图
-
DeepEncoder:分层视觉编码器的设计原理和实现细节
-
SAM-base 组件:窗口注意力机制在视觉感知中的作用
-
16× 卷积压缩器:视觉 token 压缩的关键组件
-
CLIP-large 组件:全局注意力在视觉知识提取中的作用
-
MoE 解码器:混合专家架构在文本生成中的优势
-
交叉注意力机制:视觉 token 与文本 token 的交互方式
-
模型训练:两阶段训练流程和关键技巧
-
模型推理:多分辨率推理流程和优化策略
适用对象:本文适合希望深入理解 DeepSeek-OCR 工作原理的读者,建议先了解 Transformer 架构、视觉-语言模型(VLM)、OCR 任务和混合专家(MoE)模型的基本原理。
DeepSeek-OCR 发展历程
DeepSeek-OCR 的发展历程展示了从传统 OCR 系统到端到端视觉-语言模型的演进路径。以下是关键发展节点:
graph LR
A[传统OCR系统\n检测+识别分离] --> B[端到端OCR\nNougat 2023]
B --> C[OCR 2.0\nGOT-OCR2.0 2024]
C --> D[视觉-文本压缩\nDeepSeek-OCR 2025]
D --> E[上下文光学压缩\n10倍压缩比验证]
发展历程说明:
-
传统 OCR 系统(2023 年之前):传统的 OCR 系统采用检测和识别分离的管道架构,需要单独的检测模型和识别模型。这种方法虽然成熟,但存在流程复杂、误差累积等问题。
-
端到端 OCR(2023 年):Nougat 首次在 arXiv 上采用端到端框架进行学术论文 OCR,展示了模型在处理密集感知任务方面的潜力。这种方法简化了 OCR 系统,但视觉 token 数量仍然较大。
-
OCR 2.0(2024 年):GOT-OCR2.0 将 OCR 的范围扩展到包括更多合成图像解析任务(图表、化学公式、几何图形等),并设计了具有性能-效率权衡的 OCR 模型。然而,对于包含 1000 个单词的文档,至少需要多少个视觉 token 才能进行解码的问题仍未解决。
-
视觉-文本压缩(2025 年初):DeepSeek-OCR 提出,通过 DeepEncoder 的分层设计实现了高效的视觉 token 压缩。在 Fox 基准测试上,模型在 9-10× 文本压缩时达到 96%+ 的 OCR 解码精度,证明了视觉-文本压缩的可行性。
-
上下文光学压缩验证(2025 年):DeepSeek-OCR 在 OmniDocBench 上仅使用 100 个视觉 token 就超越了 GOT-OCR2.0(每页 256 个 token),在使用少于 800 个视觉 token 的情况下,性能超过了 MinerU2.0(平均每页 6000+ token)。这为历史长上下文压缩和 LLM 中的记忆遗忘机制等研究领域展现了巨大潜力。
DeepSeek-OCR 模型构成
DeepSeek-OCR 模型包含两个核心组件:DeepEncoder(视觉编码器)和DeepSeek3B-MoE(解码器)。这些组件的参数分布如下:
| 组件 | 参数量 | 激活参数量 | 主要功能 |
|---|---|---|---|
| DeepEncoder | ~380M | ~380M | 视觉特征提取和 token 压缩 |
| ├─ SAM-base | 80M | 80M | 窗口注意力,局部特征提取 |
| ├─ 16× 卷积压缩器 | ~0.5M | ~0.5M | 视觉 token 16× 下采样 |
| └─ CLIP-large | 300M | 300M | 全局注意力,语义知识提取 |
| DeepSeek3B-MoE Decoder | 3B | 570M | 文本生成(激活 6/64 专家) |
| Total | ~3.38B | ~950M | 端到端 OCR 系统 |
关键观察:
-
DeepEncoder 是核心压缩引擎:虽然只占模型总参数的约 11%,但负责将高分辨率图像压缩为少量视觉 token,是实现高效压缩的关键。通过 SAM-base 的窗口注意力处理大量 token,再通过 16× 卷积压缩器减少 token 数量,最后通过 CLIP-large 的全局注意力提取语义知识,形成了"局部细节→压缩→全局语义"的分层压缩逻辑。
-
MoE 解码器实现高效推理:虽然总参数量为 3B,但推理时只激活 570M 参数(6 个路由专家 + 2 个共享专家),实现了 3B 模型的表达能力,同时享受 500M 小模型的推理效率。这种设计非常适合以领域为中心(OCR)的 VLM 研究。
-
压缩比与精度平衡:在 10× 压缩比内,模型可以达到约 97% 的解码精度;在 20× 压缩比下,精度仍可接近 60%。这为不同应用场景提供了灵活的选择空间。
这些组件协同工作,共同实现了从高分辨率图像到结构化文本的端到端转换。下面我们将详细解析每个组件的原理和作用。
DeepSeek-OCR 网络结构
DeepSeek-OCR 的网络结构展示了编码器和解码器之间的连接关系和数据流向。整体架构如下:
graph TB
subgraph 输入层
InputImage[输入图像\n高分辨率文档图像]
end
subgraph DeepEncoder 视觉编码器
subgraph SAM-base 模块
SAM[SAM-base\n窗口注意力\n80M参数]
PatchEmbed[Patch嵌入\n16*16补丁]
WindowAttn[窗口自注意力\n局部特征提取]
SAM --> PatchEmbed
PatchEmbed --> WindowAttn
end
subgraph 16* 卷积压缩器
Conv1[卷积层1\n3*3, stride=2]
Conv2[卷积层2\n3*3, stride=2]
Conv1 --> Conv2
end
subgraph CLIP-large 模块
CLIP[CLIP-large\n全局注意力\n300M参数]
GlobalAttn[全局自注意力\n语义知识提取]
CLIP --> GlobalAttn
end
WindowAttn --> Conv1
Conv2 --> GlobalAttn
GlobalAttn --> VisionTokens[视觉Token输出\n压缩后的视觉表示]
end
subgraph DeepSeek3B-MoE 解码器
TextPrompt[文本Prompt\n任务指令]
TextEmbed[文本嵌入层]
CrossAttn[交叉注意力\nVision Tokens作为K/V]
MoELayers[MoE Transformer层\n6个路由专家+2个共享专家]
OutputProj[输出投影层]
TextPrompt --> TextEmbed
TextEmbed --> CrossAttn
VisionTokens -.->|Key/Value| CrossAttn
CrossAttn --> MoELayers
MoELayers --> OutputProj
end
subgraph 输出层
OutputText[结构化文本输出\nMarkdown/JSON/坐标]
end
InputImage --> SAM
OutputProj --> OutputText
style InputImage fill:#e3f2fd,stroke:#1565c0
style VisionTokens fill:#fff3e0,stroke:#ef6c00
style CrossAttn fill:#f3e5f5,stroke:#7b1fa2
style OutputText fill:#fce4ec,stroke:#c2185b
网络结构说明:
-
输入层模块:
-
输入图像:支持多种分辨率的文档图像(512×512 到 1280×1280,以及动态分辨率模式)
-
图像预处理:根据分辨率模式进行填充或调整大小,保持宽高比
-
-
DeepEncoder 模块:
-
SAM-base 模块:使用窗口注意力机制处理图像,将图像分割为 16×16 的补丁 token。对于 1024×1024 图像,生成 4096 个补丁 token。窗口注意力只在局部窗口内计算注意力,大幅降低了计算复杂度。
-
16× 卷积压缩器:两层卷积网络,每层核大小为 3,步长为 2,填充为 1,通道数从 256 增加到 1024。将 4096 个 token 压缩为 256 个 token,实现 16× 下采样。
-
CLIP-large 模块:使用全局注意力机制提取全局语义知识。移除了第一个补丁嵌入层,因为输入不再是原始图像,而是来自 SAM-base 的输出 token。全局注意力让模型能够理解文档的整体布局和结构。
-
-
DeepSeek3B-MoE 解码器模块:
-
文本嵌入层:将文本 prompt 和已生成的文本 token 转换为向量表示
-
交叉注意力:文本 token 作为 Query,视觉 token 作为 Key 和 Value,建立视觉和文本之间的对应关系
-
MoE Transformer 层:12 层 Transformer,每层包含 MoE 前馈网络。推理时激活 6 个路由专家和 2 个共享专家,总激活参数约 570M
-
输出投影层:将解码器输出转换为词汇表上的概率分布
-
-
输出层模块:
- 结构化文本输出:根据 prompt 生成 Markdown、JSON、坐标信息等结构化文本
-
数据流向:
-
输入图像 → SAM-base(窗口注意力)→ 4096 个补丁 token → 16× 卷积压缩器 → 256 个视觉 token → CLIP-large(全局注意力)→ 压缩后的视觉 token
-
文本 prompt → 文本嵌入 → 交叉注意力(Query)← 视觉 token(Key/Value)→ MoE Transformer 层 → 输出投影 → 结构化文本
-
-
关键连接:
-
SAM-base 到卷积压缩器:窗口注意力提取的局部特征通过卷积压缩,减少 token 数量
-
卷积压缩器到 CLIP-large:压缩后的 token 进入全局注意力,提取语义知识
-
视觉 token 到交叉注意力:视觉 token 作为 Key 和 Value,与文本 Query 交互,建立视觉-文本对应关系
-
MoE 专家路由:根据输入 token 的特征,门控网络选择激活的专家,实现稀疏激活
-
DeepEncoder
DeepEncoder 是 DeepSeek-OCR 的核心视觉编码器,负责将高分辨率图像压缩为少量视觉 token,同时保持低激活内存。DeepEncoder 采用分层设计,通过窗口注意力和全局注意力的串联,实现了高效的视觉特征提取和压缩。
DeepEncoder 的工作原理:在 DeepSeek-OCR 里,DeepEncoder 的任务是将输入图像 转换为压缩后的视觉 token 序列 ,其中 。编码过程包括:
-
SAM-base 窗口注意力处理:输入图像首先通过 SAM-base 的补丁嵌入层,将图像分割为 16×16 的补丁,生成初始补丁 token:
对于 1024×1024 图像,生成 64×64=4096 个补丁 token。SAM-base 使用窗口注意力机制,只在局部窗口内计算注意力,大幅降低了计算复杂度:
其中窗口大小通常为 7×7 或 14×14,使得每个窗口内的 token 数量远小于全局 token 数量。
-
16× 卷积压缩:SAM-base 输出的补丁 token 通过两层卷积网络进行 16× 下采样:
每层卷积的核大小为 3,步长为 2,填充为 1,通道数从 256 增加到 1024。对于 4096 个 token,压缩后变为 4096/16=256 个 token。
-
CLIP-large 全局注意力处理:压缩后的 token 进入 CLIP-large 的全局注意力层,提取全局语义知识:
全局注意力让每个 token 都能关注到所有其他 token,从而理解文档的整体布局和结构。
-
输出视觉 token:经过全局注意力处理后,得到压缩后的视觉 token 序列 ,其中 是压缩后的 token 数量(如 256), 是潜在维度(通常为 1024)。
为什么 DeepEncoder 要采用分层设计:
-
计算效率:窗口注意力只在局部窗口内计算,计算复杂度为 ,其中 是窗口大小,远小于全局注意力的 。这使得 SAM-base 能够高效处理大量补丁 token(如 4096 个)。
-
内存效率:窗口注意力大幅减少了激活内存,使得模型能够在高分辨率输入下保持低激活。卷积压缩进一步减少了 token 数量,使得后续的全局注意力计算更加高效。
-
特征层次:SAM-base 提取局部细节特征(如字符边缘、笔画),卷积压缩保留关键信息,CLIP-large 提取全局语义知识(如文档布局、段落结构)。这种"局部→压缩→全局"的设计符合视觉特征提取的自然层次。
-
预训练收益:SAM-base 和 CLIP-large 都是在大规模数据上预训练的模型,通过复用这些预训练权重,DeepEncoder 能够快速适应 OCR 任务,而不需要从头训练。
SAM-base 组件
SAM-base 是 DeepEncoder 的第一部分,负责使用窗口注意力机制提取图像的局部特征。SAM-base 基于 Meta 的 Segment Anything Model(SAM)架构,采用窗口注意力机制,能够在高分辨率输入下保持低激活内存。
SAM-base 的工作原理:在 DeepSeek-OCR 里,SAM-base 的任务是将输入图像转换为补丁 token 序列,并通过窗口注意力提取局部特征。具体过程包括:
-
补丁嵌入:输入图像 通过补丁嵌入层,分割为 16×16 的补丁,每个补丁转换为 维向量:
对于 1024×1024 图像,生成 64×64=4096 个补丁 token,每个 token 的维度为 256。
-
窗口注意力:SAM-base 使用窗口注意力机制,将补丁 token 划分为多个不重叠的窗口,每个窗口内独立计算自注意力:
其中窗口大小通常为 7×7 或 14×14。对于 64×64 的补丁 token,如果窗口大小为 14×14,则每个窗口包含 196 个 token,总共有约 21 个窗口。窗口注意力只在窗口内计算,计算复杂度为 ,其中 是窗口大小,远小于全局注意力的 。
-
位置编码:SAM-base 使用相对位置编码,为每个窗口内的 token 添加位置信息,帮助模型理解空间关系。
-
多层堆叠:SAM-base 包含多个 Transformer 层,每层都使用窗口注意力,逐步提取更高级的视觉特征。
为什么 SAM-base 要使用窗口注意力:
-
计算效率:窗口注意力将全局注意力的 复杂度降低到 ,其中 是窗口大小。对于 4096 个 token,全局注意力需要计算 4096×4096 的注意力矩阵,而窗口注意力(窗口大小为 14×14)只需要计算 21 个 196×196 的注意力矩阵,计算量大幅减少。
-
内存效率:窗口注意力大幅减少了激活内存,使得模型能够在高分辨率输入下保持低激活。这对于处理大图像(如 1024×1024 或更大)至关重要。
-
局部特征提取:窗口注意力专注于局部区域,能够更好地提取字符边缘、笔画等细节特征,这对于 OCR 任务非常重要。
-
预训练收益:SAM-base 基于 Meta 的 SAM 模型,已经在大规模图像分割数据上预训练,具有强大的视觉特征提取能力。通过复用这些预训练权重,DeepEncoder 能够快速适应 OCR 任务。
16× 卷积压缩器
16× 卷积压缩器是 DeepEncoder 的关键组件,负责将 SAM-base 输出的补丁 token 进行 16× 下采样,大幅减少视觉 token 数量,为后续的全局注意力计算提供高效输入。
16× 卷积压缩器的工作原理:在 DeepSeek-OCR 里,卷积压缩器的任务是将 SAM-base 输出的补丁 token 序列 压缩为 ,实现 16× 下采样。具体过程包括:
-
第一层卷积:输入补丁 token 通过第一层卷积,核大小为 3,步长为 2,填充为 1,通道数从 256 增加到 512:
这一层将空间维度从 降低到 ,实现 4× 下采样。
-
第二层卷积:第一层输出通过第二层卷积,核大小为 3,步长为 2,填充为 1,通道数从 512 增加到 1024:
这一层将空间维度从 降低到 ,再次实现 4× 下采样。
-
总压缩比:两层卷积总共实现 16× 下采样(4× × 4× = 16×)。对于 1024×1024 图像,SAM-base 输出 64×64=4096 个 token,经过卷积压缩后变为 16×16=256 个 token。
为什么需要 16× 卷积压缩器:
-
减少计算量:全局注意力的计算复杂度为 ,其中 是 token 数量。将 token 数量从 4096 减少到 256,计算量从 减少到 ,减少了约 256 倍。
-
降低内存消耗:全局注意力需要存储 的注意力矩阵,将 token 数量从 4096 减少到 256,内存消耗从 减少到 ,大幅降低了内存需求。
-
保留关键信息:卷积操作具有平移不变性和局部感受野,能够有效保留图像的关键特征。通过两层卷积的逐步压缩,模型能够学习到更高级的视觉表示,同时减少冗余信息。
-
适配全局注意力:压缩后的 token 数量(如 256)更适合全局注意力计算,既能够捕捉全局语义,又不会导致计算和内存开销过大。
CLIP-large 组件
CLIP-large 是 DeepEncoder 的第二部分,负责使用全局注意力机制提取图像的全局语义知识。CLIP-large 基于 OpenAI 的 CLIP 模型,采用全局注意力机制,能够理解文档的整体布局和结构。
CLIP-large 的工作原理:在 DeepSeek-OCR 里,CLIP-large 的任务是将卷积压缩器输出的 token 序列转换为富含全局语义知识的视觉 token。具体过程包括:
-
输入处理:CLIP-large 的输入不再是原始图像,而是来自卷积压缩器的输出 token。因此,CLIP-large 移除了第一个补丁嵌入层,直接处理 token 序列:
其中 是压缩后的 token 数量(如 256), 是 token 维度(1024)。
-
全局自注意力:CLIP-large 使用全局自注意力机制,让每个 token 都能关注到所有其他 token:
全局注意力能够捕捉 token 之间的长距离依赖关系,理解文档的整体布局、段落结构、表格关系等全局信息。
-
位置编码:CLIP-large 使用位置编码为 token 添加位置信息,帮助模型理解空间关系。由于输入 token 已经经过压缩,位置编码需要相应调整。
-
多层堆叠:CLIP-large 包含多个 Transformer 层,每层都使用全局注意力,逐步提取更高级的语义特征。
-
输出视觉 token:经过多层全局注意力处理后,得到最终的视觉 token 序列 ,其中 是潜在维度(1024)。
为什么 CLIP-large 要使用全局注意力:
-
全局语义理解:全局注意力让每个 token 都能关注到所有其他 token,从而理解文档的整体布局、段落结构、表格关系等全局信息。这对于 OCR 任务非常重要,因为文档的布局和结构信息对于正确识别文本至关重要。
-
长距离依赖:全局注意力能够捕捉 token 之间的长距离依赖关系,例如表格中的行列关系、段落之间的逻辑关系等。这对于理解复杂文档结构非常重要。
-
预训练收益:CLIP-large 基于 OpenAI 的 CLIP 模型,已经在海量图像-文本对上进行了对比学习预训练,具有强大的视觉语义理解能力。通过复用这些预训练权重,DeepEncoder 能够快速适应 OCR 任务。
-
与窗口注意力互补:SAM-base 的窗口注意力专注于局部细节,CLIP-large 的全局注意力专注于全局语义,两者互补,形成了"局部细节→全局语义"的分层特征提取。
MoE 解码器
MoE 解码器(DeepSeek3B-MoE)是 DeepSeek-OCR 的文本生成组件,采用混合专家(Mixture of Experts)架构,在保持 3B 参数表达能力的同时,推理时只激活 570M 参数,实现了高效的文本生成。
MoE 解码器的工作原理:在 DeepSeek-OCR 里,MoE 解码器的任务是基于视觉 token 和文本 prompt,生成结构化文本输出。解码过程包括:
-
文本嵌入:文本 prompt 和已生成的文本 token 通过嵌入层转换为向量表示:
其中 是文本序列长度, 是文本嵌入维度。
-
交叉注意力:文本 token 作为 Query,视觉 token 作为 Key 和 Value,计算交叉注意力:
其中 来自文本 token, 和 来自视觉 token。交叉注意力建立了视觉和文本之间的对应关系,让解码器能够根据视觉信息生成文本。
-
MoE Transformer 层:解码器包含 12 层 Transformer,每层包含:
-
掩码自注意力:文本 token 之间的自注意力,使用掩码防止看到未来信息
-
交叉注意力:文本 token 与视觉 token 的交叉注意力
-
MoE 前馈网络:混合专家前馈网络,根据输入 token 的特征,门控网络选择激活的专家
-
-
专家路由:MoE 前馈网络包含 64 个路由专家和 2 个共享专家。对于每个输入 token,门控网络计算每个专家的权重:
其中 和 是门控网络的参数,TopK 选择权重最大的 6 个专家。推理时只激活这 6 个路由专家和 2 个共享专家,总激活参数约 570M。
-
输出投影:最后一层解码器的输出通过线性层和 Softmax 转换为词汇表上的概率分布:
其中 是最后一层解码器的输出, 和 是输出投影层的参数。
为什么 MoE 解码器要使用混合专家架构:
-
参数效率:MoE 架构在保持大模型表达能力的同时,推理时只激活部分参数,大幅提高了推理效率。DeepSeek3B-MoE 总参数量为 3B,但推理时只激活 570M 参数,实现了 3B 模型的表达能力,同时享受 500M 小模型的推理效率。
-
专家分化:不同的专家可以学习不同的任务模式,例如一个专家专注于处理表格结构,另一个专家专注于处理自然语言文本。这种专家分化提高了模型的表达能力。
-
领域适配:MoE 架构非常适合以领域为中心(OCR)的 VLM 研究,因为可以通过微调特定专家来适应特定任务,而不影响其他专家的能力。
-
训练效率:MoE 架构在训练时可以使用更多的专家,提高模型的容量和学习能力,同时推理时只激活部分专家,保持高效推理。
交叉注意力机制
交叉注意力机制是 DeepSeek-OCR 中连接视觉和文本的关键组件,负责建立视觉 token 与文本 token 之间的对应关系,让解码器能够根据视觉信息生成文本。
交叉注意力机制的工作原理:在 DeepSeek-OCR 里,交叉注意力的任务是让文本 token 关注视觉 token,建立视觉-文本对应关系。具体过程包括:
-
Query、Key、Value 生成:
-
Query(Q):来自文本 token,表示当前要生成的文本位置需要关注哪些视觉信息
-
Key(K)和 Value(V):来自视觉 token,表示视觉特征和对应的值
其中 是文本嵌入, 是视觉 token,、、 是可学习的权重矩阵。
-
-
注意力分数计算:对于文本位置 和视觉位置 ,计算注意力分数:
其中 是缩放因子,防止点积值过大。
-
注意力权重归一化:对每个文本位置的注意力分数应用 softmax,得到注意力权重:
注意力权重满足 ,表示文本位置 对所有视觉位置的关注程度。
-
加权求和:根据注意力权重对视觉 Value 进行加权求和,得到文本位置 的新表示:
-
矩阵形式:整个过程可以用矩阵形式表示为:
其中 ,,输出 。
为什么需要交叉注意力机制:
-
建立视觉-文本对应关系:交叉注意力让文本 token 能够关注到相关的视觉 token,建立视觉和文本之间的对应关系。例如,当生成表格中的某个单元格文本时,交叉注意力会让模型关注到对应的视觉区域。
-
利用视觉上下文:视觉 token 包含了丰富的视觉上下文信息,包括文档布局、段落结构、表格关系等。交叉注意力让解码器能够利用这些信息生成更准确的文本。
-
动态对齐:交叉注意力的权重是动态计算的,能够根据不同的输入图像和文本 prompt 自适应地调整视觉-文本对齐关系。
-
可解释性:交叉注意力的权重可以可视化,帮助我们理解模型在生成文本时关注哪些视觉区域,这对于调试和改进模型非常有帮助。
模型训练
DeepSeek-OCR 的训练过程包括两个阶段:1) 独立训练 DeepEncoder;2) 训练完整的 DeepSeek-OCR 模型。训练阶段的核心是让模型学习从高分辨率图像到结构化文本的映射关系。
训练阶段详细流程:
-
阶段一:训练 DeepEncoder
-
数据准备:使用 OCR 1.0 数据(文档 OCR、场景 OCR)、OCR 2.0 数据(图表、化学公式、几何图形)和通用视觉数据(从 LAION 数据集中采样 1 亿数据)
-
训练框架:使用紧凑语言模型,采用下一个 token 预测框架训练 DeepEncoder
-
训练配置:
-
批次大小:1280
-
优化器:AdamW
-
学习率:5e-5
-
调度器:余弦退火调度器
-
训练轮数:2 个 epoch
-
序列长度:4096
-
-
训练目标:让 DeepEncoder 学会将图像压缩为视觉 token,并保留足够的视觉信息供后续解码使用
-
-
阶段二:训练 DeepSeek-OCR
-
数据准备:使用第 3.4 节中提到的所有数据,包括 OCR 数据(70%)、通用视觉数据(20%)和纯文本数据(10%)
-
模型配置:
-
DeepEncoder:冻结 SAM-base 和压缩器参数,只训练 CLIP-large 部分
-
解码器:训练所有 MoE 专家和门控网络
-
-
并行策略:
-
管道并行(PP):模型分为 4 部分,DeepEncoder 占两部分(SAM+压缩器在 PP0,CLIP 在 PP1),解码器占两部分(各 6 层)
-
数据并行(DP):40,全局批次大小为 640
-
-
训练配置:
-
节点数:20 个节点(每个节点 8 个 A100-40G GPU)
-
优化器:AdamW
-
学习率:3e-5(基于步长的调度器)
-
训练速度:纯文本数据每天 900 亿 token,多模态数据每天 700 亿 token
-
-
训练目标:让完整的 DeepSeek-OCR 模型学会从图像生成结构化文本,包括 OCR、文档解析、图表解析等任务
-
训练阶段流程:
sequenceDiagram
participant Data as 训练数据<br/>OCR/视觉/文本数据
participant DeepEncoder as DeepEncoder<br/>SAM+压缩器+CLIP
participant Decoder as MoE解码器<br/>12层Transformer
participant Loss as 损失计算<br/>交叉熵损失
Note over Data: 阶段一:训练DeepEncoder
Data->>DeepEncoder: 图像 + 文本对
DeepEncoder->>DeepEncoder: SAM-base窗口注意力
DeepEncoder->>DeepEncoder: 16×卷积压缩
DeepEncoder->>DeepEncoder: CLIP-large全局注意力
DeepEncoder->>Loss: 视觉Token输出
Data->>Loss: 真实文本标签
Loss->>DeepEncoder: 反向传播更新参数
Note over Data: 阶段二:训练完整模型
Data->>DeepEncoder: 输入图像
DeepEncoder->>DeepEncoder: 提取视觉Token(冻结SAM+压缩器)
DeepEncoder->>Decoder: 视觉Token(Key/Value)
Data->>Decoder: 文本Prompt(Query)
Decoder->>Decoder: 交叉注意力
Decoder->>Decoder: MoE Transformer层
Decoder->>Loss: 解码器输出
Data->>Loss: 真实文本标签
Loss->>Decoder: 反向传播更新参数
Loss->>DeepEncoder: 反向传播更新CLIP部分
训练关键点:
-
两阶段训练策略:先独立训练 DeepEncoder,让视觉编码器学会提取和压缩视觉特征,再训练完整模型,让解码器学会利用视觉 token 生成文本。这种策略能够稳定训练过程,提高训练效率。
-
参数冻结:在训练完整模型时,冻结 SAM-base 和压缩器参数,只训练 CLIP-large 部分。这是因为 SAM-base 和压缩器已经在第一阶段训练好,冻结它们可以避免过拟合,同时加快训练速度。
-
数据混合:训练数据包括 OCR 数据(70%)、通用视觉数据(20%)和纯文本数据(10%)。OCR 数据让模型学会 OCR 任务,通用视觉数据保留通用视觉接口,纯文本数据保持语言能力。
-
多分辨率训练:同时训练多种分辨率模式(Tiny/Small/Base/Large/Gundam),让单个模型支持多种分辨率,提高模型的灵活性和实用性。
-
MoE 专家训练:MoE 解码器的专家通过稀疏激活训练,每个 token 只激活部分专家,提高了训练效率,同时让不同专家学习不同的任务模式。
模型推理
DeepSeek-OCR 的推理过程包括图像编码、视觉 token 提取、交叉注意力和自回归文本生成等关键步骤。推理阶段的核心是基于输入图像和 prompt 生成结构化文本,支持多种分辨率模式和不同的输出格式。
推理阶段详细流程:
-
图像预处理:根据选择的分辨率模式(Tiny/Small/Base/Large/Gundam),对输入图像进行预处理:
-
Tiny/Small 模式:直接调整图像大小到目标分辨率(512×512 或 640×640)
-
Base/Large 模式:保持宽高比,将图像填充到目标分辨率(1024×1024 或 1280×1280)
-
Gundam 模式:将图像分割为多个分块(n×640×640)和一个全局视图(1024×1024)
-
-
DeepEncoder 编码:
-
SAM-base 处理:预处理后的图像通过 SAM-base,使用窗口注意力提取局部特征,生成补丁 token(如 4096 个)
-
卷积压缩:补丁 token 通过 16× 卷积压缩器,压缩为少量视觉 token(如 256 个)
-
CLIP-large 处理:压缩后的 token 通过 CLIP-large,使用全局注意力提取全局语义知识,得到最终的视觉 token
-
-
解码器自回归生成:
-
初始化:从特殊 token(如
<start>)或 prompt 开始 -
迭代生成:
-
当前已生成的文本序列通过文本嵌入层转换为向量表示
-
文本 token 作为 Query,视觉 token 作为 Key 和 Value,计算交叉注意力
-
通过掩码自注意力处理文本 token 之间的关系
-
通过 MoE Transformer 层处理,门控网络选择激活的专家(6 个路由专家 + 2 个共享专家)
-
通过输出投影层得到下一个 token 的概率分布
-
选择概率最高的 token(greedy decoding)或使用采样策略(top-k、top-p)
-
将新生成的 token 添加到序列中
-
-
重复生成:重复上述过程,直到生成结束 token(如
<end>)或达到最大长度
-
-
输出后处理:根据 prompt 的要求,将生成的文本转换为相应的格式(Markdown、JSON、坐标信息等)
推理阶段流程:
sequenceDiagram
participant Input as 输入图像<br/>高分辨率文档
participant DeepEncoder as DeepEncoder<br/>SAM+压缩器+CLIP
participant VisionTokens as 视觉Token<br/>压缩后的视觉表示
participant Decoder as MoE解码器<br/>12层Transformer
participant Output as 输出文本<br/>结构化文本
Input->>DeepEncoder: 图像预处理<br/>(根据分辨率模式)
DeepEncoder->>DeepEncoder: SAM-base窗口注意力<br/>(4096个补丁token)
DeepEncoder->>DeepEncoder: 16×卷积压缩<br/>(256个token)
DeepEncoder->>DeepEncoder: CLIP-large全局注意力<br/>(全局语义提取)
DeepEncoder->>VisionTokens: 视觉Token输出
Note over Decoder: 自回归生成<br/>(逐个生成token)
loop 生成每个token
Decoder->>Decoder: 当前文本序列<br/>(已生成部分)
VisionTokens->>Decoder: 视觉Token(Key/Value)
Decoder->>Decoder: 交叉注意力<br/>(文本Query × 视觉K/V)
Decoder->>Decoder: 掩码自注意力<br/>(文本token关系)
Decoder->>Decoder: MoE Transformer层<br/>(激活6个专家)
Decoder->>Decoder: 输出投影层
Decoder->>Decoder: 选择下一个token<br/>(Argmax或采样)
Decoder->>Decoder: 添加到序列
Note over Decoder: 重复直到生成
end
Decoder->>Output: 结构化文本输出<br/>(Markdown/JSON/坐标)
推理关键点:
-
多分辨率支持:DeepSeek-OCR 支持多种分辨率模式,可以根据输入图像的大小和复杂度选择合适的分辨率。对于简单文档,可以使用 Tiny 模式(64 个 token);对于复杂文档,可以使用 Large 或 Gundam 模式(400+ token)。
-
视觉 token 缓存:编码器输出的视觉 token 只需要计算一次,可以缓存起来供解码器多次使用,避免重复计算,提高推理效率。
-
MoE 稀疏激活:推理时只激活 6 个路由专家和 2 个共享专家,总激活参数约 570M,实现了 3B 模型的表达能力,同时享受 500M 小模型的推理效率。
-
采样策略:除了选择概率最高的 token(greedy decoding),还可以使用采样策略(top-k、top-p、temperature sampling)增加生成的多样性,这对于某些任务(如创意写作)可能更有帮助。
-
输出格式控制:通过不同的 prompt,可以控制模型的输出格式,例如:
-
"<image>\nFree OCR.":无布局 OCR,只输出文本内容 -
"<image>\nParse this document with layout.":有布局 OCR,输出文本和坐标信息 -
"<image>\nParse this chart.":图表解析,输出 HTML 表格格式
-
训练与推理的关键区别:
-
并行性:训练时解码器可以并行处理整个目标序列(使用掩码),推理时必须自回归地逐个生成 token,无法并行。
-
视觉 token 计算:训练时每个样本都需要计算视觉 token,推理时可以缓存视觉 token,避免重复计算。
-
专家激活:训练时所有专家都可能被激活(用于学习),推理时只激活部分专家(用于高效推理)。
-
批次处理:训练时使用大批次(如 640),推理时通常使用小批次或单样本,以降低延迟。
实现细节
DeepSeek-OCR 的实现是模块化和可扩展的,具有清晰的组件划分和灵活的配置选项。以下是 DeepEncoder 和 MoE 解码器的关键实现细节:
DeepEncoder 实现
import torch
import torch.nn as nn
from transformers import CLIPVisionModel, SamModel
class DeepEncoder(nn.Module):
"""DeepEncoder: 分层视觉编码器
由 SAM-base(窗口注意力)+ 16×卷积压缩器 + CLIP-large(全局注意力)组成
"""
def __init__(self, config):
super().__init__()
self.config = config
# SAM-base: 窗口注意力,局部特征提取
self.sam_base = SamModel.from_pretrained("facebook/sam-vit-base")
# 移除 SAM 的 mask decoder,只保留图像编码器
# 16× 卷积压缩器
self.compressor = nn.Sequential(
nn.Conv2d(256, 512, kernel_size=3, stride=2, padding=1),
nn.ReLU(),
nn.Conv2d(512, 1024, kernel_size=3, stride=2, padding=1),
nn.ReLU()
)
# CLIP-large: 全局注意力,语义知识提取
self.clip_large = CLIPVisionModel.from_pretrained("openai/clip-vit-large-patch14")
# 移除 CLIP 的第一个补丁嵌入层,因为输入不再是图像
def forward(self, images):
"""
Args:
images: [B, H, W, 3] 输入图像
Returns:
vision_tokens: [B, n, d] 压缩后的视觉token
"""
# SAM-base: 窗口注意力处理
# 输出: [B, H/16, W/16, 256]
sam_output = self.sam_base.vision_encoder(images)
patch_tokens = sam_output.last_hidden_state # [B, (H/16)*(W/16), 256]
# 重塑为空间维度用于卷积
B, N, C = patch_tokens.shape
H_patch, W_patch = int(N ** 0.5), int(N ** 0.5)
patch_tokens_2d = patch_tokens.view(B, H_patch, W_patch, C).permute(0, 3, 1, 2)
# 16× 卷积压缩
# 输出: [B, 1024, H/64, W/64]
compressed_tokens = self.compressor(patch_tokens_2d)
# 重塑为序列
B, C, H_comp, W_comp = compressed_tokens.shape
compressed_tokens_seq = compressed_tokens.view(B, C, -1).permute(0, 2, 1)
# CLIP-large: 全局注意力处理
# 输出: [B, n, 1024],其中 n = (H/64) * (W/64)
vision_tokens = self.clip_large(
inputs_embeds=compressed_tokens_seq
).last_hidden_state
return vision_tokens
MoE 解码器实现
import torch
import torch.nn as nn
from transformers import DeepSeekMoEForCausalLM
class DeepSeekOCRDecoder(nn.Module):
"""DeepSeek3B-MoE 解码器
基于 DeepSeekMoE,添加交叉注意力层处理视觉token
"""
def __init__(self, config):
super().__init__()
self.config = config
# 基于预训练的 DeepSeekMoE
self.decoder = DeepSeekMoEForCausalLM.from_pretrained(
"deepseek-ai/deepseek-moe-3b"
)
# 交叉注意力层(视觉token作为K/V)
self.cross_attention = nn.MultiheadAttention(
embed_dim=config.d_model,
num_heads=config.num_heads,
batch_first=True
)
def forward(self, input_ids, vision_tokens, attention_mask=None):
"""
Args:
input_ids: [B, T] 文本token ID
vision_tokens: [B, n, d] 视觉token(来自DeepEncoder)
attention_mask: [B, T] 文本注意力掩码
Returns:
logits: [B, T, vocab_size] 输出logits
"""
# 文本嵌入
text_embeds = self.decoder.model.embed_tokens(input_ids)
# 交叉注意力:文本作为Query,视觉作为Key/Value
cross_output, _ = self.cross_attention(
query=text_embeds,
key=vision_tokens,
value=vision_tokens
)
# MoE Transformer层处理
# 注意:这里简化了实现,实际需要集成到decoder的每一层
decoder_outputs = self.decoder.model(
inputs_embeds=cross_output,
attention_mask=attention_mask
)
# 输出投影
logits = self.decoder.lm_head(decoder_outputs.last_hidden_state)
return logits
多分辨率支持实现
class MultiResolutionProcessor:
"""多分辨率图像处理器
支持 Tiny/Small/Base/Large/Gundam 等多种分辨率模式
"""
def __init__(self, mode='base'):
self.mode = mode
self.resolutions = {
'tiny': (512, 512, 64),
'small': (640, 640, 100),
'base': (1024, 1024, 256),
'large': (1280, 1280, 400),
}
def process(self, image):
"""处理图像,返回预处理后的图像和有效token数量"""
target_size, _, expected_tokens = self.resolutions[self.mode]
if self.mode in ['tiny', 'small']:
# 直接调整大小
processed = resize(image, target_size)
valid_tokens = expected_tokens
else:
# 保持宽高比,填充
processed, valid_tokens = self._pad_to_size(image, target_size)
return processed, valid_tokens
def _pad_to_size(self, image, target_size):
"""填充图像到目标大小,保持宽高比"""
h, w = image.shape[:2]
target_h, target_w = target_size
# 计算缩放比例
scale = min(target_h / h, target_w / w)
new_h, new_w = int(h * scale), int(w * scale)
# 调整大小
resized = resize(image, (new_h, new_w))
# 填充到目标大小
padded = np.zeros((target_h, target_w, 3), dtype=np.uint8)
padded[:new_h, :new_w] = resized
# 计算有效token数量
valid_tokens = int(expected_tokens * (1 - (max(h, w) - min(h, w)) / max(h, w)))
return padded, valid_tokens
这种实现突出了 DeepSeek-OCR 的模块化设计。此外,DeepSeek-OCR 支持多种变体,如不同分辨率模式(Tiny/Small/Base/Large/Gundam)、不同输出格式(Markdown/JSON/坐标)等。这些实现细节强调了 DeepSeek-OCR 在适应不同任务和场景方面的灵活性。
现状和展望
当前应用现状
DeepSeek-OCR 目前已经在文档 OCR、数据生成、长上下文压缩等领域得到了广泛应用。以下是当前的主要应用情况:
应用领域:
-
大规模训练数据生成:DeepSeek-OCR 在生产环境中每天可以为 LLM 或 VLM 生成 3300 万页训练数据(使用 20 个节点,每个节点 8 个 A100-40G GPU)。这为 LLM 的预训练提供了大量高质量的 OCR 数据。
-
文档解析和 OCR:DeepSeek-OCR 在 OmniDocBench 上仅使用 100 个视觉 token 就超越了 GOT-OCR2.0(每页 256 个 token),在使用少于 800 个视觉 token 的情况下,性能超过了 MinerU2.0(平均每页 6000+ token)。这证明了 DeepSeek-OCR 在实际 OCR 任务中的强大能力。
-
复杂文档理解:DeepSeek-OCR 不仅支持传统的文档 OCR,还支持图表解析、化学公式识别、几何图形理解等 OCR 2.0 任务,展现了其在复杂文档理解方面的能力。
性能表现:
-
压缩比与精度:在 Fox 基准测试上,DeepSeek-OCR 在 9-10× 文本压缩时达到 96%+ 的 OCR 解码精度,在 10-12× 压缩时达到约 90%,在 20× 压缩时达到约 60%。这证明了视觉-文本压缩的可行性。
-
推理效率:MoE 解码器在推理时只激活 570M 参数(6 个路由专家 + 2 个共享专家),实现了 3B 模型的表达能力,同时享受 500M 小模型的推理效率。
-
多分辨率支持:DeepSeek-OCR 支持多种分辨率模式(Tiny/Small/Base/Large/Gundam),可以根据输入图像的大小和复杂度选择合适的分辨率,提高了模型的灵活性和实用性。
存在的挑战:
-
压缩比与精度的权衡:虽然 DeepSeek-OCR 在 10× 压缩比下达到 97% 精度,但在 20× 压缩比下精度降至 60%。如何在保持高压缩比的同时提高精度,仍然是一个挑战。
-
长文档处理:对于超长文档(如报纸),即使使用 Gundam 模式,也可能需要多个分块,增加了处理复杂度。如何更好地处理超长文档,仍然需要进一步研究。
-
格式对齐:DeepSeek-OCR 的输出格式可能与真实标签存在差异,特别是在布局信息、坐标精度等方面。如何提高输出格式的准确性,仍然是一个挑战。
未来发展方向
DeepSeek-OCR 的未来发展主要集中在以下几个方面:
技术改进方向:
-
提高压缩比与精度:通过改进 DeepEncoder 的架构设计、优化训练策略、引入更先进的压缩技术,在保持高压缩比的同时提高 OCR 精度。目标是在 20× 压缩比下达到 80%+ 精度。
-
优化长文档处理:通过改进 Gundam 模式、引入更智能的分块策略、优化全局-局部视图的融合方式,更好地处理超长文档。目标是在保持高精度的同时,减少分块数量和处理复杂度。
-
增强格式对齐能力:通过改进训练数据标注、优化损失函数、引入格式对齐的专门模块,提高输出格式的准确性。目标是让模型输出的格式更接近真实标签,减少后处理的需求。
应用拓展方向:
-
历史长上下文压缩:DeepSeek-OCR 的视觉-文本压缩能力可以应用于 LLM 的长上下文处理,通过将历史对话文本渲染为图像进行压缩,实现 10× 的上下文压缩效率。这为 LLM 的长上下文挑战提供了一个有前景的解决方案。
-
记忆遗忘机制:通过将前几轮历史文本渲染到图像上进行初始压缩,然后逐步调整旧图像的大小以实现多级压缩,模拟人类记忆的遗忘机制。其中 token 数量逐渐减少,文本变得越来越模糊,从而完成文本遗忘。
-
多模态智能体:DeepSeek-OCR 的视觉-文本压缩能力可以应用于多模态智能体系统,通过压缩视觉信息减少 token 消耗,提高智能体的处理效率和响应速度。
研究热点:
-
数字-光学文本交错预训练:将数字文本和光学文本(图像中的文本)交错进行预训练,让模型更好地理解视觉-文本压缩的本质,提高压缩比和精度。
-
大海捞针测试:通过设计专门的测试集,验证 DeepSeek-OCR 在不同压缩比下的信息保留能力,特别是在长文档中查找特定信息的能力。
-
视觉 token 优化:研究如何优化视觉 token 的分配策略,在保持高精度的同时,进一步减少视觉 token 数量,提高压缩比。
总结:
DeepSeek-OCR 作为视觉-文本压缩的先驱模型,在压缩比与精度平衡、多分辨率支持、MoE 高效推理等方面表现出色。通过 DeepEncoder 的分层设计和 MoE 解码器的稀疏激活,DeepSeek-OCR 实现了高效的视觉-文本压缩,为长上下文处理和 LLM 训练数据生成提供了高效解决方案。随着技术的不断发展和应用场景的拓展,DeepSeek-OCR 有望在压缩比与精度提升、长文档处理优化、格式对齐增强等方面取得更大突破,为视觉-文本压缩研究和实际应用提供更好的支持。