PyMuPDF4LLMの使い方|PDFをMarkdownへ変換しRAG前処理を実装する【2026年版】
PyMuPDF4LLMは、PDFを1行のコードでMarkdownに変換するPythonライブラリです。RAG(検索拡張生成)やLLMにPDFを読み込ませる前処理で、見出し・表・箇条書きといった文書構造を保ったままテキスト化できるのが特徴です。ネット上には「PyMuPDF4LLMの使い方」としてimport fitz(素のPyMuPDF)とmarkdownifyを組み合わせたコードを載せた記事が少なくありませんが、それはPyMuPDF4LLMを使っていません。正しい入口はpymupdf4llm.to_markdown()のひとつだけです。この記事では最新の1.28.0(2026年6月29日リリース)を基準に、正しいコード・RAG向けのページ単位チャンク・画像抽出・他ツールとの比較・AGPLライセンスの注意までをまとめます。
まとめ
- 正体:PyMuPDF(
fitz)を土台にした高水準ラッパー。PDFの全ページを1本のMarkdown文字列にまとめて返す。 - 導入:
pip install pymupdf4llmだけ。PyMuPDF本体とレイアウト解析用のpymupdf_layoutも自動で入る。Python 3.10以上が必要。 - 基本API:
pymupdf4llm.to_markdown("input.pdf")でMarkdown文字列を取得。markdownifyは不要。 - RAG向け:
page_chunks=Trueでページ単位の辞書リストになり、ページ番号やファイル名を出典情報としてベクトルDBに渡せる。write_images=Trueで画像も抽出できる。 - 最大の注意点:ライセンスはAGPL-3.0(またはArtifexの商用ライセンス)。自社SaaSに組み込むならソース開示義務か商用ライセンス購入かの判断が要る。
- 2024年の情報は古い:現行版はOCRを内蔵し既定で自動実行する(Tesseractプラグイン対応)。「OCR非対応」という古い解説はそのまま信用しない。
PyMuPDF4LLMとは|PyMuPDF(fitz)との違いとRAGでの役割
PyMuPDF4LLMが解決する課題|Markdown一発変換
PDFからテキストを素朴に抜き出すと、見出しも表も段落も区別のない平文になり、どこが章でどこが箇条書きだったのかが失われます。この「構造が消える」問題が、LLMに文書を読ませるうえで精度低下の原因になります。PyMuPDF4LLMは、各ページの本文と表をまとめてGitHub互換のMarkdown文字列として出力します。公式ドキュメントも「PyMuPDF関数の高水準ラッパーであり、各ページの標準テキストと表テキストを統合したMarkdown文字列を全ページにわたって出力する」と説明しています。見出しは#、太字は**、表はパイプ記法という具合に構造がテキスト上に残るため、後段のチャンク分割が構造を手がかりにできます。
PyMuPDF(fitz)・markdownifyとの違い
ここが混同されやすい点です。PyMuPDF4LLMは、PDF描画エンジンであるPyMuPDF(インポート名fitz、現在はpymupdfでも可)の上に載った薄い層です。素のPyMuPDFにもpage.get_text()はありますが、返るのはMarkdown構造を持たない平文で、見出しや表を自分で組み立て直す必要があります。冒頭で触れた「fitzで本文を取り出しmarkdownifyでHTML風に変換する」やり方は、実際にはPyMuPDF4LLMの表検出も見出し推定も使っておらず、表がただの文字列に潰れます。PyMuPDF本体の役割や機能を押さえたい場合はPyMuPDF(fitz)とは|インストールから使い方・ライセンスまでを先に読むと、両者の分担が理解しやすくなります。目的が「LLMに渡すMarkdown化」なら、get_text()を組み合わせるのではなくto_markdown()を直接使うのが正解です。
RAGでMarkdown化が有効な理由|構造保持とチャンク境界
RAGでは、PDFを適切な長さのチャンクに割ってベクトル化し、検索してLLMに渡します。このとき見出しや段落の境界が残っていれば、意味のまとまりを壊さずにチャンクを切れます。逆に平文だと文の途中で機械的に切れ、検索精度が落ちます。Markdownは見出し階層がテキストに残るので、LangChainのMarkdown対応スプリッタなどが構造に沿ってチャンクを作れます。抽出したチャンクを格納する先の選定はベクトルデータベースとグラフデータベースの違い|比較表と使い分け・GraphRAGでの併用が判断材料になります。PyMuPDF4LLMは、この「PDF→構造付きテキスト」という前処理の最初の一手を担います。
PyMuPDF4LLMのインストールと動作要件
導入はpipひとつです。次のコマンドで、PyMuPDF本体とレイアウト解析ライブラリpymupdf_layout(1.27.2.1以降は自動同梱)も含めて入ります。
pip install pymupdf4llm
動作要件はPython 3.10以上です。2026年7月時点の最新は1.28.0(2026年6月29日公開)で、バージョン番号はかつての0.0.x系からPyMuPDFファミリーに合わせた採番に統一されました。WordやPowerPointなどOffice文書を入力にする場合のみ、別途PyMuPDF Proが必要になります。なお後述のLlamaIndex連携を使うならpip install llama-indexは別に必要で、PyMuPDF4LLMには自動で入りません。
to_markdownの基本的な使い方|変換とファイル保存
最小コード|PDFをMarkdown文字列へ
入口の関数はto_markdown()だけです。PDFのパスを渡すと、全ページを結合したMarkdown文字列(str)が返ります。
import pymupdf4llm
md_text = pymupdf4llm.to_markdown("input.pdf")
print(md_text)
これだけで見出しや表を含んだMarkdownが得られます。markdownifyや自前の整形は不要です。特定ページだけ処理したいときはpages=[0, 1, 2]のように0始まりのページ番号リストを渡します。
Markdownファイルへの保存
結果をそのまま.mdファイルに書き出す公式パターンは、pathlibでバイト列として書き込む方法です。日本語を含むPDFでも文字化けしないようencode()で明示的にUTF-8バイト列にします。
import pymupdf4llm
from pathlib import Path
md_text = pymupdf4llm.to_markdown("input.pdf")
Path("output.md").write_bytes(md_text.encode())
主要パラメータ一覧|pages・table_strategy・margins
to_markdown()は多くのキーワード引数を持ちます。実務で使う頻度が高いものを絞って挙げます。全引数は公式APIリファレンスに載っています。
| 引数 | 既定値 | 役割 |
|---|---|---|
| pages | None | 処理対象ページ(0始まりのリスト) |
| page_chunks | False | Trueでページ単位の辞書リストを返す |
| write_images | False | 画像領域をファイル書き出し |
| embed_images | False | 画像をbase64で本文に埋め込み |
| image_path | 空文字 | 画像の保存先フォルダ |
| dpi | 150 | 抽出画像の解像度 |
| table_strategy | lines_strict | 表検出の方式 |
| margins | 0 | 処理する版面の余白範囲 |
| use_ocr | True | テキスト層が無いページの自動OCR |
| show_progress | False | 進捗バー表示 |
迷ったらpagesで範囲を絞り、表が崩れるならtable_strategyを切り替える、という2つを最初に覚えておけば十分です。
RAG向けの応用|ページ単位チャンクと画像・表の抽出
page_chunksでページ単位の辞書リストを取得
RAGで効くのがpage_chunks=Trueです。返り値が1ページ1辞書のリストになり、各辞書はmetadata(page_numberやfile_pathを含む)・toc_items・tables・images・text(そのページのMarkdown)といったキーを持ちます。ここで注意したいのが番号の基準で、入力のpagesは0始まりですが、出力のpage_numberは1始まりです。両者を取り違えると出典のページがずれます。ページ番号とファイル名をそのまま出典メタデータとしてベクトルDBに保存すれば、生成結果に「何ページ由来か」を添えられます。
import pymupdf4llm
chunks = pymupdf4llm.to_markdown("input.pdf", page_chunks=True, show_progress=True)
for ch in chunks:
page_no = ch["metadata"]["page_number"]
source = ch["metadata"]["file_path"]
text = ch["text"]
# page_no と source を出典として付け、text をベクトルDBへ登録する
1ページが長い文書では、このtextをさらにMarkdown対応スプリッタで見出し単位に割ると精度が上がります。
画像抽出でマルチモーダルRAGに対応
図表を画像として扱いたいマルチモーダルRAGでは、write_images=Trueで画像領域をPNGとして書き出し、Markdown中に画像参照を挿入できます。保存先はimage_path、解像度はdpiで指定します。
import pymupdf4llm
md_text = pymupdf4llm.to_markdown(
"input.pdf",
write_images=True,
image_path="images",
dpi=200,
)
ファイルを増やしたくない場合はembed_images=Trueで画像をbase64として本文に直接埋め込めますが、出力サイズが大きく膨らむため、埋め込みは単一ファイルで完結させたいときに限るのが現実的です。
表のMarkdown変換と精度確認
表は既定のtable_strategy="lines_strict"で自動検出され、罫線で区切られた素直な表はパイプ記法のMarkdown表にきれいに変換されます。一方、セル結合や罫線の無い表は列がずれたり潰れたりしがちです。崩れたときはtable_strategy="lines"(すべての罫線ベクトルを使う)や"text"(テキストの整列で判定)に切り替えて出力を見比べてください。表を含むPDFでは、変換後に必ず該当ページのMarkdownを目視確認し、崩れた表だけ手で直す運用が確実です。
LlamaIndex連携|LlamaMarkdownReader
LlamaIndexを使うなら、専用のリーダーLlamaMarkdownReaderが用意されています。load_data()はページごとにLlamaIndexのDocumentオブジェクトを返すので、そのままインデックス構築に流せます。内部ではto_markdown()が呼ばれています。
import pymupdf4llm
reader = pymupdf4llm.LlamaMarkdownReader()
docs = reader.load_data("input.pdf")
for doc in docs:
print(doc.text)
前述のとおりLlamaIndex本体は別インストールが必要です。抽出したMarkdownをどうチャンク分割し検索につなぐかというRAGフレームワークの考え方は、言語は異なりますがLangChain.jsとは?その概要と特徴で概念を押さえられます。
他のPDF→Markdown変換ツールとの比較
PDFをMarkdown化するツールはPyMuPDF4LLMだけではありません。速度重視か、複雑レイアウトの精度重視かで選ぶツールが変わります。主要な選択肢を整理します。
| ツール | 概要 | ライセンス | PyMuPDF4LLMとの違い |
|---|---|---|---|
| PyMuPDF get_text() | 同じエンジンの平文抽出 | AGPL-3.0 | 最速だがMarkdown構造なし |
| markitdown | Microsoft製の多形式変換 | MIT | 非常に速いが表の構造再現は弱め |
| marker | 深層学習のレイアウト解析 | GPL(商用は別途) | 複雑・スキャンに強いが低速でGPU前提 |
| docling | IBM製の構造保持パーサ | MIT | 意味構造は最強だが重く遅い |
| unstructured | 汎用の文書分割ツール | Apache-2.0 | 対応形式が広いが依存が重い |
| pdfplumber | 純Pythonの精密抽出 | MIT | 単純な表に強いがMarkdown出力なし |
選び分けの結論を言い切ります。ネイティブPDF(デジタル生成のPDF)を大量に速く処理したいならPyMuPDF4LLMが第一候補です。表・見出しの検出とページ単位チャンクが揃い、GPUも要りません。逆に、スキャン主体で複雑な段組みや結合セルの表が多い文書では、精度優先でmarkerやdoclingを選ぶべきで、ここでPyMuPDF4LLMに固執すると表崩れの手直しコストが逆に増えます。さらに後述のAGPLライセンスが自社の配布形態と合わない場合は、速度が魅力でも採用を見送り、MITライセンスのmarkitdownなどに切り替える判断が要ります。速度・精度・ライセンスの3点で、PDFの性質に合わせて使い分けるのが実務解です。
つまずきやすいポイントと商用利用の注意
スキャンPDFのOCR|自動OCRとTesseract・日本語対応
「PyMuPDF4LLMはOCRができない」という解説は2024年頃の古い情報です。現行版はuse_ocr=Trueが既定で、テキスト層を持たないページにだけ自動でOCRを走らせます(テキスト層のあるページは飛ばすため無駄がありません)。1.27.2.2でOCR周りが刷新され、Tesseract-OCRがプラグインとして正式対応しました。したがってプラグイン経路を使うにはTesseract本体のインストールが前提になります。ただしTesseractの日本語認識は文書の質によって精度が振れます。日本語のスキャン文書で精度が出ないときは、変換前に日本語特化のOCRでテキスト層を付与しておくと安定します。ブラウザで試せる選択肢としてNDLOCR-Lite Webの使い方と精度・商用利用が参考になります。
多段組・複雑な表・暗号化PDFの対処
多段組みはpymupdf_layoutのレイアウト解析(1.27.2.1以降は自動同梱)で処理されますが、段が密で不規則な誌面では読み順が乱れることがあります。段組みの激しいPDFでは、変換後に本文の並び順を必ず確認してください。パスワード付きの暗号化PDFは、先にPyMuPDFで開いてdoc.authenticate(password)で復号し、そのDocumentオブジェクトをto_markdown(doc)に渡せば処理できます。巨大なPDFでpage_chunks=Trueを使うとリスト全体がメモリに載るため、pagesで範囲を区切って逐次処理するとメモリを抑えられます。
AGPLライセンスと商用利用
採用前に必ず確認すべきなのがライセンスです。PyMuPDF4LLMはAGPL-3.0とArtifexの商用ライセンスのデュアルライセンスです。AGPL-3.0は強いコピーレフトで、ネットワーク越しに提供するサービス(SaaS)に組み込んだ場合でも利用者にソースコード開示義務が及びます。ソースを公開できないクローズドな商用プロダクトに組み込むなら、Artifexから商用ライセンスを購入する必要があります。社内の一時的なバッチ処理などクローズドな配布を伴わない用途なら影響は小さいですが、プロダクトに同梱する前提なら法務確認は省略しないでください。ライセンス条項の詳細はPyMuPDF本体と共通のため、PyMuPDF(fitz)のライセンス解説も併せて確認すると判断が固まります。
よくある質問
PyMuPDFの読み方は?
「パイミューピーディーエフ」と読みます。PyはPython、MuPDFは土台となっているC言語製PDFライブラリのMuPDFを指します。PyMuPDF4LLMはその後ろに「for LLM」の意味で4LLMが付いた名称で、「パイミューピーディーエフ・フォー・エルエルエム」となります。
PyMuPDF4LLMとPyMuPDFの違いは?
PyMuPDFはPDFを開いて描画・編集・テキスト抽出まで行う土台のライブラリで、インポート名はfitzです。PyMuPDF4LLMはその上に載る薄いラッパーで、機能は基本的にto_markdown()によるMarkdown化に特化しています。PDFを細かく操作したいならPyMuPDF、LLMに渡すMarkdownが欲しいだけならPyMuPDF4LLM、という住み分けです。
pip install pymupdf4llmで何がインストールされますか?
PyMuPDF4LLM本体に加え、依存するPyMuPDF本体と、1.27.2.1以降はレイアウト解析用のpymupdf_layoutも自動で入ります。追加でmarkdownifyなどを入れる必要はありません。ただしLlamaIndex連携を使う場合のllama-indexは別途インストールが必要です。
PyMuPDF4LLMはOCRに対応していますか?
対応しています。現行版はuse_ocr=Trueが既定で、テキスト層の無いスキャンページにだけ自動でOCRを実行します。1.27.2.2からTesseract-OCRがプラグイン対応したため、プラグイン経路を使うにはTesseractのインストールが必要です。日本語スキャン文書で精度が不足する場合は、日本語特化OCRで事前にテキスト層を付ける方法が有効です。
PyMuPDF4LLMは無料で商用利用できますか?
ライセンスはAGPL-3.0またはArtifexの商用ライセンスです。AGPL-3.0の条件(SaaSを含めたソース開示義務)を守れば無料で使えますが、ソースを公開できない商用プロダクトに組み込むなら商用ライセンスの購入が必要になります。配布形態によって扱いが変わるため、プロダクト同梱前に法務確認をおすすめします。