1 ポイント 投稿者 GN⁺ 3 시간 전 | 1件のコメント | WhatsAppで共有
  • ローカルなコーディングエージェント構成は、インターネット障害時でも macOS 上で OpenAI 互換 API によりモデルを実行し、Pi でテキストと画像入力を処理できるようにする設定
  • Apple M1 Max 64GB、macOS 15.7.7 で llama.cpp Metal と Gemma 4 26B-A4B GGUF モデルを使用し、基本の生成速度は 58.2 tok/s だった
  • MTP draft model を追加し、--spec-draft-n-max 3 に調整した後、生成速度は 72.2 tok/s まで向上し、約 24% 改善した
  • mmproj-BF16.gguf--mmproj で読み込み、Pi のモデル入力を ["text", "image"] に設定することで、スクリーンショットのような 画像入力 が渡される
  • 最終構成では llama.cpp サーバーを 127.0.0.1:8080/v1 で実行し、Pi がそれをローカルプロバイダーとして使用する。Qwen3.6 35B-A3B はより優れたコーディングエージェントのベンチマークを示したが、このテストでは 55 tok/s とより遅かった

ローカルなコーディングエージェント構成の目標

  • インターネット障害が何度か発生し、コーディングエージェントを使えなかったことが、ローカル実行構成を試すきっかけになった
  • 望んでいた構成は、Mac で実用的な速度で動作し、OpenAI 互換 API を通じて他のツールからも利用できることだった
  • 必要なときにスクリーンショットや画像を処理し、エージェントが作成した結果を再び入力として渡せる構成を目指した
  • 最終構成は llama.cpp、Gemma 4 26B-A4B GGUF、Q8 MTP draft model、Gemma 4 multimodal projector、Pi ターミナルコーディングエージェントで構成される
  • テスト環境は Apple M1 Max、64GB 統合メモリ、macOS 15.7.7 だった

モデル

  • メインモデルは gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf で、Hugging Face の unsloth-gemma-4-26B-A4B-it-GGUF リポジトリにある
  • このファイルサイズは約 16GB で、MTP draft head と multimodal projector を合わせて置くと、モデルフォルダーは約 17GB になる
  • ベンチマーク用プロンプトは Write a compact Python function that parses a unified diff and returns the changed file paths. Then explain two edge cases. だった
  • 各ベンチマークでは約 128 トークンを生成する

基本実行: llama.cpp + Metal

  • メインモデルは llama.cppMetal アクセラレーション で直接実行した
  • 実行コマンドは llama-cli にモデルパス、-ngl 999-fa on-c 4096-n 128 を指定する形だった
  • 基本構成でのプロンプト処理速度は 298.0 tok/s、生成速度は 58.2 tok/s だった
  • 58 tok/s は高速とまでは言えないが実用可能な水準であり、コーディングエージェントの作業ではツール呼び出しが多いため、できるだけ高速である必要がある

MTP draft model の追加

  • Gemma 4 には MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf 形式の MTP draft model が提供されている
  • llama.cpp ではこれを --model-draft--spec-type draft-mtp--spec-draft-n-max で speculative decoding に読み込む
  • MTP の最初の実行では、draft token 4 個で 69.2 tok/s を記録した
  • Unsloth のドキュメントでは --spec-draft-n-max 2 を開始点として推奨しているが、1 から 6 までをハードウェアごとに試し、最も速い値を使うよう勧めている
  • --spec-draft-n-max を調整した結果、draft token 3 個で 72.2 tok/s が最速だった
  • メインモデル単体は 58.2 tok/s で、Q8 MTP draft model を追加した構成は 72.2 tok/s だった
  • プロンプト処理速度はほぼ維持され、生成速度は約 24% 改善した

MTP チューニング結果

  • --spec-draft-n-max の値を 1 から 6 までテストした
  • 値 1 はプロンプト 295.5 tok/s、生成 68.4 tok/s だった
  • 値 2 はプロンプト 299.1 tok/s、生成 72.0 tok/s だった
  • 値 3 はプロンプト 295.6 tok/s、生成 72.2 tok/s で最速だった
  • 値 4 は生成 70.7 tok/s、値 5 は 63.7 tok/s、値 6 は 61.2 tok/s と遅くなった
  • M1 Max 環境では 3 が最速で、2 も十分近い結果だった

