Hacker News 热门(buzzing.cc 中文翻译)
精选
70AI 编辑部评分,满分 100

如何在macOS上设置本地编码代理

2026-06-13 04:18· 65天前· kkm
AI 导读

来自ikyle.me的教程,指导在macOS上搭建本地编码代理,获Hacker News社区104个点赞。

推荐理由

这篇文章不是泛泛的「本地跑大模型」,而是给 Mac 开发者一个实测过的、能打的生产环境编码代理方案,尤其 MTP 加速让速度不再鸡肋,可以直接抄作业。

正文 · AI 翻译

最近我的网络断了几次,导致我无法使用编程智能体,所以当我看到 Gemma 4 的“MTP 多 token 预测”更新,声称“Gemma 4 现在运行速度快了 2 倍”时,我决定尝试让它跑起来。

我想要一个本地编程智能体配置,它需要:

  • 速度快到能在我的 Mac 上实际使用
  • 通过兼容 OpenAI 的 API 工作(这样我就能在其他工具中使用它)
  • 并且最好能在需要时处理截图/图像,这样我就可以把制作好的截图喂给它。

而我做到了!这个视频是实时的。它展示了智能体以完全可用的速度进行响应。

经过一番测试,我最终确定的配置是:

  • 在 macOS 上使用 Metal 构建的 llama.cpp
  • GGUF 格式的 Gemma 4 26B-A4B
  • 用于推测解码的 Q8 MTP 草稿模型
  • Gemma 4 多模态投影器
  • Pi 作为终端编程智能体

这是在配备 64 GB 统一内存的 Apple M1 Max 上测试的,运行 macOS 15.7.7。

模型

主模型是:gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf。

该文件大约 16 GB。加上 MTP 草稿头和多模态投影器,模型文件夹大约 17 GB。

基准测试提示词是:

Write a compact Python function that parses a unified diff and returns the changed file paths. Then explain two edge cases.

每次基准测试生成约 128 个 token。

基线:llama.cpp + Metal

首先,我直接通过 llama.cpp 并使用 Metal 加速运行了主模型:

repos/llama.cpp/build/bin/llama-cli \
  -m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  -ngl 999 \
  -fa on \
  -c 4096 \
  -n 128

结果:

配置 提示词 token/秒 生成 token/秒
Gemma 4 26B-A4B Q4, llama.cpp Metal 298.0 58.2

58 token/秒不算快,但可用,不过对于编程智能体工作来说,你希望它尽可能快,尤其是当智能体在进行多次工具调用时。

添加 MTP 草稿模型

Gemma 4 现在提供了 MTP 草稿模型:

MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf

这可以通过 llama.cpp 作为推测性草稿模型加载:

repos/llama.cpp/build/bin/llama-cli \
  -m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  --model-draft models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
  --spec-type draft-mtp \
  --spec-draft-n-max 3 \
  -ngl 999 \
  -fa on \
  -c 4096 \
  -n 128

首次使用 MTP 运行时,使用 4 个草稿 token,速度达到了 69.2 token/秒。然而,Unsloth 的《如何运行 MTP 模型》指南中包含以下说明:

“我们发现 --spec-draft-n-max 2 是最好的起点,但不要假设 2 是最优的,因为性能取决于硬件。尝试 1 到 6 之间的任何值,并使用对您的系统最快的那个。”

在遍历 --spec-draft-n-max 后,使用 3 个草稿 token 获得了最佳结果,即 72.2 token/秒。

配置 提示词 token/秒 生成 token/秒 加速比
仅主模型 298.0 58.2 1.00x
主模型 + Q8 MTP 草稿 295.6 72.2 1.24x

有用的部分是,提示词处理速度基本保持不变,而生成速度提升了约 24%。

调整 MTP

我测试了 --spec-draft-n-max 参数从 1 到 6 的值。

--spec-draft-n-max 提示词 tok/s 生成 tok/s
1 295.5 68.4
2 299.1 72.0
3 295.6 72.2
4 297.3 70.7
5 297.9 63.7
6 296.3 61.2

