glm-ocr とは?ローカルLLM で OCR は実用になるのか検証してみた(Ollama × n8n)

glm-ocr とは?ローカルLLM で OCR は実用になるのか検証してみた(Ollama × n8n) 無料で AI を使う
広告

ローカルLLM で OCR をやろうとすると、思ったよりうまくいかないことが多いです。

特に、

  • 表が崩れる
  • 日本語が不安定
  • レイアウトが壊れる

といった問題が出やすく、「結局クラウド API に頼るしかないのか」と感じる場面もあります。

そこで試したのが、Ollama で使える OCR 特化モデル「glm-ocr」です。

この記事では、glm-ocr の概要だけでなく、実際に n8n と組み合わせて レシートOCR を運用してみた結果をもとに、

  • 精度はどれくらい出るのか
  • どこでつまずくのか
  • 実用レベルに持っていくには何が必要か

を整理していきます。

glm-ocr とは

glm-ocr は、画像から文字を読み取ることに特化したマルチモーダルモデルです。

一般的な LLM( gpt-oss や qwen 系など)でも画像入力は可能ですが、OCR 用途では精度や安定性に課題があります。

glm-ocr はその点、

  • OCR 専用に設計されている
  • 表・数式・帳票などの構造理解が強い
  • 比較的軽量(約2GB)でローカル動作可能

といった特徴があります。

Ollama にも対応しており、以下のようにすぐ試せます。

ollama run glm-ocr Text Recognition: ./image.jpg

以下は実際の読み取り結果です。

Ollama glm-ocr 動作テスト

元画像はこちら。

動作環境について

今回の検証は主に Mac mini M4(メモリ 32GB)の環境で行っています。なお、軽く試した範囲では、Mac mini M1(メモリ 8GB)でも glm-ocr 自体は動作しました。ただし、後に紹介する gpt-oss:20b はメモリの制約上、Mac mini M1(メモリ 8GB)では動作不可です。OCR 用途( glm-ocr 単体)であれば、低スペック環境でも試すことは可能です。

なぜ専用モデルを使うのか

今回の検証で大きかったのはここです。

OCR は「読む」だけでなく、

  • レイアウトを(ある程度)維持する
  • 数値を正しく拾う
  • 意味のある単位で分割する

といった処理が必要になります。

汎用モデルでも一応できるのですが、

  • 数字がズレる
  • 行が混ざる
  • JSON が崩れる

といった問題が頻発します。

そこで、

  • 文字認識 → glm-ocr
  • 構造化 → 別モデル( gpt-oss など)

という役割分担にすることで、安定性が大きく向上しました。

実際に構築した構成( n8n × Ollama )

今回作ったのは、

「レシートを撮影して Google ドライブに入れるだけで、家計簿が更新される仕組み」です。

全体の流れは以下です。

  • Google Drive に画像アップロード
  • n8n がトリガーで起動
  • 未処理ファイルのみ抽出
  • glm-ocr で文字認識
  • gpt-oss で JSON 整形
  • Google Sheets に書き込み

ポイントは、

👉 OCR と整形を分離していること

これによって、

  • 精度の改善がしやすい
  • モデルの入れ替えが可能
  • トラブルの切り分けができる

というメリットがあります。

精度はどれくらい出るのか

実際に使ってみた体感は以下の通りです。

  • 印字文字 → かなり高精度
  • 店名(カタカナ) → やや不安定
  • 半角カナ → かなり不安定
  • 手書き → ほぼ不可

説明書やレシートの印字部分は問題なく読み取れます。

glm-ocr で説明書を読み取った結果
glm-ocr でレシートを読み取った結果(一部抜粋)

一方で、

  • 手書きメモ
  • 崩れたフォント
  • 低画質画像

はまだ厳しい印象です。

ここは glm-ocr というより、現状の OCR 全体の限界に近い部分です。

glm-ocr で手書きメモを読み取った結果

手書きの文字が汚すぎるのがそもそもの問題でしょうね・・・(笑)

プロンプト設計で精度が変わる

今回一番ハマったのがここです。

最初は、

「インボイス番号を取得して」

といった指示をしていましたが、

  • #7336
  • null

など、意図しない結果が出ていました。

原因はシンプルで、

👉 レシートには「登録番号」と書かれている

この気づきから、

  • 登録番号を取得してください
  • Tから始まる13桁です
  • インボイス番号と書かれている場合もあります

といった形に修正。

これだけで精度が大きく改善しました。

👉 実データに合わせることが最重要

JSON スキーマ指定はほぼ必須

n8n で扱う場合、もう一つ重要なのが出力形式です。

自由出力のままだと、

  • フィールドが欠ける
  • 余計な文章が混ざる
  • パースに失敗する

といった問題が出ます。

そこで、

  • 型を固定
  • 必須項目を指定
  • 余計な出力を禁止

といった JSON スキーマを設定。

これにより、後処理が一気に安定します。

JSON スキーマを設定して AI に出力させる

改善していくと精度は上がる

運用しながら以下の改善を行いました。

  • 割引の読み取り対応
  • 消費税の追加
  • 不要行の除外

例えば消費税では、

「外8% タイショウ ¥XXXX」

のような行を誤って拾う問題がありました。

これも、

👉 「小計は除外する」と明示

することで解決。

このように、

👉 パターンを学習 → プロンプトに反映

というループで精度が上がっていきます。

ローカル OCR は実用になるのか

結論としては、

👉 条件付きで実用レベル

です。

  • 印字中心 → 実用可能(カタカナ、特に半角カナに課題あり)
  • 手書き → 厳しい
  • プロンプト調整 → 必須

ただし、

  • API 課金なし
  • ローカル完結
  • 試行回数無制限

というメリットは非常に大きく、

👉 「試して改善する前提」ならかなり強い

です。

参考:実験ログ(詳細)

今回の内容は、実際の検証ログをもとに整理しています。

より細かい試行錯誤や改善過程については、以下にまとめています。

➡️ n8n × Ollama:glm-ocr で文字認識

➡️ レシート読み取り → 家計簿自動化

➡️ 割引・消費税対応の改善

次のステップ

今回の構成ができれば、

  • 領収書の自動仕訳
  • 家計簿の完全自動化
  • 他の帳票処理

といった応用も見えてきます。

n8n とローカルLLM を組み合わせることで、

👉 「無料でどこまで自動化できるか」

というテーマが一気に現実的になります。

このあたりはまだ検証途中のため、引き続き試行錯誤していきます。

タイトルとURLをコピーしました