MLX との比較

  • Mac でモデルを動かすより高速な方法があるかを確認するため、mlx-lm ベースの MLX モデルもテストした
  • llama.cpp Metal + MTP は Unsloth GGUF Q4 と Q8 MTP の組み合わせで 72.2 tok/s を記録した
  • llama.cpp Metal 単体は Unsloth GGUF Q4 で 58.2 tok/s を記録した
  • MLX-LM は Unsloth UD MLX 4-bit で 45.8 tok/s を記録した
  • MLX-LMmlx-community 4-bit で 43.9 tok/s、mlx-community OptiQ 4-bit で 38.1 tok/s を記録した
  • この特定の構成では llama.cpp が MLX より高速で、MTP を適用した llama.cpp が最良の選択だった
  • gemma-4-swift-mlx で Gemma 4 MTP も試したが、テストした 26B 4-bit MLX チェックポイントがローダーの想定する weight key と一致せず、新しいモデルを再ダウンロードして調整することなく中断した

画像サポートの追加

  • Pi でスクリーンショットを添付するには、モデル入力がテキスト専用ではいけない
  • 元のローカルモデル項目は "input": ["text"] に設定されており、この場合 Pi は画像ツールの出力をモデルに正しく送れなかった
  • llama.cpp サーバーでも、マルチモーダル機能のために Gemma 4 の multimodal projector である mmproj-BF16.gguf が必要になる
  • --mmproj で projector を読み込むと、llama.cpp がマルチモーダル対応を通知し、Pi が画像を送れるようになる
  • projector なしで llama.cpp Metal + MTP を実行したテストでは、プロンプト 120.3 tok/s、生成 71.4 tok/s だった
  • mmproj-BF16.gguf を読み込んだ最終実行では、プロンプト 297.4 tok/s、生成 72.2 tok/s だった
  • projector を読み込んだ最終実行では、テキスト生成速度の低下は見られなかった

llama.cpp のインストール

  • 依存関係は Homebrew で cmakegittmuxpython@3.11 をインストールする
  • ~/Developer/ML-Models/Gemma4/repos パスを作成し、ggml-org/llama.cpp リポジトリを repos/llama.cpp にクローンする
  • ビルドは cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_METAL=ON -DGGML_ACCELERATE=ON で構成する
  • その後 cmake --build build --config Release -j でリリースビルドを行う
  • テストしたビルドは GGML_METAL=ONGGML_ACCELERATE=ONGGML_BLAS=ONGGML_BLAS_VENDOR=Apple の設定を持つ

モデルファイルのダウンロード

  • Python 3.11 の仮想環境を作成し、huggingface_hubhf_xet をインストールする
  • huggingface-cli download で Gemma 4 メインモデル、mmproj-BF16.gguf、MTP draft model をダウンロードする
  • ダウンロード対象ファイルは gemma-4-26B-A4B-it-UD-Q4_K_XL.ggufmmproj-BF16.ggufMTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf である
  • 最終的なモデルフォルダーは models/unsloth-gemma-4-26B-A4B-it-GGUF/ 配下に 3 つのファイルを含む

ローカルサーバーの起動

  • 最終サーバーは llama-server で実行し、メインモデル、MTP draft model、multimodal projector をすべて指定する
  • 主なオプションは --spec-type draft-mtp--spec-draft-n-max 3-ngl 999-fa on-c 65536--parallel 1 である
  • サーバーは --host 127.0.0.1 --port 8080 で起動する
  • OpenAI 互換エンドポイントは http://127.0.0.1:8080/v1 である
  • start_server.sh ラッパーは tmux セッションでサーバーを実行し、ログを logs/llama-server-mtp.log に残す
  • chmod +x start_server.sh の後、./start_server.sh でサーバーを起動する
  • サーバーが動作しているかは curl http://127.0.0.1:8080/v1/models で確認する

Pi の設定

  • Pi はモデルプロバイダー設定を ~/.pi/agent/models.json から読み込む
  • ローカルプロバイダー gemma4-localbaseUrlhttp://127.0.0.1:8080/v1 を指す
  • apiopenai-completions で、ローカルサーバーなので authHeaderfalse にしておく
  • モデル ID は gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf、名前は Gemma 4 26B-A4B Q4 + MTP に設定する
  • input["text", "image"] でなければならず、そうでない場合 Pi はモデルをテキスト専用として扱う
  • コンテキストウィンドウは 65536、最大トークン数は 8192 に設定する
  • 必要であれば ~/.pi/agent/settings.jsondefaultProvidergemma4-localdefaultModel を該当する GGUF ファイル名に指定する
  • pi --offline --list-models gemma を実行したとき、画像対応が yes と表示されることを期待する
  • ローカルモデルの実行は pi --provider gemma4-local --model gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf で行う
  • 非対話型実行は pi -p --provider gemma4-local --model gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf "Explain what this repository does" の形で行う
  • スクリーンショット入力は pi -p @"/path/to/screenshot.png" "Describe this image and point out anything relevant to the UI" の形で行う

