Ollama 与 vLLM 怎么选:本地推理还是高并发服务
Ollama 适合单用户、本地或 CPU 推理,vLLM 面向 GPU 高吞吐服务。本文对比并发、量化、资源需求与真实启动命令,帮您按工作负载选择。
Ollama 与 vLLM:一段话说明
Ollama 是带有服务端的模型管理器:它会下载量化权重、加载模型,并在 127.0.0.1:11434 上响应请求;如果服务器只有 CPU,也可以使用 CPU。vLLM 是吞吐引擎:它让 GPU 同时处理大量请求并保持高利用率,因此不适合没有 GPU 的机器。这就是全部区别。一个人向本地助手提问,适合使用 Ollama。一个面向团队提供服务的应用,适合使用 vLLM。
两者都提供兼容 OpenAI 的 HTTP API,因此只需修改 base URL,客户端代码即可在两者之间切换。区别不在 API,而在第一个请求仍在生成 token 时,第二个请求到达后系统如何处理。
Ollama 的实际作用
Ollama 是一个便捷层。只需运行一条安装命令,它就能提供模型注册表(ollama pull llama3.1:8b)、本地权重存储、聊天提示词、systemd 服务和 HTTP API。它提供的模型是 GGUF 文件,通常经过 4-bit 量化。因此,7B 或 8B 模型在磁盘上通常约占 5 GB,而不是 16 GB。量化使 CPU 推理成为可能。
它的运行器基于 llama.cpp。llama.cpp 是一个 C++ 推理库,使 GGUF 量化可以在普通硬件上实际使用。此后,Ollama 为一些较新的模型系列加入了自己的引擎,但它提供的大多数内容仍以 llama.cpp 为底层基础。因此,人们比较 Ollama 和 llama.cpp 时,主要是在比较一个易用性层和它所封装的底层组件。
它的设计目标是供单个用户使用。截至 July 2026,OLLAMA_NUM_PARALLEL 的默认值为 1。这表示一个模型一次只处理一个请求,其他请求都会进入默认容量为 512 个条目的队列(OLLAMA_MAX_QUEUE)等待。您可以提高并行设置,下面的章节会说明这样做的代价。如果您之前没有运行过 Ollama,请先阅读在 VPS 上托管 Ollama 并保持端口 11434 关闭,因为该 API 完全不提供身份验证。
vLLM 的实际功能
vLLM 只是推理服务器。它不管理模型库,没有聊天提示词,也不会在收到请求时替您下载模型。您在启动时指定一个 Hugging Face 仓库,vLLM 加载该仓库中的一个模型,并持续提供服务,直到您停止进程。
这种专注带来的优势是吞吐量。两个机制共同实现了这一点。PagedAttention 将 KV cache(键值缓存,即模型为每个活动请求的每个 token 保留的注意力状态)存储在固定大小的块中,原理类似于操作系统分页管理内存。请求不再需要根据最坏情况预留一大块连续内存,因此原本被预留但未使用的内存可以用于处理更多并发请求。Continuous batching 允许新请求在下一次解码步骤加入正在运行的批处理,而不必等待当前批处理完成。序列完成后会立即离开批处理,其位置会被新请求占用。
实际效果是:在单个 GPU 上,并发用户数从 1 增加到 30 时,总 tokens/秒会显著提高,而每个用户的速度下降幅度远小于预期。在 Ollama 的默认行为下,用户数从 1 增加到 30 只会让另外 29 个人等待。
连续批处理决定了全部性能差异
假设有 5 个请求在同一时刻到达每台服务器,且硬件完全相同。
Ollama 使用默认设置时,会先处理完第 1 个请求,再处理第 2 个请求,依此类推。第 5 个调用方需要等待前面 4 次完整生成。总吞吐量大致等于单次生成的速度,因为处理器始终只处理一个序列。
vLLM 会在同一次前向传递中解码全部 5 个请求。为 5 个序列各生成 1 个 token,成本几乎不比为 1 个序列生成 1 个 token 高,因为最耗时的部分是从内存中读取模型权重,而这次读取由整个批次共享。这正是 CPU 推理速度慢的内存带宽原因:成本主要来自移动权重,而不是执行算术运算。
您可以设置 OLLAMA_NUM_PARALLEL=4,获得部分类似效果。代价是内存。每个并行槽都需要自己的 KV 缓存,而 Ollama 会在这些槽之间分配上下文窗口。因此,对于配置为 8192 tokens 的模型,4 个并行请求会使每个请求只能获得 2048 tokens 的上下文。8192 本身也是一个配置选择,并非固定值,因此 提高 num_ctx 并为其内存开销配置 RAM 决定了 4 个槽是否真正可用。vLLM 的分页缓存可以避免这种取舍,因为它会随着请求实际增长,逐步为请求分配缓存块。无论采用哪种方式,单台服务器能够同时服务多少用户,最终都取决于 KV 缓存大小、预填充开销和队列深度。这也解释了为什么一台单用户使用时运行良好的服务器,在 5 个用户同时使用时会变得很慢。
使用 Ollama 安装并提供服务
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.1:8b
ollama run --verbose llama3.1:8b "Write two sentences about Linux."安装脚本会创建一个 ollama 系统用户,安装二进制文件,并注册绑定到 127.0.0.1:11434 的 ollama.service。--verbose 输出的 eval rate 行表示该主机上的实际每秒令牌数。应以此为准,不要依赖任何已发布的数据。单次提示词的一次测量只能作为起点,不能代表容量。因此,只有在不同并发度下测量每秒令牌数,才能判断主机是否能承受预期负载,以及租用 GPU 是否比按令牌付费更划算。
要提高并发度,请使用 systemd drop-in,这样升级时不会覆盖该修改:
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_KEEP_ALIVE=30m"sudo systemctl restart ollama
ollama psollama ps 显示当前已加载的配置,其 PROCESSOR 列才是实际生效的值。100% CPU 表示未使用 GPU,这是大多数 Ollama 运行缓慢报告的真实原因。该 drop-in 中的 OLLAMA_KEEP_ALIVE=30m 行同样会影响空闲主机,因为默认情况下,模型在没有请求 5 分钟后会被卸载,而让模型在请求之间保持驻留可以避免空闲 1 小时后发送的第一个提示词再次承担完整的加载时间。
使用 vLLM 安装并提供服务
vLLM 需要 Linux 和 Python 3.10 到 3.13。请将其安装到独立的虚拟环境中,因为它会引入特定的 PyTorch 构建版本:
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=auto然后提供模型服务。名称必须是 Hugging Face 仓库 ID,而不是简短标签:
vllm serve Qwen/Qwen2.5-1.5B-Instruct首次启动速度较慢,因为程序需要先下载权重,然后分析 GPU,以确定适合的 KV 缓存块数量。服务监听 8000 端口。编写客户端代码前,先检查服务是否正常:
curl http://localhost:8000/v1/models
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [{"role": "user", "content": "Who won the world series in 2020?"}]}'如果服务器上已经安装 Docker,官方镜像可以省去 CUDA 依赖配置:
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HF_TOKEN=$HF_TOKEN" \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model Qwen/Qwen3-0.6B--ipc=host 是必需配置,不是装饰性参数:PyTorch 通过共享内存在进程之间传递张量,而 Docker 的默认共享内存分配对于张量并行推理来说太小。
生产环境中最重要的参数包括 --max-model-len(可接受的上下文窗口大小)、--gpu-memory-utilization(vLLM 可占用的显存比例;截至 2026 年 7 月,默认值为 0.92)、用于将一个模型拆分到多个 GPU 上的 --tensor-parallel-size,以及 --api-key。
vLLM 提供一个认证参数,而 Ollama 没有
如果提供 bearer token,vLLM 会强制要求请求携带该 token:
vllm serve Qwen/Qwen2.5-1.5B-Instruct --api-key token-abc123同一个值也可以通过 VLLM_API_KEY 环境变量提供。不携带该 token 的请求会收到 HTTP 401 响应。但这仍不足以成为在公网接口上开放 8000 端口的理由,因为 vLLM 没有速率限制,而且纯 HTTP token 在传输过程中可被读取。不过,这意味着服务器能够识别请求方。
Ollama 没有任何认证机制。它没有密钥、登录功能或允许列表。任何能够访问 11434 的进程都可以运行、拉取或删除模型。请将其限制在 loopback 接口上,并通过 自行托管的 WireGuard VPN 访问,或使用会终止 TLS(传输层安全)的认证反向代理。
硬件:各自的需求
Ollama 在 CPU 上运行。4-bit 量化模型每 10 亿个参数大约需要 0.5 GB RAM,此外还需要约 1 GB 运行时开销,并需要为上下文预留更多内存。因此,3B 模型需要约 4 GB 可用内存,8B 模型需要约 8 GB。在共享 vCPU 上,速度通常为每秒个位数到十几枚 token。这是内存带宽造成的限制,不是配置错误,也没有任何 flag 可以修复。若要查看具体版本的实际资源消耗,而不是依赖经验值,请参阅在 VPS 上运行 Nemotron 3.5 Lightning,其中会明确要拉取的确切 tag、模型加载后的内存占用,以及仅使用 CPU 的速度是否足够实用。
vLLM 默认使用 GPU。其默认路径以 16-bit 精度提供未量化权重,平均每 10 亿个参数约需要 2 GB 显存:8B 模型仅权重就需要约 16 GB 显存,尚未计算为并发请求而设置的 KV cache。在 24 GB 显卡上,还能为缓存留出可用空间。在 16 GB 显卡上则无法满足,因此需要选择更小的模型,或对量化 checkpoint 传递 --quantization。虽然存在 CPU backend,但标准 wheel 并未针对它构建,而且这样会失去运行 vLLM 的主要意义。
因此,大多数情况下,硬件问题也就决定了软件选择。没有 GPU,就使用 Ollama。租用的 GPU 利用率只有 5%,因为请求被串行处理时,就使用 vLLM。
适合您的工作负载
- 单人使用、配备 1 个 CPU VPS,用于起草和摘要:Ollama。速度可以接受,而且没有更简单的方案。
- 编程助手,或通过连接您的工具与本地模型的 MCP 服务器,且只有您自己调用:Ollama。实际工作负载是并发数为 1。
- 本周要比较 5 个模型:Ollama。拉取和删除带标签的模型正是它擅长的工作,而 vLLM 每切换 1 个模型都需要重启进程。
- 内部应用、聊天产品或面向真实用户的检索流水线:vLLM。这类场景可以通过批处理提升 GPU 投入的价值。
- 需要在一夜间为 100000 份文档评分的批处理作业:vLLM,并设置较高的
--max-num-seqs。吞吐量是唯一重要的指标,单份文档的延迟并不重要。 - 多个自行托管的 AI 代理会同时访问模型的代理平台:vLLM,因为代理流量具有突发性,而且天然是并行的。
故障模式及其对应的提示信息
vLLM 因 KV cache 错误拒绝启动。 提示信息会同时列出这两个数值:
ValueError: The model's max seq len (32768) is larger than the maximum number of tokens that can be stored in KV cache (8192). Try increasing gpu_memory_utilization or decreasing max_model_len when initializing the engine.模型声明的上下文窗口大于加载权重后剩余的显存。使用 --max-model-len 8192 将其调低;如果没有其他程序使用该 GPU,也可以提高 --gpu-memory-utilization。将利用率推高到约 0.95 以上,通常会把启动错误换成后续负载下的 CUDA 显存不足崩溃,后者更难处理。
Ollama 在生成过程中输出 Killed。 Linux 的内存不足终止程序,因为模型所需的 RAM 超过了服务器的实际容量。使用 sudo dmesg | grep -i oom 确认。解决方法是使用更小或量化程度更高的模型,而不是修改设置。
Ollama 单独运行时回答正常,但在负载下停滞。 系统中不会出现任何错误。调用方越多,请求耗时越长,因为 OLLAMA_NUM_PARALLEL=1 会将请求串行处理。较长的回答会使队列更加严重:一个调用方占用唯一的并发槽位,直到模型决定停止,后续所有请求都会被阻塞。因此,使用 num_predict 限制回复长度可以限制单次请求占用服务器的时间。提高并行设置,并接受每个请求可用上下文变小;或者将工作负载迁移到 vLLM。
vLLM 对每次调用都返回 401。 你使用 --api-key 启动了服务,但客户端没有发送 Authorization 请求头。大多数 OpenAI 客户端库会将你传入的值作为 key 发送,因此应在客户端中设置该值,而不是删除启动参数。
vLLM 提示找不到模型。 Ollama 会按需拉取模型,而 vLLM 不会。请求正文中的 model 字段必须与启动 vLLM 时使用的 repository id 匹配;如果设置了 --served-model-name,则必须与其值匹配。使用 curl http://localhost:8000/v1/models 确认准确的字符串。
同时运行两者是合理的方案
两者并不互斥。一种常见架构是:在 GPU 实例上运行 vLLM,为应用提供服务;在旁边的普通 VPS 上运行 Ollama,用于本地脚本、cron 任务和试用新发布的模型。两者的端点都兼容 OpenAI,因此只需使用同一个客户端库并切换 base URL 即可。相比选择哪种引擎,成本控制在这里更重要,因为空闲 GPU 的计费与繁忙 GPU 相同,而让代理和推理成本保持可预测本身又是独立于服务器选择的一项工作。
FAQ
vLLM 比 Ollama 快吗?
对于同一 GPU 上的单个请求,两者差距不大,因为执行的计算相同。对于大量并发请求,vLLM 明显更快,因为连续批处理会在一次前向传播中解码所有活动序列,而 Ollama 默认会依次处理这些请求。在仅使用 CPU 的机器上,这个问题不适用:Ollama 可以运行,而 vLLM 实际上无法运行。
vLLM 可以在没有 GPU 的情况下运行吗?
不能有效运行。标准 wheel 面向 NVIDIA 或 AMD GPU,而 vLLM 的核心用途是让加速器持续处理批量请求;在 CPU 上,这一用途不复存在。vLLM 提供 CPU 后端用于开发工作。对于实际的 CPU 推理,请直接使用 Ollama 或 llama.cpp。
Ollama 和 llama.cpp 有什么区别?
llama.cpp 是推理库,GGUF 是其量化权重格式。Ollama 的运行器基于 llama.cpp 构建,并补充了 llama.cpp 留给用户处理的部分:模型注册表、自动下载、常驻服务器、systemd 单元和兼容 OpenAI 的端点。Ollama 已为部分较新的模型系列加入自有引擎,因此两者底层已不再完全相同。
vLLM 运行 8B 模型需要多少 GPU 显存?
在 16 位精度下,仅权重就约需 16 GB,通常每 10 亿个参数约需 2 GB,此外还要为 KV cache 预留空间。24 GB 显存的显卡使用起来比较宽裕。16 GB 显存的显卡需要量化 checkpoint 或更小的模型。vLLM 使用由 --gpu-memory-utilization 设置的显存比例;截至 July 2026,该参数默认为 0.92。
在两者之间切换时,需要修改应用代码吗?
通常只需修改 base URL、API key 和模型名称。Ollama 在 http://127.0.0.1:11434/v1 提供兼容 OpenAI 的接口,并忽略 API key;vLLM 在 http://localhost:8000/v1 提供接口,如果设置了 API key,则会强制校验。模型名称的格式不同:Ollama 使用 llama3.1:8b,vLLM 使用完整的仓库 ID,例如 Qwen/Qwen2.5-1.5B-Instruct。