ベンチマークの幻想と実務の現実
エンジニアとしてローカルLLMを実務に組み込もうとするとき、我々が最も陥りやすい罠は「トークン毎秒(tok/s)という数字の魔力」に囚われることだ。今回、MacBook Pro(M4 Max・128GB)という、現時点で開発者が手に入れうる最強のローカル環境の一つを用いて、Qwen3.8 Flash Nextを動かすための3つのランタイム(llama.cpp、oMLX、mlx-serve)を徹底比較した。結論から言えば、ベンチマーク上の速度と、エージェントがタスクを完遂するまでの「実効時間」は、驚くほど乖離している。
まず、推論のフェーズを「プレフィル(入力処理)」と「デコード(生成)」に厳密に分離して測定した。プレフィルは計算律速であり、デコードはメモリ帯域律速である。この両者を均した平均値で語ることは、もはや無意味だ。実測の結果、mlx-serveはプレフィルでllama.cppの約2.6倍(13kトークン時)、デコードでも約2倍の速度を叩き出した。しかし、この圧倒的な速度差が、実際のコード修正タスクにおいてそのまま「開発時間の短縮」に直結したかといえば、答えはノーである。
実際にエージェントを走らせると、mlx-serveはテストの実行回数がllama.cppよりも大幅に増えるという挙動を見せた。結果として、デコードが2倍速いにもかかわらず、完走までの所要時間はllama.cppの方が短かった。これは、LLMの推論速度よりも、エージェントが「いかに無駄な試行をせず、適切なツール呼び出しを行うか」という推論の質と戦略が、トータルの開発時間を支配していることを示唆している。我々エンジニアは、GPUやメモリのスペックを追い求める前に、ランタイムがエージェントのループ内でどのような挙動をとるのか、その「実効的なワークフロー」を評価すべきなのだ。
ランタイム選定の技術的境界線
今回比較した3つのランタイムには、それぞれ明確な「限界」と「適性」が存在する。まず、oMLXは単体ベンチマークでは優秀な数字を出すものの、エージェントループに入るとキャッシュの不整合(QSAKVCacheの破損)によりスループットが崩壊する。これは、Flash Nextのスパースアテンション用KVキャッシュを、現在のoMLXのプレフィックスキャッシュが正しく扱えていないことに起因する。ベンチマークが通るからといって、実務で使えるとは限らないという典型例だ。
一方で、mlx-serveは速度面で圧倒的だが、モデルの形式やメモリ管理に非常に厳しい制約がある。特に、Metalの作業セットを基準としたメモリ検査は、macOSの報告値と乖離しており、–skip-mem-preflightオプションなしでは起動すらままならないケースがある。また、GGUF形式のサポートについても、qwen4expアーキテクチャが本家llama.cppに取り込まれていない現状では、専用の変換版モデルを用意しなければならず、ディスク容量を圧迫する。同じモデルを3形式で保持すれば286GBものストレージを消費する事実は、ローカルLLM開発における「モデル管理のコスト」を如実に物語っている。
以下の表は、今回検証した3つのランタイムの特性をまとめたものである。
| ランタイム | 実装言語 | モデル形式 | 特徴 |
|---|---|---|---|
| llama.cpp | C++ | GGUF | 安定性重視、エージェント用途に最適 |
| oMLX | Python | MLX | ベンチマークは良好だがキャッシュに難あり |
| mlx-serve | Zig | MLX | 圧倒的な速度、メモリ管理に厳格 |
結局のところ、現時点での最適解は「安定した完走」を約束するllama.cppである。思考モードの制御(–reasoning off)がサーバー側で完結し、クライアント側の実装に依存しない点も、複雑なエージェントシステムを構築する上では大きなアドバンテージとなる。我々が明日から取るべき対策は、単に「速いランタイム」を探すことではなく、自身のワークフローにおいて「どの程度の推論精度と安定性が必要か」を定義し、その境界線上で最も信頼できるランタイムを選択することに他ならない。
エンジニアへの問い:速度の先にあるもの
今回の検証を通じて、私は一つの痛烈な問いを突きつけられた。それは「我々は、LLMの推論速度を追求するあまり、本来の目的である『課題解決の効率』を見失っていないか」ということだ。ベンチマークの数字は、あくまで特定の条件下でのスナップショットに過ぎない。エージェントがテストを14回回すか2回で済ませるかという差は、モデルの量子化精度やランタイムの推論戦略によって大きく変動する。この「見えないコスト」を無視して、単にトークン毎秒の速さだけでランタイムを比較することは、本質的なエンジニアリングとは言えない。
今後、ローカルLLMを実務に導入する際、我々は「モデルの重み」や「ランタイムの仕様」といった低レイヤーの制約と、エージェントが生成する「コードの品質」という高レイヤーの成果を、いかにして統合的に評価していくべきだろうか。思考モードをオフにすることで単発の応答は速くなるが、エージェントループ全体で見れば、その差は相殺される。この事実は、LLMの挙動が極めて非線形であり、単純な最適化が必ずしも全体最適に繋がらないことを示している。
読者諸氏に問いたい。あなたの開発環境において、LLMが「速く動くこと」と「確実にタスクを完遂すること」、どちらがビジネス価値に直結しているだろうか。もし後者であれば、ベンチマークのランキングを眺める時間を、エージェントの試行回数を減らすためのプロンプトエンジニアリングや、ツール呼び出しの精度向上に充てるべきではないか。技術の進化は速いが、その技術を「道具」として使いこなすための知見は、こうした泥臭い実測と失敗の積み重ねの中にしかない。明日、あなたが選ぶランタイムは、単なる速度の追求か、それとも確実な成果への投資か。その選択こそが、シニアエンジニアとしての真価を問うことになるだろう。


コメント