「OCRが遅いのはなぜ?」バッチ処理が遅くなる3つの根本原因と、それぞれの解決策

ほとんどのOCRベンチマークはスペックシート上では優秀に見えます。Tesseractは1ページ1秒未満を謳い、GPU上のEasyOCRは毎分190ページを記録します。ところが、実際に自分のバッチ(200枚のサプライヤー請求書、スマホ写真とスキャンPDFが混在)を実行すると、突然1ページあたり30秒かかってしまいます。週末は台無しです。ボトルネックはほぼ常に3つのうちのどれかです。あなたの原因を見つける方法をご紹介します。

手入力をやめよう — AIに読み取らせるだけ
画像やPDFをアップロード — 10秒で構造化データに
今すぐ試す
登録不要 · カード不要 · 10秒で結果
OCRが遅い — GPU、解像度、並列処理によるバッチ処理速度のボトルネック診断

重要ポイント

  1. 200枚の請求書バッチで1ページ30秒 — 同じOCRエンジンが1秒未満をベンチマークしている場合、それはバグではなく、3つの独立した速度低下がパイプライン内で静かに複合的に作用しているのです。
  2. 3つの増加倍率がパイプライン内で複合的に作用 — GPUがないと3~7倍遅くなり、画像サイズが大きすぎると4倍のペナルティが加わり、逐次処理ではCPUの4分の3がアイドル状態になります。それぞれ数分で診断でき、個別に修正可能です。
  3. 3つの修正をすべて最大限に施しても、バッチ処理に1時間以上かかる場合、ボトルネックはもはやパイプライン内にはありません。最速の残された手段は、調整ノブを回し続けるのではなく、アーキテクチャを変更することです。

原因1:計算負荷の高いパイプラインでGPUアクセラレーションが使われていない

症状。処理中にCPU使用率が100%に張り付き、クリーンなドキュメントでも1ページあたり1秒以上かかる。バッチにファイルを追加してもスループットは向上せず、パイプラインが飽和状態。

根本原因。OCRエンジンは内部構造が大きく異なる。GoogleがメンテナンスするオープンソースのベンチマークTesseractは、純粋なCPUベースのエンジン。従来のコンピュータビジョンパイプライン(連結成分分析、ページレイアウト分析、LSTMベースの文字認識)を使用しており、GPUの並列処理を活用しない。ある研究者のベンチマークでは、Tesseract 5は現代的なCPUでクリーンな印刷テキストを処理する場合、1ページあたり約0.8秒。数ページなら許容範囲だが、500ページでは苦痛。

EasyOCRは異なるアーキテクチャを採用。ディープラーニングバックボーン(CRAFTテキスト検出 + PyTorch認識ネットワーク)はGPU上で動作可能で、その場合、劇的に高速化する。しかし、多くの人が見落とす落とし穴がある。EasyOCRは互換性のあるGPUが検出されないと、自動的にCPUにフォールバックする。CPU上では、EasyOCRを高精度にする同じディープラーニングパイプラインが、GPUモードよりも3~4倍遅くなる。NVIDIA T4でのベンチマークでは、EasyOCR GPUは1ページあたり約0.6秒(Tesseractと同等)だが、EasyOCR CPUは1ページあたり約2.5秒にまで伸びる。

修正方法。OCRパイプラインが実際にGPUを使用しているか確認する:

  • EasyOCRの場合、reader = easyocr.Reader(['en'], gpu=True)が実際にCUDAを検出しているか確認する。ライブラリが静かにフォールバックすると、1ページあたりの時間が2倍以上になる。処理中にnvidia-smiを実行し、GPU使用率が0%なら、パイプラインはCPUで動作している。
  • TesseractにはGPUトグルはなく、GPUアクセラレーションをサポートしていない。数百ページ以上を処理する場合は、GPU対応エンジンへの切り替えを検討する。
  • PaddleOCRのような専用OCRエンジンは、GPU向けにゼロから構築されている。独立した速度ベンチマークでは、RTX 3090上のPaddleOCRは、最適化されたバッチ推論とCUDA統合により、1分あたり約190ページ(1秒あたり3ページ以上)を達成。

