VPS 上 Ollama 还是 llama.cpp:CPU 服务器怎么选?
了解 Ollama 与 llama.cpp 的分层关系,比较 CPU-only VPS 上量化选择对 RAM 的影响,核对 v0.40.12 与 v0.7.0 的版本差异,并确认 25 GB root 卷何时会不够用。
Ollama 与 llama.cpp:您希望运行哪一层?
Ollama 和 llama.cpp 并不是问题所暗示的那种竞争关系。llama.cpp 是推理引擎:它加载模型文件,并将提示转换为 token。Ollama 是模型管理器、后台 daemon 和 HTTP API,运行在该引擎之上。Ollama 的 README 仍将 llama.cpp 列为其推理后端(截至 27 October 2026 检查)。因此,真正的问题是您希望在 VPS 上运行哪一层,而不是哪一个速度更快。
如果您希望获得一个可以按名称获取模型、无需持续维护也能运行的服务,请运行 Ollama。如果 VPS 资源有限,而您需要精确选择模型文件、上下文大小和线程数,请直接运行 llama.cpp,因为在小型 VPS 上,这些设置中的每一项都会占用本就不足的内存。
每个项目的实际定位
llama.cpp 是基于 ggml 库实现的 C 和 C++ Transformer 推理程序。它读取 GGUF 文件。GGUF(GGML universal file format)是一个单文件容器,其中包含引擎运行模型所需的权重、分词器和元数据。该项目为不同任务提供独立的二进制文件。llama-server 是 HTTP 服务器,llama-cli 是交互式提示程序,llama-bench 用于测量吞吐量。该项目现在按语义化版本(MAJOR.MINOR.PATCH)发布;v0.7.0 于 15 October 2026 发布,截至 27 October 2026 是最新版本。带构建编号的 nightly 标签仍会与这些版本一同发布,每天有多个;截至 27 October 2026,最新标签是 b11913。
Ollama 是一个 Go 程序。使用 ollama serve 启动的后台 daemon 会加载模型并响应 HTTP 请求,命令行客户端则与该 daemon 通信。两者背后都有一个位于 ollama.com 的 registry,其中存放预打包模型。Ollama 使用语义化版本。v0.32.5 于 27 July 2026 发布,v0.40.12 于 27 October 2026 00:07 UTC 发布。ollama pull 会获取 GGUF、prompt template 和一组默认参数,然后在 Linux 上将其存储到 /usr/share/ollama/.ollama/models。这些文件位于 root 磁盘上,每个文件可能达到数 GB,因此在 root 卷为 25 GB 的 VPS 上,第三次下载占满磁盘之前,最好先了解 pull 会留下哪些文件,以及如何将模型目录移到其他位置。
这就是两者的全部区别。Ollama 会替你决定量化方式、模板和上下文长度,并提供一个便于记忆的名称。llama.cpp 则通过 flags 暴露这些选项;对于未设置的参数,它会自动使用默认值。
轴 1:模型与量化控制
量化使用少于原始模型 16 或 32 位的位数来存储权重,常见的 GGUF 构建平均每个权重约为 4、5 或 8 位。文件中的精度并不统一。根据 llama.cpp 的量化器源码(读取于 27 October 2026),Q4_K_M 构建会将大多数张量保持为 4 位,但将输出层,以及大约一半层中的注意力 value 张量和前馈 down 张量改用 6 位的 Q6_K;norm 等小型张量则完全不量化。这正是 8 billion 参数模型可以装入普通 VPS RAM 的原因。了解命名规则后,GGUF 名称很容易读懂:Q4_K_M 表示 4-bit K-quant,medium size。数字越大,保留的精度越高,占用的内存也越多。
此图表背后的数据
[
{
"label": "Q2_K",
"file_size_gib": 2.96
},
{
"label": "Q3_K_M",
"file_size_gib": 3.74
},
{
"label": "Q4_K_M",
"file_size_gib": 4.58
},
{
"label": "Q5_K_M",
"file_size_gib": 5.34
},
{
"label": "Q6_K",
"file_size_gib": 6.14
},
{
"label": "Q8_0",
"file_size_gib": 7.95
}
]这些是 Hugging Face 上 bartowski/Meta-Llama-3.1-8B-Instruct-GGUF repository 中发布的文件大小,读取于 2 August 2026,并已从 bytes 转换为 GiB。一个模型共有 6 个构建,最小的是 2.96 GiB,最大的是 7.95 GiB。常见的默认构建 Q4_K_M 为 4.58 GiB。在 4 GiB VPS 上,这个单独的选择就决定了模型能否加载。大小只决定了一半,因为买得起某一行并不代表它值得使用;Q4、Q8 和 fp16 实际会对回答质量造成什么影响 才能说明额外的 gigabytes 是否能带来你确实能察觉的收益。
使用 llama.cpp 时需要指定文件,因此由您自行选择这一行。
llama-server -m ~/models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf \
-c 4096 -t 4 --host 127.0.0.1 --port 8080-c 是以 tokens 计的 context size,-t 是 thread count,-ngl 设置移到 GPU 的层数(仅 CPU 的主机上为 0)。未设置的选项会使用默认值;--fit 默认启用,会调整未设置的参数以适应 device memory。
使用 Ollama 时,量化版本会随您拉取的 tag 一起确定,ollama ls 可显示磁盘上实际已有的版本。如果 registry 中没有您需要的构建,可以自行导入 GGUF。创建一个 Modelfile:
FROM ./Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf
PARAMETER num_ctx 4096然后构建并检查结果:
ollama create llama31-q4 -f ./Modelfile
ollama lsContext length 是最容易出问题的设置。Ollama 会根据可用 VRAM 选择默认值;没有 GPU 的主机会落入最小档位:4096 tokens。向它发送 20,000 token 的文档时,多出的 tokens 会在模型看到文档之前被丢弃,因此模型只读了一半文件,却会自信地给出错误答案。可以在 daemon 上使用 OLLAMA_CONTEXT_LENGTH 提高该值,也可以在 Modelfile 中使用 PARAMETER num_ctx。如果只有一个任务需要更大的窗口,可以按请求设置 num_ctx,而不是对整个 server 统一设置,这样 daemon 处理其他任务时就不会一直保留额外的 cache。llama.cpp 也没有值得信任的默认值。请显式设置 -c,并确认实际设置的值。
内存计算中没人告诉你的部分
模型文件并不是全部开销。KV cache(键值缓存)为上下文中的每个 token、每一层保存一条记录,并且会随着对话增长。
以 Llama 3.1 8B 为例。该模型有 32 层、8 个键/值头,head dimension 为 128。f16 中每个 token 的 key 和 value 各占 2 bytes,因此每层需要 2 x 8 x 128 x 2 = 4096 bytes。32 层合计为每个 token 128 KiB。因此,4096 token 的上下文需要 512 MiB,32,768 token 的上下文需要 4 GiB。
因此,Q4_K_M 8B 模型在 4k 上下文下,需要约 4.58 GiB 的权重空间,另外还要加上约 0.5 GiB 的缓存和运行时本身的开销。它无法放入 4 GiB RAM。使用 8 GiB RAM 时可以运行,并留有一定余量。在同一台 8 GiB 主机上将上下文提高到 32k 后,缓存本身就会耗尽余量。模型加载期间,使用 free -h 实时查看内存占用;不要相信未经实际测量的估算。如果目标模型明显超过 8B,那么 仅使用 CPU 的 VPS 运行 27B 模型中的相同计算可以说明 8 到 64 GB 的各个内存级别实际能够容纳什么。
Ollama 会进一步放大这一影响。OLLAMA_NUM_PARALLEL 的默认值为 1,模型所需的内存会随该值和上下文长度的乘积增长。两者同时提高时,daemon 会在不明显提示的情况下请求数倍于预期的 RAM。同样的计算也决定了同时服务的用户上限,因为每个并发请求都需要占用自己的 KV cache,这就是服务器单用户运行正常、五名用户同时使用却停滞的原因。
轴 2:需要管理的守护进程
Ollama 安装脚本会写入 systemd 单元,创建一个 ollama system 用户,并启用该服务。无需手动编写这些配置,即可获得生命周期管理功能。配置通过 systemd 完成:
sudo systemctl edit ollama[Service]
Environment="OLLAMA_CONTEXT_LENGTH=8192"
Environment="OLLAMA_KEEP_ALIVE=30m"sudo systemctl daemon-reload
sudo systemctl restart ollama
journalctl -e -u ollamaOLLAMA_KEEP_ALIVE 在 CPU VPS 上比在其他环境中更重要。模型默认在内存中保留 5 分钟,然后卸载。下一次请求必须重新加载整个文件,之后才能生成响应。如果内核仍将文件保留在页缓存中,加载会很快;但只有空闲 RAM 才能让文件继续留在缓存中。一旦其他任务将其逐出,文件就会从磁盘重新读取。因此,在慢速存储上,重新加载 4.58 GiB 的文件,可能会让两秒的响应变成三十秒。延长 keep-alive 可以消除延迟,但会永久占用 RAM。这两者都会产生实际成本。请选择影响较小的一种。如果您决定让模型始终驻留在内存中,设置 keep_alive,使模型在空闲期间和重启后继续驻留只需几行配置,并且每次服务器重启后都无需手动预热模型。
llama.cpp 不提供守护进程或服务用户,因此需要自行配置。从构建时使用的 llama.cpp 目录开始,将二进制文件及其库安装到 /usr/local,创建一个 llama 用户,并为其复制一份模型:
sudo cmake --install build
sudo ldconfig
sudo useradd --system --no-create-home --shell /usr/sbin/nologin llama
sudo install -d -o llama -g llama /srv/models
sudo install -o llama -g llama -m 644 ~/models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf /srv/models/model-Q4_K_M.gguf如果您使用的是发行版压缩包而不是自行构建,请将 ExecStart 指向其中的 llama-server,因为压缩包会将库文件放在二进制文件旁边。然后按 /etc/systemd/system/llama-server.service 编写该单元:
[Unit]
Description=llama.cpp server
After=network-online.target
[Service]
ExecStart=/usr/local/bin/llama-server -m /srv/models/model-Q4_K_M.gguf -c 4096 -t 4 --host 127.0.0.1 --port 8080
Restart=always
RestartSec=3
User=llama
[Install]
WantedBy=multi-user.target使用 sudo systemctl enable --now llama-server 启用该单元。此后,进程会在整个生命周期内保留模型。默认情况下,模型不会因空闲而卸载;但添加 --sleep-idle-seconds 后,可以在不停止服务的情况下自动卸载和重新加载模型。如果您不熟悉编写单元,这与在 VPS 上通过 systemd 运行自有服务使用的是同一种模式。
轴 3:应用将调用的 API
这一轴的差异已经大幅缩小。现在两个项目都支持 OpenAI 聊天格式,因此大多数客户端库只需修改基础 URL,即可用于任一项目。
Ollama 监听 127.0.0.1:11434。其 OpenAI 兼容路由是 http://localhost:11434/v1/chat/completions,同时还提供原生 API /api/chat。此外,文档还说明了 Anthropic 兼容路由。这些路由都不会让模型自行查询信息。因此,如果应用需要回答超出模型训练数据范围的问题,应规划通过 Ollama API、Open WebUI 或简短的工具调用循环接入 网页搜索。
curl -X POST http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "llama31-q4", "messages": [{"role": "user", "content": "Say this is a test"}]}'使用上述标志启动后,llama-server 监听 127.0.0.1:8080。单独运行时,它现在默认使用端口 9931(已于 27 October 2026 检查),因此如果应用需要 8080,请在命令行中保留 --port。它提供 /v1/chat/completions、/v1/completions 和 /v1/embeddings,还提供自己的 /completion 端点以及内置 Web UI。它还暴露了 Ollama 没有的运维路由:/health 用于就绪探针,/props 用于查看已加载模型的设置,/slots 用于查看每个请求槽的状态;添加 --metrics 后,还会以 Prometheus 格式提供 /metrics,因为该端点默认关闭。如果计划监控此服务,这一差异可能会决定最终选择。
两个服务器都不会自动启用身份验证。出于合理的安全原因,二者默认只监听回环地址。请通过 SSH 隧道或反向代理访问它们,绝不要将 11434 或 8080 暴露到互联网。
CPU-only VPS 能实际做到什么
CPU-only VPS 可以缓慢运行小型模型。简而言之,关键是了解它的能力边界。在围绕它进行设计前,先进行测量:
llama-bench -m ~/models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -p 512 -n 128pp 列表示提示词处理速度,tg 列表示令牌生成速度,单位均为每秒令牌数。在共享 vCPU 方案上,8B 模型使用 Q4_K_M 时,tg 通常只有个位数。真正影响体验的是提示词处理:模型必须先处理完整提示词,才会生成第一个输出令牌,因此较长的系统提示词会让每个请求都增加等待时间。回复长度是你唯一可以直接控制的成本部分,因为生成速度为每秒 3 个令牌时,一个滔滔不绝、输出 600 个令牌的模型会占用该 VPS 200 秒,仅生成过程就超过 3 分钟。因此,使用 通过 num_predict 限制输出 是防止一次冗长回复导致超时的最低成本方法。
CPU 上适用的场景:使用 1B 到 4B 模型进行分类、信息提取、简短摘要或路由。回复会在数秒内到达,内存需求也符合普通方案。对于这一尺寸范围中的一个具体示例,在 VPS 上拉取并测量 Nemotron 3.5 Lightning 提供了确切的标签、实际所需的 RAM,以及无 GPU 时能够保持的速度。CPU 上不适用的场景:按阅读速度进行交互式聊天、代码助手、长文档处理,或需要通过 agent 循环连续发起多次调用的任务。一个连续发起 12 次调用、每次耗时 4 秒的循环,在产生任何结果前就需要 1 分钟。如果原计划是使用代码助手,让 agent 指向自行托管的模型 说明了小型本地模型真正擅长哪些任务,以及哪些任务必须继续使用托管 API。
当这些数据不理想时,有两种解决方向。如果问题是并发,即多个用户同时访问同一个模型,应更换推理引擎;Ollama 与 vLLM 并发服务对比对此进行了说明。如果问题是原始速度,答案是配备 GPU 的 VPS,此时 -ngl 才真正具有实际意义。在这两种方案之前,先为硬件本身建立基线,因为磁盘和内存带宽与 CPU 一样会影响加载时间。可重复的 VPS 基准测试值得投入这 1 小时。
安装 llama.cpp,并固定到指定构建版本
这两个项目每周都会更新,因此请记录已部署的版本。上游提供的一行命令会安装当前构建版本:
curl -LsSf https://llama.app/install.sh | sh
llama serve -hf ggml-org/Qwen3.5-0.8B-GGUF如需固定到特定构建版本,请改为从 releases 页面获取预构建 tarball。该项目现在也发布语义化版本:v0.7.0 是 27 October 2026 的最新版本,其 release 页面为二进制文件指向 nightly b11669。v0.8.0 于 28 October 2026 发布,其 release 页面为二进制文件指向 nightly b11960。以下命令使用 b10224,即 2 August 2026 的当前标签;请替换为已测试的标签:
curl -LO https://github.com/ggml-org/llama.cpp/releases/download/b10224/llama-b10224-bin-ubuntu-x64.tar.gz
tar xf llama-b10224-bin-ubuntu-x64.tar.gz
find . -type f -name 'llama-server'或者从源代码构建同一标签:
sudo apt update && sudo apt install -y build-essential cmake git libssl-dev
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
git checkout b10224
cmake -B build
cmake --build build --config Release -j $(nproc)libssl-dev 是 HTTPS 功能的文档规定依赖项。编译需要几分钟,并且比最小规格的计划需要更多 RAM,因此请在更大的服务器上构建;如果小型服务器内存不足,再将二进制文件复制过去。
安装 Ollama 并固定版本
curl -fsSL https://ollama.com/install.sh | OLLAMA_VERSION=0.32.5 sh
ollama -v该脚本会读取 OLLAMA_VERSION,因此您可以固定使用已验证的稳定版本,而不是直接安装当天发布的版本。v0.32.5 于 27 July 2026 发布。如果您不希望将脚本通过管道传入 shell,也可以手动安装:
sudo rm -rf /usr/lib/ollama
curl -fsSL https://ollama.com/download/ollama-linux-amd64.tar.zst | sudo tar x -C /usr
ollama -v手动安装不会创建 systemd 单元或服务用户,因此需要您自行创建。VPS 上部署 Ollama 的完整指南将逐步介绍服务配置过程。
故障模式及您将看到的字符串
Ollama 拒绝加载模型。 较旧的 Ollama 版本会在加载前检查大小,ollama run 会返回以下格式的行:
Error: model requires more system memory (5.6 GiB) than is available (3.2 GiB)当前 Ollama 源代码已不再包含该消息(已于 27 October 2026 检查)。Ollama 现在将加载交给 llama-server 处理,因此不适合加载的模型会显示为运行程序故障,错误通常以以下内容开头:
llama-server reported out-of-memory during startup
llama-server process has terminated无论是哪种情况,修复方法都相同。向下选择一个量化级别,降低上下文长度,或选择更小的模型。
llama.cpp 不会失败,而是运行极慢。 llama.cpp 默认使用内存映射加载 GGUF,因此大于 RAM 的文件仍然可以启动。随后,内核会在每个 token 生成期间从磁盘反复换入和换出权重;磁盘占用率会固定在 100%,生成速度降至每个 token 需要数秒。传递 --load-mode none 可禁用内存映射。该选项取代了 --no-mmap;在固定的 b10224 构建中,该选项已标记为弃用,在当前构建中也已不再出现(已于 29 October 2026 检查)。内核介入时,dmesg 会显示原因:
Out of memory: Killed process 1234 (llama-server)模型文件完全无法加载。 如果 GGUF 是为比您的引擎更新的模型系列构建的,错误会指出引擎不识别的架构;其中 <arch> 是文件元数据中存储的名称:
llama_model_load: error loading model: unknown model architecture: '<arch>'修复方法是升级引擎,而不是更换文件。这就是固定版本的代价,也是您需要记录构建编号的原因。您必须知道当前要从哪个版本升级。
API 在本机可以响应,但您的应用无法访问。 Ollama 绑定到 127.0.0.1:11434,因此其他主机会收到连接被拒绝。仅当该端口位于防火墙或私有网络之后时,才通过 systemctl edit ollama 设置 OLLAMA_HOST=0.0.0.0:11434,因为 API 前面没有身份验证。
暂停后收到的第一条响应非常慢。 5 minute 空闲卸载已发生,模型正在重新加载;如果页面缓存未保留模型,则会从磁盘加载。就在请求前运行 ollama ps 会显示没有已加载内容,从而确认这一点。提高 OLLAMA_KEEP_ALIVE。
那么你应该运行哪一个?
如果你希望模型由系统自动管理,并直接获得一个无需额外配置的 OpenAI 兼容接口,请运行 Ollama。对于首次部署以及模型需求频繁变动的场景,这是默认的首选方案。
当内存资源紧张,需要你自行选择量化版本,或者需要 /health、/slots 和 /metrics 进行监控,又或者需要使用 Ollama 未提供的特定标志时,请直接运行 llama.cpp。在模型勉强能塞进 VPS 的情况下,这是更稳妥的选择,因为 Ollama 替你自动选定的设置正是让模型能够运行的关键。
同时运行两者是很常见的做法。使用 Ollama 进行实验,使用 llama.cpp 运行那个已投入生产且无需变动的模型。
FAQ
Ollama 只是 llama.cpp 的包装器吗?
基本可以这样理解,但这个包装器确实执行了实际工作。Ollama 的 README 将 llama.cpp 列为其推理后端(截至 27 October 2026 检查)。Ollama 在此基础上增加了模型注册表、将聊天消息转换为提示词的提示词模板、一组默认采样参数、支持空闲卸载的守护进程,以及 HTTP API。在设置完全相同的情况下比较每秒生成的 token 数,比较的是同一个引擎本身。实际需要选择的是管理层。
仅使用 CPU 的 VPS 上哪个更快?
两者使用同一个引擎,因此在模型文件、量化方式、上下文大小和线程数相同的情况下,性能通常接近。人们报告的差异通常来自不同的默认设置,最常见的是上下文长度和线程数,而不是引擎本身。使用 llama-bench -m <file> -p 512 -n 128 测量,并在相信任何已发布数据前,比较自己服务器上的 tg 列。
可以在 Ollama 中使用自己的 GGUF 文件吗?
可以。将文件放到服务器上,编写一个 Modelfile,其第一行是 FROM ./your-model.gguf,再添加所需的 PARAMETER 行,例如 num_ctx,然后运行 ollama create your-name -f ./Modelfile。ollama ls 会将它与从注册表拉取的其他内容一起列出。这样即可使用注册表中没有提供的量化版本。
8B 模型需要多少 RAM?
需要为模型文件大小、KV cache 和运行时额外预留内存。Llama 3.1 8B 的 Q4_K_M 构建版本在磁盘上约占 4.58 GiB,4096 token 的上下文大约会增加 512 MiB cache,因此 8 GiB RAM 足够,而 4 GiB 不够。cache 大小会随上下文扩展:同一模型使用 32,768 token 的上下文时,单独就需要约 4 GiB cache。使用 Ollama 时,还要注意这一要求也会随 OLLAMA_NUM_PARALLEL 扩展。