firecrawl/pdf-inspector
PDFを開き切る前に仕分けて、OCRに回す枚数そのものを減らす
どういうものか
PDF から文字を取り出して Markdown にする Rust 製のライブラリです。ただし主役は変換のほうではなく、その前段にある仕分けの部分にあります。手元の PDF が、文字データを持っているものなのか、紙をスキャンしただけの画像なのかを判定します。作者は Firecrawl で、README には「OCR を要らないのは約54%の PDF」とあります。その54%のぶんだけ、外部サービスの費用と待ち時間を丸ごと消すのが狙いです。
判定のために全文を解析しない、というのがこのライブラリの設計です。読むのは相互参照テーブルとページツリーだけ。あとはコンテンツストリームを拾い読みして、文字を置く命令(Tj / TJ)が出てくるか、画像を貼る命令(Do)が出てくるかを見ます。結果は「テキスト」「スキャン」「画像」「混在」の4つに分けられ、確信度の数値が付きます。ここまでが、おおよそ 10〜50ミリ秒です。
判定はファイル全体の分類として返り、そこにOCR が要るページ番号の一覧が付きます。混在した PDF——本文は文字だが、途中の数ページだけスキャン画像、という書類——で、その数ページだけを OCR に送れます。また、パイプライン向けに早めに打ち切る、精度優先で全ページ見る、巨大な PDF は間引く、といった走査のしかたを選べます。Rust のクレートのほか、Python・Node.js・ブラウザ向け WebAssembly・コマンドライン(pdf2md / detect-pdf)から使えます。
どんなときに使うか
PDFの処理費用が、思ったより膨らんでいるとき
大量の PDF を OCR に投げる作りにしていると、実は文字データを持っていた PDF にも同じ料金と待ち時間が掛かっています。仕分けを前に置けば、その差がそのまま消えます。判定自体が数十ミリ秒なので、入れたことによる遅れはほぼ出ません。
ファイルを外に出したくないとき
ブラウザ向けの WebAssembly 版があり、CMap を内蔵してサーバへの往復なしで動くと書かれています。判定と Markdown 化までを手元で終わらせられるので、外に出す必要があるページだけを選んで送る、という運用ができます。
注意点
PDF ライブラリの置き換えではありません。 狙いは仕分けと、素直な文書の Markdown 化までです。README が向いている相手として挙げているのは、文字データを持つ PDF のうち、速度・読み順・表の構造が要るもの。汎用の PDF 操作ライブラリの代わりになるものとしては書かれていません。
得意な文書の形が決まっています。 想定されているのはレポート、論文、財務資料、請求書、法務文書です。見出しの判定は文字の大きさ、コードの判定は等幅フォント、というように見た目の特徴からの推測で組み立てられています。凝ったレイアウトのものほど、期待どおりにはなりにくいはずです。
OCR は使えますが、経路ごとに条件が違います。 Python と Node のパッケージには OCR の連携が入っていて、PP-OCRv6 Small を手元で走らせられます。Rust とコマンドラインから使う場合は、ビルドのときに OCR を有効にする必要があります。Rust の既定のビルドは OCR なしの抽出だけで、ブラウザ版にはそもそも OCR の経路がありません。
自分で用意するのは PDFium と ONNX Runtime の2つで、置き場所を環境変数で教えます。モデルのほうは用意する必要がなく、最初に OCR へ回ったページで自動的に取得されます(3点で約31MB、中身を検証したうえで手元に残ります)。どちらも、OCR に回るページが出なければ触られません。なお説明書きは、通しで動作を確認しているのは Linux の x64 で、macOS と Windows は preview 扱いだと断っています。
ライセンスは MIT で、商用利用の妨げになる条項はありません。