在我的 M1 Max 机器上,值为 3 时最快,值为 2 时也非常接近,两者都可以接受。高于这些值的参数则变慢了。

MLX 对比

我还通过 mlx-lm 测试了 MLX 模型,以找出在 Mac 上运行模型更快的方式:是 llama.cpp 还是 mlx。

运行时 模型 生成 tok/s
llama.cpp Metal + MTP Unsloth GGUF Q4 + Q8 MTP 72.2
llama.cpp Metal Unsloth GGUF Q4 58.2
MLX-LM Unsloth UD MLX 4-bit 45.8
MLX-LM mlx-community 4-bit 43.9
MLX-LM mlx-community OptiQ 4-bit 38.1

我原以为 MLX(针对 Mac 优化)会是最快的。然而,对于这个特定配置,llama.cpp 比 MLX 更快,而带有 MTP 的 llama.cpp 显然是最佳选择。

我猜,llama.cpp 长期以来投入的所有优化和调整工作,意味着它在 macOS 上优化得相当好,尽管它是一个跨平台工具。

我还尝试通过 gemma-4-swift-mlx 运行 Gemma 4 MTP,但测试的 26B 4-bit MLX 检查点与加载器期望的权重键不匹配,而且我已经完成了之前的 MLX 测试,所以就继续往下进行了,没有再重新下载新模型并尝试调整参数来匹配。

添加图像支持

对于 Pi,我还希望能够附加截图。我最初为它设置的本地模型条目将模型声明为纯文本模型:

"input": ["text"]

这意味着 Pi 没有将图像工具输出正确地发送给模型。

llama.cpp 服务器还需要 Gemma 4 多模态投影仪,多模态部分才能正常工作(只有 12B 版本是原生多模态的):

mmproj-BF16.gguf

当使用 --mmproj 加载时,llama.cpp 会宣传支持多模态,并且 Pi 可以发送图像。

我重新运行了加载投影仪后的文本基准测试,以检查它是否改变了速度:

设置 投影仪 提示词 tok/s 生成 tok/s
llama.cpp Metal + MTP 120.3 71.4
llama.cpp Metal + MTP mmproj-BF16.gguf 297.4 72.2

最终加载投影仪后的运行并未显示文本生成速度下降。


以下是设置说明:

安装 llama.cpp

安装依赖项:

brew install cmake git tmux python@3.11

克隆并构建 llama.cpp:

mkdir -p ~/Developer/ML-Models/Gemma4/repos
cd ~/Developer/ML-Models/Gemma4

git clone https://github.com/ggml-org/llama.cpp repos/llama.cpp

cd repos/llama.cpp
cmake -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DGGML_METAL=ON \
  -DGGML_ACCELERATE=ON

cmake --build build --config Release -j

我测试的构建版本包含:

GGML_METAL=ON
GGML_ACCELERATE=ON
GGML_BLAS=ON
GGML_BLAS_VENDOR=Apple

下载模型文件

创建一个 Python 环境:

cd ~/Developer/ML-Models/Gemma4
python3.11 -m venv .venv
source .venv/bin/activate
pip install -U huggingface_hub hf_xet

下载文件:

mkdir -p models/unsloth-gemma-4-26B-A4B-it-GGUF

huggingface-cli download unsloth/gemma-4-26B-A4B-it-GGUF \
  gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  mmproj-BF16.gguf \
  MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
  --local-dir models/unsloth-gemma-4-26B-A4B-it-GGUF

最终你应该得到:

models/unsloth-gemma-4-26B-A4B-it-GGUF/
  gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf
  mmproj-BF16.gguf
  MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf

启动本地服务器

这是最终的服务器命令:

repos/llama.cpp/build/bin/llama-server \
  -m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  --model-draft models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
  --mmproj models/unsloth-gemma-4-26B-A4B-it-GGUF/mmproj-BF16.gguf \
  --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 中运行:

#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SESSION_NAME="${SESSION_NAME:-gemma4-server}"
HOST="${HOST:-127.0.0.1}"
PORT="${PORT:-8080}"
CTX_SIZE="${CTX_SIZE:-65536}"
PARALLEL="${PARALLEL:-1}"

