译者:Carl Cui

Gemini Generated Image 38l7zz38l7zz38l7

Ollama 每月有 5200 万次下载,这几乎是每个教程都推荐的工具。我使用了六个月,觉得它“可以用于生产环境”,并把它部署给 40 个内部用户。结果响应时间从 3 秒增加到超过一分钟,并且请求开始超时。模型并没有问题,出问题的是 Ollama。

这次事件促使我深入测试了三大本地 LLM 运行工具:Ollama、vLLM 和 llama.cpp。测试结果彻底改变了我对本地 AI 部署的看法。一个让人难以接受的事实是:推荐给新手用的工具,其实在生产环境下表现不佳;而那些所谓“复杂”的工具,其实设置起来并不难。

1. 为什么本地 LLM 部署越来越流行

这里有一组数字:llama.cpp 在 2026 年 3 月达到 100,000 个 GitHub star,比 PyTorch 或 TensorFlow 更快到达这一里程碑,llama.cpp 只是一个三年前还不存在的项目;Ollama 在 2026 年第一季度达到了 5200 万次月下载量,是 2023 年第一季度 10 万次月下载量的 520 倍;Hugging Face 上超过 60% 的量化模型现在以 GGUF 格式发布,这是 llama.cpp 创建的标准。

这已经不再是业余爱好者在笔记本电脑上运行聊天机器人的阶段了。团队正在通过部署本地 LLM 来控制成本,避免数据离开他们的网络,并获得云 API 难以达到的百毫秒内延迟。这些区别,不仅仅在于开发体验,关键还在于你的应用能不能经受住真实用户的考验。

2. 如何测试三大工具

我在相同的硬件(配置 RTX-4090 24GB VRAM 和 64GB RAM 的工作站)上运行每个工具,基于相同的模型 Llama-4-Scout-17B-Instruct,测试了三种场景:

测试场景用户数量测试目的测试方法关键测量指标场景意义
场景 1单用户测试基本性能简单的提示补全每秒 token 数(TPS)、延迟评估工具在理想条件下的基础性能
场景 210个并发用户测试中等负载处理能力模拟 10 个同时的 API 请求每个工具处理中等负载的能力评估工具在实际使用中的表现
场景 350个并发用户模拟生产场景多个用户同时访问同一个端点总吞吐量、p95 延迟p95 延迟决定了应用程序感觉慢还是崩溃的关键指标

每个测试运行五次,然后取平均值。

3. Ollama — 备受新手喜爱的工具

Ollama 本身是一个用户友好型工具:安装二进制文件,运行 ollama pull llama4-scout:17b,在两分钟内就能跑起一个模型。支持 OpenAI 兼容的 API,无需 Python 环境,无需依赖管理,无需 GPU 配置,它就能工作。

# 安装 (macOS)
brew install ollama
# 安装 (Linux)
curl -fsSL https://ollama.com/install.sh | sh
# 拉取并运行 Llama 4 Scout
ollama pull llama4-scout:17b
# 启动 API 服务器 (端口 11434)
ollama serve
# 测试它
curl http://localhost:11434/api/generate \
  -d '{"model":"llama4-scout:17b","prompt":"What is PagedAttention?"}'

它的单用户性能很不错:每秒 40 ~ 50 个 token,稳定、可预测。内存占用非常少:消耗 1.8GB 的系统内存,而 vLLM 则需要 4.6GB 系统内存。CPU 使用率在正常情况下保持在 8% 左右。

然后我运行了并发负载测试:在 10 个并发用户的情况下,Ollama 总共能处理每秒大约 148 个 token,尚可接受;当并发用户数量达到 50 时,它稳定在每秒约 155 个 token,几乎没有改进,但是 p95 延迟爆炸到 18.4 秒,P99 则达到了 24.7 秒。

这不是一个 bug,这是架构使然:Ollama 通过先进先出队列处理请求,每个新请求等待当前请求完成后才开始。随着并发性增加,等待时间会堆积起来。第 3 个用户在用户 1 和 2 等待响应时到达,会等待前两个完成后才能看到一个 token,第 40 个用户需要等待用户 1 到 39 完成。

