双机本地 AI 部署全记录:Mac M3 Pro + Ubuntu RTX 5070 跑 Gemma 4 26B

用了将近一周,踩了无数坑,终于让 Gemma 4 26B 在 Mac M3 Pro + Ubuntu RTX 5070 双机 RPC 分布式下跑起来了。记录完整踩坑过程,包括 CUDA 版本问题、编译方法、tensor-split 调参、思考模式控制等。

用了将近一周,踩了无数坑,终于让 Gemma 4 26B 在 Mac + Linux 双机 RPC 分布式下跑起来了。记录一下完整过程,希望能帮到有类似想法的人。


硬件配置

机器 配置 角色
MacBook Pro Apple M3 Pro,18GB 统一内存 llama-server 主控端
Ubuntu 台式机 RTX 5070(8GB VRAM),Ubuntu 26.04 RPC 远程 GPU 节点

两台机器通过局域网连接,Ubuntu 机器 IP 为 192.168.1.105


为什么要双机

M3 Pro 只有 18GB 统一内存,Metal 可用约 13.6GB。

Gemma 4 26B-A4B 各量化版本体积:

  • Q3_K_M ≈ 12GB
  • Q4_K_M ≈ 16GB

Q4_K_M 单机完全放不下,Q3_K_M 加上 KV cache 也很勉强。所以想把一部分层卸载到 Ubuntu 那台 RTX 5070 上,两台机器合力跑。

这就是 llama.cpp 的 RPC(Remote Procedure Call) 功能——把远端 GPU 当成本地 GPU 来用,通过网络传输张量数据。


第一阶段:尝试 exo(放弃)

最初想用 exo 做分布式推理,但发现:

  • exo 主要为 Apple Silicon 多机(MLX Ring)优化
  • Mac + Linux 混合集群支持非常弱
  • Gemma 4 架构太新(MoE + 混合注意力),exo 的 shard planner 还没适配
  • 运行时报 No valid configurations,根本跑不起来

放弃 exo,转投 llama.cpp RPC。


第二阶段:llama.cpp RPC 基础搭建

原理

Mac (llama-server) ←→ 网络 ←→ Ubuntu (rpc-server)
     主控端,Metal GPU           远端 CUDA GPU

llama-server 在 Mac 运行,把模型的部分层(通过 tensor-split 指定比例)分配到远端 rpc-server 处理。

Ubuntu 上编译 rpc-server

Ubuntu 26.04 + RTX 5070 这台需要自己编译,因为 llama.cpp 官方 Release 不提供 Linux CUDA 预编译版(Windows 有,Linux 没有)。

cd ~/AI
git clone --depth 1 --branch b9266 https://github.com/ggml-org/llama.cpp.git llama.cpp-b9266
cd llama.cpp-b9266

cmake -B build \
  -DGGML_CUDA=ON \
  -DGGML_RPC=ON \
  -DCMAKE_CUDA_ARCHITECTURES="120" \
  -DCMAKE_BUILD_TYPE=Release

cmake --build build --config Release -j $(nproc)

注意:RTX 5070 是 Blackwell 架构,compute capability 12.0,所以是 CUDA_ARCHITECTURES="120"。老卡(30系/40系)对应 86/89。

Mac 上使用预编译版

Mac 这边直接用官方 Release 的预编译包:

wget https://github.com/ggml-org/llama.cpp/releases/download/b9266/llama-b9266-bin-macos-arm64.tar.gz
tar -xzf llama-b9266-bin-macos-arm64.tar.gz

第三阶段:踩坑记录

坑 1:SOFT_MAX CUDA 错误

最早用的是 b9247 版本,Gemma 4 一跑就崩:

ggml_cuda_compute_forward: SOFT_MAX failed
CUDA error: invalid argument

原因:CUDA 13.2 + Gemma 4 的混合注意力(sliding window + global attention)不兼容,SOFT_MAX kernel 计算时出现 invalid argument。

Unsloth 文档有明确警告:不要对 Gemma 4 GGUF 使用 CUDA 13.2 runtime。

Mistral 24B 能正常跑,Gemma 4 就崩——根本原因在于 Gemma 4 使用了 Mistral 没有的混合注意力机制。

坑 2:Ubuntu 26.04 + CUDA 12.8 不兼容