LLAMA_SERVER="$ROOT_DIR/repos/llama.cpp/build/bin/llama-server"
MODEL="$ROOT_DIR/models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf"
DRAFT_MODEL="$ROOT_DIR/models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf"
MMPROJ="$ROOT_DIR/models/unsloth-gemma-4-26B-A4B-it-GGUF/mmproj-BF16.gguf"
LOG_FILE="$ROOT_DIR/logs/llama-server-mtp.log"

mkdir -p "$ROOT_DIR/logs"

tmux new-session -d -s "$SESSION_NAME" -c "$ROOT_DIR" \
  "$LLAMA_SERVER \
    -m '$MODEL' \
    --model-draft '$DRAFT_MODEL' \
    --mmproj '$MMPROJ' \
    --spec-type draft-mtp \
    --spec-draft-n-max 3 \
    -ngl 999 \
    -fa on \
    -c '$CTX_SIZE' \
    --parallel '$PARALLEL' \
    --host '$HOST' \
    --port '$PORT' \
    2>&1 | tee -a '$LOG_FILE'"

启动它:

chmod +x start_server.sh
./start_server.sh

检查服务器是否正在运行:

curl http://127.0.0.1:8080/v1/models

配置 Pi

Pi 从以下位置读取模型提供商配置:

~/.pi/agent/models.json

添加一个本地提供商:

{
  "providers": {
    "gemma4-local": {
      "name": "Gemma 4 Local",
      "baseUrl": "http://127.0.0.1:8080/v1",
      "api": "openai-completions",
      "apiKey": "local",
      "authHeader": false,
      "compat": {
        "supportsDeveloperRole": false,
        "supportsReasoningEffort": false
      },
      "models": [
        {
          "id": "gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf",
          "name": "Gemma 4 26B-A4B Q4 + MTP",
          "reasoning": false,
          "input": ["text", "image"],
          "contextWindow": 65536,
          "maxTokens": 8192,
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          }
        }
      ]
    }
  }
}

重要的部分包括:

  • baseUrl 指向 llama.cpp 的兼容 OpenAI 的服务器。
  • api 设置为 openai-completions。
  • authHeader 设置为 false,因为这是一个本地服务器。
  • input 同时包含 text 和 image,否则 Pi 会将其视为纯文本模式。

可选地,将其设为默认配置,在:

~/.pi/agent/settings.json
{
  "defaultProvider": "gemma4-local",
  "defaultModel": "gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf",
  "defaultThinkingLevel": "minimal"
}

然后检查 Pi 是否能识别它:

pi --offline --list-models gemma

预期输出:

provider      model                               context  max-out  thinking  images
gemma4-local  gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf  65.5K    8.2K     no        yes

使用本地模型运行 Pi:

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
草稿模型 gemma-4-26B-A4B-it-Q8_0-MTP.gguf
MTP 设置 --spec-draft-n-max 3
多模态投影器 mmproj-BF16.gguf
服务器 运行在 127.0.0.1:8080 的 llama-server
API 兼容 OpenAI 的 /v1
编程智能体 Pi
Pi 模型输入 ["text", "image"]

主要结论是,MTP 草稿模型值得使用。在这台机器上,它使 Gemma 4 的推理速度从 58.2 tokens/秒提升到了 72.2 tokens/秒,同时保持了足够简单的配置,使其能够作为本地兼容 OpenAI 的服务器运行。


附注:有人建议使用 Qwen3.6 35B-A3B 替代 Gemma 4 26B-A4B。根据我能找到的基准测试,Qwen 作为编程智能体的表现远优于 Gemma 4。然而,它的速度也更慢。Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf + unsloth-Qwen3.6-35B-A3B-MTP-GGUF + mmproj-BF16.gguf 的结果是 55 tk/s,而不是 72 tk/s。当你坐在那里等待时,这个差距是相当明显的。

下载模型:

mkdir -p models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF

