MLX-VLM 实战指南:在 Mac 上使用 GLM-OCR 完成文档解析与结构化信息提取
【免费下载链接】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
GLM-OCR 是一个针对光学字符识别(OCR)任务优化的视觉语言模型,擅长文档解析(文本、公式、表格识别)与结构化信息抽取。本文将围绕其官方模型说明文档展开,结合 MLX-VLM 仓库中的源码实现,完整讲解安装方式、CLI 与 Python 两种调用路径、两类 Prompt 场景、核心生成参数以及可落地的完整 OCR 流水线,帮助你直接在 Apple Silicon Mac 上把纸质文档、公式图片、表格和证件图片快速转化为可机读的结构化数据。
模型概述:为 OCR 而生的视觉语言模型
GLM-OCR 是 GLM 系列中面向 OCR 场景的专用模型,由 ZAI 团队开发,MLX-VLM 将其移植到 Apple 的 MLX 框架上,使其可以在 Mac(含统一内存架构)上直接完成推理。根据官方模型说明(见 模型文档),其核心信息如下:
- 模型 ID:
mlx-community/GLM-OCR-bf16(bf16 精度权重,由 MLX 社区发布) - 架构:视觉语言模型,采用M-RoPE(Multi-dimensional Rotary Position Embedding)多维旋转位置编码
- 支持任务:文本识别、公式识别、表格识别、结构化信息提取
从源码看,模型由三大组件构成(见 glm_ocr.py):vision_tower(视觉塔)、language_model(语言模型)以及负责把图像特征与文本嵌入合并的merge_input_ids_with_image_features逻辑。配置文件 config.py 中可以看到更精确的规模信息:
- 语言模型(
TextConfig):隐藏维度 1536、16 层、16 个注意力头、8 个 KV 头、词表 59392、最大位置编码 131072,rope_parameters中mrope_section = [16, 24, 24],这正是 M-RoPE 将位置维度划分为时间、高度、宽度三个通道的实现依据; - 视觉塔(
VisionConfig):24 层、patch 大小 14、输入图像 336、空间合并大小(spatial_merge_size)为 2、时间 patch 大小为 2。
文档解析类任务对长文档与密集版面的位置关系敏感,M-RoPE 让模型能够同时感知图像块的“时间(帧)/高/宽”三维位置,这是 GLM-OCR 在版面还原上优于普通 2D 位置编码模型的重要基础。
安装 MLX-VLM
在开始之前,请确保你的 Mac 已安装 Apple Silicon 平台所需的 MLX 依赖(macOS 环境、Python 3.9+)。MLX-VLM 提供了两种安装方式:
pip 安装:
pip install mlx-vlmuv 安装(更快的 Python 包管理器):
uv pip install mlx-vlm模型权重无需手动下载:mlx-community/GLM-OCR-bf16会在首次load()或 CLI 运行时自动从 Hugging Face Hub 拉取并缓存到本地。如果你希望完全离线运行,可先使用huggingface-cli download mlx-community/GLM-OCR-bf16预下载,再通过本地路径加载。
使用方式一:CLI 快速上手
CLI 是最快的验证方式,核心命令为mlx_vlm generate。官方文档给出了四种典型场景,它们共享同一套命令结构,差别仅在于--prompt的内容:
基础文本识别:
uv run mlx_vlm generate --model mlx-community/GLM-OCR-bf16 --image document.png --prompt "Text Recognition:"公式识别:
uv run mlx_vlm generate --model mlx-community/GLM-OCR-bf16 --image equation.png --prompt "Formula Recognition:"表格识别:
uv run mlx_vlm generate --model mlx-community/GLM-OCR-bf16 --image table.png --prompt "Table Recognition:"结构化信息提取(以身份证为例,Prompt 必须遵循 JSON 格式):
uv run mlx_vlm generate --model mlx-community/GLM-OCR-bf16 --image id_card.png --prompt '请按下列JSON格式输出图中信息: { "id_number": "", "last_name": "", "first_name": "", "date_of_birth": "", "address": { "street": "", "city": "", "state": "", "zip_code": "" }, "dates": { "issue_date": "", "expiration_date": "" }, "sex": "" }'CLI 的完整参数(如--max-tokens、--temperature、--top-p)可在 CLI 参考文档 与 generate/cli.py 中查看,它们与下文 Python 接口的生成参数一一对应。
使用方式二:Python API 编程调用
对于需要集成进业务系统的场景,Python API 提供了更强的可控性。加载与生成的核心依赖为load、generate与apply_chat_template(分别导出自 utils.py 与 prompt_utils.py,入口见init.py)。
文档解析——文本识别:
from mlx_vlm import load, generate from mlx_vlm.prompt_utils import apply_chat_template # Load model model, processor = load("mlx-community/GLM-OCR-bf16") # Document Parsing - Text Recognition prompt = "Text Recognition:" formatted_prompt = apply_chat_template(processor, model.config, prompt, num_images=1) result = generate( model, processor, formatted_prompt, image=["document.png"], max_tokens=512, verbose=True, ) print(result.text)公式识别:
prompt = "Formula Recognition:" formatted_prompt = apply_chat_template(processor, model.config, prompt, num_images=1) result = generate( model, processor, formatted_prompt, image=["equation.png"], max_tokens=256, ) print(result.text)表格识别:
prompt = "Table Recognition:" formatted_prompt = apply_chat_template(processor, model.config, prompt, num_images=1) result = generate( model, processor, formatted_prompt, image=["table.png"], max_tokens=1024, ) print(result.text)结构化信息提取(JSON Schema 驱动):
# Define JSON schema for extraction prompt = """请按下列JSON格式输出图中信息: { "id_number": "", "last_name": "", "first_name": "", "date_of_birth": "", "address": { "street": "", "city": "", "state": "", "zip_code": "" }, "dates": { "issue_date": "", "expiration_date": "" }, "sex": "" }""" formatted_prompt = apply_chat_template(processor, model.config, prompt, num_images=1) result = generate( model, processor, formatted_prompt, image=["id_card.png"], max_tokens=512, ) print(result.text)关于apply_chat_template,其签名(prompt_utils.py)显示它接收processor、config、prompt以及add_generation_prompt、num_images等参数。它首先从config.model_type判断模型类型,再为当前模型调用对应的聊天模板封装用户消息。GLM-OCR 属于仓库MODEL_CONFIG注册的视觉语言模型,因此会走带图像占位符的消息构建分支;num_images=1告知模板当前输入包含 1 张图,从而在 prompt 中正确插入<|image|>占位符。
底层发生了什么:从图片到 token
GLM-OCR 的推理链路在仓库中有完整的实现,理解它有助于你调优输入图片:
- 图像预处理(processing.py):
GlmOcrProcessor包装了图像处理器与分词器。图像处理器先通过smart_resize把图片按 28 的倍数(patch_size * merge_size,即 14 × 2)缩放,控制像素总量在min_pixels与max_pixels之间(默认112 × 112至14 × 14 × 2 × 2 × 2 × 6144),再进行归一化(ImageNet 均值/方差)与temporal_patch_size维度的复制,最终输出pixel_values与image_grid_thw两个字段; - 占位符展开:Processor 根据
image_grid_thw计算每张图展开后的视觉 token 数量(prod(grid) // merge_length,其中merge_length = merge_size²),把 prompt 中的<|image|>替换为对应数量的图像 token; - 视觉塔编码(vision.py):
GlmOcrVisionPatchEmbed使用 Conv3d(时间 patch 2 × 空间 patch 14 × 14)切分 patch;24 层GlmOcrVisionBlock内使用 RMSNorm 归一化的 Q/K 与二维(高、宽)旋转位置编码;最后由downsample(2×2 卷积)与GlmOcrVisionPatchMerger(SwiGLU 结构)把视觉特征映射到语言模型的隐藏维度; - 特征合并(glm_ocr.py):
merge_input_ids_with_image_features在<|image|>token 位置把视觉特征插入文本嵌入序列,同时get_rope_index依据mrope_section = [16, 24, 24]为每个 token 计算时间/高/宽三维位置 ID,预填充 M-RoPE 位置信息,供语言模型逐层自回归生成文本。
支持的 Prompt 场景
GLM-OCR 官方文档将用法划分为两大场景,两类场景的 Prompt 组织方式完全不同,务必区分使用:
1. 文档解析(Document Parsing)
提取文档中的原始内容,使用固定任务 Prompt:
| 任务 | Prompt |
|---|---|
| 文本识别 | Text Recognition: |
| 公式识别 | Formula Recognition: |
| 表格识别 | Table Recognition: |
2. 信息抽取(Information Extraction)
从文档中提取结构化信息,Prompt 必须遵循严格的 JSON Schema 格式。模型会依据你在 Prompt 中给出的空 JSON 骨架,将图片中的对应字段填充后输出。
示例——身份证抽取:
请按下列JSON格式输出图中信息: { "id_number": "", "last_name": "", "first_name": "", "date_of_birth": "", "address": { "street": "", "city": "", "state": "", "zip_code": "" }, "dates": { "issue_date": "", "expiration_date": "" }, "sex": "" }示例——发票抽取:
请按下列JSON格式输出图中信息: { "invoice_number": "", "date": "", "vendor": "", "items": [], "subtotal": "", "tax": "", "total": "" }注意:使用信息抽取时,输出必须严格符合定义的 JSON Schema,以保证下游处理(如入库、校验、对接业务系统)的兼容性。字段建议全部使用英文键名,数组字段(如
items)预置为空数组即可。
生成参数说明
CLI 与 Python API 共享同一套解码参数,官方文档给出的默认值如下:
| 参数 | 说明 | 默认值 |
|---|---|---|
max_tokens | 最大生成 token 数 | 256 |
temperature | 采样温度(0 表示确定性输出) | 0.0 |
top_p | Nucleus 采样参数 | 1.0 |
实操建议:
- 表格识别信息密度高、输出长,官方示例将
max_tokens设为 1024,防止输出被截断; - 公式识别输出通常较短,
max_tokens=256足够; - 结构化抽取建议保持
temperature=0(默认值),确保同一张图多次推理结果稳定,便于回归测试与下游校验; - 若输出出现乱码或重复,可优先调低
top_p(如 0.9)再配合低温使用。
示例:完整 OCR 流水线
官方文档提供了一个将“文档解析”与“结构化抽取”封装为两个函数的完整流水线,模型只加载一次、可复用多次,非常适合批量处理场景:
from mlx_vlm import load, generate from mlx_vlm.prompt_utils import apply_chat_template import json # Load model once model, processor = load("mlx-community/GLM-OCR-bf16") def extract_text(image_path: str) -> str: """Extract raw text from an image.""" prompt = "Text Recognition:" formatted_prompt = apply_chat_template(processor, model.config, prompt, num_images=1) result = generate(model, processor, formatted_prompt, image=[image_path], max_tokens=1024) return result.text def extract_structured(image_path: str, schema: dict) -> dict: """Extract structured information using a JSON schema.""" prompt = f"请按下列JSON格式输出图中信息:\n{json.dumps(schema, indent=4, ensure_ascii=False)}" formatted_prompt = apply_chat_template(processor, model.config, prompt, num_images=1) result = generate(model, processor, formatted_prompt, image=[image_path], max_tokens=512) return json.loads(result.text) # Usage text = extract_text("document.png") print(f"Extracted text: {text}") # Structured extraction schema = { "title": "", "author": "", "date": "", "content": "" } data = extract_structured("article.png", schema) print(f"Extracted data: {data}")这个流水线的价值在于:extract_text负责“看懂版面”——把整页内容还原为可读文本;extract_structured负责“读懂语义”——把特定字段抽取为可直接json.loads的字典。二者组合即可覆盖“先全文 OCR、再字段抽取”的典型业务链路。
使用建议与注意事项
- 输入图片质量优先:GLM-OCR 内部会按 28 的倍数缩放并裁剪像素总量(见 processing.py 的
smart_resize),过小或严重失真的图片会损失细节;扫描件建议保证分辨率与对比度; - 不同任务选对 Prompt:三类“Recognition”任务使用固定英文 Prompt,信息抽取使用中文 JSON 模板;混用会显著影响效果;
- 长文档分批处理:语言模型最大位置编码为 131072(config.py),常规单页文档远低于此上限,但超长多页文档仍建议按页切分后逐页解析再合并;
- 结构化输出需做健壮性处理:真实场景中模型偶尔会输出 JSON 外的多余文本,建议在
extract_structured中对result.text做 JSON 提取与异常兜底(如查找首个{到末尾}的片段),避免直接json.loads抛错; - 硬件前提:本模型针对 Apple Silicon Mac 设计,基于 MLX 框架推理;bf16 权重对内存有基本要求,加载前可留意 Mac 统一内存容量。
通过本文的 CLI 命令与 Python 流水线,你已经可以在 Mac 上完整跑通“图片输入 → 文本/公式/表格识别 → JSON 结构化输出”的 GLM-OCR 全流程。更多模型参数与批量生成能力可继续查阅仓库中的 generate 模块 与 server 文档。
【免费下载链接】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),仅供参考