想降级到 CUDA 12.8 绕开这个 bug,但 Ubuntu 26.04 用的是 GCC 14 + 新版 glibc,CUDA 12.8 的头文件声明与 glibc 冲突:

/usr/include/x86_64-linux-gnu/bits/mathcalls.h(206): error:
exception specification is incompatible with that of previous function "rsqrt"

CUDA 12.8 是为 Ubuntu 24.04(GCC 12-13)设计的,不支持 Ubuntu 26.04 的 glibc 2.41。

坑 3:Ubuntu 26.04 的 CUDA 现状

Ubuntu 26.04 是第一个原生分发 CUDA 的 Ubuntu 版本,但:

  • 系统 nvidia-cuda-toolkit 包实际是 CUDA 12.4(不是 13.1)
  • NVIDIA 官方仓库目前没有 ubuntu2604 支持
  • 只能用 24.04 的仓库强装,会遇到 GCC/glibc 兼容问题

坑 4:CUDA 13.1 的 rsqrt 冲突

从 NVIDIA 24.04 仓库装 CUDA 13.1,比 12.8 少了几个报错,但还剩 2 个:

error: exception specification is incompatible with that of previous function "rsqrt"
error: exception specification is incompatible with that of previous function "rsqrtf"

解决方案:手动给 CUDA 头文件打补丁,在 rsqrtrsqrtf 的声明末尾加 noexcept(true)

sudo nano /usr/local/cuda-13.1/targets/x86_64-linux/include/crt/math_functions.h

找到约第 629 行:

// 改前
extern __DEVICE_FUNCTIONS_DECL__ __cudart_builtin__ double rsqrt(double x);
// 改后
extern __DEVICE_FUNCTIONS_DECL__ __cudart_builtin__ double rsqrt(double x) noexcept(true);

同样修改 rsqrtf(约 653 行)。修改后重新编译,成功

坑 5:CMake 缓存目录冲突

之前删文件夹用的"移到废纸篓"而不是彻底删除,导致:

CMake Error: The current CMakeCache.txt directory .../Trash/files/llama.cpp-b9266/build/CMakeCache.txt
is different than the directory /home/rcwalter/AI/llama.cpp-b9266/build

解决:

rm -rf ~/.local/share/Trash/files/llama.cpp-b9266
rm -rf ~/AI/llama.cpp-b9266/build

坑 6:tensor-split 比例不对导致分配失败

早期尝试了各种 split 比例(30/70、35/65 等),全部失败:

E alloc_tensor_range: failed to allocate RPC0 buffer of size 8768359296

原因:RPC server 报告的可用显存是乐观估计,实际能分配的单个 buffer 远小于报告值。RTX 5070 的 8GB VRAM,实际能用约 6.5GB。

最终可用的比例是 63,37(Mac 占 63%,RPC 占 37%)。

坑 7:中文逗号

命令里写了中文全角逗号 45,55,导致 tensor-split 解析失败,实际没有按比例分配。

一定要用英文半角逗号:45,55

坑 8:–no-webui 后忘记加反斜杠

# 错误:--no-webui 后没有 \,后面的参数被忽略了
--no-webui
--jinja \
--reasoning off

导致 --jinja--reasoning off 完全没有生效。每行末尾都需要 \,最后一行不需要。


第四阶段:成功运行

Ubuntu 启动 rpc-server

cd ~/AI/llama.cpp-b9266
./build/bin/rpc-server -H 0.0.0.0 -p 50052 -d CUDA0 -m 6000

-m 6000 限制最大显存使用 6000MiB,防止分配超出实际可用量。

启动后确认看到:

ggml_cuda_init: found 1 CUDA devices:
  Device 0: NVIDIA GeForce RTX 5070 ...

Mac 启动 llama-server(最终命令)

./llama-server \
  --rpc 192.168.1.105:50052 \
  --device MTL0,RPC0 \
  --tensor-split 63,37 \
  -m ./models/google_gemma-4-26B-A4B-it-Q4_K_M.gguf \
  --mmproj ./models/mmproj-google_gemma-4-26B-A4B-it-f16.gguf \
  -ngl 99 \
  -c 4096 \
  -np 1 \
  --temp 1.0 \
  --top-p 0.95 \
  --top-k 64 \
  --repeat-penalty 1.0 \
  --flash-attn on \
  --cache-type-k q8_0 \
  --cache-type-v q8_0 \
  --jinja \
  --reasoning off \
  --host 0.0.0.0 \
  --port 7081 \
  --no-webui

