
文章目录百度Unlimited OCR一、论文基础信息研究背景与现存痛点二、核心创新R-SWA参考滑动窗口注意力Reference Sliding Window Attention1. 核心设计逻辑2. 数学与KV缓存优势3. 三大对比优势三、Unlimited OCR整体模型架构1. DeepEncoder高压缩图像编码器完全复用、冻结训练2. MoE解码器全部注意力层替换为R-SWA完整工作流程四、实验设置1. 训练数据2. 训练细节3. 评测基准与指标五、核心实验结果1. 单页文档SOTAOmniDocBench2. 推理效率TPS每秒生成token3. 长文档一次性解析能力核心独有能力4. 显存节省量化六、现有局限与未来工作1. 当前限制2. 短期规划3. 长期规划七、论文整体贡献总结SGLang 启动服务Unlimited OCR Workshttps://arxiv.org/pdf/2606.23050https://github.com/baidu/Unlimited-OCRA Unified Framework for Context-Aware and Relation-Aware Graph Retrieval-Augmented Generationhttps://www.alphaxiv.org/abs/2606.18075v1百度Unlimited OCR一、论文基础信息核心目标是解决现有端到端OCR长文档一次性解析瓶颈提出通用注意力机制R-SWA构建Unlimited OCR模型实现数十页文档单次前向推理解析同时显存占用、推理速度不随输出长度恶化。研究背景与现存痛点现有OCR两大路线缺陷流水线OCR分检测识别多阶段依赖人工规则拼接多页文档需逐页循环处理每次重置记忆上下文断裂、阅读顺序易出错属于工程折中方案而非原生长上下文建模。端到端LLM-OCR以DeepSeek OCR为代表采用标准多头注意力MHAKV缓存随输出token线性增长解码越长显存占用越高、推理延迟持续上升无法一次性解析10页以上文档只能分页循环推理。人类抄录行为启发人抄写长文档时存在工作记忆软遗忘机制全程完整参考原始图文静态全局信息仅保留最近少量手写内容定位上下文不会存储全部历史输出低认知负载完成长文本转录。现有模型完全不具备该特性。核心矛盾传统滑动窗口注意力SWA会把视觉token纳入滑动淘汰反复更新导致图像特征逐步模糊、识别精度下降全量注意力显存爆炸二者无法兼顾长文档效率与识别精度。二、核心创新R-SWA参考滑动窗口注意力Reference Sliding Window Attention1. 核心设计逻辑将注意力划分为永久参考段Prefixm因果滑动输出窗口n默认128两部分完全模拟人类抄书记忆逻辑参考段m固定不变包含所有图像视觉token提示词全程全局可见、不参与滑动淘汰、不做状态更新图像编码一次后永久静态杜绝视觉特征模糊问题输出滑动窗口n固定容量仅保留最近生成的128个文本token新token生成时淘汰窗口最旧token输出侧KV缓存容量恒定不会随解码长度扩张。2. 数学与KV缓存优势标准MHA缓存C M H A ( T ) L m T C_{MHA}(T)L_mTCMHA(T)LmT随输出长度T无限线性上涨R-SWA缓存C R − S W A ( T ) L m m i n ( n , T ) ≤ L m n C_{R-SWA}(T)L_mmin(n,T)≤L_mnCR−SWA(T)Lmmin(n,T)≤Lmn全局恒定常数长序列下缓存占比ρ ( T ) ≈ ( L m n ) / T \rho(T)≈(L_mn)/Tρ(T)≈(Lmn)/T输出越长显存节省越显著从显存线性增长变为固定占用。3. 三大对比优势对比标准全注意力MHA计算量、显存固定长文本推理速度无衰减对比普通滑动窗口SWA视觉参考token永久保留不会逐步模糊图像特征识别精度不损失通用性非OCR专用可迁移至ASR语音识别、机器翻译等所有带参考输入的长序列任务。三、Unlimited OCR整体模型架构以DeepSeek OCR为基线改造整体端到端视觉语言MoE架构分为两大模块1. DeepEncoder高压缩图像编码器完全复用、冻结训练堆叠SAM-ViT窗口注意力CLIP-ViT全局注意力16倍视觉token压缩1024×1024单页PDF仅压缩为256个视觉token两种分辨率模式Base1024×1024多页批量解析、Gundam动态分辨率单页高精度优势大幅降低Prefill阶段视觉token长度是一次性解析数十页文档的基础。2. MoE解码器全部注意力层替换为R-SWA参数规模总3B MoE推理仅激活500M参数轻量化高吞吐改动移除原生MHA所有解码器层统一使用R-SWA推理特性全程KV缓存固定Flash Attention v3内核延迟恒定无速度衰减支持32K最大序列长度单次可输入2–50页文档联合解析。完整工作流程多页PDF图像→DeepEncoder压缩为静态视觉参考token→R-SWA解码器全程读取全部图像token仅缓存最近128个输出文本token连续生成全部页面文本、公式、表格、阅读顺序一次前向完成数十页解析。四、实验设置1. 训练数据总计200万PDF文档样本单页:多页9:1多页数据20万份每份2–50页page做页面分隔符全部打包至32K序列长度单页使用PaddleOCR标注坐标与文本真值。2. 训练细节预训练权重DeepSeek OCR权重续训4000步冻结DeepEncoder仅更新LLM解码器硬件8×A800全局batch256AdamW优化器、余弦退火lr1e-4框架Megatron-LMDeepEP专家并行EP4推理部署在Transformers、SGLang引擎实现R-SWA缓存管理支持恒定TPS与显存占用。3. 评测基准与指标OmniDocBench v1.5/v1.6通用文档SOTA对比评测维度文本编辑距离越低越好、公式CDM、表格TEDS/TEDS-S、阅读顺序编辑距离综合加权总分。自建长文档多页测试集2/5/10/20/40页书籍/论文指标Distinct-n文本完整性越高越好、编辑距离识别误差。五、核心实验结果1. 单页文档SOTAOmniDocBenchv1.5版本综合得分93.23%相比基线DeepSeek OCR87.01%提升6.22个百分点全维度全面领先文本编辑距离0.038原0.073误差大幅降低公式CDM 92.61原83.37、表格TEDS 90.93原84.97阅读顺序误差0.045原0.086。v1.6最新榜单综合93.92%端到端模型第一公式识别95.79%超越所有竞品仅3B总参、500M激活参数大幅领先数百B超大参数量VL模型Qwen3-VL 235B仅89.15%。细分文档测试PPT、报纸、教材、论文9类全部指标优于DeepSeek OCR/DeepSeek OCR 2复杂布局无性能衰减。2. 推理效率TPS每秒生成token单页场景512并发下TPS 5580基线DeepSeek OCR为4951提速12.7%长输出场景6144 token基线TPS衰减至5822Unlimited OCR稳定7847速度领先35%内核延迟基线解码步数越高延迟越高存在显存对齐突刺Unlimited OCR延迟全程平稳无波动显存占用恒定。3. 长文档一次性解析能力核心独有能力单次输入2–40页文档持续解码性能稳定20页以内Distinct-20≥98.73%编辑距离≤0.05740页长文档Distinct-3596.90%编辑距离仅0.1069少量识别误差来源多页模式固定1024分辨率小字模糊非R-SWA机制缺陷。4. 显存节省量化输出序列越长R-SWA缓存压缩比趋近于0数万token长文本显存占用远低于传统MHA低显存硬件即可处理整本图书一次性解析。六、现有局限与未来工作1. 当前限制虽命名“Unlimited”但受32K最大上下文长度约束页面越多视觉参考token总量越长Prefill阶段会触达序列上限无法做到理论无限页数输入。2. 短期规划训练128K超长上下文版本支持单次输入更多页面。3. 长期规划构建Prefill缓存池模型自动按需加载视觉KV片段模拟人类翻页记忆实现真正无页数限制OCR将R-SWA通用注意力机制迁移至ASR语音转写、长文本翻译等所有带固定参考输入的长序列任务。七、论文整体贡献总结算法创新提出通用R-SWA注意力机制区分静态参考token与滑动输出token实现恒定KV缓存解决长序列显存与速度双重瓶颈同时规避普通滑动窗口视觉特征退化问题模型落地基于DeepSeek OCR构建Unlimited OCR3B轻量化MoE架构单页文档达到业界SOTA支持数十页文档单次前向解析推理速度不随文本长度下降理论验证验证线性复杂度注意力在多模态文档解析场景的有效性无需暴力扩展上下文长度即可实现长程依赖建模工程价值开源代码与权重R-SWA可通用迁移至语音、翻译等多类长序列任务为长文本解析提供通用优化范式。示例importosimporttorch from transformersimportAutoModel, AutoTokenizer model_namebaidu/Unlimited-OCRtokenizerAutoTokenizer.from_pretrained(model_name,trust_remote_codeTrue)modelAutoModel.from_pretrained(model_name,trust_remote_codeTrue,use_safetensorsTrue,torch_dtypetorch.bfloat16,)modelmodel.eval().cuda()# ── Single image supports two configs: gundam or base ──# gundam: base_size1024, image_size640, crop_modeTrue# base: base_size1024, image_size1024, crop_modeFalsemodel.infer(tokenizer,promptimagedocument parsing.,image_fileyour_image.jpg,output_pathyour/output/dir,base_size1024,image_size640,crop_modeTrue,max_length32768,no_repeat_ngram_size35,ngram_window128,save_resultsTrue,)# ── Multi page / PDF only uses base (image_size1024) ──model.infer_multi(tokenizer,promptimageMulti page parsing.,image_files[page1.png,page2.png,page3.png],output_pathyour/output/dir,image_size1024,max_length32768,no_repeat_ngram_size35,ngram_window1024,save_resultsTrue,)# ── PDF (convert pages to images, then multi-page parsing) ──importtempfile, fitz# PyMuPDFdef pdf_to_images(pdf_path,dpi300): docfitz.open(pdf_path)tmp_dirtempfile.mkdtemp(prefixpdf_ocr_)matfitz.Matrix(dpi /72, dpi /72)paths[]fori, pageinenumerate(doc): outos.path.join(tmp_dir, fpage_{i1:04d}.png)page.get_pixmap(matrixmat).save(out)paths.append(out)doc.close()returnpaths model.infer_multi(tokenizer,promptimageMulti page parsing.,image_filespdf_to_images(your_doc.pdf,dpi300),output_pathyour/output/dir,image_size1024,max_length32768,no_repeat_ngram_size35,ngram_window1024,save_resultsTrue,)SGLang 启动服务https://github.com/baidu/Unlimited-OCR/blob/main/infer.pyuv venv--python3.12source.venv/bin/activate uv pipinstallwheel/sglang-0.0.0.dev11416g92e8bb79e-py3-none-any.whl uv pipinstallkernels0.11.7 uv pipinstallpymupdf1.27.2.2python-msglang.launch_server\--modelbaidu/Unlimited-OCR\--served-model-name Unlimited-OCR\--attention-backend fa3\--page-size1\--mem-fraction-static0.8\--context-length32768\--enable-custom-logit-processor\--disable-overlap-schedule\--skip-server-warmup\--host0.0.0.0\--port10000importbase64importjsonimportosimporttempfileimportfitzimportrequests from sglang.srt.sampling.custom_logit_processorimportDeepseekOCRNoRepeatNGramLogitProcessor server_urlhttp://127.0.0.1:10000sessionrequests.Session()session.trust_envFalse def pdf_to_images(pdf_path,dpi300): docfitz.open(pdf_path)tmp_dirtempfile.mkdtemp(prefixpdf_ocr_)matfitz.Matrix(dpi /72, dpi /72)image_paths[]fori, pageinenumerate(doc): image_pathos.path.join(tmp_dir, fpage_{i 1:04d}.png)page.get_pixmap(matrixmat).save(image_path)image_paths.append(image_path)doc.close()returnimage_paths def encode_image(image_path): extos.path.splitext(image_path)[1].lower()mimeimage/jpegifextin(.jpg,.jpeg)elsefimage/{ext.lstrip(.)}with open(image_path,rb)as f: database64.b64encode(f.read()).decode(utf-8)return{type:image_url,image_url:{url:fdata:{mime};base64,{data}}}def build_content(prompt, image_paths):return[{type:text,text:prompt}][encode_image(path)forpathinimage_paths]def generate(prompt, image_paths, image_mode, ngram_window): payload{model:Unlimited-OCR,messages:[{role:user,content:build_content(prompt, image_paths)}],temperature:0,skip_special_tokens:False,images_config:{image_mode:image_mode},custom_logit_processor:DeepseekOCRNoRepeatNGramLogitProcessor.to_str(),custom_params:{ngram_size:35,window_size:ngram_window,},stream:True,}responsesession.post(f{server_url}/v1/chat/completions,headers{Content-Type:application/json},datajson.dumps(payload),timeout1200,streamTrue,)response.raise_for_status()chunks[]forlineinresponse.iter_lines(chunk_size1,decode_unicodeTrue):ifnot line or not line.startswith(data: ):continuedataline[len(data: ):]ifdata[DONE]:breakeventjson.loads(data)deltaevent[choices][0].get(delta,{}).get(content,)ifdelta: print(delta,end,flushTrue)chunks.append(delta)print()return.join(chunks)# Single image supports two configs: gundam or base. Example below uses gundam.generate(document parsing.,[your_image.jpg],image_modegundam,ngram_window128)# Multi image (base only)generate(Multi page parsing.,[page1.png,page2.png],image_modebase,ngram_window1024)# PDF (base only)generate(Multi page parsing., pdf_to_images(your_doc.pdf,dpi300),image_modebase,ngram_window1024)