ローカルVLM(視覚言語モデル)の速度比較記事はいくつもあるが、載っているMacはM4 ProやM4/M5 Maxばかりで、M1 Max 64GBの実測行は1本も見当たらない。手元にちょうどQwen2.5-VL 7Bが入っていたので、OCR(画像→テキスト書き起こし)タスクで実際に測った。結論から書くと、出力速度は画像の内容にほぼ関係なく23.4〜26.0 tok/sの狭い帯に収まった。速度を決めていたのは画像の複雑さではなく、書き起こす文章の長さだった。
検証環境と方法
ハード: M1 Max 64GB
Ollama: 0.30.8(
ollama --version実測)モデル:
qwen2.5vl:7b(6.0GB、2026-07-24に追加済)。ollama show実測では architecture=qwen25vl / parameters=8.3B(タグ名は7bだが、視覚エンコーダを含めた実パラメータは8.3B) / quantization=Q4_K_M推論バックエンド: サーバーログの
srv/slot/clip_model_loader形式から llama.cpp系のGGUFランタイム(MLXではない)
テスト画像は外部から拾わず、HTML→ヘッドレスChromeのスクリーンショットで自作した3種類。
画像サイズ内容
test_a900×620ターミナルのエラー画面(英語コード、612字相当)
test_b900×620和文契約書調の密文(356字、句読点の多い長文)
test_c420×420レシート(品目と金額、数字中心の構造化データ)
実行前に自社のgpucheck.shでGPUがアイドルであることを確認し、Ollamaの/api/generate(stream:false)を4回叩いた。
run1_cold_a : 初回(モデル未ロードの状態からtest_a)
run2_warm_a : 直後にtest_aを再送(画像・プロンプトとも完全一致)
run3_warm_b : test_b(新規画像)
run4_warm_c : test_c(新規画像)
レスポンスJSONのeval_count/eval_duration/prompt_eval_count/prompt_eval_duration/load_durationを取り、~/.ollama/logs/server.logのslot print_timing行と突合して一致を確認した(二重検証)。
結果: 出力速度は画像の内容にほぼ関係なく23.4〜26.0 tok/s
4回の実測内訳。loadはモデル読込、prompt_evalは画像エンコード+プリフィル、evalは出力生成にかかった時間。
run画像totalloadprompt_evaleval(出力)tok/s
run1(cold)test_a17.51s5.05s5.78s(1095tok)6.67s(173tok)25.95
run2(warm・再送)test_a7.65s0.19s0.05s(キャッシュ)7.39s(173tok)23.41
run3(warm)test_b17.11s0.20s5.51s(1095tok)11.37s(273tok)24.01
run4(warm)test_c11.91s0.19s5.77s(1131tok)5.92s(143tok)24.16
異なる画像3枚(run1・run3・run4)のtok/sを平均すると24.71 tok/s((25.95+24.01+24.16)/3)。全4回でも最小23.41〜最大25.95tok/sの幅に収まっており、テキスト主体の英語コード画面でも、句読点の多い和文密文でも、数字が並ぶレシートでも、出力速度そのものはほとんど変わらなかった。
今回の空白を埋めるために比較材料にしたinsiderllm.comの速度表では、Mac上での最速行は「M4 Pro 24GB」でQwen3-VL 8B=40〜60 t/sとされている(2026-07-29時点、M1 Maxの実測行は無し)。モデルもチップ世代も違うので単純比較はできないが、4年前のM1 Max 64GBはこの数字の半分強という位置づけになる。
画像側の前処理コストは「複雑さ」でなく、ほぼ固定コスト
prompt_eval_count(画像+プロンプトのトークン数)は run1=1095, run3=1095, run4=1131 と、900×620の密文(run3)も420×420のレシート(run4)も、900×620のコード画面(run1)とほぼ同じ範囲に収まった。ピクセル数も内容の複雑さもまったく違う3枚が、トークン数ではほぼ横並びになる。なぜレシート(run4)がやや多いのかは正確な内訳を検証できていないので「不明」と書いておく(アスペクト比の丸め処理の影響と推測はできるが、断定はしない)。
サーバーログを見ると、画像のエンコード自体はimage processed in 2410〜2667 msとほぼ一定。prompt_eval全体(5.51〜5.78s、run2を除く)のうち約半分がこの画像エンコードで、残りはプリフィル(プロンプト全体をモデルに読ませる処理)にあたる。
唯一の例外がrun2で、test_aと完全に同じ画像・同じプロンプトを直後に再送したところ、prompt_eval_durationが5.78s→0.05sまで落ちた。サーバーログにもimage processedの行自体が出ておらず、画像エンコードそのものがスキップされている。つまりOllamaは同一コンテキストの再送に対してキャッシュを効かせるが、1文字でも画像や内容が変われば、毎回この5.5〜5.8秒の前処理コストを払い直す。
精度実測: レシート100%・コード実質100%・密文99.72%
各レスポンスを元テキストとdifflib.SequenceMatcherで突合した(空白・改行の差は正規化して除外)。
画像文字数一致率誤り
test_c レシート(数字・構造化)123字100.0%なし(区切り線の表記ゆれを除く)
test_a コード画面612字実質100%HTMLエンティティの表記差(<→<)のみ、内容は完全一致
test_b 和文密文356字99.72%1文字誤変換(「自己の費用負担」→「自己的費用負担」)
金額9箇所を含むレシートは1文字も落とさず完全一致。長い和文の自由文だけ、356字中1字だけ助詞の「の」を「的」に取り違えた。3種類・計1,091字を通しての誤りはこの1文字のみで、実務で使う分には十分な精度だが、「絶対に間違えない」ものではないという前提で使う必要がある。
まとめ: 実務でどう使うか
1枚あたり6〜17秒(モデルロード後)かかるため、チャットのような即応答ではなく、バッチ/非同期の書き起こし処理向き。
速度のボトルネックは画像の複雑さではなく出力トークン数。書き起こす文章が長い画像ほど遅くなる(run3の273tok出力は run4の143tok出力よりevalだけで約2倍時間がかかった)。
同一画像への再送はキャッシュが効いて速いが、実運用でそれを当てにできる場面は少ない。基本は「新規画像=毎回5.5〜5.8秒の前処理コスト」で見積もる。
精度は数字・構造化データほど安定し、長い自由文ほど低確率で1文字単位の誤りが出る。
なお、insiderllm.comの速度表本体・huggingfaceのolmOCR-2-7B-1025-MLX-8bit(MLX量子化の専用OCR VLM)は、今回の検証(Ollama/GGUF経路)の対象外として実際には開いていない。前者は事前調査で内容を確認した要約を出典として引用したのみ、後者はローカルOCR特化VLMへの関心の高さを示す文脈として触れたのみで、自分では試していない。

Top comments (0)