ハードウェアが固定されている場合(ディスクリートGPUなしのノートPC、共有サーバー、GPUなしのクラウドVM)、GPUパスは直接利用できない。その場合は、GPU搭載インフラ上でドキュメントを処理するクラウドベースのOCRサービス(ハードウェアを自分で用意する必要なし)が問題を完全に回避する。

GPU対応OCRエンジンの比較については、最高のオープンソースOCRツールのまとめを参照。

1つのGPUは印刷ドキュメントを1秒あたり3~5ページ処理できる。同じパイプラインをCPUで実行すると、1秒あたり0.3~0.5ページに低下する。このハードウェアの差は、バッチ処理時間に10倍の影響を与える。

原因その2:OCRに必要な画像サイズが大きすぎる

症状。見た目は問題ないページで処理が止まってしまう。12メガピクセルのスマホで撮影したレシートは5~8秒かかるのに、同じ文書のスキャンPDFは2秒未満で処理が完了する。

根本原因。ほとんどのOCRエンジンは画像の全ピクセルを処理する。解像度を各軸で2倍(150 DPI→300 DPI)にすると、ピクセル数は4倍になる(幅2倍×高さ2倍)。入力が4倍になれば、同じ内容でも処理時間は約4倍になる。スマホ写真(4000×3000ピクセル)は1200万ピクセル。同じ文書を300 DPIでスキャン(レターサイズで約2550×3300)すると840万ピクセル。200 DPIでスキャンした文書(ほとんどのOCRに十分)は370万ピクセルしかない。

OCR性能チューニングの最も権威ある資料の一つであるABBYY FineReader Engine Performance Guideでは、推奨入力範囲として200~400 DPIを指定している。150 DPI未満では文字認識が低下する。400 DPIを超えても、測定可能な精度向上はなく、計算時間の無駄になる。この原則は、オープンソース・プロプライエタリを問わず、あらゆるOCRエンジンに当てはまる。

修正方法。OCRエンジンに画像を渡す前にリサイズする前処理ステップを追加する。目標は出力画像で150~300 DPI。一般的な文書では長辺が約1200~2500ピクセルになる。

Pillowを使ったシンプルなPython前処理パイプライン:

from PIL import Image

def resize_for_ocr(image_path, max_dim=2000):
    img = Image.open(image_path)
    # 縮小のみ、拡大はしない
    if max(img.size) > max_dim:
        ratio = max_dim / max(img.size)
        new_size = (int(img.size[0] * ratio),
                    int(img.size[1] * ratio))
        img = img.resize(new_size, Image.LANCZOS)
    return img

この1ステップで、元画像にもよるが、1ページあたりの処理時間を40~70%削減でき、抽出精度にはまったく影響しない。画像の前処理(二値化、傾き補正、コントラスト正規化など)の完全ガイドは、OCR画像前処理ガイドをご覧ください。

原因その3:並列実行できる処理を逐次処理している

症状。バッチ実行中、CPU使用率が30~40%程度で推移する。パイプラインはファイルを1つずつ処理するため、プログレスバーが1ファイルずつ進むだけで、速度が向上することはありません。

根本原因。ほとんどのOCRパイプラインは単純なループで記述されています:for file in files: ocr(file)。これはデフォルトでシングルスレッドです。最近のCPUは4、8、16コアを搭載していますが、逐次ループはそのうちの1コアしか使用しません。ページがキューに並んでいる間、他のコアはアイドル状態です。

修正は非常に簡単な並列化です。あるページのOCRは他のページのOCRとは独立しています。同期すべき共有状態はありません。つまり、NコアのマシンでNページを同時に処理でき、理論上はN倍のスループットが達成できます。実際には、4~8コアまではほぼ線形にスケーリングし、それ以上はメモリ帯域幅やI/O競合の影響で効果が薄れます。