huggingface-cli download unsloth/Qwen3.6-35B-A3B-MTP-GGUF \
  Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf \
  mmproj-BF16.gguf \
  --local-dir models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF

启动服务器:

LLAMA_SERVER=/Users/kylehowells/Developer/ML-Models/Gemma4/repos/llama.cpp/build/bin/llama-server

$LLAMA_SERVER \
  -m models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF/Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf \
  --mmproj models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF/mmproj-BF16.gguf \
  --spec-type draft-mtp \
  --spec-draft-n-max 3 \
  -ngl 999 \
  -fa on \
  -c 65536 \
  --parallel 1 \
  --host 127.0.0.1 \
  --port 8081

Pi 配置:

{
  "providers": {
    "qwen36-local": {
      "name": "Qwen3.6 Local",
      "baseUrl": "http://127.0.0.1:8081/v1",
      "api": "openai-completions",
      "apiKey": "local",
      "authHeader": false,
      "compat": {
        "supportsDeveloperRole": false,
        "supportsReasoningEffort": false
      },
      "models": [
        {
          "id": "Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf",
          "name": "Qwen3.6 35B-A3B Q4 + MTP",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 65536,
          "maxTokens": 8192,
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          }
        }
      ]
    }
  }
}

参考链接:

  • unsloth.ai/docs/models/qwen3.6
  • unsloth.ai/docs/models/gemma-4
  • unsloth.ai/docs/models/mtp
  • github.com/ggml-org/llama.cpp
  • github.com/earendil-works/pi
  • 介绍 Gemma 4 12B:一个统一的、无编码器的多模态模型
  • "MTP 使 Google Gemma 4 运行速度提升约 1.4–2.2 倍,且精度无损失"
  • unsloth/gemma-4-26B-A4B-it-GGUF
  • unsloth/Qwen3.6-35B-A3B-MTP-GGUF

来源:Hacker News 热门(buzzing.cc 中文翻译) · ikyle.me

如何在macOS上设置本地编码代理

Hacker News 热门(buzzing.cc 中文翻译)·2026-06-13 04:18·65天前·kkm
AI 导读

来自ikyle.me的教程,指导在macOS上搭建本地编码代理,获Hacker News社区104个点赞。

正文 · AI 翻译

最近我的网络断了几次,导致我无法使用编程智能体,所以当我看到 Gemma 4 的“MTP 多 token 预测”更新,声称“Gemma 4 现在运行速度快了 2 倍”时,我决定尝试让它跑起来。

我想要一个本地编程智能体配置,它需要:

  • 速度快到能在我的 Mac 上实际使用
  • 通过兼容 OpenAI 的 API 工作(这样我就能在其他工具中使用它)
  • 并且最好能在需要时处理截图/图像,这样我就可以把制作好的截图喂给它。

而我做到了!这个视频是实时的。它展示了智能体以完全可用的速度进行响应。

经过一番测试,我最终确定的配置是:

  • 在 macOS 上使用 Metal 构建的 llama.cpp
  • GGUF 格式的 Gemma 4 26B-A4B
  • 用于推测解码的 Q8 MTP 草稿模型
  • Gemma 4 多模态投影器
  • Pi 作为终端编程智能体

这是在配备 64 GB 统一内存的 Apple M1 Max 上测试的,运行 macOS 15.7.7。

模型

主模型是:gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf。

该文件大约 16 GB。加上 MTP 草稿头和多模态投影器,模型文件夹大约 17 GB。

基准测试提示词是:

Write a compact Python function that parses a unified diff and returns the changed file paths. Then explain two edge cases.

每次基准测试生成约 128 个 token。

基线:llama.cpp + Metal

首先,我直接通过 llama.cpp 并使用 Metal 加速运行了主模型:

repos/llama.cpp/build/bin/llama-cli \
  -m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  -ngl 999 \
  -fa on \
  -c 4096 \
  -n 128

结果:

配置 提示词 token/秒 生成 token/秒
Gemma 4 26B-A4B Q4, llama.cpp Metal 298.0 58.2