GitHub issue #9054 明确说明了这一点:“Ollama 不利用同一模型的多个实例进行并行处理。” 这个问题自 2024 年以来一直开放,截至 2026 年 4 月,这仍然是基本设计。

对于于本地测试的开发者,Ollama 堪称完美;而对于共享内部工具的五人团队,它开始吱吱作响;对于 40 个人,它就崩溃了。

Ollama 结论:卓越的开发者体验,生产上限约 5 个并发用户。

4. vLLM — 生产级工具

vLLM 来自加州大学伯克利分校的 Sky Computing Lab,其核心创新是分页注意力机制(PagedAttention)。这个机制值得理解,因为它解释了为什么 vLLM 在负载情况下表现得如此不同。

传统的 LLM 服务为每个请求的 KV 缓存预分配一个连续的 GPU 显存,模型用这块显存来追踪上下文。问题是:这块显存必须基于最大可能的序列长度预先保留,即使实际的请求很短。在简单的实现中,GPU 显存浪费率高达 60% ~ 80%。这就限制了可以同时处理的请求数量。

PagedAttention 借鉴了操作系统的虚拟内存概念。它不再使用一个大的连续内存块,而是把 KV 缓存分割成小的固定大小的页,这些页可以存放在 GPU 显存的任何地方。页面随着序列增长按需分配,并在请求完成后立即释放。GPU 显存浪费率降至 4% 以下,这意味着在相同的硬件上可以容纳更多的并发请求。

将此与连续批处理(continuous batching)结合起来,vLLM 会将新请求放到到当前处理批次中,无需等待先前请求完成,这样得到了一个与 Ollama 基于队列的方法根本不同的并发模型。

# 安装 vLLM
pip install vllm
# 开始服务 Llama 4 Scout (OpenAI 兼容 API 在端口 8000)
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-4-Scout-17B-Instruct \
  --gpu-memory-utilization 0.9 \
  --max-model-len 32768
# 使用 OpenAI 客户端测试 (直接替代)
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="token-here")
response = client.chat.completions.create(
  model="meta-llama/Llama-4-Scout-17B-Instruct",
  messages=[{"role": "user", "content": "Explain PagedAttention in 2 sentences."}]
)

50 个并发用户时的性能数据:总共 920 token/sec,p95 延迟 2.1 秒,p99 延迟 2.8 秒。在 128 个并发连接时,vLLM 保持了 100% 的请求成功率。在相同负载下,Ollama 的队列已经崩溃了。

在单块 H100 80GB 显卡上运行 Llama-3.1-8B-BF16,vLLM 每秒大约能处理 12,500 个 token,这完全是另一个级别的性能了。

缺点也是实实在在的:vLLM 需要 NVIDIA GPU,必须是支持 CUDA 7.0 或更高的(V100、T4、A10、A100、H100),不支持 Mac,不支持纯 CPU。大多数模型不自带 ROCm 支持。设置起来更复杂,需要 Python 3.12 或更高版本、CUDA 工具包、正确的环境配置。

谁“钟情”于 vLLM 呢?Amazon Rufus(服务 2.5 亿客户)、LinkedIn、Roblox(每周 40 亿 token)、Mistral AI 和 Stripe。当 Hugging Face 在 2025 年 12 月弃用 TGI(文本生成推理)时,他们正式推荐 vLLM 作为继任者。

vLLM 结论:在 NVIDIA 硬件上进行生产多用户服务的唯一真正选择。

5. llama.cpp — 可移植性

llama.cpp 是三大工具中最容易被误解的一个。人们认为它是“困难”选项或“业余爱好者”选项,这两种说法都不准确。

这个项目由 Georgi Gerganov 于 2023 年 3 月创建,纯 C/C++ 实现,无外部依赖,llama.cpp 已成为生态系统中其余部分的基础设施:Ollama 在底层运行 llama.cpp;Hugging Face 有 60% 以上的量化模型是采用 GGUF 格式发布的(GGUF 格式是 llama.cpp 创建的文件标准)。该项目有 100,000 个 GitHub star(2026 年 3 月),700+ 贡献者,仅在 2025 年就处理了 3,800 个 PR。

