用了将近一周,踩了无数坑,终于让 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 头文件打补丁,在 rsqrt 和 rsqrtf 的声明末尾加 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 切换按钮,可以:
- 安装社区 Function:Thinking Toggle,安装后聊天界面出现🧠按钮,一键切换
- 或者 server 启动时写死
--reasoning off,OpenWebUI 无需任何配置
官方推荐推理参数
| 参数 | 值 |
|---|---|
| temperature | 1.0 |
| top_p | 0.95 |
| top_k | 64 |
| repeat_penalty | 1.0 |
总结
整个过程最大的坑在于:
- CUDA 版本:Ubuntu 26.04 太新,CUDA 12.x 装不上,CUDA 13.2 有 Gemma 4 bug,CUDA 13.1 需要手动打补丁才能编译
- Gemma 4 架构:MoE + 混合注意力,对推理框架的兼容性要求更高,很多坑都是新架构带来的
- 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