修正方法。OCR呼び出しを並列実行フレームワークでラップします:

  • GNU Parallel(Linux/macOS):スクリプトベースのパイプラインに最も簡単なアプローチ。parallel -j 4 ocrmypdf {} output/{} ::: *.pdf で4つのOCRプロセスを同時実行します。
  • Python multiprocessingmultiprocessing.Pool を使用してファイルをワーカープロセスに分散します。各ワーカーは独自のOCRエンジンインスタンスを持ち、完了した結果が収集されます。
  • バッチ処理ツール:OCRmyPDFのような専用バッチOCRツールは、組み込みの並列処理をサポートしています。--jobs パラメータで同時実行数を制御します。GNU Parallelと組み合わせて(I/O飽和を避けるために並列数を2に制限する)使用することは、実績のある本番パターンです。

重要な実用的な考慮事項:各並列ワーカーは、そのページの画像と中間バッファを保持するために十分なメモリを必要とします。8GBのRAMを搭載したマシンで8つのワーカーを実行すると、スワッピングが発生します。標準的なドキュメント画像の場合、安全な出発点は並列ワーカーあたり2GBのRAMです。CPUコア数に達する前に、メモリ予算に合わせて並列度を調整してください。

並列バッチパイプラインの設定に関する完全なチュートリアルについては、複数ファイルのバッチ処理ガイドをご覧ください。

エスカレーションのタイミング — チューニングではなくツールの切り替え

GPUが動作している、画像サイズが適切である、パイプラインが並列実行されている — これら3つの原因をすべて確認しても、処理がワークロードに対して遅すぎる場合、ボトルネックは設定ではなくアーキテクチャにある可能性があります。

根本的に異なるアプローチを検討すべき3つのシグナルがあります。

1. ボリュームが常に高い。 毎日500ページ以上を処理し、バッチ完了時間が常に課題となっている場合、ローカルOCRパイプラインのチューニングでは、専用のクラウドサービスには及びません。クラウド抽出サービスは、サーバーグレードのGPUクラスターで自動負荷分散を行い、ハードウェアを用意することなく、単一のバッチを数十の並列ワーカーに分散処理できます。

2. ドキュメントが多様で未加工である。 クリーンなスキャンPDFに最適化されたパイプラインは、スマートフォン写真、くしゃくしゃのレシート、手書き文書には対応できません。新しい入力タイプごとに異なる前処理パラメータが必要です。ImageToTable.aiは、ドキュメントを意味的に読み取るビジョン言語モデルを使用し、ドキュメントタイプごとのチューニングを必要とせず、人間と同じようにページレイアウトを解釈します。クラウドパイプラインが推論前に自動的にスケーリングを処理するため、解像度正規化のための個別の前処理ステップは不要です。

3. 結果が数時間ではなく数分で必要である。 300ページのバッチを昼休み中に処理してエクスポートする必要がある場合、速度調整されたローカルパイプラインでも対応できません。クラウドバッチ処理はドキュメント全体を並列化します。シングルCPUマシンで3〜4時間かかる300ページのバッチも、20〜40の並列GPUワーカーで同じ処理を実行するクラウドインフラでは5〜10分で完了します。

OCRが遅い3つの根本原因 — GPUなし、画像サイズ過大、逐次実行 — はコードのバグではありません。ドキュメント量と処理パイプラインのアーキテクチャのミスマッチです。最も効率的な修正は、パイプラインをチューニングするのではなく、変更することである場合もあります。
手入力をやめよう — AIに読み取らせるだけ
画像やPDFをアップロード — 10秒で構造化データに
今すぐ試す
登録不要 · カード不要 · 10秒で結果

よくある質問

TesseractはEasyOCRより速いですか?

CPUの場合、Tesseractの方が一般的に速く、鮮明な印刷テキストで1ページあたり約0.8秒に対し、EasyOCRは約2.5秒です。GPUでは比較が逆転します。NVIDIA GPU上のEasyOCRは1ページあたり約0.6秒で動作し、Tesseractのスループットに匹敵またはそれを上回り、劣化画像、手書き注釈、混在レイアウトでは大幅に優れた精度を提供します。実用的な結論:GPUがある場合はEasyOCR(またはPaddleOCR)を使用してください。CPUのみの場合は、Tesseractが鮮明な文書でより良いスループットを提供しますが、複雑な入力では精度が低くなることが予想されます。