参数说明:

  • --tensor-split 63,37:Mac 承担 63% 的层,Ubuntu RPC 承担 37%
  • --mmproj:视觉投影器,启用多模态图像输入
  • --flash-attn on:Flash Attention,走不同代码路径,规避了部分 SOFT_MAX 问题
  • --cache-type-k/v q8_0:KV cache 量化到 8bit,节省约一半显存
  • --jinja:启用 Jinja 模板引擎,支持变量传参(思考模式控制等)
  • --reasoning off:禁用 Gemma 4 的 thinking 模式(默认开启会显著变慢)

推理速度

成功跑起来后的实测数据:

指标 数值
Prompt processing ~144 tokens/s
Token generation ~23 tokens/s

对于跨网络 RPC 分布式推理来说,23 tokens/s 是相当不错的速度。

注意:Gemma 4 的 sliding window attention(SWA)机制会导致 cache 失效,在长对话或上下文切换时会强制重新处理 prompt,速度会短暂下降到 13-17 tokens/s,这是正常现象。


Gemma 4 的思考模式

Gemma 4 内置 thinking 模式(和 DeepSeek、Qwen3 类似),默认开启。

思考模式的问题:

  • 每次回复先生成大量推理 token,速度变慢
  • llama.cpp 有已知 bug,长上下文时可能输出乱码占满 max_tokens
  • 部分客户端显示问题

关闭方法:

旧参数(已弃用但仍可用):

--jinja --chat-template-kwargs '{"enable_thinking":false}'

新参数(推荐):

--jinja --reasoning off

在 API 请求里动态控制(不写死 server 参数的情况下):

{
  "messages": [...],
  "chat_template_kwargs": {"enable_thinking": false}
}

多模态(图像输入)

Gemma 4 是多模态模型,支持图像输入,但需要额外的 mmproj 文件。

模型文件分两部分:

  • 主模型:google_gemma-4-26B-A4B-it-Q4_K_M.gguf(文本推理)
  • 投影器:mmproj-google_gemma-4-26B-A4B-it-f16.gguf(图像编码)

下载投影器:

huggingface-cli download lmstudio-community/gemma-4-26B-A4B-it-GGUF \
  mmproj-google_gemma-4-26B-A4B-it-f16.gguf \
  --local-dir ./models

bf16 和 f16 版本:两者体积相同(都是 16 位),f16 在 Apple Silicon Metal 后端兼容性更好,选 f16 即可。


OpenWebUI 集成

llama-server 提供 OpenAI 兼容 API,OpenWebUI 直接连接即可。

思考模式控制:OpenWebUI 原生没有 thinking 切换按钮,可以:

  1. 安装社区 Function:Thinking Toggle,安装后聊天界面出现🧠按钮,一键切换
  2. 或者 server 启动时写死 --reasoning off,OpenWebUI 无需任何配置

官方推荐推理参数

参数
temperature 1.0
top_p 0.95
top_k 64
repeat_penalty 1.0

总结

整个过程最大的坑在于:

  1. CUDA 版本:Ubuntu 26.04 太新,CUDA 12.x 装不上,CUDA 13.2 有 Gemma 4 bug,CUDA 13.1 需要手动打补丁才能编译
  2. Gemma 4 架构:MoE + 混合注意力,对推理框架的兼容性要求更高,很多坑都是新架构带来的
  3. RPC 调参:tensor-split 比例需要根据实际可用显存仔细调整,不能只看 nvidia-smi 报告的数字

如果你的 Ubuntu 是 22.04 或 24.04,整个过程会顺畅很多——CUDA 12.x 直接能装,不需要打补丁。

最后,18GB Mac 跑 Q4_K_M 量化的 26B 模型需要 RPC,但如果你手头有 36GB 的 Mac,其实可以直接单机跑,速度反而比 RPC 更快(省去了网络传输开销)。


硬件:M3 Pro 18GB + RTX 5070 8GB | 软件:llama.cpp b9266 | 模型:Gemma 4 26B-A4B Q4_K_M

Leave a Reply

Your email address will not be published. Required fields are marked *