58 token/秒不算快,但可用,不过对于编程智能体工作来说,你希望它尽可能快,尤其是当智能体在进行多次工具调用时。

添加 MTP 草稿模型

Gemma 4 现在提供了 MTP 草稿模型:

MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf

这可以通过 llama.cpp 作为推测性草稿模型加载:

repos/llama.cpp/build/bin/llama-cli \
  -m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  --model-draft models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
  --spec-type draft-mtp \
  --spec-draft-n-max 3 \
  -ngl 999 \
  -fa on \
  -c 4096 \
  -n 128

首次使用 MTP 运行时,使用 4 个草稿 token,速度达到了 69.2 token/秒。然而,Unsloth 的《如何运行 MTP 模型》指南中包含以下说明:

“我们发现 --spec-draft-n-max 2 是最好的起点,但不要假设 2 是最优的,因为性能取决于硬件。尝试 1 到 6 之间的任何值,并使用对您的系统最快的那个。”

在遍历 --spec-draft-n-max 后,使用 3 个草稿 token 获得了最佳结果,即 72.2 token/秒。

配置 提示词 token/秒 生成 token/秒 加速比
仅主模型 298.0 58.2 1.00x
主模型 + Q8 MTP 草稿 295.6 72.2 1.24x

有用的部分是,提示词处理速度基本保持不变,而生成速度提升了约 24%。

调整 MTP

我测试了 --spec-draft-n-max 参数从 1 到 6 的值。

--spec-draft-n-max 提示词 tok/s 生成 tok/s
1 295.5 68.4
2 299.1 72.0
3 295.6 72.2
4 297.3 70.7
5 297.9 63.7
6 296.3 61.2

在我的 M1 Max 机器上,值为 3 时最快,值为 2 时也非常接近,两者都可以接受。高于这些值的参数则变慢了。

MLX 对比

我还通过 mlx-lm 测试了 MLX 模型,以找出在 Mac 上运行模型更快的方式:是 llama.cpp 还是 mlx。

运行时 模型 生成 tok/s
llama.cpp Metal + MTP Unsloth GGUF Q4 + Q8 MTP 72.2
llama.cpp Metal Unsloth GGUF Q4 58.2
MLX-LM Unsloth UD MLX 4-bit 45.8
MLX-LM mlx-community 4-bit 43.9
MLX-LM mlx-community OptiQ 4-bit 38.1

我原以为 MLX(针对 Mac 优化)会是最快的。然而,对于这个特定配置,llama.cpp 比 MLX 更快,而带有 MTP 的 llama.cpp 显然是最佳选择。

我猜,llama.cpp 长期以来投入的所有优化和调整工作,意味着它在 macOS 上优化得相当好,尽管它是一个跨平台工具。

我还尝试通过 gemma-4-swift-mlx 运行 Gemma 4 MTP,但测试的 26B 4-bit MLX 检查点与加载器期望的权重键不匹配,而且我已经完成了之前的 MLX 测试,所以就继续往下进行了,没有再重新下载新模型并尝试调整参数来匹配。

添加图像支持

对于 Pi,我还希望能够附加截图。我最初为它设置的本地模型条目将模型声明为纯文本模型:

"input": ["text"]

这意味着 Pi 没有将图像工具输出正确地发送给模型。

llama.cpp 服务器还需要 Gemma 4 多模态投影仪,多模态部分才能正常工作(只有 12B 版本是原生多模态的):

mmproj-BF16.gguf

当使用 --mmproj 加载时,llama.cpp 会宣传支持多模态,并且 Pi 可以发送图像。

我重新运行了加载投影仪后的文本基准测试,以检查它是否改变了速度:

设置 投影仪 提示词 tok/s 生成 tok/s
llama.cpp Metal + MTP 120.3 71.4
llama.cpp Metal + MTP mmproj-BF16.gguf 297.4 72.2

最终加载投影仪后的运行并未显示文本生成速度下降。


以下是设置说明:

安装 llama.cpp

安装依赖项:

brew install cmake git tmux python@3.11

克隆并构建 llama.cpp:

