はじめに
GLM-OCRは画像からテキスト、数式、表を認識できるモデルです。
複数の認識タイプに対応しており、日本語も含めた様々な言語のテキスト認識が可能です。
今回はGradioを使用してWebUI化し、実際に動作を確認してみました。
PC環境
Windows 11
Python環境構築
uvを使っています。pyproject.tomlを載せておくので uv sync のみで環境構築可能です。
transformersについては、最新の機能を使用するためにgit経由でのインストールを指定しています。
[project] name = "glmocr" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.13" dependencies = [ "accelerate==1.12.0", "torch==2.10.0+cu126", "torchvision==0.25.0+cu126", "transformers @ git+https://github.com/huggingface/transformers.git", "gradio==6.5.1", "pillow==10.0.0", ] [[tool.uv.index]] name = "torch-cuda" url = "https://download.pytorch.org/whl/cu126" explicit = true [tool.uv.sources] torch = [{ index = "torch-cuda" }] torchvision = [{ index = "torch-cuda" }]
特徴
GLM-OCRの主な特徴は以下の通りです:
- 複数の認識モード - テキスト認識、数式認識、表認識に対応
- マルチリンガル対応 - 日本語を含む複数言語のテキスト認識が可能
結果
元画像
#テキスト認識(Text Recognition)
通常のテキスト認識モードです。印刷されたテキストや手書きテキストを認識できます。
f(x) = sin x g(x) = cos(-x) h(x) = tan(1/x)
数式認識(Formula Recognition)
数学的な数式を認識して、LaTeX形式で出力してくれました。
$$
\begin{array}{l} f (x) = \sin x \\ g (x) = \cos (- x) \\ h (x) = \tan (1 / x) \\ \end{array}
$$
Pythonスクリプト
uv run main.py で実行するとWebUIが起動します。
from transformers import AutoProcessor, AutoModelForImageTextToText import torch import gradio as gr from PIL import Image MODEL_PATH = "zai-org/GLM-OCR" # Global variables for model caching processor = None model = None def load_model(): global processor, model if processor is None or model is None: processor = AutoProcessor.from_pretrained(MODEL_PATH) model = AutoModelForImageTextToText.from_pretrained( pretrained_model_name_or_path=MODEL_PATH, torch_dtype="auto", device_map="auto", ) return processor, model def recognize_text(image, prompt="Text Recognition:"): """ Recognize text from an image using GLM-OCR model. Args: image: PIL Image object prompt: Text prompt for the model Returns: Recognized text from the image """ processor, model = load_model() messages = [ { "role": "user", "content": [ { "type": "image", "image": image }, { "type": "text", "text": prompt } ], } ] inputs = processor.apply_chat_template( messages, tokenize=True, add_generation_prompt=True, return_dict=True, return_tensors="pt" ).to(model.device) inputs.pop("token_type_ids", None) generated_ids = model.generate(**inputs, max_new_tokens=1024) output_text = processor.decode( generated_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True ) return output_text # Create Gradio interface with gr.Blocks(title="GLM-OCR") as demo: gr.Markdown("# GLM-OCR テキスト認識") gr.Markdown("画像をアップロードしてテキストを認識します。") with gr.Row(): with gr.Column(): image_input = gr.Image(type="pil", label="画像をアップロード") prompt_input = gr.Dropdown( choices=[ ("テキスト認識", "Text Recognition:"), ("数式認識", "Formula Recognition:"), ("表認識", "Table Recognition:") ], value="Text Recognition:", label="認識タイプ" ) submit_btn = gr.Button("認識する", variant="primary") with gr.Column(): output_text = gr.Textbox(label="認識結果", lines=15) submit_btn.click( fn=recognize_text, inputs=[image_input, prompt_input], outputs=output_text ) if __name__ == "__main__": demo.launch()