关键功能:llama.cpp 可以在任何地方运行。纯 CPU、NVIDIA CUDA、Apple Metal、AMD ROCm、用于边缘设备的 Vulkan。其他任何工具都不具备这样的能力。

在 Apple Silicon 上,带有 Metal 后端的 llama.cpp 在 M3/M4 机器上每秒能处理 50 到 100+ token,在相同硬件上比 Ollama 更好,因为你可以直接调整 Metal 卸载。-ngl 99 标志告诉 llama.cpp 将所有 transformer 层卸载到 Metal GPU。

# macOS (Homebrew — 自动构建 Metal)
brew install llama.cpp
# 或从源代码构建 Metal (获取最新功能)
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build -DGGML_METAL=ON -DGGML_NATIVE=ON
cmake --build build -j$(nproc)
# 下载 GGUF 模型 (Q5_K_M = 最佳质量/大小权衡)
huggingface-cli download bartowski/Llama-4-Scout-17B-Instruct-GGUF \
  Llama-4-Scout-17B-Instruct-Q5_K_M.gguf
# 启动内置 HTTP 服务器
./build/bin/llama-server \
  -m Llama-4-Scout-17B-Instruct-Q5_K_M.gguf \
  -ngl 99 \
  --port 8080 \
  --ctx-size 32768
# 服务器暴露一个 OpenAI 兼容的 /v1/chat/completions 端点

2026 年新增功能:llama.cpp 添加了 MCP 客户端支持(通过模型上下文协议直接在llama-server中进行工具调用)、基于 RPC 支持多 GPU 分布式推理,以及一个能自动处理新模型结构化输出的解析器。2026 年 3 月的发布还实现了跨 GPU 上下文的并行模型加载。

它的限制与 Ollama 类似:GGUF 量化为了可移植性牺牲了一些精度,Q5_K_M(5-bit 量化)非常出色,但不是 BF16。在并发负载下,llama.cpp 有与 Ollama 类似的基于队列的限制,它专为单用户或低并发工作负载构建,而不是高吞吐量服务。

llama.cpp 结论:Apple Silicon、边缘设备、仅 CPU 部署以及想要获得最大控制权的开发人员的最佳选择。

6. 测试结果对比

=================================================================
 工具       | 设置时间 | 单用户 TPS | 50用户 TPS | p95 (50u)
=================================================================
 Ollama     | 5 分钟   | 40-50      | ~155       | 18.4s
 vLLM       | 20 分钟  | 485        | 920        | 2.1s
 llama.cpp  | 10 分钟  | 50-100*    | N/A**      | N/A**
=================================================================
* Apple Silicon  MetalNVIDIA CUDA 性能因 GPU 而异
** llama.cpp llama-server 处理并发请求但在高负载下
   有与 Ollama 类似的基于队列的限制

吞吐量差距是真实存在的:在 50 个并发用户时,vLLM 比 Ollama 多提供 5.9 倍的每秒 token 数;在 128 个并发连接时,vLLM 保持 100% 成功率,Ollama 失败;在负载下,Ollama 的 TTFR(首次响应时间)达到 3,200 毫秒,vLLM 保持在 145 毫秒。

