M1 Maxで5つのローカルLLM推論エンジンの速度を比べてみた
目次
Magnitude、uzu、Localsの公称速度は、それぞれM4 Pro、M5 Max、M2 Maxなど異なるMacで測られていて、同一の環境では比べにくい。
そこでM1 Max 64GBの実機を使い、Ollamaとllama.cppを基準に置いて、短い質問、コード生成、長文要約、連続会話、並列リクエストを走らせてみた。
各エンジンで推奨・採用されるモデル形式(GGUFやMLX)や量子化、投機的デコードの設定が異なるため、本記事では「同一条件でエンジン同士を比べられた組み合わせ」と「そのエンジン推奨設定での実効速度」を分けて記録している。
具体的には、llama.cppとMagnitudeは同一GGUFで、Localsと標準mlx-lmは同一MLX 4bitモデルで直接比較し、Ollamaやuzuはそれぞれの実用構成での速度を確認した。
実験機と採用したモデル
| 項目 | 値 |
|---|---|
| マシン | MacBook Pro、M1 Max、CPU 10コア、GPU 32コア、統合メモリ64GB |
| OS | macOS 27.0 (26A428) |
| Apple Silicon | arm64、Metal 4 |
| 開発ツール | Command Line Tools、Apple clang 21.0.0 |
| Ollama | 0.40.11(Homebrew版) |
| llama.cpp | 0.7.0(build 11669、Homebrew版) |
2026年10月28日、brew upgrade ollama llama.cpp を実行した。
既存のOllama.app由来の /usr/local/bin/ollama は上書きを避け、新しいHomebrew版を別ポート 127.0.0.1:11436、別モデルディレクトリで起動した。
Qwen公式の公開モデルから Qwen/Qwen3.5-9B を採用し、各エンジンで動かした。
Qwen/Qwen3.8-27B はモデルサイズが約20.5GBあり、手元のメモリを圧迫しやすいため、今回は9Bに絞って測定している。
モデル形式として、llama.cppやMagnitudeが使うGGUF形式(1ファイルに重みとメタデータを収めた形式)と、LocalsやOllamaが使うMLX形式(Apple Siliconに最適化されたフレームワーク用の形式)がある。
また、9Bモデルを元の16ビット精度のまま動かすと約18GB以上のメモリを消費するため、各エンジンとも重みを4ビット幅に圧縮してメモリを節約する4bit量子化モデルを採用した。
uzuが使うMirai Mediumは、Qwen3.5-9Bを4bit量子化した後に追加で蒸留したモデルだ。
標準的なGGUFやMLXの4bit量子化とは重みが一致しないため、同じQwen系列の別チェックポイントとして扱う。
Magnitudeのカタログには、ドラフトモデルなどを含む9B Q4で8.4GB、27B Q4で20.5GBと記載されている。
投機的デコードは、軽量なドラフトモデルや追加層(ヘッド)で先の複数トークンを事前に予測・提案し、本体モデルでまとめて検証することで推論を高速化する仕組みだ。
llama.cppの複数トークン同時予測(MTP)や、Magnitude・uzuが使うDFlashなどがこれに当たる。
| エンジン | 採用モデル形式 | 投機的デコード設定 | 参照した公称値の測定機 |
|---|---|---|---|
| Ollama | MLX Safetensors、NVFP4 | モデルのドラフトヘッドで動作 | 公称値との照合対象ではない |
| llama.cpp | GGUF、UD-Q4_K_XL | MTPを検証 | 公称値との照合対象ではない |
| Magnitude | GGUF | 9BはDFlash | M4 Pro 48GB |
| uzu | uzu独自の形式(Safetensors) | 公式設定はM5系列のみ有効 | M5 Max 128GB |
| Locals | MLX 4bit アフィン量子化 | 使用しない | M2 Max 96GBなど |
uzuの公称値である273 tok/s(9B)はM5 Max 128GB・投機的デコード有効時の数字だ。
uzuのベンチマークコードではDFlashがM5系列でのみ有効化される設定になっており、手元のM1 Maxでは標準でDFlashが動かない。
LocalsもM1 Maxでの公式実測値は公開されていない。
測定条件と生成課題
測定に使った課題は次の6種類とした。
入力文はすべて英語で、同じ課題では各エンジンへ同一の文章を送っている。
| ケース | 内容 | 入力 / 出力上限 |
|---|---|---|
| A 短文 | 初回だけ遅いHTTPサービスの原因説明 | 約140 / 256トークン |
| B コード | 区間を結合するPython関数 | 約121 / 1024トークン |
| C 約8K長文 | 障害記録125件の5文要約 | 8,512 / 512トークン |
| D 約27K長文 | 障害記録400件の5文要約 | 27,077 / 512トークン |
| E 連続会話 | Aの説明に追加質問を9回 | 初回Aと同じ / 各回128トークン |
| F 並列 | Bの関数を2・4・8本同時に生成 | Bと同一 / 各回512トークン |
A〜Dと並列Fはウォームアップ後に各5回測定し、連続会話Eは10ターンの会話を1回実行した。
全エンジンで temperature 0、thinking OFF、同一の出力上限にそろえた。
測定指標として、プロンプトを読み込む入力処理速度(tok/s)、回答を1トークンずつ生成するデコード速度(tok/s)、リクエスト送信から空白以外の最初のトークンが返ってくるまでのTTFT(秒)、送信から回答終了までの全体時間であるE2E(秒)を記録した。
「tok/s」は1秒あたりに処理または生成したトークン数を表す。
出力上限に達する前に自然に回答を終えた試行では、出力トークン数が異なるためE2Eを固定長出力の速度比較には使わず、デコード速度(tok/s)を主な基準とする。
測定に使ったプロンプトと回答例
各課題でエンジンへ送ったプロンプトと、生成された回答の抜粋を示す。
Aのプロンプトでは、モデルロード、プロンプト処理、トークン生成が初回の遅延にどう影響するかを説明し、切り分ける測定方法を2つ提案するよう求めた。
Hello! Let’s break down why your service feels slow on the very first request but speeds up afterward. This is a classic pattern in AI applications, and understanding the three distinct phases—Model Loading, Prompt Processing, and Token Generation—will help us pinpoint the exact bottleneck.
Bのコード生成課題では、区間の結合処理を行う関数を要求した。元の指示は次の文章で、関数の型ヒント、docstring、4つの assert 例まで指定している。
Write a complete Python 3 function
merge_intervals(items)that accepts an iterable of(start, end)integer pairs. Reject a pair whenstart > endwithValueError. Return a new list of non-overlapping intervals sorted by start, merging intervals that overlap or touch. Do not mutate the input. Include type hints, a short docstring, and fourassertexamples covering empty input, unsorted input, touching intervals, and an invalid pair. Return only Python code.
生成されたコードには、次のような区間結合ループが含まれていた。
for current_start, current_end in sorted_intervals[1:]:
last_start, last_end = merged[-1]
# Check if intervals overlap or touch
if current_start <= last_end:
# Merge intervals
merged[-1] = (last_start, max(last_end, current_end))
else:
merged.append((current_start, current_end))
CとDの長文要約では、サービス名、HTTPエラー、重大度、所要時間、チケットキーを含む障害レコードを並べ、5文での要約を求めた。
各レコードのチケットキー末尾を試行ごとに変え、前回の入力キャッシュが長文の測定結果に混入しないように配慮した。
The incident register documents 125 independent offline software system failures involving a rotating set of services including worker, gateway, scheduler, storage, indexer, search, and notifier across four geographic regions. The highest severity level recorded across these entries is “high,” which appears frequently alongside medium and low severity incidents.
Eの連続会話では、Aの回答履歴を保持したまま give one additional practical detail と9回続けて指示を送った。
Fの並列測定では、Bと同一のコード生成指示を、会話履歴のない独立したリクエストとして同時に送信した。
llama.cppで同じGGUFをキャッシュなしで測定した
最初の短文テストでは llama-server のプロンプトキャッシュが働き、140トークン中136トークンが再利用された。
これでは入力処理速度が正確に測れないため、--no-cache-prompt オプションを付けてサーバーを再起動した。
再起動後は各回とも140トークンが新規に処理され、キャッシュ数は0になった。
モデルファイルにはMagnitudeカタログから取得したQwen3.5-9BのGGUF(UD-Q4_K_XL)をそのまま読み込ませた。
これでMagnitudeとの本体ファイルが一致する。
単発タスクでの速度
共通条件: GGUF UD-Q4_K_XL、キャッシュOFF、投機OFF、各5回測定の中央値。
| ケース | 入力処理速度 | デコード速度 | TTFT中央値 | E2E中央値 | 出力トークン中央値 |
|---|---|---|---|---|---|
| A 短文(約140入力) | 348.55 tok/s | 36.59 tok/s | 0.445秒 | 7.415秒 | 256 |
| B コード(約121入力) | 355.55 tok/s | 37.07 tok/s | 0.387秒 | 13.768秒 | 497 |
| C 約8K長文(8,512入力) | 452.33 tok/s | 34.03 tok/s | 18.915秒 | 23.717秒 | 168 |
| D 約27K長文(27,077入力) | 403.18 tok/s | 31.38 tok/s | 67.332秒 | 72.532秒 | 166 |
長文になるほど入力処理に時間が取られ、TTFTがAの0.445秒からDの67.332秒まで長くなった。
デコード速度は入力長が増えても31〜37 tok/sの範囲で推移した。
連続会話と並列リクエスト
連続会話Eでは、同一セッションで10ターン会話を行った。
累積コンテキストは10回目で1,433トークンに達したが、実際に新規処理されたのは153トークンで、1,280トークンがKVキャッシュから再利用された。
10ターンのTTFT中央値は0.565秒、デコード中央値は37.28 tok/sとなった。
並列リクエストFは --parallel 8 --ctx-size 32768(各スロット4,096文脈)で起動し、2・4・8本を同時に送信した。
| 並列数 | 合計速度中央値 | 各応答デコード中央値 | 各応答TTFT中央値 | 各応答E2E中央値 |
|---|---|---|---|---|
| 2 | 42.36 tok/s | 21.84 tok/s | 0.69秒 | 22.85秒 |
| 4 | 78.00 tok/s | 20.73 tok/s | 1.34秒 | 25.19秒 |
| 8 | 122.00 tok/s | 16.89 tok/s | 2.41秒 | 31.63秒 |
並列数を増やすと各応答のデコード速度は21.84 tok/sから16.89 tok/sへと緩やかに下がるが、全体の合計速度は42.36 tok/sから122.00 tok/sまで伸びた。
MTPでの投機的デコード
同じ9B GGUFに対し、--spec-type draft-mtp --spec-draft-n-max 3 を付けてMTPによる投機的デコードを有効化した。
投機OFFと同じプロンプトで各5回測定した結果を比較する。
| ケース | 投機OFFデコード | MTP ONデコード | 速度倍率 | MTP ONのTTFT | MTP ONのE2E |
|---|---|---|---|---|---|
| A 短文 | 36.59 tok/s | 48.46 tok/s | 1.32倍 | 0.445秒 | 5.742秒 |
| B コード | 37.07 tok/s | 60.22 tok/s | 1.62倍 | 0.387秒 | 8.542秒 |
| C 約8K長文 | 34.03 tok/s | 40.90 tok/s | 1.20倍 | 20.151秒 | 24.150秒 |
| D 約27K長文 | 31.38 tok/s | 32.53 tok/s | 1.04倍 | 72.480秒 | 76.966秒 |
コード生成Bではドラフトトークンの受理率が約80%に達し、デコード速度が1.62倍(37.07→60.22 tok/s)に向上した。
短文Aの受理率は約58%、要約Cは約52%、Dは約48%だった。
長文CやDでは投機処理によるオーバーヘッドでTTFTがわずかに長くなり、全体のE2E時間も長くなった。
生成されたコードはいずれも構文解析を通過し、指定された4つの assert 例が含まれていた。
Magnitudeで同じGGUFのDFlash効果を測定した
Magnitude 0.2.12を使い、カタログからインストールしたQwen3.5-9B(DFlash付属)をテストした。
使用されている本体GGUFはllama.cppで使ったファイルと同一である。
同じテンソルで投機をOFFにする手順
カタログモデルは設定からドラフトモデルを外せない仕様だった。
そこでGGUFファイルをAPFSクローンで複製し、モデル表示名 general.name のハイフン1文字だけを空白に書き換えた。
テンソルの重みデータや量子化は一切変更していない。
Magnitudeはこのファイルを別モデルとして認識したため、magnitude models drafter ... none コマンドで投機OFFに設定できた。
単発タスクでの速度
共通条件: Magnitude 0.2.12、投機OFF、各5回測定の中央値。
| ケース | 入力処理速度 | デコード速度 | TTFT中央値 | E2E中央値 | 出力トークン中央値 |
|---|---|---|---|---|---|
| A 短文 | 333.10 tok/s | 41.61 tok/s | 0.451秒 | 6.652秒 | 256 |
| B コード | 340.20 tok/s | 41.56 tok/s | 0.328秒 | 12.189秒 | 490 |
| C 約8K長文 | 541.27 tok/s | 40.33 tok/s | 15.786秒 | 19.444秒 | 146 |
| D 約27K長文 | 382.40 tok/s | 37.54 tok/s | 60.786秒 | 64.910秒 | 155 |
投機OFFの状態では、デコード速度が短文・コードともに約41.6 tok/sで安定していた。
llama.cppの投機OFF(約37 tok/s)に比べてデコード速度は約1.12〜1.14倍速い数値となった。
DFlash有効時のデコード速度
カタログ本来のDFlash有効設定と、投機OFFの設定を比較した。
| ケース | 投機OFFデコード | DFlash ONデコード | 速度倍率 | 投機OFF TTFT | DFlash ON TTFT |
|---|---|---|---|---|---|
| A 短文 | 41.61 tok/s | 41.19 tok/s | 0.99倍 | 0.451秒 | 0.476秒 |
| B コード | 41.56 tok/s | 82.58 tok/s | 1.99倍 | 0.328秒 | 0.343秒 |
| C 約8K長文 | 40.33 tok/s | 37.64 tok/s | 0.93倍 | 15.786秒 | 16.461秒 |
| D 約27K長文 | 37.54 tok/s | 33.93 tok/s | 0.90倍 | 60.786秒 | 62.799秒 |
コード生成BではDFlashが効果を発揮し、内部デコード速度が41.56 tok/sから82.58 tok/sへと1.99倍に跳ね上がった。
E2E所要時間も12.189秒から6.559秒へと半減した。
一方で、短文Aでは倍率0.99倍とほぼ変わらず、長文CやDでは投機オーバーヘッドによりデコード速度が0.90〜0.93倍に低下し、TTFTもわずかに長くなった。
連続会話と並列リクエスト
連続会話E(10ターン)では、10回すべて128トークンを生成し、TTFT中央値0.575秒、デコード中央値41.40 tok/sとなった。
最終ターンでは入力1,473トークン中1,318トークンがキャッシュ再利用された。
並列リクエストF(各バッチ5回)の測定結果は次のとおりだ。
| 並列数 | 合計速度中央値 | 各応答デコード中央値 | TTFT中央値 |
|---|---|---|---|
| 2 | 56.82 tok/s | 29.91 tok/s | 0.693秒 |
| 4 | 72.21 tok/s | 19.14 tok/s | 1.258秒 |
| 8 | 132.97 tok/s | 19.51 tok/s | 3.658秒 |
8並列時の合計速度は132.97 tok/sに達し、全40リクエストが約29秒前後で完了した。
Ollamaを別ポートで起動して測定した
Homebrew版Ollama 0.40.11を別ポート 11436 で起動し、qwen3.5:9b タグを取得した。
取得されたモデルはMLX Safetensors形式のNVFP4量子化で、ファイルサイズは約7.64GBだった。
draft_num_predict=0 を指定して投機的デコードを無効化しようとしたが、OllamaのMLXランナーはモデル内のドラフトヘッドを検出すると自動的に投機機構を構築する実装になっていた。
ログ上でもドラフトトークンの生成と受理が記録されたため、以下の測定値は投機的デコードが有効な状態での結果となる。
単発タスクでの速度
共通条件: Ollama 0.40.11、MLX NVFP4、投機ON、各5回測定の中央値。
| ケース | 入力処理速度 | デコード速度 | TTFT中央値 | E2E中央値 | 出力トークン中央値 |
|---|---|---|---|---|---|
| A 短文(128入力) | 298.83 tok/s | 47.27 tok/s | 0.565秒 | 5.912秒 | 256 |
| B コード(約121入力) | 329.76 tok/s | 53.37 tok/s | 0.449秒 | 9.716秒 | 498 |
| C 約8K長文(8,500入力) | 352.08 tok/s | 46.40 tok/s | 24.272秒 | 28.012秒 | 176 |
| D 約27K長文(27,065入力) | 328.23 tok/s | 39.67 tok/s | 82.603秒 | 87.106秒 | 170 |
デコード速度はコード生成Bで53.37 tok/s、長文要約Dでも39.67 tok/sを維持した。
Bで生成された5本のコードはすべてPythonの構文を満たし、指定された4つの assert 例を含んでいた。
連続会話と並列リクエスト
連続会話Eでは、10ターンのTTFT中央値が0.459秒、デコード中央値が53.58 tok/sとなった。
初回のロード時を除き、2ターン目以降は0.45〜0.60秒のTTFTで軽快に応答した。
並列リクエストFは OLLAMA_NUM_PARALLEL=8 を設定し、2・4・8本を同時送信した。
| 並列数 | 合計速度中央値 | 各応答デコード中央値 | TTFT中央値 |
|---|---|---|---|
| 2 | 53.20 tok/s | 55.77 tok/s | 4.85秒 |
| 4 | 54.54 tok/s | 56.11 tok/s | 13.21秒 |
| 8 | 54.76 tok/s | 56.40 tok/s | 30.05秒 |
Ollamaでは並列数を増やしても合計速度が約54 tok/sでほぼ頭打ちになった。
各応答のデコード速度は56 tok/sのままで落ちない代わりに、TTFTが並列数に応じて8〜9秒ずつ順に伸びており、内部でリクエストがほぼ1本ずつ順次処理されている挙動が見られた。
uzuでMirai MediumをM1 Maxで動かしてみた
uzu 0.6.13を専用の仮想環境で実行し、蒸留モデルである trymirai/Qwen3.5-9B-M(約5.38GB)を読み込ませた。
単発タスクでの速度
共通条件: uzu 0.6.13、Mirai Medium、投機OFF(M1 Max標準)、各5回測定の中央値。
| ケース | 入力処理速度 | デコード速度 | TTFT中央値 | E2E中央値 | 出力トークン中央値 |
|---|---|---|---|---|---|
| A 短文 | 225.29 tok/s | 55.19 tok/s | 0.699秒 | 5.320秒 | 256 |
| B コード | 231.10 tok/s | 55.20 tok/s | 0.523秒 | 14.620秒 | 782 |
| C 約8K長文 | 376.06 tok/s | 51.75 tok/s | 22.749秒 | 26.153秒 | 177 |
| D 約27K長文 | 332.49 tok/s | 47.91 tok/s | 81.620秒 | 84.675秒 | 150 |
単発タスクのデコード速度は47〜55 tok/sと高速だった。
ただしコード生成Bでは、出力された5本すべてがPythonの構文エラーとなった。
生成コードの行末に assert ... == [...] -> [...] is incorrect logic in thought といった自己修正の思考テキストが混入し、正常なコードとして実行できなかった。
thinking OFF の指定下でもこの混入が発生しており、蒸留チェックポイント固有の課題がうかがえる。
連続会話と並列リクエスト
連続会話Eでは、過去履歴を保持するセッション仕様に合わせ、10ターンとも128トークンを安定して出力した。
TTFT中央値は0.228秒、デコード中央値は57.12 tok/sで、キャッシュ再利用が機能した。
並列リクエストFの測定結果は次のとおりだ。
| 並列数 | 合計速度中央値 | 各応答デコード中央値 | TTFT中央値 |
|---|---|---|---|
| 2 | 54.79 tok/s | 28.55 tok/s | 0.748秒 |
| 4 | 54.96 tok/s | 14.21 tok/s | 1.207秒 |
| 8 | 54.95 tok/s | 7.08 tok/s | 2.149秒 |
uzuでも並列数を増やした際の合計生成速度は約55 tok/sにとどまった。
各応答のデコード速度が並列数に応じて反比例(28.55 → 14.21 → 7.08 tok/s)して下がっており、GPUリソースを時分割で分け合っている挙動となった。
Localsを同じMLX重みのmlx-lmと比べた
Locals 0.2.1の性能を評価するため、Apple公式のMLXリファレンス実装である標準 mlx-lm 0.32.2をベースラインとして用意した。
両者に同一のローカルモデル mlx-community/Qwen3.5-9B-MLX-4bit(約5.98GB)を読み込ませて測定した。
Localsの起動前チューニング(quick)を実行すると、GPUの量子化行列計算マイクロベンチマークにおいて、標準カーネルの93.05msから最適化カーネルの30.90msへと短縮された。
単発タスクでの速度
共通条件: Locals 0.2.1、MLX 4bit、1スロット、各5回測定の中央値。
| ケース | デコード速度 | TTFT中央値 | E2E中央値 | 出力トークン中央値 |
|---|---|---|---|---|
| A 短文 | 59.99 tok/s | 0.428秒 | 4.663秒 | 256 |
| B コード | 62.82 tok/s | 0.310秒 | 10.418秒 | 636 |
| C 約8K長文 | 51.17 tok/s | 14.913秒 | 18.281秒 | 169 |
| D 約27K長文 | 43.73 tok/s | 51.840秒 | 55.549秒 | 178 |
単発でのデコード速度は短文で約60 tok/s、コードで約63 tok/sと、投機的デコードなしの単一モデル推論としては今回の検証中で最も高い基本速度を出した。
Bの生成コードは5本ともPython構文を満たし、指定された4つの assert 例を含んでいた。
連続会話と並列リクエスト
連続会話Eでは、10ターンのTTFT中央値が0.165秒、デコード中央値が118.56 tok/sに達した。
2ターン目以降は会話履歴の大部分がキャッシュされ、極めて高速に応答した。
並列リクエストFでは、Localsと標準mlx-lmをそれぞれ8スロット設定で起動し、同一プロンプトでの合計速度を直接比較した。
| 並列数 | Locals合計速度 | 標準mlx-lm合計速度 | 速度比 | Locals TTFT | mlx-lm TTFT |
|---|---|---|---|---|---|
| 2 | 100.36 tok/s | 71.43 tok/s | 1.40倍 | 0.563秒 | 0.738秒 |
| 4 | 124.65 tok/s | 79.35 tok/s | 1.57倍 | 1.097秒 | 1.655秒 |
| 8 | 203.14 tok/s | 69.65 tok/s | 2.92倍 | 1.992秒 | 3.123秒 |
標準mlx-lmは並列数を増やしても合計約70〜79 tok/sで頭打ちになるのに対し、Localsは8並列で203.14 tok/sまでスケーリングした。
8並列時の合計速度比は2.92倍に達した。
なお、同一の8スロット設定で単発Aを実行したところ、Localsが58.21 tok/s、標準mlx-lmが54.63 tok/s(1.07倍)となり、単発での差は控えめだった。
Localsの最適化カーネルとバッチ処理機構は、複数リクエストが並行して走る状況で強みを発揮した。
エンジン間の速度比較と測定条件の整理
各エンジンで条件をそろえて比較できた点と、前提条件が異なる点を整理する。
同一のGGUF(UD-Q4_K_XL)を投機OFFで動かしたllama.cppとMagnitude 0.2.12の比較では、短文Aで36.59 tok/s対41.61 tok/s(1.14倍)、コードBで37.07 tok/s対41.56 tok/s(1.12倍)となり、Magnitudeが約1割強上回った。
長文CやDでは、Magnitudeのモデル文脈上限が256K、llama.cppが32Kとサーバー設定に差があるものの、デコード速度はそれぞれ40 tok/s前後と31〜34 tok/sで推移した。
投機的デコードの効果は課題によって大きく分かれた。
コード生成Bのようにトークンの予測が当たりやすい課題では、llama.cppのMTPで1.62倍(37.07 → 60.22 tok/s)、MagnitudeのDFlashで1.99倍(41.56 → 82.58 tok/s)と大きな加速が得られた。
一方で、文脈が長くなるCやDではドラフトの受理率が約50%前後に落ち込み、検証コストによってTTFTが延び、E2E全体の所要時間も長くなった。
短文やコード生成などの適した課題で選んで使うのが有効だ。
同一のMLX 4bitモデルを用いたLocalsと標準mlx-lmの比較では、並列リクエスト時の差が際立った。
単発での差は1.07倍にとどまるが、8並列時には標準mlx-lmの69.65 tok/sに対してLocalsが203.14 tok/sに達し、約2.92倍の総スループットを記録した。
Ollamaやuzuの8並列合計速度は約55 tok/sだったが、これらはモデル形式やスケジューラ仕様が異なるため、参考値となる。
生成コードの品質と測定対象外の指標
生成物の品質面では、uzuのコード生成Bで5試行すべてに自己修正思考テキストが混入し、構文エラーとなった。
ほかのエンジン(llama.cpp、Magnitude、Ollama、Locals)が出力したコードBは、いずれも構文解析を通過し、要求した型ヒントや4つの assert 例を満たしていた。
今回の測定では5つの推論エンジンすべてがM1 Max 64GB上で動作した。
なお、27Bモデルについては9Bの検証資産だけでも十分なデータが得られたことと、ダウンロード容量を考慮して今回は対象外とした。
GPU使用率はroot権限なしに一貫して取得できる安全な手段がなかったため未測定としている。
測定データの保存先
測定に使用したプロンプト、起動パラメータ、各試行の最小値・最大値を含む詳細な集計ログは、リポジトリ内の llm-engine-benchmark/results/summary.csv および llm-engine-benchmark/results/summary.md に保存している。