【MLX】DeepSeekOCRをMac(Apple Silicon)でサクッと実行する
はじめに
DeepSeekOCR は大規模言語モデル DeepSeek-VL をベースにしたマルチモーダル OCR です。本来はトークン圧縮を狙った研究成果ですが、今回はその OCR 性能にフォーカスし、純粋な文字起こしシステムとしての実力を検証します。
Apple Silicon + MLX 版が公開されたおかげで、GPU を積んだ Linux マシンがなくてもローカルでサクッと試せるようになりました。本記事では、Mac (Apple Silicon) でのセットアップから実行時の注意点までをまとめます。
DeepSeekOCR とは
DeepSeekOCR は画像の文脈を理解した上でテキスト化する OCR モデルです。複数言語に対応しており、表形式や吹き出しのようなレイアウトでも精度の高い出力が得られます。特に漢字やかな混じりの文章で誤変換が少なく、後段の翻訳や要約と組み合わせやすいのが特徴です。
MLX 版モデルの入手先
MLX コミュニティが提供している 8bit 量子化モデルが Hugging Face で公開されています。
モデルとプロセッサ、設定ファイルがまとめて配布されているので、mlx_vlm のユーティリティ関数で読み込むだけで実行できます。
実行環境
- MacBook Pro / Apple M1 Pro
- メモリ 32 GB
- Python 3.10 +
mlx/mlx-vlm
32GBのPCを使ってはいますが、今回の常駐メモリはおおよそ 6 GB 程度でしたので、もう少しメモリ少ないMacでも行けると思います。
セットアップ手順
- Homebrew 等で Python 環境を用意した後、
pip install -U mlx-vlmを実行。 -
python -m pip show mlx-vlmなどでバージョンが 0.3.5 以上であることを確認。 - 画像ファイル (PNG/JPG) を実行ディレクトリに置き、後述のスクリプトにパスを渡して実行。
公式のサンプルコード
mlx_vlm 付属のユーティリティを使うと、チャットテンプレートや画像枚数を意識した入力整形を自動で行ってくれます。公式ドキュメントで紹介されている以下の CLI コマンドは画像の説明文を生成する用途のため、文字起こしは行われません。
python -m mlx_vlm.generate \
--model mlx-community/DeepSeek-OCR-8bit \
--max-tokens 100 \
--temperature 0.0 \
--prompt "Describe this image." \
--image <path_to_image>
今回検証で使ったコード
適切にチャットテンプレートを指定し、プロンプトを文字起こし用に調整しています。
日本語のプロンプトでは上手くいかなかったので、読み込む文書は日本語でもプロンプト自体は英語で書く必要があるように思われます。
from mlx_vlm import load, generate
from mlx_vlm.prompt_utils import apply_chat_template
from mlx_vlm.utils import load_config
model_path = "mlx-community/DeepSeek-OCR-8bit"
model, processor = load(model_path)
config = load_config(model_path)
images = ["<path_to_image>"]
prompt = "Output the text contained in this image in Japanese."
# 画像枚数に合わせてテンプレート整形(必須)
formatted = apply_chat_template(processor, config, prompt, num_images=len(images))
out = generate(
model, processor, formatted, images,
max_tokens=3000, temperature=0.0, verbose=False
)
# ---- GenerationResult.text のみ取得 ----
if isinstance(out, list):
pure_text = out[0].text
else:
pure_text = out.text
print(pure_text)
max_tokens は短すぎると文章が途中で切れるのである程度の量を設定してください。
文字サイズによる読み取り精度評価
ページ全体を1024×1024pxに正規化し、本文1文字 ≒ 20×20px を基準サイズとした上で縮小率ごとの精度を比較しました(タイトルや見出しはこの基準よりやや大きめ)。
1枚あたりの処理時間は常に約5秒、文字数は1,200字前後です。
- 100% サイズ: 精度 92.57%。前半は問題なく読めた一方、なぜか最終段落が丸ごと欠落して満点に届かず。
- 50% サイズ: 精度 96.43%。段落欠落は解消。ただし「自然科学会席上の講義」が「自然科学研究会の講義」になるなど固有名詞で微妙な揺れが発生。
- 40% サイズ: 精度 95.40%。挙動は 50% とほぼ同じ。
- 30% サイズ: 精度 94.63%。こちらも 50% と同等の傾向。
- 20% サイズ: 精度 1.62%。タイトルくらいは読み取れますが、それ以降は妄想の文章が出力されました。
余白を足してみる
最終段落が切れるのを防ぎたかったので本文だけを 50% まで縮小したうえで、1024×1024px のキャンバスに余白を整えながら貼り直してみました。
これだけで精度は 99.28% まで向上し、欠落していた段落問題も解消したので、書類をスキャンして読み込む場合は余白を足したほうが良さそうです。
実際に使った画像
基準となる 100% 画像、余白を整えた 50% 画像、30% 画像を以下に掲載します。
追記:ダークテーマでない場合背景と同化して余白が分かりづらいです。。すみません。
100%(原寸)

50% + 余白調整

30%

結果まとめ
DeepSeekOCR の精度は文字サイズだけでなく余白の取り方にも大きく左右されます。本文を一定サイズ以上に保ちつつ適切な余白を与えるだけで、処理時間(約 5 秒)を変えずに精度を底上げ可能です。とくに上下左右に余白が少ない冊子スキャンでは、余白をあらかじめ付けて読ませた方が良いかもしれないです。
まとめ
- MLX 版 DeepSeekOCR は Apple Silicon だけで数十トークン/秒の速度で動作し、実務レベルの OCR が可能。
- 入力画像の解像度を変えてもあまり処理速度に変化はない。
- 本文を 50% 程度まで縮小しても、余白を整えてから推論すれば 99% 近い精度で読めるため、1024px のまま維持する必要はない。
ローカルで OCR を完結できると情報漏えいの心配も減るので、社内資料の転記や翻訳にも使いやすいです。ぜひ試してみてください。
今回は精度比較のために青空文庫からドキュメントをお借りしました。出典:青空文庫(www.aozora.gr.jp)/アルベルト・アインシュタイン「相対性理論」石原純訳。
Discussion