mkdir -p ~/Developer/ML-Models/Gemma4/repos
cd ~/Developer/ML-Models/Gemma4

git clone https://github.com/ggml-org/llama.cpp repos/llama.cpp

cd repos/llama.cpp
cmake -B build \
  -DCMAKE_BUILD_TYPE=Release \
  -DGGML_METAL=ON \
  -DGGML_ACCELERATE=ON

cmake --build build --config Release -j

我测试的构建版本包含:

GGML_METAL=ON
GGML_ACCELERATE=ON
GGML_BLAS=ON
GGML_BLAS_VENDOR=Apple

下载模型文件

创建一个 Python 环境:

cd ~/Developer/ML-Models/Gemma4
python3.11 -m venv .venv
source .venv/bin/activate
pip install -U huggingface_hub hf_xet

下载文件:

mkdir -p models/unsloth-gemma-4-26B-A4B-it-GGUF

huggingface-cli download unsloth/gemma-4-26B-A4B-it-GGUF \
  gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  mmproj-BF16.gguf \
  MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
  --local-dir models/unsloth-gemma-4-26B-A4B-it-GGUF

最终你应该得到:

models/unsloth-gemma-4-26B-A4B-it-GGUF/
  gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf
  mmproj-BF16.gguf
  MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf

启动本地服务器

这是最终的服务器命令:

repos/llama.cpp/build/bin/llama-server \
  -m models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf \
  --model-draft models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf \
  --mmproj models/unsloth-gemma-4-26B-A4B-it-GGUF/mmproj-BF16.gguf \
  --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 中运行:

#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SESSION_NAME="${SESSION_NAME:-gemma4-server}"
HOST="${HOST:-127.0.0.1}"
PORT="${PORT:-8080}"
CTX_SIZE="${CTX_SIZE:-65536}"
PARALLEL="${PARALLEL:-1}"

LLAMA_SERVER="$ROOT_DIR/repos/llama.cpp/build/bin/llama-server"
MODEL="$ROOT_DIR/models/unsloth-gemma-4-26B-A4B-it-GGUF/gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf"
DRAFT_MODEL="$ROOT_DIR/models/unsloth-gemma-4-26B-A4B-it-GGUF/MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf"
MMPROJ="$ROOT_DIR/models/unsloth-gemma-4-26B-A4B-it-GGUF/mmproj-BF16.gguf"
LOG_FILE="$ROOT_DIR/logs/llama-server-mtp.log"

mkdir -p "$ROOT_DIR/logs"

tmux new-session -d -s "$SESSION_NAME" -c "$ROOT_DIR" \
  "$LLAMA_SERVER \
    -m '$MODEL' \
    --model-draft '$DRAFT_MODEL' \
    --mmproj '$MMPROJ' \
    --spec-type draft-mtp \
    --spec-draft-n-max 3 \
    -ngl 999 \
    -fa on \
    -c '$CTX_SIZE' \
    --parallel '$PARALLEL' \
    --host '$HOST' \
    --port '$PORT' \
    2>&1 | tee -a '$LOG_FILE'"

启动它:

chmod +x start_server.sh
./start_server.sh

检查服务器是否正在运行:

curl http://127.0.0.1:8080/v1/models

配置 Pi

Pi 从以下位置读取模型提供商配置:

~/.pi/agent/models.json

添加一个本地提供商:

{
  "providers": {
    "gemma4-local": {
      "name": "Gemma 4 Local",
      "baseUrl": "http://127.0.0.1:8080/v1",
      "api": "openai-completions",
      "apiKey": "local",
      "authHeader": false,
      "compat": {
        "supportsDeveloperRole": false,
        "supportsReasoningEffort": false
      },
      "models": [
        {
          "id": "gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf",
          "name": "Gemma 4 26B-A4B Q4 + MTP",
          "reasoning": false,
          "input": ["text", "image"],
          "contextWindow": 65536,
          "maxTokens": 8192,
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          }
        }
      ]
    }
  }
}