OCR速度に最適な画像解像度は?

200~300 DPIがほとんどのOCRエンジンにとって最適な範囲です。150 DPI未満では、特に小さなフォントサイズで文字認識精度が著しく低下します。400 DPIを超えると、精度の向上が無視できるかゼロであるにもかかわらず、処理時間が2~4倍になります。標準的なレターサイズ文書(8.5"×11")の場合、200 DPIで約1700×2200ピクセル(約3.7メガピクセル)の画像になります。これは一般的なスマートフォンの写真よりもはるかに小さく、処理時間もわずかです。

複数のGPUを使用してOCRを高速化できますか?

はい、OCRエンジンが対応しており、ワークロードが十分に大きい場合に可能です。PaddleOCRとEasyOCRは、異なる文書バッチを異なるGPUインスタンスに割り当てることで、複数のGPUに分散できます。実際には、1台の最新GPU(RTX 3090以上)で標準文書を毎分150~190ページ処理できるため、マルチGPU構成は非常に大量(1日あたり10,000ページ以上)の場合にのみ必要です。その規模では、主なボトルネックは計算からI/O(ファイルの読み取り、結果の書き込み)に移行するため、マルチGPU構成は高速ストレージ(NVMe SSD)と十分なRAMと組み合わせる必要があります。

GPUはCPUと比べてOCRがどのくらい速くなりますか?

EasyOCRやPaddleOCRのような深層学習ベースのOCRエンジンでは、GPUアクセラレーションにより、CPUのみの処理と比較して、GPUモデルや画像の特性にもよりますが、通常3~7倍の速度向上が得られます。一般的なクラウドGPUであるNVIDIA T4では、EasyOCRはCPUフォールバック時と比べて約4倍高速です。RTX 3090のようなコンシューマー向けGPUでは、PaddleOCRは毎分190ページ以上を処理し、同じパイプラインを実行する4コアCPUと比較して5~7倍の改善を示します。TesseractはGPUアクセラレーションをサポートしていないため、その速度はCPUの性能に完全に依存し、直接比較することはできません。

画像サイズを小さくするとOCR精度は低下しますか?

画像サイズの縮小は、OCRエンジンが小さな文字を読み取るために必要な最小解像度を下回った場合にのみ精度を低下させます。ほとんどの印刷文書では、200 DPIで99%以上の文字精度が十分に得られます。150 DPIを下回ると、8ptフォントの脚注、小数点、下付き文字などの細かい部分が失われ始める可能性があります。安全な方法は、200~300 DPIの目標解像度にリサイズすることです。これにより、読みやすさを維持しながら、処理を遅くするだけの4~5メガピクセルの冗長データを排除できます。文書に非常に小さな文字(例:6~8ptの法的な細則)が含まれている場合は、300 DPIを下限として設定してください。

いつチューニングをやめて別のツールに切り替えるべきですか?

バッチ処理時間が、OCRエンジン自体ではなく、前処理、ファイルI/O、シリアライズといったパイプラインのオーバーヘッドによって支配されている場合、ローカルでのチューニングの実用的な限界に達しています。切り替え時を示す兆候としては、GPUアクセラレーション、解像度の正規化、並列処理をすでに実装しているにもかかわらず、300ページのバッチ処理に依然として1時間以上かかる場合や、文書の種類が多様(スマートフォン写真、スキャン、スクリーンショット、手書き文字の混在など)で、ページごとに前処理パラメータを調整する必要がある場合などが挙げられます。このようなシナリオでは、GPUワーカー間で処理を並列化し、文書を意味的に読み取る(タイプごとのチューニングが不要な)クラウドベースの抽出サービスの方が、速度と精度の両方でローカルでチューニングされたパイプラインを上回ります。

📮 contact email: [email protected]