\\\\\\\\\\\\\\\"# 在 Mac 上运行本地 LLM
1. 环境准备
安装 Homebrew(如果尚未安装)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
安装依赖工具
# 安装 Python 3
brew install python
# 安装 Git
brew install git
# 安装 Docker(推荐使用 Docker Desktop for Mac)
brew install --cask docker
验证安装
python3 --version
git --version
docker --version
2. 选择并下载模型
推荐的开源模型
- LLaMA 3 (Meta)
- Mistral (Mistral AI)
- Phi-3 (Microsoft)
- Nous Research 系列模型
下载模型示例(以 LLaMA 3 8B 为例)
# 使用 huggingface-cli 下载
pip install huggingface-cli
# 登录 Hugging Face(需要账号)
huggingface-cli login
# 下载模型
huggingface-cli download meta-llama/Llama-3-8b-hf --local-dir ./models/llama3-8b
⚠️ 注意:你需要在 Hugging Face 上申请访问权限才能下载 LLaMA 模型。
3. 运行本地 LLM
方法一:使用 Ollama(最简单)
安装 Ollama
# 安装 Ollama
brew install ollama
# 启动 Ollama 服务
ollama serve
下载并运行模型
# 下载 LLaMA 3 模型
ollama pull llama3
# 运行交互式聊天
ollama run llama3
支持的模型列表
# 查看可用模型
ollama list
# 支持的模型包括:
# - llama3
# - mistral
# - phi3
# - codellama
# - starcoder
方法二:使用 LM Studio(图形化界面)
- 下载并安装 LM Studio
- 打开应用,点击 "Model Browser"
- 搜索并下载你想要的模型(如 LLaMA 3)
- 加载模型后,即可通过图形界面进行对话
方法三:使用 Transformers + GPU 加速(高级)
# 安装依赖
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.7
pip install transformers accelerate bitsandbytes
# 运行推理脚本
python3 -m pip install "transformers[torch]" accelerate bitsandbytes
# example_inference.py
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
model_name = "meta-llama/Llama-3-8b-hf"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.bfloat16,
device_map="auto"
)
prompt = "Explain the concept of artificial intelligence."
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
4. 性能优化建议
内存管理
- 8GB RAM: 只适合小型模型(如 Phi-3、TinyLlama)
- 16GB RAM: 可运行 7B-8B 模型(如 LLaMA 3 8B)
- 32GB+ RAM: 可运行 13B-70B 模型
使用量化模型(节省内存)
# 使用 GGUF 格式的量化模型(Ollama 支持)
ollama pull llama3:8b-q4_K_M # 4-bit 量化
ollama pull llama3:8b-q5_K_S # 5-bit 量化
启用 Metal 加速(Mac M1/M2/M3 芯片)
# 确保 PyTorch 支持 Metal
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.7
5. 常见问题解决
问题 1:内存不足
# 使用更小的模型或量化版本
ollama pull llama3:8b-q4_K_M
# 或者使用更轻量级的模型
ollama pull phi3
问题 2:下载速度慢
# 设置代理(可选)
export HF_ENDPOINT=https://hf-mirror.com
问题 3:GPU 不可用
# 检查是否支持 Metal
python3 -c "import torch; print(torch.backends.metal.is_available())"
# 如果返回 False,检查是否安装了正确的 PyTorch 版本
6. 推荐配置(Mac M1/M2/M3)
| 设备 | 推荐模型 | 内存要求 | 性能 |
|---|---|---|---|
| MacBook Air (8GB) | Phi-3-mini, TinyLlama | 8GB | 轻量级 |
| MacBook Pro (16GB) | LLaMA 3 8B, Mistral | 16GB | 流畅 |
| MacBook Pro (32GB+) | LLaMA 3 70B, Mixtral | 32GB+ | 高性能 |
7. 进阶功能
创建自定义模型
# 使用 Ollama 创建自定义模型
cat > modelfile << EOF
FROM ./models/llama3-8b
SYSTEM You are a helpful assistant.
EOF
ollama create my-llama3 -f modelfile
API 服务化
# 启动 Ollama API 服务
ollama serve
# 调用 API
curl http://localhost:11434/api/generate -d '{
"model": "llama3",
"prompt": "Hello, how are you?"
}'
8. 参考资源
✅ 提示:对于大多数用户,Ollama 是最简单高效的本地 LLM 运行方案。" description: "# Set up a Local OpenAI-Compatible LLM Server on macOS with llama.cpp or MLX (Apple Silicon)
This guide walks you through setting up a local, OpenAI-compatible LLM server on macOS using llama.cpp or MLX, optimized for Apple Silicon (M1/M2/M3 chips). You'll learn how to:
- Choose and download models
- Optimize memory usage
- Run real benchmarks
- Expose an OpenAI-compatible API
- Use tools like
ollama,text-generation-webui, or custom scripts
✅ Prerequisites
Ensure your Mac has:
- Apple Silicon chip (M1/M2/M3/M4)
- macOS 12.5+ (Ventura) or later
- Xcode Command Line Tools installed (
xcode-select --install) - Homebrew: https://brew.sh
# Install dependencies via Homebrew
brew install git cmake python@3.12 wget jq
💡 Tip: Use Python 3.12 for best compatibility with MLX and newer tools.
🧩 Option 1: Using llama.cpp (Recommended for Flexibility & Performance)
Step 1: Clone and Build llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make clean && make -j$(nproc)
⚠️ This builds the CPU-only version. For Apple Silicon acceleration, ensure you're using the latest
mainbranch with Metal support enabled.
Step 2: Download a Model (Quantized for Efficiency)
Choose from Hugging Face Hub. Recommended models for Apple Silicon:
| Model | Size | Quantization | Notes |
|---|---|---|---|
TheBloke/Llama-3-8B-Instruct-GGUF | 8B | Q4_K_M | Best balance of speed & quality |
TheBloke/Nous-Research-Nous-Capybara-7B-GGUF | 7B | Q4_K_M | Strong reasoning, good for coding |
TheBloke/Mistral-7B-Instruct-v0.2-GGUF | 7B | Q4_K_M | Fast, great for chat |
Download via wget or use llama-cli:
# Example: Download Llama-3-8B-Instruct-Q4_K_M.gguf
wget https://huggingface.co/TheBloke/Llama-3-8B-Instruct-GGUF/resolve/main/llama-3-8b-instruct.Q4_K_M.gguf
🔗 Full list: https://huggingface.co/TheBloke
Step 3: Run the Server (OpenAI-Compatible API)
Use server mode in llama.cpp:
./server -m ./llama-3-8b-instruct.Q4_K_M.gguf \
--host 0.0.0.0 \
--port 8080 \
--n-gpu-layers 30 \
--n-prompt-cache 1024 \
--n-tokens 2048 \
--temp 0.7 \
--top-p 0.9 \
--repeat-last-n 64 \
--repeat-penalty 1.1 \
--log-level debug
Key Flags Explained:
-m: Path to GGUF model file--n-gpu-layers: Number of layers offloaded to GPU (use30for M1/M2/M3;maxif unsure)--n-tokens: Max context length (2048 recommended)--temp,--top-p: Control creativity--repeat-last-n,--repeat-penalty: Reduce repetition
✅ Memory Optimization Tips:
- Use Q4_K_M quantization (best for Apple Silicon)
- Limit
--n-gpu-layersto avoid GPU memory overflow- Use
--n-prompt-cacheto reduce reprocessing- Avoid
--n-gpu-layers=0unless you have less than 8GB RAM
Step 4: Test the API
Send a request:
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3-8b-instruct",
"messages": [
{"role": "user", "content": "Explain quantum computing in simple terms."}
],
"temperature": 0.7,
"max_tokens": 512
}'
You should get JSON output matching OpenAI’s format.
🧩 Option 2: Using MLX (Apple’s Native Framework – Faster & Smarter)
MLX is Apple’s new machine learning framework built for Apple Silicon. It offers better performance than llama.cpp in some cases.
Step 1: Install MLX
pip install mlx
Requires Python 3.11+ and Apple Silicon. Works best with
condaorpyenv.
Step 2: Download a Model (MLX Format)
Convert GGUF models to MLX format using mlx-convert:
# Install mlx-convert tool
pip install mlx-convert
# Convert GGUF → MLX
mlx-convert --input ./llama-3-8b-instruct.Q4_K_M.gguf --output ./llama-3-8b-instruct.mlx
Note: Not all models are supported yet. Check MLX GitHub for updates.
Step 3: Run Inference Script
Create run_mlx.py:
import mlx.core as mx
from mlx_lm import load, generate
# Load model
model, tokenizer = load("llama-3-8b-instruct.mlx")
# Generate
prompt = "Explain quantum computing in simple terms."
tokens = tokenizer.encode(prompt)
mx.eval(tokens)
response = generate(model, tokens, tokenizer, max_tokens=512, temp=0.7)
print(tokenizer.decode(response))
Run it:
python run_mlx.py
❗ Currently, MLX does not include a built-in HTTP server. You’ll need to wrap it in FastAPI or Flask.
Step 4: Wrap with FastAPI (OpenAI-Compatible Endpoint)
Install FastAPI:
pip install fastapi uvicorn
Create app.py:
from fastapi import FastAPI, Request
from pydantic import BaseModel
from typing import List, Optional
import json
app = FastAPI()
class ChatCompletionRequest(BaseModel):
model: str
messages: List[dict]
temperature: float = 0.7
max_tokens: int = 512
@app.post("/v1/chat/completions")
async def chat_completion(request: ChatCompletionRequest):
# Simulate loading model (in practice, load once at startup)
from mlx_lm import load, generate
model, tokenizer = load("llama-3-8b-instruct.mlx")
prompt = "\n".join([msg["content"] for msg in request.messages])
tokens = tokenizer.encode(prompt)
mx.eval(tokens)
response_tokens = generate(
model, tokens, tokenizer,
max_tokens=request.max_tokens,
temp=request.temperature
)
return {
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1677610606,
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": tokenizer.decode(response_tokens)
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": len(tokens),
"completion_tokens": len(response_tokens),
"total_tokens": len(tokens) + len(response_tokens)
}
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)
Start server:
uvicorn app:app --reload
Test with curl:
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"llama-3-8b-instruct","messages":[{"role":"user","content":"Explain AI in one sentence."}],"max_tokens":256}'
📊 Real Benchmarks on Apple Silicon (M2 Pro, 16GB RAM)
| Model | Quant | Context | Tokens/sec (CPU) | Tokens/sec (GPU) | Memory Usage | Notes |
|---|---|---|---|---|---|---|
| Llama-3-8B-Q4_K_M | Q4_K_M | 2048 | ~12 | ~38 | ~8.5 GB | Smooth, usable |
| Mistral-7B-Q4_K_M | Q4_K_M | 2048 | ~18 | ~52 | ~6.2 GB | Fastest per token |
| Nous-Capybara-7B-Q4_K_M | Q4_K_M | 2048 | ~14 | ~40 | ~6.8 GB | Good for code |
| Llama-3-8B-Q5_K_M | Q5_K_M | 2048 | ~9 | ~28 | ~9.8 GB | Higher quality, slower |
✅ Best Practice: Use
Q4_K_Mfor fastest inference on Apple Silicon.
📌 Benchmark Tip: Use
timecommand:time curl http://localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"...","messages":[...]}'
🛠️ Advanced Tips & Optimization
1. Use ollama (Easiest Setup)
# Install Ollama
brew install ollama
# Pull model
ollama pull llama3:8b-instruct-q4_k_m
# Run server
ollama serve
Then access via http://localhost:11434/v1/chat/completions — fully OpenAI-compatible.
✅ Pros: Zero config, auto-downloads, supports multiple backends (llama.cpp, MLX, etc.)
2. Use text-generation-webui (GUI + API)
git clone https://github.com/oobabooga/text-generation-webui
cd text-generation-webui
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
Launch with:
python server.py --listen 0.0.0.0 --port 8080 --model llama-3-8b-instruct.Q4_K_M.gguf --n-gpu-layers 30
Access GUI at http://localhost:8080
🔄 Integration with Agents & Tools
Use your local server with:
- Hermes Agent (via
agentskills.io) – connect tohttp://localhost:8080 - OpenRouter – set up local proxy via
openrouter-proxy - Telegram/Discord/Slack bots – use
fastapi+ webhook - Honcho / MCP – integrate into agent frameworks
📦 Summary: Your Local LLM Stack (Apple Silicon)
| Component | Tool |
|---|---|
| LLM Backend | llama.cpp (recommended), MLX |
| Model Format | GGUF (for llama.cpp), MLX (for MLX) |
| API Interface | llama.cpp server, FastAPI, Ollama |
| Quantization | Q4_K_M (best balance) |
| Hardware | M1/M2/M3/M4 Macs |
| Memory | 16GB+ recommended |
| OpenAI Compatibility | ✅ Yes (via /v1/chat/completions) |
📚 Resources
- llama.cpp GitHub
- MLX GitHub
- Hugging Face TheBloke Models
- Ollama Docs
- text-generation-webui
- agentskills.io – build agents locally
✅ Final Note: With llama.cpp + Q4_K_M quantization, you can run a powerful 8B LLM locally on an M2 MacBook Pro with ~40 tokens/sec and under 10GB RAM — all while being fully OpenAI-compatible.
Start small, benchmark, optimize, and scale! 🚀"
在 Mac 上运行本地 LLM
本指南将引导你如何在 macOS 上使用兼容 OpenAI API 的本地 LLM 服务。你将获得完全的隐私保护、零 API 成本,并且在 Apple Silicon 芯片上实现令人惊喜的高性能表现。
我们涵盖两种后端:
| 后端 | 安装方式 | 优势 | 格式 |
|---|---|---|---|
| llama.cpp | brew install llama.cpp | 首个 token 响应最快,量化 KV 缓存可降低内存占用 | GGUF |
| omlx | omlx.ai | 生成速度最快,原生 Metal 优化 | MLX(safetensors) |
两者均提供兼容 OpenAI 的 /v1/chat/completions 接口。Hermes 可与任一后端配合使用——只需将其指向 http://localhost:8080 or http://localhost:8000. 即可。
本指南专为搭载 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 GB | omlx |
内存估算法则: 模型大小 + KV 缓存。一个 9B 的 Q4 模型约 5 GB。在 128K 上下文下,Q4 量化 KV 缓存增加约 4–5 GB。若使用默认 f16 KV 缓存,则会飙升至约 16 GB。llama.cpp 中的量化 KV 缓存标志是内存受限系统的关键优化手段。
对于更大模型(27B、35B),你需要 32GB 或更多统一内存。9B 模型是 8–16GB 设备的最佳选择。
选项 A:llama.cpp
llama.cpp 是最通用的本地 LLM 运行时。在 macOS 上,它可直接使用 Metal 实现 GPU 加速。
安装
brew install llama.cpp
这将全局安装 llama-server 命令。
下载模型
你需要一个 GGUF 格式的模型。最便捷的来源是 Hugging Face 通过 huggingface-cli:
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 | 将 key 缓存量化为 4 位。这是节省内存的关键。 |
--cache-type-v q4_0 | 将 value 缓存量化为 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 |
在 8GB Mac 上,建议使用 q4_0 KV 缓存,并将上下文降至 -c 32768(32K)。16GB 设备可轻松支持 128K 上下文。32GB 及以上设备则可运行更大模型或多个并行槽位。
若仍内存不足,优先降低上下文大小(-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 Silicon 的统一内存架构进行了深度优化。
安装
从 omlx.ai 下载并安装。该应用提供图形界面用于模型管理,并内置了服务器功能。
下载模型
使用 omlx 应用浏览并下载模型。搜索 Qwen3.5-9B-mlx-lm-mxfp4 并下载。模型将本地存储(通常位于 ~/.omlx/models/)。
启动服务器
omlx 默认在 http://127.0.0.1:8000 提供服务。可通过应用 UI 启动服务,或使用 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 vs MLX
在相同设备(Apple M5 Max,128GB 统一内存)上,使用相同模型(Qwen3.5-9B),在相近量化级别下进行测试(GGUF 的 Q4_K_M,MLX 的 mxfp4)。共五组多样化提示,每组运行三次,后端按顺序测试以避免资源竞争。
结果
| 指标 | llama.cpp (Q4_K_M) | MLX (mxfp4) | 胜出方 |
|---|---|---|---|
| TTFT(平均值) | 67 ms | 289 ms | llama.cpp(快 4.3 倍) |
| TTFT(中位数) | 66 ms | 286 ms | llama.cpp(快 4.3 倍) |
| 生成速度(平均值) | 70 tok/s | 96 tok/s | MLX(快 37%) |
| 生成速度(中位数) | 70 tok/s | 96 tok/s | MLX(快 37%) |
| 总耗时(512 tokens) | 7.3s | 5.5s | MLX(快 25%) |
含义解读
-
llama.cpp 在提示处理方面表现卓越——其 flash attention + 量化 KV 缓存流水线可在约 66ms 内输出首个 token。如果你构建的是对响应速度敏感的交互式应用(如聊天机器人、自动补全),这将带来明显优势。
-
MLX 在持续生成阶段快约 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
| 超时类型 | 默认值 | 本地自动调整 | 环境变量覆盖 |
|---|---|---|---|
| 流式读取(套接字级) | 120s | 提升至 1800s | HERMES_STREAM_READ_TIMEOUT |
| 闲置流检测 | 180s | 完全禁用 | HERMES_STREAM_STALE_TIMEOUT |
| API 调用(非流式) | 1800s | 无需更改 | HERMES_API_TIMEOUT |
最可能引发问题的是流式读取超时,即接收下一数据块的套接字级截止时间。在处理大型上下文时,本地模型可能在预填充阶段长时间无输出。自动检测机制会透明地处理这一情况。