重要的部分包括:

  • baseUrl 指向 llama.cpp 的兼容 OpenAI 的服务器。
  • api 设置为 openai-completions。
  • authHeader 设置为 false,因为这是一个本地服务器。
  • input 同时包含 text 和 image,否则 Pi 会将其视为纯文本模式。

可选地,将其设为默认配置,在:

~/.pi/agent/settings.json
{
  "defaultProvider": "gemma4-local",
  "defaultModel": "gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf",
  "defaultThinkingLevel": "minimal"
}

然后检查 Pi 是否能识别它:

pi --offline --list-models gemma

预期输出:

provider      model                               context  max-out  thinking  images
gemma4-local  gemma-4-26B-A4B-it-UD-Q4_K_XL.gguf  65.5K    8.2K     no        yes

使用本地模型运行 Pi:

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
草稿模型 gemma-4-26B-A4B-it-Q8_0-MTP.gguf
MTP 设置 --spec-draft-n-max 3
多模态投影器 mmproj-BF16.gguf
服务器 运行在 127.0.0.1:8080 的 llama-server
API 兼容 OpenAI 的 /v1
编程智能体 Pi
Pi 模型输入 ["text", "image"]

主要结论是,MTP 草稿模型值得使用。在这台机器上,它使 Gemma 4 的推理速度从 58.2 tokens/秒提升到了 72.2 tokens/秒,同时保持了足够简单的配置,使其能够作为本地兼容 OpenAI 的服务器运行。


附注:有人建议使用 Qwen3.6 35B-A3B 替代 Gemma 4 26B-A4B。根据我能找到的基准测试,Qwen 作为编程智能体的表现远优于 Gemma 4。然而,它的速度也更慢。Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf + unsloth-Qwen3.6-35B-A3B-MTP-GGUF + mmproj-BF16.gguf 的结果是 55 tk/s,而不是 72 tk/s。当你坐在那里等待时,这个差距是相当明显的。

下载模型:

mkdir -p models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF

huggingface-cli download unsloth/Qwen3.6-35B-A3B-MTP-GGUF \
  Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf \
  mmproj-BF16.gguf \
  --local-dir models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF

启动服务器:

LLAMA_SERVER=/Users/kylehowells/Developer/ML-Models/Gemma4/repos/llama.cpp/build/bin/llama-server

$LLAMA_SERVER \
  -m models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF/Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf \
  --mmproj models/unsloth-Qwen3.6-35B-A3B-MTP-GGUF/mmproj-BF16.gguf \
  --spec-type draft-mtp \
  --spec-draft-n-max 3 \
  -ngl 999 \
  -fa on \
  -c 65536 \
  --parallel 1 \
  --host 127.0.0.1 \
  --port 8081

Pi 配置:

{
  "providers": {
    "qwen36-local": {
      "name": "Qwen3.6 Local",
      "baseUrl": "http://127.0.0.1:8081/v1",
      "api": "openai-completions",
      "apiKey": "local",
      "authHeader": false,
      "compat": {
        "supportsDeveloperRole": false,
        "supportsReasoningEffort": false
      },
      "models": [
        {
          "id": "Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf",
          "name": "Qwen3.6 35B-A3B Q4 + MTP",
          "reasoning": true,
          "input": ["text", "image"],
          "contextWindow": 65536,
          "maxTokens": 8192,
          "cost": {
            "input": 0,
            "output": 0,
            "cacheRead": 0,
            "cacheWrite": 0
          }
        }
      ]
    }
  }
}

参考链接:

  • unsloth.ai/docs/models/qwen3.6
  • unsloth.ai/docs/models/gemma-4
  • unsloth.ai/docs/models/mtp
  • github.com/ggml-org/llama.cpp
  • github.com/earendil-works/pi
  • 介绍 Gemma 4 12B:一个统一的、无编码器的多模态模型
  • "MTP 使 Google Gemma 4 运行速度提升约 1.4–2.2 倍,且精度无损失"
  • unsloth/gemma-4-26B-A4B-it-GGUF
  • unsloth/Qwen3.6-35B-A3B-MTP-GGUF

来源:Hacker News 热门(buzzing.cc 中文翻译)· ikyle.me