跳到主要内容

在 Mac 上运行本地 LLM

本指南将引导您在 macOS 上使用兼容 OpenAI 的 API 运行本地 LLM 服务器。您将获得完全的隐私保护、零 API 成本,并在 Apple Silicon 芯片上实现令人惊讶的出色性能。

我们涵盖两种后端:

后端安装方式优势格式
llama.cppbrew install llama.cpp首个 token 生成速度最快,量化 KV 缓存可降低内存占用GGUF
omlxomlx.ai最快的 token 生成速度,原生 Metal 优化MLX (safetensors)

两者均提供兼容 OpenAI 的 /v1/chat/completions 端点。Hermes 可与任一后端配合使用——只需将其指向 http://localhost:8080http://localhost:8000 即可。

仅限 Apple Silicon

本指南针对搭载 Apple Silicon(M1 及更新型号)的 Mac。Intel Mac 可使用 llama.cpp,但无法获得 GPU 加速——性能将显著降低。


选择模型

开始使用时,我们推荐 Qwen3.5-9B —— 这是一个强大的推理模型,经过量化后可在 8GB 及以上统一内存中舒适运行。

变体磁盘占用大小内存需求(128K 上下文)后端
Qwen3.5-9B-Q4_K_M (GGUF)5.3 GB~10 GB(含量化 KV 缓存)llama.cpp
Qwen3.5-9B-mlx-lm-mxfp4 (MLX)~5 GB~12 GBomlx

内存使用经验法则: 模型大小 + KV 缓存。一个 9B 的 Q4 模型约为 5 GB。在 128K 上下文且 Q4 量化的情况下,KV 缓存增加约 4–5 GB。若使用默认的 f16 KV 缓存,内存需求将飙升至约 16 GB。llama.cpp 中的量化 KV 缓存标志是内存受限系统的关键优化手段。

对于更大模型(27B、35B),您需要 32 GB 及以上统一内存。9B 模型是 8–16 GB 设备的最佳选择。


选项 A:llama.cpp

llama.cpp 是最通用的本地 LLM 运行时。在 macOS 上,它可原生使用 Metal 实现 GPU 加速。

安装

brew install llama.cpp

这将全局安装 llama-server 命令。

下载模型

您需要一个 GGUF 格式的模型。最简单的来源是通过 huggingface-cli 从 Hugging Face 获取:

brew install huggingface-cli

然后下载:

huggingface-cli download unsloth/Qwen3.5-9B-GGUF Qwen3.5-9B-Q4_K_M.gguf --local-dir ~/models
受限模型

Hugging Face 上的一些模型需要身份验证。如果遇到 401 或 404 错误,请先运行 huggingface-cli login

启动服务器

llama-server -m ~/models/Qwen3.5-9B-Q4_K_M.gguf \
-ngl 99 \
-c 131072 \
-np 1 \
-fa on \
--cache-type-k q4_0 \
--cache-type-v q4_0 \
--host 0.0.0.0

以下是各标志的含义:

标志用途
-ngl 99将所有层卸载到 GPU(Metal)。使用高数值以确保无任何内容留在 CPU 上。
-c 131072上下文窗口大小(128K tokens)。内存不足时可减小此值。
-np 1并行槽位数量。单用户使用时保持为 1——更多槽位会分割您的内存预算。
-fa on启用 Flash Attention。可减少内存占用并加快长上下文推理速度。
--cache-type-k q4_0将键缓存量化为 4 位。这是节省内存的关键。
--cache-type-v q4_0将值缓存量化为 4 位。与上一项结合使用,相比 f16 可将 KV 缓存内存减少约 75%。
--host 0.0.0.0监听所有网络接口。如无需网络访问,可使用 127.0.0.1

当您看到以下输出时,服务器即已准备就绪:

main: server is listening on http://0.0.0.0:8080
srv update_slots: all slots are idle

内存受限系统的优化策略

--cache-type-k q4_0 --cache-type-v q4_0 标志是内存受限系统最重要的优化手段。在 128K 上下文下的效果如下:

KV 缓存类型KV 缓存内存(128K 上下文,9B 模型)
f16(默认)~16 GB
q8_0~8 GB
q4_0~4 GB

在 8 GB 的 Mac 上,使用 q4_0 KV 缓存并将上下文减小至 -c 32768(32K)。在 16 GB 上,可轻松支持 128K 上下文。在 32 GB 及以上设备上,可运行更大模型或多个并行槽位。

