6/6 · 6/6
1問ずつ:両モデルとも全問正解
9/18 対 17/18
同じ問題をまとめると:MoE対dense
0/3 対 2/3
まとめた実行で全問正解だった回
≈2.1倍
デコード速度。それでも実時間は同程度
このテストを行った理由
私たちは、コーディングエージェントの中でローカルモデルを使っています。モデルは読み取り専用のツールでファイルを読み、コードベースについての質問に答えます。こうしたモデルを確かめる普通のやり方は、1問だけ質問して答えが合っているかを見ることです。私たちは、それで本当に足りるのかを知りたいと思いました。
差が見つかったのは偶然でした。ループの中でエージェントのプロセスが標準入力を飲み込んでしまい、2問目から6問目が、5つの別々の質問ではなく、1つの大きなプロンプトとしてモデルに届いたのです。結果がはっきり違って見えたので、このまとめて渡す条件を正式なテストにしました。
この記事は、そのテストの報告です。モデルの順位づけではなく、テストの設計についてのささやかな観察です。
1問ずつのテストでは、この差は決して見えなかったでしょう。
テストの環境
すべて1台のマシンで、モデルは1つずつ動かしました。
- マシン
- Apple SiliconのMac 1台(M1 Max、64GB)
- 当時のランタイム
- Ollama 0.32.14。ロードするモデルは常に1つだけ
- モデルA
- mixture-of-experts(MoE)モデル。35B-A3B、アクティブパラメータは約3B(Qwen3.5ファミリー)、Q4_K_M
- モデルB
- dense 27Bモデル(Qwen3.8ファミリー)、Q4_K_M
- タスク
- 読み取り専用のツール(read、grep、find、ls)で自社のコードベースを読み、質問に答える。普段使っているのと同じエージェントの仕組みで実行
- 採点
- 人が確認した正解キーとの完全一致
タスク
人が確認した正確な答えのある質問
エージェントの仕組み
普段使っているものと同じ。読み取り専用ツール:read、grep、find、ls
ローカルモデル
MoEまたはdense。ロードするのは常に1つ
採点
人が確認したキーとの完全一致を、スクリプトで判定
MoEモデルは、トークンごとにパラメータの一部だけを使います(ここでは約3B)。denseモデルはすべてを使います。コードベースのファイル名、設定名、コードは公開しないため、タスクは一般的な言葉で説明しています。
どんな質問をしたか
6つの質問があり、それぞれに、人が確認した正確な答えがあります。
- 1共通の接頭辞を持つ設定を15個挙げる。
- 23段階の原因の連鎖をたどり、チェックID、その元になる関数、定数を答える。
- 3ある分岐が取る正確な値を答える。
- 4「どれか1つでも一致するか」を調べる判定が、空のリストでは何を返すかを推論する。
- 5コメントを除いて、ある文字列が現れる行番号を答える。
- 6ある式が何回出てくるかを数える。
結果1:1回に1問ずつ
まず、6つの質問を1回に1問ずつ実行しました。どちらのモデルも、6問すべてに正解しました。
所要時間は、MoEが合計137.3秒、denseが合計417.4秒で、denseは3.0倍遅くなりました。ただし品質については、このテストでは違いがまったく見えませんでした。
1回に1問:質問ごとの所要時間
6つの質問それぞれの所要時間(秒)。どちらのモデルも6問すべてに正解し、denseはすべての質問でより長くかかりました。
- 問117.543.9
- 問221.0135.3
- 問329.2121.0
- 問448.167.6
- 問515.731.5
- 問65.818.1
- 合計 · MoE
- 137.3 秒
- 合計 · dense
- 417.4 秒
データを表で見る
| 質問 | MoE | dense |
|---|---|---|
| 質問1 | 17.5 | 43.9 |
| 質問2 | 21.0 | 135.3 |
| 質問3 | 29.2 | 121.0 |
| 質問4 | 48.1 | 67.6 |
| 質問5 | 15.7 | 31.5 |
| 質問6 | 5.8 | 18.1 |
| 合計 | 137.3 | 417.4 |
| 正解 | 6/6 | 6/6 |
ここで止めていたら、この作業については2つのモデルは同じくらい信頼できる、と結論づけていたはずです。
結果2:1つの文脈にまとめた場合
次に、同じ6問を1つの文脈にまとめ、モデルごとに3回ずつ実行しました。1モデルあたり18個の小問です。
1問ずつのテストが隠していた差が、ここではっきり現れます。
文脈にまとめた場合:全小問を回ごとに
モデルごとに3回、1回あたり6つの小問。✓は完全一致、✕は不正解、斜線の行は出力がまったくなかった回です。
MoE
dense
データを表で見る
| 回 | MoE | dense |
|---|---|---|
| 1回目 | 0/6 · 187.7 秒 出力が空 | 6/6 · 375.5 秒 すべて正解 |
| 2回目 | 4/6 · 168.9 秒 項目が1つ欠落、真偽の誤りが1つ | 5/6 · 346.8 秒 15項目は正しいが、存在しない名前を2つ追加(17項目) |
| 3回目 | 5/6 · 155.5 秒 関数名と定数名を答えるべきところに、式とローカル変数を回答 | 6/6 · 364.4 秒 すべて正解 |
| 合計 | 9/18 (50%) | 17/18 (94%) |
まとめた条件の概要
18小問中の正解数、3回中の全問正解の回数、1回あたりの平均時間。
正解した小問
全問正解の回
1回あたりの平均時間
データを表で見る
| 指標 | MoE | dense |
|---|---|---|
| 正解した小問 | 9/18 (50%) | 17/18 (94%) |
| 全問正解の回 | 0/3 | 2/3 |
| 1回あたりの平均時間 | 170.7 秒 | 362.2 秒 |
MoEは合計9/18(50%)で、全問正解の回はなく(0/3)、平均時間は170.7秒でした。denseは合計17/18(94%)で、全問正解の回は3回中2回、平均時間は362.2秒、MoEの2.12倍の遅さでした。
MoEの1回目は、標準出力にも標準エラーにも1バイトも出さないまま、187.7秒後に静かに終了しました。
失敗の仕方の違い
正解数だけでは、実行がどう壊れたのかがわかりません。そこで、失敗の種類も記録しました。
何がどう間違ったか(種類別)
失敗の種類を小問の数で数えました(1回の実行の1問が1件)。MoEの無言の回だけで6件になります。
データを表で見る
| 失敗の種類 | MoE | dense |
|---|---|---|
| 無言の空出力 | 6 | 0 |
| 項目の欠落 | 1 | 0 |
| 真偽の誤り | 1 | 0 |
| 浅い推論 | 1 | 0 |
| でっち上げ | 0 | 1 |
MoEモデル(負荷がかかったとき)
- 無言の空出力:1回目は、標準出力にも標準エラーにも何も出さずに終了した。
- 項目の欠落:15項目のうち1つが抜け、真偽の答えも1つ間違えた。
- 浅い推論:呼び出しの連鎖を実際の関数と定数まで追わず、表面的なところで止まった。
denseモデル
- でっち上げ:実在する15項目に加えて、存在しない名前を2つ付け足した。
判断を任せる役割では、無言の空実行のほうが、より有害な失敗だと私たちは考えています。
デコード速度と実時間
速度の話では、たいていデコード速度、つまりモデルが1秒に何トークン書けるかが使われます。しかし実際のエージェント作業にはprefillもあります。与えられたものすべて(ここではエージェントが開くファイル)をモデルが読み込む処理です。同じプロンプトで、ウォームな状態、thinkingオフにして、denseモデルについて両方を測りました。
デコード速度と実時間(denseモデル、2つのエンジン)
各3回。MLXエンジンのデコードは速かったものの、まとめた実行の所要時間はほぼ同じでした。
デコード速度、tok/s(棒が長いほど速い)
dense、Q4_K_M(GGUF)
9.2 / 8.7 / 7.2 tok/s
dense、MLX(nvfp4)
18.3 / 18.2 / 17.2 tok/s
≈2.1× デコードが速い(MLX対GGUF)
所要時間、秒(棒が短いほど速い)
dense、Q4_K_M(GGUF)
529.4 / 468.0 / 447.8 秒 · 平均 481.7
dense、MLX(nvfp4)
639.8 / 338.5 / 498.3 秒 · 平均 492.2
実時間:意味のある差なし
理由:実際のエージェント作業の大半はprefill、つまり与えられたファイルをモデルが読む処理で、デコード速度はこれを測っていません。
データを表で見る
| 構成 | 1回目 | 2回目 | 3回目 | 平均 |
|---|---|---|---|---|
| MoE、Q4_K_M · tok/s | 39.9 | 40.0 | 40.0 | — |
| dense、Q4_K_M(GGUF) · tok/s | 9.2 | 8.7 | 7.2 | — |
| dense、Q4_K_M(GGUF) · 秒 | 529.4 | 468.0 | 447.8 | 481.7 |
| dense、MLX(nvfp4) · tok/s | 18.3 | 18.2 | 17.2 | — |
| dense、MLX(nvfp4) · 秒 | 639.8 | 338.5 | 498.3 | 492.2 |
MLXエンジンのデコードは、GGUFの約2.1倍でした。ところが6問をまとめた実行の所要時間は、ほぼ同じでした。平均はGGUFが481.7秒、MLXが492.2秒で、意味のある差はありません。実際のエージェント作業では、時間の大半はデコードではなくprefill(ファイルの読み込み)にかかります。
どちらの構成も、あとからのコード修正の影響を受けない質問には正しく答えました(下の制約を参照)。
MoEとdenseの速度比も、プロンプトによって変わります。今回のテストでは4.8倍(40.0対8.4 tok/s)、以前のテストでは7倍でした。「7倍」を一般的な数字として引用しないでください。
いま私たちがやっていること
- エージェントは、実際に直面する負荷の形、つまり長くまとまった文脈でテストする。1問ずつだけで終わらせない。
- 点数だけでなく、失敗の種類を記録する:無言の空出力、項目の欠落、浅い推論、でっち上げ。
- prefillが大半を占めるとき、デコードのtok/sは作業時間の当てにならない指標だと考える。
- 人が確認した正解キーに対して、スクリプトで採点する。生ログは残す。
- 環境と限界を明記する。n=3を順位表にしない。
制約と注意点
- 小さなテストです。6問×3回×2モデル、マシン1台、コードベース1つ、各セルn=3。モデルの順位づけではなく、テスト設計についての観察です。
- ソフトウェアは先へ進んでいます。ここで使ったOllamaの構成は、その後、私たちの環境ではllama.cppに置き換わりました。モデルのファミリーはテストしたとおりに記載しており、現在は結果が違うかもしれません。現行バージョンについては何も主張しません。
- 速度の条件は、コード修正によって質問の1つ(5問目)の答えが変わったあとに実行しました。そのため、この条件は残りの5問だけで比較しています。
- ハードウェアはApple SiliconでNVIDIAではありません。他の人の環境の数字とは混ぜないでください。
- 採点は、人が確認したキーとの完全一致で行いました。最初の目視確認ではdenseの2回目のでっち上げを1つ見逃し、スクリプトで修正しました。採点は必ずスクリプトで行ってください。
自分のエージェントで試すには
私たちのコードがなくても、同じ考え方を当てはめられます。
- 人が確認した正確な答えのあるタスクを用意し、スクリプトで採点できるようにする。
- 各タスクを1つずつ実行し、次に、普段の実行と同じ形で1つの長い文脈にまとめて実行する。
- 各条件を何度か繰り返し、回ごとの結果を残す。
- 不正解の回ごとに、失敗の種類を記録する:空出力、項目の欠落、浅い推論、でっち上げ。
- 実際の所要時間を測り、デコード速度は別に測る。
- スクリプトで採点し、生ログを残す。
- 環境と限界を、結果のそばに書き留める。
生の記録
実行ログ(原文のまま)
[qwen3.5:35b-a3b] C1 done 187.7s[qwen3.5:35b-a3b] C2 done 168.9s[qwen3.5:35b-a3b] C3 done 155.5s[qwen3.8:27b] C1 done 375.5s[qwen3.8:27b] C2 done 346.8s[qwen3.8:27b] C3 done 364.4s| モデル | 回 | 出力(バイト) | サイズの棒 | 秒 |
|---|---|---|---|---|
| MoE | 1回目 | 0 ⚠ | 187.7 | |
| MoE | 2回目 | 475 | 168.9 | |
| MoE | 3回目 | 488 | 155.5 | |
| dense | 1回目 | 495 | 375.5 | |
| dense | 2回目 | 533 | 346.8 | |
| dense | 3回目 | 495 | 364.4 |
| 質問 | MoE 1回目 | MoE 2回目 | MoE 3回目 | dense 1回目 | dense 2回目 | dense 3回目 |
|---|---|---|---|---|---|---|
| 質問1 | 出力なし | 不正解 | 正解 | 正解 | 不正解 | 正解 |
| 質問2 | 出力なし | 正解 | 不正解 | 正解 | 正解 | 正解 |
| 質問3 | 出力なし | 正解 | 正解 | 正解 | 正解 | 正解 |
| 質問4 | 出力なし | 不正解 | 正解 | 正解 | 正解 | 正解 |
| 質問5 | 出力なし | 正解 | 正解 | 正解 | 正解 | 正解 |
| 質問6 | 出力なし | 正解 | 正解 | 正解 | 正解 | 正解 |
用語集
- MoE(mixture of experts)
- トークンごとに、パラメータの一部だけを使うモデル。
- denseモデル
- トークンごとに、すべてのパラメータを使うモデル。
- prefill
- モデルが、与えられたものすべて(エージェントが開いたファイルなど)を読み込む段階。
- デコード
- モデルが答えを1トークンずつ書き出す段階。
- tok/s
- 1秒あたりのトークン数。デコードの速さ。
- 実時間(wall-clock)
- 実行の開始から終了までの実際の時間。prefillとデコードの合計。
- 完全一致
- 人が確認したキーと完全に同じ場合だけ、正解とする方式。
データと方法
データをダウンロード
この記事の元になった記録を、ふつうのファイルとして公開します。CSVの先頭には短いREADMEを付けています。
# 出典:私たち自身の実行ログ。2026年8月17日にApple M1 Max 64GB、Ollama 0.32.14で測定。採点はスクリプト。正解は公開しません。ライセンス:未設定。
- まとめた実行:点数、秒数、出力サイズ
bundled-runs.csvダウンロード: bundled-runs.csv - まとめた実行:全小問の結果
bundled-per-question.csvダウンロード: bundled-per-question.csv - 1問ずつ:所要時間
one-question-seconds.csvダウンロード: one-question-seconds.csv - デコード速度と実時間
speed-variants.csvダウンロード: speed-variants.csv - 実行ログ(原文)
run-log.txtダウンロード: run-log.txt - 上記をまとめたJSONファイル
local-llm-bundled-context.jsonダウンロード: local-llm-bundled-context.json
参考資料
- 実行ログと正解キー. 私たち自身の実行ログを、人が確認したキーとの完全一致で再採点したもの。チームが保管しており、キーは公開しません。
- 上のデータファイル. この記事のすべての数字が含まれています。
