拓冰建站拓冰建站
首页 / 资讯中心 / 正文

在 MLX 上运行 IndicOCR:用 mlx-vlm 解析英文与 22 种印度语言的文档页面

在 MLX 上运行 IndicOCR用 mlx-vlm 解析英文与 22 种印度语言的文档页面【免费下载链接】mlx-vlmMLX-VLM is a package for inference and fine-tuning of Vision Language Models (VLMs) on your Mac using MLX.项目地址: https://gitcode.com/GitHub_Trending/ml/mlx-vlmIndicOCR 是 mlx-vlm 内置的一个双阶段文档解析Document Parsing / OCR方案用于在 Apple Silicon Mac 上通过 MLX 将整页文档转成带阅读顺序的 Markdown、HTML 表格与 LaTeX 公式。本文以mlx_vlm/models/indic_ocr/README.md为主干结合仓库内 pipeline.py、processing_indic_ocr.py、blocks.py、reconstruct.py 等源码完整讲解从安装、单页解析到各阶段配置参数与输出格式的实战用法读完即可在自己的 Mac 上跑通并定制 IndicOCR 文档解析流水线。一、IndicOCR 是什么双阶段文档解析流水线IndicOCR 的目标是把一整页文档图像变成结构化的、按阅读顺序排列的文本覆盖英文与 22 种印度语言。它由两个独立微调模型协作完成见 indic_ocr/README.mdIndicDocLayout基于 PP-DocLayoutV3 微调的版面检测模型负责识别页面区域正文、标题、表格、公式、页眉页脚等并输出阅读顺序reading orderIndicBlockOCR基于 Qwen3.5-0.8B 微调的识别模型负责逐块转写文本、公式和表格。两个模型的权重分别来自原始模型bodhan-ai/indic-ocr与 MLX 移植版HashNuke/indic-ocr-mlxHugging Face 仓库。mlx-vlm 通过IndicOCRParser把它们组合成一个端到端流水线整体流程在 pipeline.py 的模块注释中明确给出page image - layout detect - dedup - per-block OCR - Markdown JSON从源码结构看流水线被实现为两个可独立替换的后端MLXLayoutBackend跑 MLX 版面检测模型阶段一对应 pipeline.pyBlockOCRRunner针对版面中的每个块逐个转写阶段二对应 pipeline.pyJsonLayoutBackend允许重放一份由其他工具torch 上游、手改 JSON、别的检测器生成的版面跳过阶段一直接做 OCR对应 pipeline.py。二、快速上手解析一页文档从 mlx-vlm 仓库检出checkout后先以可编辑模式安装pip install -e .然后按 README 给出的最小示例解析一页文档将page.png换成你自己的图像路径from mlx_vlm.utils import get_model_path, load_model with load_model(get_model_path(HashNuke/indic-ocr-mlx)) as parser: page parser.parse(page.png) print(page.markdown) page.save(page.json)运行后你会得到两个产物page.markdown按阅读顺序拼接的 Markdown 文本内含 HTML 表格与 LaTeX 公式page.json页面元数据与全部块的 JSON 记录page.save写入。这段代码背后有三个值得注意的设计README 明确说明解析器是一个nn.ModuleIndicOCRParser继承自mlx.nn.Module见 pipeline.py因此可以无缝融入 mlx-vlm 的标准加载流程。sanitize()负责权重路由它会把带阶段前缀的张量分别送到版面与 OCR 两个子模型各自的 sanitizer前缀规则是layout_model./ocr_model.转换后的 checkpoint 使用模块路径layout.model./ocr.model.未知键会被保留以便严格加载时报错实现见 pipeline.py。OCR 处理器按需加载OCR processor基于 Qwen3VLProcessor在parse()首次被调用时才从 OCR 阶段目录加载而不是在加载模型时立即加载对应 pipeline.py 中的懒加载逻辑。另外with语句会调用__enter__/__exit__退出上下文时自动close()两个后端释放模型引用见 pipeline.py。三、可配置的解析选项RecognizerOptions 等四大参数组README 提到在返回的 parser 上设置解析选项例如parser.ocr.options RecognizerOptions(max_tokens128)。实际上 mlx-vlm 为流水线提供了四组 frozen dataclass 选项全部定义在 pipeline.py 顶部默认值即源码中的字段默认值1. LayoutOptions —— 版面检测参数阶段一dataclass(frozenTrue) class LayoutOptions: conf: float 0.5 # 检测置信度阈值 img_size: int 1024 # 送入检测器的图像边长对应 pipeline.py。MLXLayoutBackend.detect()会把这些参数传给底层 PP-DocLayoutV3 检测模型的detect(image, conf..., img_size...)调用见 pipeline.py。版面检测出的原始记录随后被转换为像素坐标块、裁剪到页面边界、按阅读顺序重新编号为无空洞的 0 起始序号。2. CropOptions —— 块裁剪参数dataclass(frozenTrue) class CropOptions: min_px_side: int 256 # 裁剪块最短边面积下限 256^2 max_px_side: int 1536 # 裁剪块最长边面积上限 1536^2 pad_px: int 0 # 裁剪时向外扩的像素数对应 pipeline.py。min_px/max_px是只读属性直接返回边长平方作为area_clamp()的输入——该函数按比例缩放裁剪块使其面积落在[min_px, max_px]区间内并保持宽高比见 processing_indic_ocr.py。pad_px会在crop_for_block()中向外扩边后再裁剪并夹取到页面范围内见 processing_indic_ocr.py。3. DedupOptions —— 去重与嵌套公式解析参数dataclass(frozenTrue) class DedupOptions: nest: bool True # 是否解析嵌套公式 mode: str both # both / text_only / eq_only contain: float 0.90 # 嵌套重复判定阈值小框在大框内的占比 wrap: float 0.5 # 页眉页脚包裹内容判定阈值 nested: float 0.70 # 嵌套公式判定阈值对应 pipeline.py。其中clean_layout()见 blocks.py做三件事剔除嵌套重复框一个小框contain比例落在更大框内则删除、页眉页脚各保留最大一个、没有包裹任何内容的空页眉页脚直接丢弃resolve_nested_equations()见 blocks.py把嵌套在文本/公式容器内部的公式框删除mode决定哪种容器可以吸收嵌套公式both表示文本与公式容器都可以text_only只允许文本容器eq_only只允许公式容器。传入非法mode会在构造时直接抛ValueError。4. RecognizerOptions —— 识别器阶段二参数dataclass(frozenTrue) class RecognizerOptions: max_tokens: int 2048 # 每个块生成的最大 token 数 temperature: float 0.0 # 贪心解码也是唯一可复现的设置 table_format: str html # html / markdown对应 pipeline.py。README 特别强调temperature0.0贪心是唯一可复现的设置这与 processing_indic_ocr.py 中transcribe_blocks()通过标准mlx_vlm.generate流程逐块解码的实现一致。table_format只允许html或markdown它会决定表格块使用哪条提示词见下节。5. PageResult —— 输出数据结构dataclass class PageResult: image: str # 图像文件名basename width: int # 页面像素宽 height: int # 页面像素高 blocks: list # Block 列表 markdown: Optional[str] None对应 pipeline.py。as_record()生成可序列化字典save(path)用 UTF-8、indent2写出 JSONfrom_record()支持严格模式校验会检查必需键、order是否为非负整数、bbox_xyxy是否为 4 个数字、type/label是否在已知分类中并检查order是否重复见 blocks.py。四、输出格式阅读顺序 Markdown 与 JSON 块记录Markdown 输出page.markdown由 reconstruct.py 的reconstruct()生成规则如下按block.order0 起始升序拼接每个块的文本块与块之间用空行分隔DROP_TYPESFigure/Picture见 processing_indic_ocr.py不参与拼接但仍在 JSON 中保留没有文本的块不贡献内容但也不会被删除——它们仍会以text: 出现在 JSON 里若公式块文本中既没有$也没有\[/\(前缀则自动包上$$...$$显示公式定界符最终经过dehyphenate()与repair_math()后处理。dehyphenate()reconstruct.py会把因换行断裂的连字符词重新拼接word-\nword→wordword迭代到不动点。repair_math()reconstruct.py则修复每个数学片段把印度文字串包进\text{...}数学模式没有这些字形的字形把显示公式里的裸换行转成\\确保输出是合法 LaTeX。三种块级提示词逐块转写时prompt_for()见 processing_indic_ocr.py按块类型选择提示词块类型提示词要点文本Text 等Transcribe the text in this image. Write any mathematical expressions in LaTeX, using$...$for inline math and$$...$$for display equations.公式EquationOutput only the LaTeX for this equation image.表格Tabletable_formathtml时要求输出带colspan/rowspan合并单元格与br/换行的 HTML 表格table_formatmarkdown时要求输出 GitHub 风格 Markdown 表格完整提示词原文见 processing_indic_ocr.py。JSON 块记录page.save(page.json)写出的每条块记录字段见 blocks.pyorder零基阅读顺序整数label检测器原始标签保留原拼写type映射后的流水线类型Text / Title / SectionHeader / Table / Equation / Caption / Footnote / PageHeader / PageFooter / PageNumber 等见KEPT_BLOCK_TYPESbbox_xyxy像素坐标[x0, y0, x1, y1]保留 1 位小数conf检测置信度保留 3 位小数text转写文本OCR 后被有意跳过的块为。五、标签体系IndicDocLayout 与 PP-DocLayoutV3 双分类兼容IndicOCR 的标签映射体现了对两种版面分类体系的兼容见 processing_indic_ocr.pyLABEL_TO_TYPEIndicDocLayout 微调标签如table、table-caption、equation、expression、title、chapter-title、section-title、header、footer、folio等PP_DOCLAYOUT_LABEL_TO_TYPE原版 PP-DocLayoutV3 标签如abstract、algorithm、formula、doc_title、seal、reference_content等记录中保留其原始拼写仅在选定 OCR 角色时做映射。map_label()会先查LABEL_TO_TYPE再查PP_DOCLAYOUT_LABEL_TO_TYPE都未命中则回退为Text。这解释了from_pretrained()文档字符串中Both IndicDocLayout and stock PP-DocLayoutV3 label taxonomies are supported的表述见 pipeline.py。此外CLASSES列出了 37 类 IndicDocLayout 分类Question、Paragraph、Answer、List、MCQ、Infobox、Solved-example、Code、Table-of-contents、Index、Advertisement、Website-link 等见 processing_indic_ocr.py其中MARGINALIAHeader/Footer/Page-number/Folio作为独立分组清理避免跨页段落把页码吞掉见 blocks.py 与 processing_indic_ocr.py。六、更换版面模型与复用外部版面README 给出两个高级用法更换版面检测模型parser.layout.model load_model(layout_path)parser.layout是MLXLayoutBackend其model属性就是底层版面检测器。由于IndicOCRParser.sanitize()按阶段前缀路由权重替换layout.model后只要新模型遵循同一套sanitize协议即可正常工作。在from_pretrained()中也可以直接通过layout_repoHashNuke/pp-doclayout-v3-mlx这类参数覆盖内置版面阶段见 pipeline.py——当传入layout_repo或使用扁平 OCR 模型时_resolve_layout_source()会据此定位版面权重来源单仓库形态则默认从weights/layout子目录加载见 pipeline.py。单独使用 OCR 阶段README 说明mlx_vlm.load与generate可以只作用于 OCR 阶段——它会从下载仓库的weights/ocr目录加载。这对应 pipeline.py 中扁平 OCR 阶段的加载分支仓库根config.json的stages字段描述各阶段位置OCR 阶段默认在weights/ocr加载时用mlx_vlm.load(str(ocr_dir))拿到(ocr_model, ocr_processor)随后可直接对裁剪块做生成式转写。复用外部版面JsonLayoutBackendfrom mlx_vlm.models.indic_ocr import JsonLayoutBackendJsonLayoutBackend接受PageResult、JSON 路径或 dict 三种输入detect()只是原样重放块并按顺序重新编号见 pipeline.py。这意味着你可以用 torch 上游 IndicOCR、手写 JSON 或任意其他检测器产出版面再让 mlx-vlm 的 OCR 阶段完成转写——流水线的两个阶段因此可以自由组合。七、模型架构与配置Qwen3.5 的薄封装从 indic_ocr.py 的模块文档看IndicBlockOCR 是 Qwen3.5 实现的薄封装相同架构、相同权重名model.language_model.*/model.visual.*只是词表换成了 Indic 词汇表大小 262157token id 由ModelConfig携带。Model.__init__会把 checkpoint 的model_type替换为qwen3_5从而复用 Qwen3.5 的 image-first 对话格式与共享提示词逻辑见 indic_ocr.py。配置侧config.py支持两种形态OCR-only 配置ModelConfig直接复用 Qwen3.5 的TextConfig/VisionConfig并声明image_token_id262155、video_token_id262156、vision_start_token_id262153、vision_end_token_id262154、vocab_size262157等 Indic 特定 token见 config.py组合配置ParserConfig同时内嵌layout_configPP-DocLayoutV3 的ModelConfig与ocr_config外加可选的ocr_model_pathOCR 处理器相对路径与weight_mapping阶段权重重命名映射由Model.__new__识别并路由到IndicOCRParser.from_config()见 indic_ocr.py 与 config.py。仓库测试 test_indic_ocr.py 验证了这些关键行为model_typeindic_ocr能被正确路由到indic_ocr模块、Indic token id 被正确携带、OCR 阶段复用 Qwen3.5 的 image-first 聊天模板图像 token 在前、文本在后、检测到 wrapper 仓库时给出可读的报错提示。八、常见问题与使用建议安装环境本文所有示例均基于 mlx-vlm 源码检出后pip install -e .的本地环境首次运行时get_model_path会自动从 Hugging Face 下载HashNuke/indic-ocr-mlx权重。复现性temperature保持默认0.0贪心解码这是唯一可复现的设置如需改变生成长度修改RecognizerOptions.max_tokens默认 2048。表格输出需要 GitHub 风格 Markdown 表格时设置RecognizerOptions(table_formatmarkdown)需要保留合并单元格结构时保持默认html。版面来源整页解析走MLXLayoutBackend若已有外部版面结果用JsonLayoutBackend重放可省去版面检测阶段。分类体系无论检测器输出 IndicDocLayout 还是 PP-DocLayoutV3 标签map_label()都会统一映射到流水线类型未知标签会在严格模式下报错并给出相似标签提示。综合来看mlx-vlm 的 IndicOCR 实现把版面检测 逐块转写 Markdown/JSON 重建整条文档解析链路完整搬到了 MLX 上既保留了 README 所描述的两阶段模型分工与可插拔设计又通过IndicOCRParser、四组选项 dataclass 与标签双分类映射让开发者能在 Mac 上以少量代码完成对英文与 22 种印度语言文档页面的结构化解析。【免费下载链接】mlx-vlmMLX-VLM is a package for inference and fine-tuning of Vision Language Models (VLMs) on your Mac using MLX.项目地址: https://gitcode.com/GitHub_Trending/ml/mlx-vlm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门