この記事ではRAGの前処理に特化して解説します。RAG全体の仕組み・構築・ベクトルDB選定は RAGとは?仕組み・構築・ベクトルDB選定までの2026年実装マップ をご覧ください。
- liteparseはLlamaIndexチームがRustで書き直したローカル実行のドキュメントパーサ。Apache-2.0で、PDFを中心にテキストとレイアウトを高速抽出する
- v2.0のグリッド射影アルゴリズムはMLモデルを使わず、文字を等幅グリッドに射影して段組みや表の整列を保つ。小さい文書で最大100倍、457ページ100MBを0.777秒で処理
- 速度・ローカル・GPU不要がエージェントや実時間RAGに刺さる一方、見出し・表をセマンティックに識別する構造化Markdownは生成しない。Docling・LlamaParseとの役割分担を理解して使う
30秒で理解するliteparse
liteparseは、LlamaIndexチームが開発したRust製のドキュメントパーサだ。RAGやAIエージェントの前処理を「速く・軽く」回すことだけに焦点を絞っている。まず要点を押さえる。
・liteparseはLlamaIndexチームが開発したRust製の高速ドキュメントパーサで、ライセンスはApache-2.0
・PDFをネイティブに解析し、Office(DOCX/XLSX/PPTX)や画像は変換を経て取り込む。出力はレイアウト保持テキスト・bbox付きJSON・スクリーンショット
・GitHubスター数は約9,049★(2026年2月公開から約4か月で到達)。RAG前処理の「遅さ」を正面から解きにきた
・v2.0でTypeScript実装からRustへ全面書き換え。小さい文書で最大100倍、大きい文書で約3倍の高速化を公称
・MLモデルを一切使わないモデル非依存設計で、クラウド送信もGPUも不要
商用APIに依存せず、ローカルで完結する前処理パイプラインを組みたい開発者に直撃する。ただし「何でも構造化Markdownにする万能ツール」ではない点を最初に押さえておきたい。本記事は公式リポジトリとLlamaIndexの技術ブログを一次ソースに、できることと限界を分けて整理する。
なぜRAG前処理のパーサが重要か
RAGの検索精度は、ベクトルDBやリランカーを磨く前に、そもそも「文書から何をどう抜き出したか」で大きく決まる。PDFやOfficeから取り出したテキストの段組みが崩れ、表のセルがぐちゃぐちゃに連結されていれば、どれだけ高性能な埋め込みモデルを使っても検索のヒット率は上がらない。前処理は地味だが、RAGの土台そのものだ。
もう一つの軸が速度である。AIエージェントが文書を読みながら推論を進める実時間パイプラインでは、パースに数秒〜数十秒かかると、その間エージェントは待たされ、タイムアウトやコスト増を招く。LlamaIndexは公式ブログで「人気のドキュメントパーサの多くは、速いが不正確(例:pypdf)か、VLM依存で高精度だが遅く・クラウドホスト・ローカルGPUを要する」と整理し、その中間が抜けていると指摘する。liteparseはこの空白、すなわち「ローカルで速く、構造をそこそこ保つ」帯域を狙って設計されている。
文書解析をRAGに組み込む発想は、Officeファイルを構文木で扱う officeParser入門:Node.jsでdocx・xlsx・pptxをAST解析してRAGパイプラインに組み込む でも掘り下げている。非構造テキストからの構造化抽出という観点では Google LangExtract完全ガイド:LLMで非構造テキストから構造化抽出、ソース位置も追跡 が補完になる。liteparseはこれらより一段手前、「生の文書をまず使えるテキストにする」レイヤーを担う。
表のセル結合が壊れると、数値とラベルの対応が崩れて誤った文脈がLLMに渡る。段組みが連結されると、左カラムの末尾と右カラムの先頭が一文として埋め込まれ、意味のないチャンクが量産される。liteparseが「構造を保ったテキスト」にこだわるのは、この下流コストを抑えるためだ。
liteparseの設計とRustを選んだ理由
liteparseはv2.0で、もともとのTypeScript/Node実装からRustへ全面的に書き換えられた。きっかけは多言語対応の要望だった。CLIを各言語からラップしてもNodeへのハードな依存は外せず、TypeScriptをバイナリにコンパイルしようとしても複雑なシステム依存で行き詰まった。そこでチームは「Rustを選び、作業に取りかかった」という。
Rust採用の狙いは三つに集約できる。Nodeランタイム非依存のネイティブバイナリにできること、メモリ安全を保ちながらC級の速度を出せること、そして並列処理を安全に書けることだ。結果としてliteparseは、単一のRustコア(liteparseクレート)から各言語バインディングを生やす構成になった。
・Rustコア(liteparseクレート)— 解析ロジックの本体
・Pythonバインディング(PyO3)— pip install liteparse
・Node/TypeScriptバインディング(napi-rs)— npm i @llamaindex/liteparse
・WASMバインディング(wasm-bindgen)— ブラウザ内で実行
PDFの実体テキスト抽出にはPDFiumを、OCRにはTesseractを利用する。下図はliteparseがファイルを受け取ってから出力するまでの流れだ。
PDF / Office / 画像] --> B{形式判定} B -->|PDF| C[PDFiumで
テキスト+座標抽出] B -->|Office| D[LibreOfficeで
PDFへ変換] B -->|画像| E[ImageMagickで
PDFへ変換] D --> C E --> C C --> F{テキスト層あり?} F -->|あり| G[グリッド射影
アルゴリズム] F -->|なし/スキャン| H[Tesseract / 外部OCR] H --> G G --> I[構造化中間表現
行・アンカー・グリッド] I --> J[出力] J --> K[レイアウト保持テキスト] J --> L[bbox付きJSON] J --> M[ページPNGスクショ]
ここで中核を担うのが、v2.0の目玉である「グリッド射影(grid projection)アルゴリズム」だ。
グリッド射影アルゴリズムの仕組み
PDFのテキスト抽出には、大きく分けて三つのアプローチがある。liteparseはそのどれとも違う第三の道を選んだ。
・素朴な連結(pypdf型):左上から右下へテキストをただ連結する。実装は簡単だが、段組み構造を破壊し整列情報を完全に失う
・MLレイアウト解析(Docling / Markitdown型):表・段組み・見出しを意味的に検出する。精度は高いが計算コストが大きく、モデルのダウンロードと推論が必要
・グリッド射影(liteparse):テキストが「何であるか」を分類せず、「どこにあるか」を等幅文字グリッド上に再現し、整列で構造を保つ
liteparseは文字を等幅(モノスペース)の文字グリッドに射影することで、意味理解に頼らず位置の整列だけで段組みや表を保持する。処理は概ね6ステップで進む。
・ステップ1 座標グルーピング:似たY座標のテキストを1行にまとめる。許容幅はtolerance = max(medianHeight * 0.5, 5.0)で、文字高の中央値から動的に決める
・ステップ2 アンカー抽出:繰り返し現れるX位置(列の先頭・余白・右端)を整列アンカーとして検出。PDFの座標誤差を吸収するため「最も近い1/4単位」に丸める
・ステップ3 スナップ分類:各テキストを左・右・中央のどのアンカーに属するか分類。競合は「最も多くの要素が共有するアンカー」を選んで解決
・ステップ4 流し込みテキスト検出:その塊が表ではなく段落本文なら、グリッド射影を回避してスペース連結に切り替え、不要なアーティファクトを防ぐ
・ステップ5 グリッド射影(中核):gridColumn = round(pdfX / medianCharWidth)で各要素をグリッド列に対応づける。前方アンカー(forward anchor)が肝で、ある要素が列Nに描画されると、その位置が以降の行へ制約として伝播し、複数行にまたがる表の列整列を維持する
・ステップ6 後処理:疎なブロックの間隔圧縮、余白除去、アーティファクト除去で仕上げる
LlamaIndexの解説では、見出し「Score」が列13に置かれると「前方アンカーがそれを列13に固定する」と説明される。一度確定した列位置が下方向の行に制約として効くため、ML推論なしでも複数行の表構造や多段組みが自然に保たれる。これがグリッド射影の発明点だ。
この設計のトレードオフは明快だ。liteparseは「これは表だ」「これは見出しだ」というセマンティックなラベル付けはしない。あくまで空間配置を文字グリッド上に再現するだけだ。だからこそ高速・軽量で、モデルもGPUも要らない。逆に、見出し階層やセル境界を明示的に構造化したいなら、別レイヤーの処理が必要になる。
ベンチマークと公称数値の読み方
liteparse v2.0が掲げる性能数値を整理する。いずれもLlamaIndexの公式ブログに記載された値で、本記事で独自に再実測したものではない。
| 指標 | 公称値 | 出典・前提 |
|---|---|---|
| 小さい文書の高速化 | v1比 最大100倍(5〜100倍) | Rust書き換え前後の比較。LlamaIndex公式ブログの記載値 |
| 大きい文書の高速化 | v1比 約3倍 | 同上 |
| 大規模PDFの処理時間 | 457ページ・100MBを0.777秒 | LlamaIndex公式ブログの計測値 |
| モデルダウンロード | 不要(0バイト) | モデル非依存設計のため |
| 精度の比較対象 | pypdf / pymupdf / markitdown / pdftotext / opendataloader / pymupdf4llm | いずれもモデル非依存パーサ |
ここで重要なのは、liteparseは意図的にVLM系ツール(LlamaParseやDocling)とは精度を比較していない点だ。LlamaIndexは「より基本的なライブラリ(pypdf・pymupdf・markitdown)と比較している」と明言している。つまりliteparseの土俵は「モデルを使わない軽量パーサの中で、最も速く・最も整列を保つ」ことであって、VLMが得意とする密な表・手書き・スキャン文書の高精度解析とは別の競技だ。
「最大100倍」はv1からの相対値であり、すべての文書で100倍速くなるわけではない。大きい文書では約3倍が目安だ。また精度比較の対象はモデル非依存パーサに限られる。VLMベースのDoclingやLlamaParseより「精度が高い」とは主張していないため、複雑文書の精度を期待して導入すると評価を見誤る。用途に合わせて土俵を見極めたい。
対応ファイル形式と出力
liteparseはPDFをネイティブに扱い、それ以外は変換を経てPDFパースに合流させる構成だ。ブランド名の印象とは違い、HTMLやMarkdownを直接の入力形式としては掲げていない点に注意したい。
・入力(ネイティブ):PDF(PDFiumでテキスト+座標を抽出。スキャンページは自動でOCRへフォールバック)
・入力(変換経由・Office):DOC/DOCX/DOCM/ODT/RTF/PPT/PPTX/PPTM/ODP/XLS/XLSX/XLSM/ODS/CSV/TSV など(LibreOfficeで一旦PDF化)
・入力(変換経由・画像):JPG/PNG/GIF/BMP/TIFF/WEBP/SVG など(ImageMagickで一旦PDF化)
・出力1:レイアウト保持のプレーンテキスト(段組み・表の整列を等幅グリッドで再現)
・出力2:bbox(バウンディングボックス)付きの構造化JSON(各テキストの座標・幅・高さ)
・出力3:ページのPNGスクリーンショット(LLMエージェントの視覚推論用フォールバック)
このスクリーンショット出力が、liteparseの「速さ優先」哲学をよく表している。まずテキストを高速に抜いて理解を試み、それでは足りない視覚的な情報が必要になったときだけ、ページ画像をLLMに渡して深く読ませる——という二段構えを前提にしている。
ローカル実行手順
ここからは実際にPythonで動かす手順を見ていく。インストールは1コマンドで、モデルのダウンロードは発生しない。
pip install liteparse
最小のPDF解析。parse()の戻り値からテキストとページ情報を取り出せる。
from liteparse import LiteParse
parser = LiteParse()
result = parser.parse("document.pdf")
print(result.text)
for page in result.pages:
print(f"Page {page.page_num}: {len(page.text_items)} text items")
bbox(座標情報)が欲しい場合や、OCR・ページ範囲・パスワードを制御する場合はコンストラクタにオプションを渡す。
parser = LiteParse(
ocr_enabled=True,
ocr_server_url="http://localhost:8828/ocr",
ocr_language="jpn", # 日本語スキャンPDFはjpnを指定
dpi=300,
target_pages="1-5", # ページ範囲を絞って高速化
password="secret", # 暗号化PDF
)
result = parser.parse("document.pdf")
ファイルパスの代わりにバイト列を直接渡すこともできる。アップロードされたPDFをディスクに書かずに処理したいときに便利だ。
with open("document.pdf", "rb") as f:
pdf_bytes = f.read()
result = parser.parse(pdf_bytes)
print(result.text)
テキスト抽出では足りず、視覚的にページを見せたいときはスクリーンショットを生成する。
screenshots = parser.screenshot("document.pdf", page_numbers=[1, 2, 3])
for s in screenshots:
print(f"Page {s.page_num}: {s.width}x{s.height}")
CLIも揃っている。大量PDFの一括処理やJSON出力はコマンド一発で済む。
lit parse document.pdf # テキストを標準出力
lit parse document.pdf --format json -o output.json # bbox付きJSONを保存
lit parse document.pdf --target-pages "1-5,10,15-20"
lit parse document.pdf --no-ocr # OCRを無効化して高速化
lit batch-parse ./input-directory ./output-directory
lit screenshot document.pdf --dpi 300 -o ./screenshots
LangChainやLlamaIndexと組み合わせる場合は、liteparseで抽出したテキストを各フレームワークのDocumentに包んでチャンク分割→埋め込みへ流すのが基本形になる。liteparseはあくまでテキスト化の段を担い、チャンク戦略や検索は下流のフレームワークに委ねる役割分担だ。
競合との比較表
liteparseと主要なドキュメントパーサを並べる。スター数は確認できた範囲のみ記載し、不明な箇所は「—」とした。
| ツール | コア言語 | 方式 | モデル/GPU | 主な出力 | ライセンス | 位置づけ |
|---|---|---|---|---|---|---|
| liteparse | Rust | グリッド射影(モデル非依存) | 不要 | レイアウト保持テキスト / bbox付きJSON / PNG | Apache-2.0 | ローカル・実時間・エージェント前処理 |
| markitdown | Python | 形式変換中心(モデル非依存) | 不要 | Markdown | MIT | 多形式をLLM投入用Markdownに |
| Docling | Python | MLレイアウト解析 | モデルDL(1〜2GB) | DoclingDocument / Markdown | MIT | 高精度な構造化、自己ホストRAG |
| Unstructured | Python | 要素分類 | 一部モデル/クラウドAPI | 意味ラベル付き要素 | Apache-2.0(オープンコア) | 要素種別フィルタ前処理 |
| PyMuPDF | C / Python | 高速テキスト抽出(モデル非依存) | 不要 | テキスト / 画像 | AGPL-3.0 / 商用 | 高速だが整列は連結寄り、ライセンス注意 |
読み解きのポイントを補足する。markitdownは多形式を手軽にMarkdown化できるが、段組みや表の空間整列はliteparseほど作り込まない。Doclingは表・見出しのセマンティック検出で品質が高い一方、初回に大きなモデルをダウンロードし、軽量サーバーレスには不向きだ。Unstructuredは「Title・Table・ListItem」のような要素ラベルが強みだが、クラウドAPI前提の機能もあり実時間エージェントには重い。PyMuPDFは非常に速いがAGPLというライセンス上の制約があり、商用組み込みでは要確認だ。liteparseはこの中で「Rust製・モデル非依存・Apache-2.0・整列保持」という組み合わせが独自の立ち位置になる。
RAGパイプライン統合パターン
liteparseを実際のRAGに組み込むとき、典型的には次の三つのパターンに落ち着く。
・パターン1:liteparse → チャンク分割 → ベクトルDB:最も標準的。liteparseで段組みを保ったテキストを得て、見出しや空行を手掛かりにチャンク分割し、埋め込みベクトルをDBへ。前処理が速いので大量文書の初期インデックス構築が短時間で済む
・パターン2:liteparse → LlamaIndex → クエリエンジン:抽出テキストをLlamaIndexのDocumentに変換し、ノードパーサと検索を任せる。同じLlamaIndexエコシステム内なので接続が素直
・パターン3:liteparse → 直接LLMコンテキスト:短い文書なら、抽出テキストをそのままLLMのコンテキストへ。テキストで足りなければスクリーンショットを添えて視覚推論にフォールバックする二段構え
このうちパターン3は、liteparseが「速くテキスト化し、ダメなら画像」という思想で作られていることをそのまま活かす形だ。LlamaIndexはこれを「速い理解のためにテキストを解析し、より深い視覚推論が必要なときはスクリーンショットにフォールバックする」と表現している。
ユースケース
大量PDFの社内ナレッジRAG
数千〜数万のPDFを抱える社内ナレッジベースでは、インデックス構築時間がそのまま運用コストになる。liteparseはモデルダウンロードもGPUも不要でlit batch-parseによる一括処理ができるため、CIやバッチジョブで定期的に再インデックスする運用に向く。段組みを保ったテキストが得られるので、表を多用する仕様書・マニュアルでも検索のヒット率を保ちやすい。
法務文書の解析
契約書や約款は、条項番号・インデント・表で構造を持つ文書が多い。グリッド射影は条項のインデントや番号の整列を保つため、条文単位のチャンク分割と相性がよい。ただし押印・手書き注記・複雑な別表が絡む場合はOCRや別ツールの併用が前提になる。契約レビューのワークフロー設計そのものは別記事で扱っている領域だが、前処理の段をliteparseが担えるイメージだ。
学術論文の構造化
論文PDFは二段組みが標準で、素朴な連結だと左右のカラムが混ざって意味が壊れる。グリッド射影は多段組みの整列を保つため、本文・参考文献・図表キャプションを比較的きれいに分離できる。一方で数式・化学式・複雑な図は構造保持の限界に当たりやすく、その箇所はスクリーンショット出力でLLMに視覚的に渡すのが現実的だ。
議事録からの自動要約
会議の議事録やレポートをエージェントが読みながら要約・アクション抽出する実時間ワークフローでは、パース速度が体感を左右する。liteparseはローカルで瞬時にテキスト化できるため、エージェントが待たされずに推論へ進める。オープンウェイトのローカルLLMと組み合わせれば、文書を一切クラウドに出さずに要約パイプラインを完結させることもできる。ローカル実行のモデル選定は MiniMax M3|SWE-Bench Pro 59.0%のオープンウェイトモデルをMSAアーキ・1M文脈で読み解く も参考になる。
よくある落とし穴
liteparseは万能ではない。導入前に押さえておきたい限界を挙げる。
・OCRが必要な紙面PDFは別ツール併用が前提:標準Tesseractは動くが、密な紙面や手書きはliteparseの守備範囲外。LlamaIndex自身も「密な表・多段組み・チャート・手書き・スキャンPDFはLlamaParseを検討せよ」と案内している
・テーブル品質はソース次第:グリッド射影は整列を保つが、元PDFのセル境界情報が壊れていれば復元には限界がある。崩れた表は下流で再整形が要る
・複雑レイアウトの構造保持には限界:雑誌・科学誌のような自由レイアウトでは、回り込みや重なりで整列が崩れることがある。そうした箇所はスクリーンショット出力に切り替える
・セマンティック構造は出力しない:liteparseは見出し・表・セクションを識別した構造化Markdownを生成しない。ヘッダー階層やセル境界が必要なら、DoclingやLlamaParse、あるいは後段の処理を足す
・Rustバイナリのプラットフォーム互換:各言語バインディングはRustコアをビルドする。Linux/macOS(Intel/ARM)/Windowsをサポートするが、特殊な環境やコンテナではビルド・実行要件を事前に確認したい
liteparseの強みは、モデルを捨てて空間整列に振り切ったことで得た速度と軽さだ。その代償として、意味理解が要る高難度文書はカバーしない。複雑文書はLlamaParseやDocling、軽量・実時間はliteparse、という棲み分けを最初に決めておくと、評価のミスマッチを避けられる。
FAQ
Q. liteparseとmarkitdownはどちらを使うべき? 速度・ローカル実行・空間レイアウト/bboxの保持を重視するならliteparse。多形式を手軽にMarkdown化してLLMに流すだけならmarkitdownでも十分。セマンティックな構造化MarkdownはDoclingやLlamaParse。
Q. OCR機能はある? 標準Tesseract内蔵で、スキャンPDFは自動フォールバック。PaddleOCR/EasyOCRのHTTPサーバ接続や独自実装も可。複雑紙面は別ツール併用が前提。
Q. 商用利用OK? 本体はApache-2.0で商用可。外部OCRエンジンを足す場合は各依存のライセンスを確認。
Q. 日本語PDFの精度は?
テキスト埋め込み済みPDFは文字コードが正しければ良好。スキャンは--ocr-language jpnで対応。縦書き・複雑レイアウトは限界あり。
Q. 並列・バッチ処理は?
lit batch-parseでディレクトリ一括。Rustコアで高速、GPU・モデルDL不要。
Q. ストリーミングパースは?
明示APIは未公開だが--target-pagesでページ範囲指定が可能。大規模は分割処理が実用的。
Q. メモリ消費の上限は? 457ページ100MBを0.777秒の軽量設計。Doclingのような1〜2GBのモデルDLは不要で、サーバーレス/エッジでも動かしやすい。
まとめ
liteparseは、RAG前処理の「速さ」と「ローカル完結」に振り切ったRust製パーサだ。v2.0のグリッド射影アルゴリズムは、MLモデルを使わずに段組みや表の整列を保つという独自の解を提示し、小さい文書で最大100倍・457ページ100MBを0.777秒という軽快さを実現した。一方で、見出しや表をセマンティックに構造化するVLM系の仕事はあえて担わない。複雑文書はLlamaParseやDocling、実時間・エッジ・大量処理はliteparse——この棲み分けを理解して組み込めば、RAGパイプラインの前処理ボトルネックを確実に軽くできる。RAG全体の設計は RAGとは?仕組み・構築・ベクトルDB選定までの2026年実装マップ と合わせて押さえておきたい。
参照ソース
・run-llama/liteparse — GitHubリポジトリ
・LiteParse: Local Document Parsing for AI Agents — LlamaIndex公式ブログ
・Up to 100x Fast Parsing with LiteParse v2.0 and Rust — LlamaIndex公式ブログ
・How LiteParse Turns PDFs into Text: A Deep Dive into the Grid Projection Algorithm — LlamaIndex公式ブログ
・What is LiteParse? — LlamaIndex Developer Documentation