7. 如何选择

  • 使用 Ollama - 你正在进行原型设计或运行个人实验,最多有 1 ~ 5 个用户访问 API,你在 Mac 上并希望最快路径获得工作模型,你正在教授 AI 概念或构建内部演示,或者你想要零维护开销。

  • 使用 vLLM - 你需要服务 10+ 个并发用户,你在 NVIDIA GPU 硬件上运行(A10、A100、H100、RTX 系列),你正在构建生产 API 端点,每个 token 成本很重要(每个 GPU 更多用户 = 更低成本),或者你需要规模上的 100% 请求可靠性。

  • 使用 llama.cpp - 你在 Apple Silicon 上并想要最大性能(Metal 后端比 Ollama 的抽象更好),你正在部署到边缘设备或仅 CPU 服务器,你需要在具有最小 RAM 的消费硬件上运行量化模型,或者你想对量化级别、上下文大小和 GPU 层分布进行原始控制。

  • Apple 硬件路径 - 如果你使用的是具有 16GB+ 统一内存的 M3/M4 Mac,直接使用 llama.cpp 是最佳选择。Ollama 在底层使用 llama.cpp 但会增加开销,使用 Metal 构建 llama.cpp 让你直接访问相同的引擎,具有更好的控制。

8. 工具快速安装

8.1 Ollama - 最便捷的

# macOS
brew install ollama && ollama pull llama4-scout:17b && ollama serve
# Linux
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama4-scout:17b
ollama serve
# API 在 http://localhost:11434 运行

8.2 vLLM - 适于生产环境

pip install vllm
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-4-Scout-17B-Instruct \
  --gpu-memory-utilization 0.9
# API 在 http://localhost:8000 运行
# 完全 OpenAI SDK 兼容 — 只需更改 base_url

8.3 llama.cpp - 原始控制

# macOS 带 Homebrew (预构建带 Metal)
brew install llama.cpp
# 下载 GGUF 模型
pip install huggingface_hub
huggingface-cli download bartowski/Llama-4-Scout-17B-Instruct-GGUF \
  Llama-4-Scout-17B-Instruct-Q5_K_M.gguf
# 启动服务器
llama-server -m Llama-4-Scout-17B-Instruct-Q5_K_M.gguf -ngl 99 --port 8080
# API 在 http://localhost:8080 运行

所有三个都暴露 OpenAI 兼容的端点。在它们之间切换只需要更改 OpenAI 客户端中的 base_url,你的应用程序代码保持相同。

9. 中肯的评价

vLLM 并不完美。SGLang 是一个较新的推理框架,在 H100 GPU 上的吞吐量比 vLLM 高 29%(每秒 16,200 vs 12,500 个 token),通过一种称为 RadixAttention 的技术,跨请求缓存共享计算结果。对于多轮聊天机器人和 RAG 流水线,SGLang 值得评估。vLLM 的核心团队会告诉你他们的优势是广度:更多硬件支持,更大的贡献者基础,以及与非典型模型架构更好的兼容性。

llama.cpp 的 GGUF 量化牺牲了精度。Q4_K_M(4-bit)用来对话通常没问题,但是在精确数值推理和编码任务中表现明显下降。生产环境中,可以使用 Q5_K_M 或 Q8_0,相比 Q4_K_M 需要更多的 VRAM。在 vLLM 中运行全精度模型和在 llama.cpp 中运行量化模型不是一个公平的比较,因为你正在以准确性换取可移植性。

Ollama 不会消失。它的路线图包括改进的并发处理,团队已经承认了生产的局限性。对于 95% 的单用户或低并发个人工具用例,它仍然是从想法到运行模型的最快途径。

写在最后

经过三周的测试,我终于意识到:最开始使用的工具不一定是部署时使用的工具。

毫无疑问,Ollama 在开发者体验上获胜,你可以使用它来构建、测试和迭代。但是一旦有超过五个人同时使用你的应用程序,就应该切换到 vLLM。性能差距不是理论上的,在 50 个并发用户时,这是 2 秒响应和 18 秒响应之间的差异。

llama.cpp 是无名英雄:它是 Ollama 的运行时基础,GGUF 是 60% 量化模型使用的格式,是使本地人工智能实用化的项目。如果你在 Apple Silicon 上或需要在 CPU 上运行,从这里开始,而不要把它当作高级选项。

我的个人设置:在我的 MacBook 上使用 Metal 的 llama.cpp 进行实验,在云 GPU 的 Docker 中使用 vLLM 处理任何有实际用户的内容。

原始链接

I Tested Ollama vs vLLM vs llama.cpp: The “Easiest” One Collapses at 5 Concurrent Users