如果仍出现内存不足,优先减小上下文大小(-c),然后尝试更小的量化级别(如 Q3_K_M 而非 Q4_K_M)。

测试

curl -s http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.5-9B-Q4_K_M.gguf",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 50
}' | jq .choices[0].message.content

获取模型名称

若忘记模型名称,可通过查询模型端点获取:

curl -s http://localhost:8080/v1/models | jq '.data[].id'

选项 B:通过 omlx 使用 MLX

omlx 是一款专为 macOS 设计的应用程序,用于管理并提供 MLX 模型服务。MLX 是 Apple 自研的机器学习框架,专为 Apple Silicon 的统一内存架构进行了优化。

安装

omlx.ai 下载并安装。该应用提供模型管理的图形界面和内置服务器。

下载模型

使用 omlx 应用程序浏览并下载模型。搜索 Qwen3.5-9B-mlx-lm-mxfp4 并下载。模型将本地存储(通常位于 ~/.omlx/models/ 目录下)。

启动服务器

omlx 默认在 http://127.0.0.1:8000 提供模型服务。可通过应用界面启动服务,或使用可用的 CLI 工具。

测试

curl -s http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3.5-9B-mlx-lm-mxfp4",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 50
}' | jq .choices[0].message.content

列出可用模型

omlx 可同时服务多个模型:

curl -s http://127.0.0.1:8000/v1/models | jq '.data[].id'

基准测试:llama.cpp 与 MLX

在相同机器(Apple M5 Max,128 GB 统一内存)上对两个后端进行了测试,运行相同的模型(Qwen3.5-9B),量化级别相近(GGUF 使用 Q4_K_M,MLX 使用 mxfp4)。共使用五个不同提示,每种情况运行三次,后端依次测试以避免资源争用。

结果

指标llama.cpp (Q4_K_M)MLX (mxfp4)胜出方
TTFT(平均)67 ms289 msllama.cpp(快 4.3 倍)
TTFT(p50)66 ms286 msllama.cpp(快 4.3 倍)
生成速度(平均)70 tok/s96 tok/sMLX(快 37%)
生成速度(p50)70 tok/s96 tok/sMLX(快 37%)
总耗时(512 tokens)7.3s5.5sMLX(快 25%)

这意味着什么

  • llama.cpp 在提示处理方面表现卓越——其 flash attention + 量化 KV 缓存流水线可在约 66ms 内输出第一个 token。如果你正在构建对感知响应速度敏感的交互式应用(如聊天机器人、自动补全),这将带来显著优势。

  • MLX 在开始生成后,token 生成速度比 llama.cpp 快约 37%。对于批量任务、长文本生成,或任何更关注总完成时间而非初始延迟的场景,MLX 能更快完成任务。

  • 两个后端均表现出极高的稳定性——各次运行间的差异可忽略不计。你可以完全信赖这些数据。

你应该选择哪一个?

使用场景推荐方案
交互式聊天、低延迟工具llama.cpp
长文本生成、批量处理MLX(omlx)
内存受限(8-16 GB)llama.cpp(量化 KV 缓存表现无与伦比)
同时服务多个模型omlx(内置多模型支持)
最大兼容性(支持 Linux)llama.cpp

连接到 Hermes

本地服务器启动后:

hermes model

选择 自定义端点 并按提示操作。系统将要求输入基础 URL 和模型名称——请使用你在上文设置的后端对应的值。


超时设置

Hermes 会自动检测本地端点(localhost、局域网 IP),并自动放宽流式传输超时时间。大多数情况下无需任何配置。

如果你仍然遇到超时错误(例如在慢速硬件上处理非常大的上下文),可以手动覆盖流式读取超时时间:

# In your .env — raise from the 120s default to 30 minutes
HERMES_STREAM_READ_TIMEOUT=1800
超时类型默认值本地自动调整环境变量覆盖
流式读取(socket 层)120s提升至 1800sHERMES_STREAM_READ_TIMEOUT
旧流检测180s完全禁用HERMES_STREAM_STALE_TIMEOUT
API 调用(非流式)1800s无需更改HERMES_API_TIMEOUT

最可能引发问题的是流式读取超时——这是接收下一数据块的 socket 层截止时间。在大上下文预填充阶段,本地模型可能在处理提示时数分钟内无输出。自动检测机制会透明地处理这一情况。