最終構成

  • 最終的な推論ランタイムは llama.cpp
  • macOS のアクセラレーションは Metal + Accelerate の組み合わせ
  • メインモデルは gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf
  • draft model は gemma-4-26B-A4B-it-Q8_0-MTP.gguf
  • MTP 設定は --spec-draft-n-max 3
  • multimodal projector は mmproj-BF16.gguf
  • サーバーは 127.0.0.1:8080llama-server
  • API は OpenAI 互換の /v1
  • コーディングエージェントは Pi で、Pi のモデル入力は ["text", "image"]
  • MTP draft model はこの環境で Gemma 4 の生成速度を 58.2 tok/s から 72.2 tok/s に引き上げ、ローカルの OpenAI 互換サーバーとして動かすのに十分シンプルな構成だった

Qwen3.6 35B-A3B の代替案

  • 一部では Gemma 4 26B-A4B の代わりに Qwen3.6 35B-A3B の使用を勧めている
  • 確認可能なベンチマークでは、Qwen は Gemma 4 よりはるかに優れたコーディングエージェントと評価されている
  • ただし Qwen の構成はより遅く、Qwen3.6-35B-A3B-UD-Q4_K_XL.ggufunsloth-Qwen3.6-35B-A3B-MTP-GGUFmmproj-BF16.gguf の組み合わせで 55 tok/s を記録した
  • 72 tok/s ではなく 55 tok/s という差は、ユーザーが待たされる場面ではかなり大きい
  • Qwen モデルのダウンロードは unsloth/Qwen3.6-35B-A3B-MTP-GGUF から Qwen3.6-35B-A3B-UD-Q4_K_XL.ggufmmproj-BF16.gguf を取得する形で行う
  • Qwen サーバーは同じ llama-server を使うが、--port 8081 で起動する
  • Pi 設定での Qwen プロバイダー名は qwen36-localbaseUrlhttp://127.0.0.1:8081/v1
  • Qwen モデル設定は reasoning: trueinput: ["text", "image"]contextWindow: 65536maxTokens: 8192 を使う

