
Ollama vs llama.cpp直接実行、同じGGUFなのに速度が2.7倍違った話
きっかけ:Ollamaは中身llama.cppなのに、直接使うとどれくらい違うのか Ollamaは内部的にllama.cpp(ggml)を使っている、というのはよく知られた話。実際、Ollamaのインストールフォルダの中にはllama-server.exeがそのまま同梱されている。 じゃあ「Ollama経由」と「llama.cppを直接叩く」で、同じGGUFファイルを使った場合にどれくらい速度が変わるのか、実際に検証してみた。今回はこれまでの比較で最速だったGemma4-12B-Hereticを使い、Ollamaのモデルストレージにある実体ファイル(.gguf)をそのままllama.cppに読み込ませて比較している。 最初の落とし穴:同梱バイナリはCPU専用だった 最初、Ollamaに同梱されているllama-server.exeをそのまま使おうとしたら、いきなり躓いた。 warning: no usable GPU found, --gpu-layers option will be ignored Ollamaに同梱されているこのバイナリ、GPUサポート無しでビルドされたものだった。Ollama自体はきちんとVulkanでGPU推論しているのに、同梱のllama-server.exe単体では動かないという、地味に紛らわしい罠。この状態で生成速度を測ったら4.1 tok/sしか出ず、当然ながらCPU実行だとこうなる。 正しく比較するため、llama.cpp公式のVulkan対応Windows版バイナリ(GitHub Releases)を別途取得して検証し直した。 本題:GPU対応版でも、Ollamaには届かなかった Vulkan対応版のllama.cppで、同じGGUFファイル・同じGPU2枚環境で計測した結果: Ollama(既定設定): 33.1 tok/s llama.cpp直接(既定設定): 12.1 tok/s llama.cpp直接(--split-mode none --main-gpu 0、GPU1枚に固定してパイプライン分割を無効化): 18.4 tok/s 既定設定のままだと、Ollamaの方が約2.7倍速いという結果になった。llama.cppの既定の--split-mode(layer、GPU間でレイヤーをパイプライン分割する方式)をnone(単一GPUのみ使用)に変えると18.4 tok/sまで改善したが、それでもOllamaには届かなかった。 前回の記事で「GPU1枚に余裕で収まるモデルは複数GPUの恩恵がない」という結果を出したばかりだが、llama.cpp側の既定設定(layer分割)では、逆に複数GPUへの分割自体がオーバーヘッドになって遅くなっていた、という点は興味深い。Ollamaはおそらく、モデルサイズとGPU容量を見て「1枚に収まるなら1枚だけ使う」という判断を内部で自動的にやってくれているのだと思われる。 結論 Ollama同梱のllama-server.exeはCPU専用ビルド — そのまま使うと不当に遅い比較になるので要注意。GPU版で検証し直す必要があった 既定設定同士の比較では、Ollamaがllama.cpp直接実行より約2.7倍速い — 同じエンジン・同じGGUFでもラッパー側のチューニングでここまで差が出る llama.cppの既定の--split-mode(layer)は、1枚に収まるモデルには不利に働く — --split-mode noneで単一GPU固定にすると速度は改善するが、それでもOllamaには届かなかった 「中身は同じllama.cppだから同じ速度のはず」は誤り — Ollamaは単なるラッパーではなく、実行時のGPU割り当てやバッチ設定などで実質的なチューニングを行っている 「速度で困ったらOllamaをやめて生のllama.cppを使えばいい」という発想は、少なくとも今回の環境・条件では成り立たなかった。むしろOllama側のデフォルトの賢さを再確認する結果になった。次はllama.cpp側のバッチサイズやスレッド数など、さらに細かいパラメータチューニングでOllamaに追いつけるか試してみたい。