使用本地 llama.cpp 模型运行 Bub
本教程演示如何让 Bub 使用本地 llama.cpp server。完成后,Bub 的模型调用会发往你机器上运行的 GGUF Gemma 模型,而不是托管 API。
当你需要在开发环境、私有实验、离线 demo,或贴近应用的低延迟任务中使用本地模型时,可以使用这条路径。本教程不覆盖模型 benchmark、fine-tuning、生产加固,也不讨论如何为所有工作负载选择最佳模型。
示例使用 ggml-org/gemma-4-E2B-it-GGUF,这是 Google Gemma 4 E2B instruction-tuned 模型的 GGUF 版本。Google 的 Gemma 4 overview 把 E2B 和 E4B 描述为适合移动和边缘设备的高效模型;Gemma 4 model card 记录了能力、限制和负责任使用相关注意事项。
你需要:
- Bub 已安装,且
uv run bub --help可以运行。 - 已安装 Docker。
~/.cache/llama.cpp/下有 GGUF 模型文件。- 系统内存足够运行所选量化版本。Gemma 4 E2B 的 Q8 GGUF 文件约 5 GB;实际运行内存还会受上下文长度、batching、GPU offload 等设置影响。
本教程使用下面两个文件名:
~/.cache/llama.cpp/ggml-org_gemma-4-E2B-it-GGUF_gemma-4-E2B-it-Q8_0.gguf
~/.cache/llama.cpp/ggml-org_gemma-4-E2B-it-GGUF_mmproj-gemma-4-E2B-it-Q8_0.gguf
如果你的文件名不同,需要相应修改 Docker 命令里的 -m 和 --mmproj 路径。
1. 启动本地 server
Section titled “1. 启动本地 server”先为本地 server 设置一个 API key:
export LLAMA_API_KEY="${LLAMA_API_KEY:-test}"
启动 llama-server:
sudo docker run --rm -it \
--security-opt label=disable \
-p 127.0.0.1:8080:8080 \
-v "$HOME/.cache/llama.cpp:/root/.cache/llama.cpp:ro" \
ghcr.m.daocloud.io/ggml-org/llama.cpp:full \
--server \
--host 0.0.0.0 \
--port 8080 \
--api-key "$LLAMA_API_KEY" \
-m /root/.cache/llama.cpp/ggml-org_gemma-4-E2B-it-GGUF_gemma-4-E2B-it-Q8_0.gguf \
--mmproj /root/.cache/llama.cpp/ggml-org_gemma-4-E2B-it-GGUF_mmproj-gemma-4-E2B-it-Q8_0.gguf
Docker 端口绑定到 127.0.0.1,因此这个 server 只在本机可访问。只有在明确需要其他机器访问时,才调整端口绑定。
在 SELinux 系统上,--security-opt label=disable 可以避免容器读取 ~/.cache/llama.cpp 下模型文件时遇到 bind mount 权限问题。如果只需要文本输入,可以删除 --mmproj 那一行。
如果 Docker 输出 no ROCm-capable device is detected,容器仍然可能回退到 CPU inference。这足够验证接入路径,但响应速度会更慢。
2. 测试 OpenAI-compatible API
Section titled “2. 测试 OpenAI-compatible API”在另一个终端发送一个小 chat 请求:
curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer $LLAMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemma-4-E2B-it",
"messages": [
{"role": "user", "content": "hello"}
]
}'
正常工作的 server 会返回一个 chat.completion JSON 对象,其中包含 assistant message。
3. 配置 Bub
Section titled “3. 配置 Bub”把 Bub 指向本地 server:
export BUB_API_BASE="http://localhost:8080/v1"
export BUB_API_KEY="$LLAMA_API_KEY"
export BUB_MODEL="openai:gemma-4-E2B-it"
运行一个 Bub turn:
uv run bub run "Reply with one short sentence: hello from a local model."
现在 Bub 会通过本地 OpenAI-compatible endpoint 进行模型调用。turn pipeline、channels、tools 和 tapes 都不需要改变。
~/bubbuild/bub$ uv run bub run "Reply with one short sentence: hello from a local model."
2026-05-19 01:32:40.601 | INFO | bub.builtin.agent:_run_tools_with_auto_handoff:271 - loop.step step=1 tape=becda04eb9f7369c__0b871d5e50e7c192 model=openai:gemma-4-E2B-it
2026-05-19 01:32:46.747 | INFO | bub.builtin.store:fork:122 - Merged 7 entries into tape "becda04eb9f7369c__0b871d5e50e7c192"
[cli:local]
hello from a local model.
4. 更换工作负载前检查模型文档
Section titled “4. 更换工作负载前检查模型文档”当你切换模型或量化版本时,先检查上游模型文档:
- Hugging Face GGUF card 会列出支持的本地运行方式和可用量化文件。
- Gemma 4 model card 会说明输入模态、上下文窗口、预期用途、许可和风险。
- 本地运行不等于免评测。本地模型仍然可能生成错误、有偏见或不安全的输出。
适合优先尝试小型本地模型的,是那些更看重延迟、隐私、成本或离线能力,而不是最高模型质量的工作负载。对于高风险或面向产品的工作流,应先在有代表性的任务上评估模型,再接入真实用户路径。
用 Ctrl-C 停止 Docker 容器。
如果要恢复到之前的 provider,清理 Bub 覆盖配置:
unset BUB_API_BASE BUB_API_KEY BUB_MODEL LLAMA_API_KEY