1件のコメント

 
GN⁺ 3 시간 전
Hacker Newsの意見
  • ベンチマークのプロンプトが「unified diffをパースして変更されたファイルパスを返す簡潔なPython関数を書き、エッジケースを2つ説明せよ」で、各ベンチマークが約128トークンを生成していたなら、良い結果を得るには 128トークン は少なすぎるように見える
    MTP高速化は予測トークンがどれだけ頻繁に採用されるかに依存するが、経験上、出力の前半ほど採用率が高いので、短いテストは 偽陽性の高速化 を生む可能性がある
    llama.cppには、サーバーを再起動してプロンプトを送る必要なく引数を一通り試せるベンチマーク専用ツールがある: https://github.com/ggml-org/llama.cpp/blob/master/tools/llam...
    モデルダウンロードのセクションでも、llama.cppの -hf 引数で代わりにモデルを取得できる点に触れるべきだった。作者が経験を共有してくれたのはありがたいが、初心者にとって最善のガイドではないかもしれない

    • そもそも正式な開発者ガイドとして書いたものではなかった。画面録画がかなりブックマークされて、設定方法を聞くメッセージが来始めたので、このテストをどう組んだかを手早くまとめただけ
      Unclotheの「2倍高速」という発表を見て、「これなら実用になるくらい速くなるのか?」と思って自分で設定してみた
      去年もDevstralのようなもので試したが、遅すぎるうえに賢くなくて使い続ける気にならなかったし、今回はついに速度と知能の両方で 実用的だ と感じるところまで来た
    • 現実的には、任意のユーザープロンプトに加えて十分な システムプロンプト も入れて実験すべきだ。最低でも1000トークン以上、実際には3000トークン程度がよさそう
      llama.cppにはそのためのツールがあり、きちんと測るにはトークン生成前に プリフィル(prefill) を入れる必要がある。32kや64kのような長いコンテキストでのトークン生成速度測定も、ますます重要になっている
    • 128トークンではオペラではなく 序曲 だけをベンチマークしているようなものだ
    • 実際の問題を見ずに「自分のマシンでは動く」と言っているのと似ている。128トークンは本当に何でもなく、短い挨拶への応答より少し長い程度だ
  • 以前、ollamaとopencodeを使って似たような記事を書いたことがある: https://blog.kulman.sk/running-local-llm-coding-server/

    • Ollama は良い選択ではない: https://sleepingrobots.com/dreams/stop-using-ollama/
      opencodeはシステムプロンプトがコンテキストを食いすぎていないか? ローカルモデルはコンテキスト制約が大きいが、記憶ではopencodeはそのうち10kほど、あるいはそれに近い量を使っていた
    • 実際に役立つし、ollama GUI を使えばおそらくもっと簡単にもできる
  • llama.cppだけを使うなら、何かをダウンロードするのに huggingface-cli が必須というわけではなさそうだ。-hf ... を渡せばモデルを取得してくれる
    ダウンロード先を変えるには LLAMA_CACHE を設定すればよい:
    LLAMA_CACHE="models" ./llama-server \\
    -hf unsloth/gemma-4-31B-it-GGUF:UD-Q4_K_XL \\
    ...

    • ドラフトモデルには -hfd を使えばよい
  • 統合メモリRAMは大きいがテラフロップスと帯域幅GB/sが中程度以下なら、通常は MoE が最も有望だ。自分の環境であるM2 Max 96GBでは、(知能, tok/s, コンテキスト深度) の基準で現在の1位は DeepSeek-V4-Flash REAP25 <65gb gguf + ds4-server + pi agent
    もちろんクラウドAPIより優れているわけではないが、必要なら受け入れて使える程度にはなっている。インターネットのない4時間のフライトでも、ローカルLLMが60Wを消費していたのにバッテリーは十分もった
    REAPをサポートするds4ブランチはこちら: https://github.com/ljubomirj/ds4/tree/reap-compact-support
    DS4Fが 784Kコンテキスト になってようやく10 tok/s未満の実用外レベルまで落ちるという点が大きな違いを生んでいる

  • こうしたローカルモデルが、特定のプログラミング言語の専門家ではないユーザーに対しても本当に問題を解決してくれるのか気になる
    インライン自動補完や単位実装を超えて、実際に動く 技術仕様 を設計して組み立てられるのか、確信が持てない

  • llama.cpp/serverを使ってローカルLLMを立ち上げ、Claude CodeやCodex-CLIと一緒に使うのは比較的簡単
    必要なllama serverの設定があちこちに散らばっていることが多いので、人気のあるオープンLLMいくつかについての手引きをここで管理している: https://pchalasani.github.io/claude-code-tools/integrations/...

    • それを 日常使い しているのか? Claude Codeのプロンプトは非常に大きいので、ローカルモデルではプロンプト処理にかなり時間がかかり、ほどなくコンテキストも使い切ってしまう
  • omlx.aiを使って自分のハードウェアに合う複数の MLXモデル をダウンロードし、そのモデルでオープンソースおよびクローズドなハーネス(Claude Code、Codex)を自動実行するのにかなりうまく使えた
    WebでもデスクトップUIでも使えるので、個人的にはomlxを使えばブログ記事をなぞる必要はない

    • 64GB M1 Maxでは、oMLXやMLXがllama.cppの GGUF より特別に有利だとは感じなかった
      これまで見つけたGemma 4 MLXビルドは、同じ量子化でより遅く、MTPでははるかに遅かった
      モデルを選んだ後はllama.cppの内蔵Web UIがかなり良く、あれこれ試すならLM Studioも悪くない
      Gemma-4とQwen 3.6には、一般的なopencodeのシステムプロンプトの大きな塊はまったく不要で、むしろ外したほうがよい
    • oMLXとPiに接続する サンドボックス を探しているならこれがある: https://github.com/Dotnaught/pi-sandbox
    • Macでのローカル推論における 最先端 だと思う。回帰が起きても開発者たちの対応が非常に速く、最近見たオープンソースプロジェクトの中でも最も印象的だ
  • antirezのds4で動かす DeepSeek v4 Flash はかなり印象的だった
    「蓄積された知識」という面ではGPT-4級モデルのように感じるが、長い流れのツール呼び出しはGPT-4級モデルよりもうまくこなす
    128GB MBP M4 Maxで生成は約24 t/s、プリフィルは約200 t/s出る。遅いだろうと思っていたし、コード生成のような作業では実際に遅いが、簡単な作業のための マシンオーケストレーター としては驚くほど有用だ
    エージェント的でない用途でも会話するには十分良いモデルで、完全に自前で動かせて非公開にできる利点もある
    [0]https://github.com/antirez/ds4

  • とにかく怠けたいなら、ターミナルでClaude Codeを開き、この記事を指して、ただ「やって」と言えばよい

    • もうGoogle検索はほとんど使わなくなった。10回中9回は情報の質がひどく、周囲のスパムの中から必要な内容を見分けるのが難しいからだ
      一方でClaudeは、一発で処理するか、ほんの少し手直しするだけでやってくれる
      知識と実行への入口は今や LLM であり、Google Searchは恐竜のように感じる
      スマートフォン以上にすごいとさえ思え、1世紀ほど未来に来てしまったような感覚だ