ローカルLLM比較ツールを作って動かしてみたら、意外な事実がわかった

カテゴリ:個人開発 / ローカルLLM
タグ:LLM, OmniCoder, Qwen2.5, Python, 比較


Contents

はじめに

「このAI、どっちが使えるの?」

ローカルLLMを複数台のMacに入れて使い始めた時、最初に気になったのはこれだった。ベンチマークのスコアを見てもピンとこない。数字じゃなく、自分の仕事に近いシーンで比べたい。

そこで作ったのが、2つのモデルに同じ質問を投げて結果を並べて表示するツール「llm-compare」だ。

今日、初めて実際に2台のMacで動かしてみた。結果は想像と違うものだった。


環境

役割マシンモデル
サーバーiMacOmniCoder-9B(GGUF / Q4_K_S)
クライアントMacBook AirQwen2.5-Coder-14B(MLX / 4bit)

両方とも LM Studio を使い、Wi-Fi LAN 経由で MacBook Air から iMac に接続する構成。

ツールは Python で書いた60行ほどのスクリプト。models.yamlprompts.yaml で設定を分けているので、モデルが変わってもコードは触らなくていい。


テストした3つの質問

  1. 挨拶テスト:「こんにちは。あなたは何ができますか?3行で教えてください。」
  2. コード生成:「Pythonで、リストの重複を除去する関数を書いてください。」
  3. 説明力テスト:「初心者にAPIとは何かを、身近な例えを使って説明してください。」

結果

応答時間の比較

テストOmniCoder-9BQwen2.5-Coder-14B
挨拶テスト78.4秒4.0秒
コード生成99.7秒20.4秒
説明力テスト114.3秒23.6秒

**Qwen2.5が圧倒的に速い。**約3〜20倍の差がついた。

回答の質の比較

挨拶テスト

OmniCoder は「3行で」という指示を律儀に守り、3行ぴったりで回答した。Qwen2.5 は1文でシンプルに返した。

コード生成

OmniCoder は5パターンのコードを、まとめ表つきで丁寧に解説した。ハッシュ不可能な要素への対応まで書いてある。一方 Qwen2.5 は2パターンで「実用的に十分」な回答を返した。

説明力テスト

ここで意外な結果が出た。OmniCoder の回答が空だった。


なぜ OmniCoder の回答が空だったのか

調べてわかったのは、OmniCoder-9B が「推論モデル」だということだ。

通常のモデルは「質問 → 即回答」という流れで動く。推論モデルは「質問 → 内部で長く考える → 回答」という流れになる。この「内部で考える」部分が reasoning_content として存在し、content(実際の回答)とは別に記録される。

curl でレスポンスを確認したら、こうなっていた:

"content": ""                  ← 回答が空
"reasoning_content": "..."     ← 内部の思考は大量にある
"reasoning_tokens": 255        ← 256トークン中255を思考に使用
"finish_reason": "length"      ← トークン上限で打ち切り

つまり、考えすぎてトークンを使い切り、回答を出す前に打ち切られていた。

max_tokens を 512 → 1024 に増やし、タイムアウトを 60秒 → 180秒 にして再実行。コード生成テストは回答が出るようになった。説明力テストは1024トークンでもまだ足りなかった。


わかったこと:2つのモデルの「性格」

ベンチマーク数値ではわからなかったことが、実際に動かしてわかった。

OmniCoder-9B = じっくり考える秀才

  • 時間をかけて網羅的な回答を作る
  • 指示の細部(「3行で」)を忠実に守る
  • 深く考えるが遅い。即答が必要な場面には向かない

Qwen2.5-Coder-14B = 要領の良い実務家

  • 4〜23秒で即答
  • 必要十分な回答を手短にまとめる
  • MLX最適化で MacBook Air との相性が良い

使い分けの結論

用途使うモデル
コードをすぐ書きたい・実装作業Qwen2.5-Coder-14B
設計・要件を深く考えたい・壁打ちOmniCoder-9B

同じ「9B / 14B」というパラメータ数の比較でも、モデルの設計思想によってまったく違う動きをする。


ツールを作ってよかったこと

一番の収穫は、「なぜ空だったのか」を自分で調べて突き止めたことだ。

finish_reason: "length" というログを見て、「トークン制限で打ち切られた」と気づく。reasoning_tokens: 255 を見て、「思考に全部使われた」と理解する。そこから max_tokenstimeout を調整して、少し改善する。

これはベンチマークを眺めているだけでは絶対に体験できない学習だった。

「自分の手を動かして、自分の環境で動かす」ことの価値を改めて実感した。


今後やること

  • OmniCoder 向けに max_tokens: 2048 + timeout: 300秒 のプロファイルを追加
  • 回答を自動的にファイルに保存する機能を追加
  • スコアをつける評価機能(将来的にはClaudeに評価させる)

llm-compare はまだ v0.1 だ。でも「動く」状態になった。ここから育てていく。


2026年5月24日