机器不是变慢,而是直接卡死
模型加上它的上下文缓存超出了 RAM,内核开始在每个 token 上都把权重换出到磁盘。要么装进内存,要么降一档——没有中间选项。

六个步骤,教你在自己的硬件上跑起一个大模型——用算式预测每秒能跑多少 token 要在买机器之前算好,4、8、16、32 GB 各能装下什么规模的模型,Ollama 本身不带的身份验证要怎么补上,还有一份老实交代哪些任务跑不动的清单。已在 Debian 12 上测试。
大小
拼的是带宽,不是核心数
安装
Ollama
实测
你自己的 tokens/s
防护
TLS + 一个令牌
连接
一个基础 URL
设限
上下文、RAM、磁盘
几乎所有关于本地跑大模型的文章讲的都是显卡,如果你手上只有一台虚拟机,这些内容帮不上什么忙。真正有用的心智模型比 GPU 那套话语体系简单得多,一句话就能说完:要生成一个 token,稠密模型必须把它所有的权重都从内存里读一遍。不是读一部分——是全部,每个 token 都要读一次。
光这一个事实就决定了整个性能问题的答案。生成速度不是由你租了多少核心决定的,而是由这台机器能以多快的速度把模型从 RAM 里读出来决定的。这样一来,你在花一分钱之前,就能在信封背面随手算出一个上限:
tokens per second ≈ memory bandwidth (GB/s) ÷ model size (GB)
一个量化后的 8B 模型大约占用 5 GB。在一台实际带宽在 20 GB/s 左右的虚拟化主机上,上限大约是每秒 4 个 token,而实测到的数字往往只有这个上限的一半到三分之二。大致是每秒 3 个词。把这当成这类任务本身的事实,而不是什么让人失望的结果:对聊天窗口来说这确实慢,但对一个负责给文档分类、返回一行 JSON 的任务来说完全够用。
核心数依然重要,只是原因和大多数人想的不一样。 增加线程数是有用的,但一旦占满内存通道就没用了,而这些机器往往很早就会撞到这个上限——通常在四到八个线程左右。过了这个点,多出来的核心只能闲着,其他一切都在等 RAM。这就是为什么一台十六核的机器生成文本的速度不会是四核机器的四倍,也是为什么为了追求速度去多花钱买核心数,是选错档位最常见的原因。
读得快,写得慢。 每一次请求都分两个阶段,它们的表现完全不一样。处理提示词——也就是预填充(prefill)阶段——是一次对整段输入一次性完成的矩阵运算,受算力限制,运行速度比生成快得多。生成答案则是前面说的那种受内存限制的部分,一个 token 一个 token 来。所以,把一份两千字的文档丢给模型、只要求返回三句话,是一项轻松的任务,而让它写一篇两千字的文章就不是了。围绕这种不对称去设计你的提示词,一台 CPU 机器给人的感觉会比它的 token 速率听起来要好得多。
| 套餐 | 内存 | 能轻松胜任的最大模型 | 数量级 | 适用场景 |
|---|---|---|---|---|
| Sentinel · $3.90 | 4 GB | 3B(Q4,约 2 GB) | 每秒一句话 | 分类、打标签、路由、嵌入 |
| Garrison · $7.90 | 8 GB | 8B(Q4,约 5 GB) | 每秒几个词 | 默认选择。摘要、JSON 提取、RAG 问答 |
| Ravelin · $16.90 | 16 GB | 14B(Q4,约 9 GB) | 大约是上面的一半 | 更强的推理、更长的上下文、批处理流水线 |
| Bulwark · $32.90 | 32 GB | 32B(Q4,约 20 GB) | 每秒不到一个词 | 重质量不重速度。只适合异步任务 |
| Citadel · $62.90 | 64 GB | 70B(Q4,约 40 GB) | 每份答案要几分钟 | 装得下。不能交互使用。适合夜间批处理 |
模型大小统一按 Q4_K_M 量化计算,这种量化用一点几乎察觉不到的质量损失,换来不到一半的内存占用。速度这一列是从上面那道算式推出来的数量级,不是跑分——第 03 步的意义就在于让你实测自己的机器,而不是相信任何一张表格,包括这一张。
这一节老实说比热情吹捧更有价值,因为放弃自建模型这个想法最快的方式,就是拿它最不擅长的那件事去为难它,然后得出“这整个主意就是异想天开”的结论。
装得下,很轻松。 任何输出简短、价值在于判断而非文采的任务。把一条消息归到几个类别之一。判断一张工单是否紧急。从一张发票里提取五个字段,输出成 JSON。把一段对话总结成三句话。给文档打标签。改写产品描述。翻译一小段文字。判断两条记录说的是不是同一个人。在一段文字发往别处之前,先把里面的姓名隐去。这些任务无一例外都是输入长、输出短——这正是 CPU 擅长应对的不对称。
装得下,但要有耐心。 没有人在等结果的那类工作。夜间批处理、队列工作进程、每晚扫一遍当天的文档、定时报告。只要没有人卡在等答案,一个在聊天窗口里让人无法忍受的 token 速率就彻底不重要了——凌晨三点跑六分钟的任务,不过就是一个跑完了的任务而已。
装不下。 一个让人真正用得舒服的交互式助手:在这种速度下,光标爬得比蜗牛还慢,体验比没有助手更糟。长篇生成——比如“帮我写两千字”——整段输出本身就是瓶颈所在。需要在大型代码仓库里反复迭代的编程智能体,无论是上下文还是质量门槛都超出了小模型能撑住的范围。任何需要十万 token 上下文的场景,光是缓存就能把机器撑爆。还有图像或视频模型,这完全是另一套体系,是真正需要 GPU 的场景。
如果你的工作负载正好落在最后那一类,理智的答案不是去买一台更大的 CPU 机器,而是走混合路线。用本地模型处理大部分调用,把少数需要前沿推理能力的请求转发给托管 API——这正是让 AI 智能体 24/7 运行的指南在运行环境那部分描述的架构。那篇指南刻意把模型本身留在了范围之外。这一篇正是补上那缺失的一半。
从任务本身倒推。先确定模型要做什么,选出能胜任的最小规模,查一下这个规模在 Q4_K_M 下占多大空间,再加上各种开销:
RAM needed = model file + KV cache + ~2 GB for the system
3B Q4_K_M ≈ 2.0 GB KV cache at 8k context ≈ 0.5–1 GB
8B Q4_K_M ≈ 4.9 GB KV cache at 32k context ≈ 2–4 GB
14B Q4_K_M ≈ 9.0 GB
32B Q4_K_M ≈ 20.0 GB
70B Q4_K_M ≈ 40.0 GB
键值缓存是大家最容易忘记的那部分开销。 对话里已经出现过的每个 token 都会被保留在内存中,这样模型就不用重新计算,而这块存储会随着你允许的上下文长度增长。上下文翻一倍,它也大致翻一倍。一个在 4k 上下文下装得下的模型,到了 32k 可能就装不下了,而且往往不是在第一次请求就失败,而是在第十次才失败,这会让人觉得莫名其妙,其实只是一道算式没算对。
这里没有什么优雅降级可言。 当总量超出 RAM 时,内核不会礼貌地慢下来:它会在每一个 token 上,把模型权重来回换出换入磁盘。本该四秒完成的生成变成四分钟,负载均值飙到两位数,机器上的其他一切——数据库、网页服务器、你的 SSH 会话——都会跟着遭殃。装进内存不是一项优化。这是硬性要求。
在面板里操作:Order → VPS → 算式指向的那个档位,镜像选 Debian 12。开户不需要邮箱地址,任何环节都不会索要身份证件,账单可以用 Monero、Bitcoin、Lightning 或其他支持的资产结算——这一点在这里比在普通的网页服务器上更重要,原因见匿名 VPS 托管支柱指南,下文的隐私章节则专门把这个道理用到了提示词上。
先把机器加固好——仅密钥登录的 SSH、一个只放行你明确要求的防火墙、无人值守的安全更新。首小时加固清单大概一个小时就能做完,而这台机器很快就会记住你问过的每一个问题。
接下来安装运行程序。Ollama 就是 llama.cpp 外面包了一层模型仓库、一个 REST API 和一个 systemd 单元,一条安装命令就能把这三样一次装好:
apt update && apt install -y curl
curl -fsSL https://ollama.com/install.sh | sh
systemctl status ollama --no-pager
ss -ltnp | grep 11434
# → 127.0.0.1:11434 — loopback only. Leave it that way.
最后那一行值得多看一遍。开箱即用时,这个服务监听的是回环接口,这完全正确,而接下来十分钟里最常见的错误,就是因为另一台机器连不上,就把 OLLAMA_HOST 改成 0.0.0.0。第 04 步讲的才是正确的连接方式;无论如何,都不应该让 11434 端口直接面向公网。
有两个设置值得现在就配好,而不是等以后才发现问题。模型默认存放在 /usr/share/ollama 下面,体积很大,所以要把它指向一个你有空间的地方。另外,默认设置会让模型在最后一次请求之后,在 RAM 里常驻五分钟,这对一台还要做别的事的机器来说有点奢侈:
systemctl edit ollama
[Service]
Environment="OLLAMA_MODELS=/var/lib/ollama/models"
Environment="OLLAMA_KEEP_ALIVE=30m"
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
systemctl daemon-reload && systemctl restart ollama
并发请求和同时加载多个模型都会成倍增加内存占用,而在一台刚好只够装下一个模型的机器上,根本挤不出多一个 GB 来放第二份拷贝。把队列串行化,在这类硬件上不是一种限制;这是唯一不会崩掉的配置。
拉取一个模型。用来做第一次测速,随便哪个目前的 8B 级指令模型都行——它们体积足够接近,测出来的时间反映的是硬件本身,而不是模型的差异:
ollama pull llama3.1:8b # ~4.9 GB at Q4_K_M
ollama list
ollama ps # nothing resident yet
现在打开计时开关,跑一次生成。真正重要的数字是生成速率——也就是提示词读完之后,每秒产生的 token 数:
ollama run llama3.1:8b --verbose "Reply with exactly one sentence about the Baltic Sea."
total duration: 14.2s
load duration: 3.1s
prompt eval count: 24 token(s)
prompt eval rate: 92.11 tokens/s ← reading: fast
eval count: 38 token(s)
eval rate: 3.42 tokens/s ← writing: the real ceiling
两行数字,两个不同的世界。读的速度跑到了每秒 90 多个 token;写的速度只有 3.5 个。这个比例正是算式那一章讲的不对称,只不过这次是在你自己的机器上实测出来的,也是你今天能拿到的最有用的一个事实。它在说:给这台机器长输入,只问它要短输出。
通过 API 做同样的测量,如果你打算写脚本批量对比两三个模型规模,这才是你真正需要的方式:
apt install -y jq
curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"prompt": "List three Nordic capitals.",
"stream": false
}' | jq '{
tokens: .eval_count,
seconds: (.eval_duration / 1000000000),
rate: (.eval_count / (.eval_duration / 1000000000))
}'
测一下小一档和大一档的模型,然后就此打住。 拉取一个 3B 和一个 14B,把同样的提示词分别跑一遍,把三个速率都记下来。这样你就能确切知道在这台机器上这笔交换要付出多少代价——通常两个方向都接近翻倍——之后就可以按任务挑模型,而不是凭印象。然后把不打算留的模型删掉,因为它们每一个都占好几个 GB。
有一点要提醒:任何模型第一次运行时,输出里的加载耗时指的是把权重从磁盘读进 RAM 所花的时间。只有模型还没有常驻内存时才会产生这笔开销,而这正是 OLLAMA_KEEP_ALIVE 控制的东西。比较速率的时候不要把它算进去,也不用为此惊慌——在 NVMe 上也就是几秒钟,而且只会发生一次。
这一节的作用是防止坏事发生,所以话要说得不留余地:Ollama 的 API 没有密码,没有令牌,没有用户体系,也没有权限系统。任何能对 11434 端口发起 TCP 连接的东西,都能在你的 CPU 上生成文本,枚举你已经拉取的模型,拉取新模型,删除你正在用的模型。这里没有一个开关可以打开,因为压根就不存在这样的机制。
11434 端口一直在被扫描,原因很直白:一个敞开的模型运行程序,对别人来说就是免费算力。这不会以一条告警的形式出现,而是机器莫名其妙慢了两个星期,带宽图上的曲线也对不上你自己做过的任何事。把这个服务留在回环接口上,再在它前面放点东西,问清楚是谁在调用。
如果这台机器之外没有任何东西需要用到这个模型,到这里就可以停了——你已经完成了。回环接口加防火墙就是一个完整的答案,跑在同一台 VPS 上的智能体、自动化流水线或网页应用,都可以直接通过 127.0.0.1 访问模型,用不上后面这些内容。只有当另一台机器上的东西需要调用它时,才需要继续往下看。
代理,加上令牌。 生成一个足够长的随机令牌,把 A 记录指向这台机器,剩下的证书和门禁都交给 Caddy 处理:
openssl rand -hex 32 # → the bearer token, store it in a password manager
apt install -y caddy
/etc/caddy/Caddyfile
llm.example.com {
@unauthorised not header Authorization "Bearer PASTE_THE_HEX_TOKEN_HERE"
respond @unauthorised "unauthorised" 401
reverse_proxy 127.0.0.1:11434 {
# Generation is slow by nature — do not let the proxy give up first.
transport http {
read_timeout 10m
}
}
}
systemctl reload caddy
ufw allow 80,443/tcp
ufw status # 11434 must appear nowhere
选用持有者令牌而不是基础身份验证,有一点小小的巧妙之处。Ollama 暴露的是一个兼容 OpenAI 的 API,而每个 OpenAI 客户端发送密钥时用的正好就是那个请求头,所以你刚生成的令牌,直接就成了你的应用早就知道该怎么携带的那个 API 密钥。不需要任何自定义请求头,轮换访问权限也只需要改 Caddyfile 里的一行,再改调用方的一个环境变量。
从另一台不是这台服务器的机器上验证。第一次调用应该被拒绝,第二次应该正常返回:
curl -s -o /dev/null -w '%{http_code}\n' https://llm.example.com/api/tags
# → 401
curl -s https://llm.example.com/api/tags -H "Authorization: Bearer THE_TOKEN" | jq '.models[].name'
# → the list of models you pulled
如果调用这个模型的是智能体而不是你自己,暴露面的问题值得看一下更完整的处理方式,参见远程 MCP 服务器托管指南——同样一套关于 TLS、令牌以及谁能从哪里访问的思路,只不过这次用在一个提供工具而不是 token 的服务上。
Ollama 在 /v1 上提供一套兼容 OpenAI 的接口,与它自己的 API 并存。集成方式就这么简单:任何为 OpenAI 构建的东西——官方 SDK、框架的封装、自动化节点——只需要改一下基础 URL 和密钥就能用,其他什么都不用变。
curl -s https://llm.example.com/v1/chat/completions \
-H "Authorization: Bearer THE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "llama3.1:8b",
"messages": [{"role":"user","content":"Reply with the word OK."}]
}' | jq -r '.choices[0].message.content'
从 Python 代码的角度看,和调用托管服务相比,唯一不同的就是开头那两行:
from openai import OpenAI
client = OpenAI(
base_url="https://llm.example.com/v1",
api_key="THE_TOKEN",
)
r = client.chat.completions.create(
model="llama3.1:8b",
messages=[{"role": "user", "content": "Classify: 'the invoice is overdue'"}],
)
print(r.choices[0].message.content)
要 JSON,就给你 JSON。 对自动化来说,最有用的功能是约束输出。Ollama 可以强制答案是合法的 JSON,而不是指望模型自觉配合,这能把一个小模型从一个不可靠的“讲故事者”变成一个靠谱的解析器——这就是一个能无人值守运行的工作流,和一个每四十条就出错一次的工作流之间的区别:
curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"prompt": "Extract the total and the currency: Invoice 4021, 1 249,90 EUR due 30 days.",
"format": "json",
"stream": false
}' | jq -r .response
# → {"total": 1249.90, "currency": "EUR"}
在自动化流水线里也是同样的道理:n8n 自带专门的 Ollama 节点,它的 OpenAI 节点也支持自定义基础 URL,所以现有工作流只需改一个凭证就能切换到本地推理。n8n 自建指南讲的是自动化引擎本身;如果条件允许,把两者放在不同的机器上跑,因为一个空闲时就占 700 MB 的引擎,和一个想要 5 GB 的模型,挤在一台 8 GB 的机器上不会相处愉快。
还有嵌入接口——这才是这台机器真正物有所值的地方。 嵌入模型比生成模型小两个数量级,每个分块只需一次前向计算,不用生成任何东西,所以 CPU 处理起来的速度几乎是瞬间完成:
ollama pull nomic-embed-text # ~275 MB
curl -s http://127.0.0.1:11434/api/embed -d '{
"model": "nomic-embed-text",
"input": ["the first chunk of a document", "the second chunk"]
}' | jq '.embeddings | length'
给上下文设个上限。 上下文长度是控制内存占用的主要旋钮,默认值对一台小机器来说通常偏大方。把它全局设成你最长的实际提示词真正需要的长度——大多数分类和提取任务,四千 token 以内就很舒服——遇到极少数需要更多的请求,再单独调高:
Environment="OLLAMA_CONTEXT_LENGTH=4096"
curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"prompt": "…a long document…",
"options": { "num_ctx": 16384 },
"stream": false
}'
决定模型在内存里待多久。 常驻模型调用起来是瞬间响应,但会占着好几个 GB 不放。在一台专门做推理的机器上,让它一直常驻就好;在一台要跑别的东西的机器上,就让它过一段时间自动释放。这个值也可以按请求单独设置,所以一个夜间批处理任务可以在运行期间把模型钉住,结束后再释放:
OLLAMA_KEEP_ALIVE=-1 # resident until the service restarts
OLLAMA_KEEP_ALIVE=30m # a sensible default on a shared box
OLLAMA_KEEP_ALIVE=0 # unload immediately after each request
ollama ps # what is resident right now, and how much it holds
把队列串行化。 对同一个模型发两个并发请求,速度不会翻倍;它们会争抢同一条已经饱和的内存通道,结果是两个都变慢,如果 Ollama 决定再加载一份拷贝来服务它们,机器就会 RAM 耗尽。在这类硬件上,一次一个请求、前面排一个队列,既是最快的配置,也是唯一安全的配置——这也是为什么 OLLAMA_NUM_PARALLEL 和 OLLAMA_MAX_LOADED_MODELS 早在第 02 步就被钉死为 1。
盯着磁盘。 对比四个模型,就会留下四个模型,每个 5 GB,磁盘在悄无声息中被占满,也没人会提醒你。把清理也当作对比流程的一部分,而不是留到以后再做:
ollama list
du -sh /var/lib/ollama/models
ollama rm mistral:7b qwen2.5:14b
最后,只备份那些无法重新生成的东西。模型权重不用备份——重新拉取一次就回来了。真正值得放进仓库的是配置、Caddyfile、令牌、你花了三周打磨出来的提示词,以及如果你搭了检索系统,还有它背后的向量索引。加密备份指南讲了具体做法;这台机器要备份的清单很短,值得写下来。
以上说的全都是生成,也就是 CPU 做得慢的那部分。检索是大多数实用系统的另一半,而它把局面完全反过来了——这也是为什么这个页面上最便宜的档位,哪怕你从不在它上面生成一个 token,也能做成一件真正有价值的事。
嵌入模型把一段文本变成一个向量。它的体积以几百 MB 计,而不是几个 GB,每个分块只需要一次前向计算,没有逐 token 的循环会被内存带宽卡住。在同一台机器上,8B 模型每秒只能吐 3 个词,嵌入模型处理一个文档库的速度却快得像在复制文件。
大致的样子。 把文档切成几百字一块的分块。每个分块生成一次嵌入并存下这个向量。提问的时候,把问题也生成嵌入,找出最接近的那几个分块,连同问题一起交给模型。存储不需要什么特别的东西:带向量扩展的 SQLite 数据库,就足够在一台 VPS 上存下几万个分块,PostgreSQL 配 pgvector 则能撑得更远。专门的向量数据库以后再想也不迟,第一天就上是没必要的依赖。
为什么这比速度更重要。 看看这两半各自会碰到什么。生成这一步接触到的是一个问题和几段文字。嵌入这一步接触到的是<em>你拥有的每一份文档</em>——整个档案库、每一份合同、每一条笔记、每一条消息,一块一块地喂给模型。如果这一步跑在托管端点上,你的整个语料库就已经为了建索引而传给了第三方。如果它跑在你自己的机器上,什么都没有离开过。
这为那些不愿放弃前沿质量的人提供了一个真正好用的混合方案:在本地建索引、在本地检索,只有当答案需要做到出色时,才把问题和检索到的那三个分块发给托管模型。语料库留在本地,只有薄薄一片会外传,而且只在需要时才传。
本站上的两个相邻话题能把这个模式讲得很具体。自建 SearXNG为检索层提供的是一个面向公开网络的私人前端,而不是语料库;自建文档存储提供的才是语料库。这两者加上模型,放在一起的档位,每月花费也比一个托管席位的价格更低。
人们谈论模型隐私时,总以为风险出在输出上。其实不是。输出是通用文本,别的一千个人拿到的可能都差不多。真正暴露信息的是输入——而一年的输入,足以拼出一幅相当完整的组织画像。
想想一份请求日志里到底装了什么。你粘贴进去要它总结的那份合同。你让它分类的客户邮件,里面还带着客户本人的信息。那封医疗信件、那个薪资数字、你正在起草的辞职信、来自某个非公开仓库的代码。再加上周围的元数据:问了哪些问题、按什么顺序、几点钟、从哪个地址、跨越了多少个月。没有人会签一份文件写着“这就是我们的战略”——但这一连串问题本身就是那份文件,是你自己一次一次调用,老老实实拼出来的。
第一层——接口本身会留下什么。 靠谱的服务商会公布靠谱的政策,好的服务商也确实不会拿商业 API 流量去训练模型。但这和“不留存”是两回事。请求通常会为了监控滥用而保存一段时间,在特定条件下员工能够查看,也可能在法律程序中被要求提供——对于运营一个大平台来说这完全正确,但对于那些你不会发给陌生人的文字来说,这恰恰是最不该出现的地方。跑在你自己机器上的模型不会有这种日志,除非是你自己写了一个。
第二层——日志关联到的身份。 光是留存本身只是暴露面的一半。另一半是它关联到的那把钥匙:一个账户、一个公司名、一个账单地址、一张卡。正是这层关联,把“有人问过怎么收购一家竞争对手”变成了“这家公司在那个周二问过这件事”。把模型从这个等式里拿掉,去掉的是留存;把身份从机器上拿掉,去掉的是关联。开一台不用邮箱、不用身份证件、注册在北欧司法管辖区、用 Monero 结算的 VPS,就是同一个动作的另一半。
第三层——你自己写的日志。 自建并不会消除风险,只是把风险挪了个位置,值得看清楚它到底落在哪里。你的应用大概率会自己记录提示词日志。你的反向代理会记录每一条请求。两个月前的一次调试,可能已经在日志里留下了详细输出。模型本身在两次调用之间什么都不会记住,但围绕它的那一整套机器很可能什么都记得住——所以要主动决定哪些东西该被写下来,给它设定留存期限,并且用你不愿意接受别人那样对待你的标准,来要求这份日志。
这些都不能让本地模型本身自动成为一份隐私保证。它带来的是唯一一种由你自己来给出这份保证的架构:文本留在你租用的硬件上,处在你选择的司法管辖区之内,藏在你自己签发的令牌背后,不用向任何其他人交代。
模型加上它的上下文缓存超出了 RAM,内核开始在每个 token 上都把权重换出到磁盘。要么装进内存,要么降一档——没有中间选项。
为了让某个客户端能连上,把 OLLAMA_HOST 设成了 0.0.0.0。这个 API 完全没有身份验证,而 11434 端口一直在被扫描。回环接口,加一个会校验令牌的代理。
选了一个 32B 模型做交互式助手。让规模匹配使用场景:交互式要小模型,追求质量就用异步。
对话越长,缓存就越大,而且每一轮都要把全部历史重新读一遍。给上下文设个上限,与其无限累加,不如另开一段新对话。
模型在最后一次调用之后依然常驻内存,这是设计使然。把 OLLAMA_KEEP_ALIVE 调成适合这台机器的值,怪罪任何别的东西之前,先看看 ollama ps 的输出。
四个候选模型,每个 5 GB,一个都没删。把 ollama rm 也纳入对比流程,磁盘告警一响就去看看模型目录。
十个问题,帮你判断纯 CPU 跑模型是不是适合你手头这项任务的工具。
能,但有一点关于速度的话要老实说在前面。量化后的模型在普通服务器 CPU 上跑得完全没问题——权重放在 RAM 里,运算量也在可承受范围内,整个过程没有哪一步非得靠显卡不可。GPU 买来的是内存带宽,而带宽决定的正是生成速度。所以一台纯 CPU 机器会给出正确、完整的答案,速度大约在每秒几个词到几十个词之间,具体取决于模型。这对聊天窗口来说是慢的,但对大多数人真正想自动化的工作来说完全够用:给一条消息分类,从文档里提取结构化 JSON,总结一个页面,为搜索生成文本嵌入,改写一段文字。问题从来不是“能不能”,而是“速度多少,这个速度对这项任务重不重要”。
自己算一下,别相信任何人的跑分,包括我们的。稠密模型每生成一个 token 就要把所有权重从内存里读一遍,所以上限大致是内存带宽除以模型大小。一个量化到约 2 GB 的 3B 模型,在有效带宽 20 GB/s 的机器上,上限接近每秒 10 个 token;一个 4.4 GB 的 7B 接近 4.5;一个 20 GB 的 32B 则不到 1。实际数字会落在上限之下——大概是 50% 到 70%——具体多少取决于宿主机、邻居和线程数。提示词处理则完全是另一回事:它受算力而非带宽限制,运行速度快得多,这也是为什么总结一篇长文档很轻松,而和一个大模型聊天却不行。
一个 Q4_K_M 量化的 8B 级指令模型,大约落在 4.5 到 5 GB,还能给操作系统和上下文缓存留出空间。这个规模是目前的甜蜜点:足够可靠地遵循指令、按要求输出合法的 JSON、做摘要、分类和改写;同时又够小,响应够快。再往下,3B 模型在分类、打标签、路由这类任务上确实好用,速度大约快一倍。再往上,14B 在多步推理上明显更强,速度大约减半——这对批处理任务是划算的交换,对任何交互式场景则不然。从 8B 开始,实测一下,再根据结果往哪个方向调整。
量化后的文件大小,加上上下文缓存,再加上留给系统的空间——总数必须装得下,因为失败的表现不是变慢,而是彻底崩溃。模型装不下时,内核会开始把模型权重换出到磁盘,本该四秒钟完成的一次生成会变成四分钟,负载均值飙升到两位数。按 Q4_K_M 估算的经验法则:3B 模型约 2 GB,8B 约 5 GB,14B 约 9 GB,32B 约 20 GB,70B 约 40 GB。再给 Debian 和它的各种服务加 2 GB,键值缓存视你允许的上下文长度再加 1 到 4 GB。然后买比算出来的答案高一档的配置,而不是刚好卡在那条线上的配置。
Ollama 本质上就是 llama.cpp,外面包了一层模型仓库、一个 REST API 和一个 systemd 服务。除非有明确的理由不用,否则就用 Ollama:一条安装命令,用 ollama pull 而不是到处找 GGUF 文件,一个兼容 OpenAI 的接口,线程数和内存也有合理的默认值。想用某个 Ollama 没暴露出来的参数、想为了可复现性钉死一个具体构建版本,或者只想用一套配置永远跑一个模型、不想让一个守护进程替你管这管那——这些情况下就直接用 llama.cpp。两者跑的是同样的权重,速度也一样;区别完全在运维层面。
不能,假装能只会浪费你一下午。API 背后的前沿模型比任何能塞进一台虚拟机的模型都大,在高难度推理、长上下文和代码上也会更强。一个小型本地模型真正能打的,是现实工作里那一大片中间地带:判断一封邮件属于六个类别中的哪一个,从发票里提取五个字段,总结一段客服对话,改写一段描述,给文档打标签,判断两条记录说的是不是同一个人。对这类任务来说,8B 和前沿模型之间的差距很小,成本上的差距却是天壤之别,隐私上的差距更是绝对的。真正务实的做法不是“取代 API”,而是“别再把那本就不该外流的 90% 也发出去了”。
不——完全没有,这是本指南中最重要的一条运维事实。没有密码,没有令牌,没有用户体系。任何能对 11434 端口发起 TCP 连接的人,都能生成文本、列出你的模型、拉取新模型、删除已有模型。这个端口会被持续扫描,未加防护的实例会被陌生人发现并当作免费算力使用,最先表现为莫名其妙的负载均值上升,随后就是一份带宽账单。把 Ollama 绑定到 127.0.0.1,在它前面放一个反向代理,在代理处终止 TLS,并要求持有者令牌或客户端证书。如果盒子外部没有任何东西需要用到这个模型,就干脆不要暴露它。
可以,而且通常只需要改一个字段。Ollama 在 /v1 上提供兼容 OpenAI 的 API,所以任何能设置基础 URL 的客户端——OpenAI SDK、LangChain、n8n 的 OpenAI 节点、大多数智能体框架——只要指向 https://your-host/v1,密钥随便填一个非空字符串,就能用起来。n8n 也自带专门的 Ollama 节点。实践中效果不错的模式是混合模式:把大批量、枯燥、高频的调用交给本地模型,把少数真正需要前沿推理能力的步骤留给托管 API,本地模型给不出合法 JSON 时再做兜底。
它们是这整个页面上性价比最高的东西。嵌入模型很小——体积以几十到几百 MB 计,而不是几个 GB——每个分块只需一次前向计算,没有逐 token 的生成过程,所以 CPU 处理起来毫无压力。这意味着 RAG 系统里检索那一半的全部工作——给文档建索引、给查询生成嵌入、找出最近的分块——在最便宜的档位上就能轻松跑起来,而这一半恰恰也是会接触到你拥有的每一份文档的那一半。就算你最终决定生成这一步要交给托管 API,把嵌入这一步留在自己的机器上,也能让你的语料库不落到别人手里。
三个理由,按重要程度从低到高排列。成本有它自己的曲线:API 一开始更便宜,但不会永远便宜下去,一个每月要分类五万条消息的工作流,账单会一直往上涨,而一台 $7.90 的 VPS 不会。可用性:没有速率限制,你围绕它搭建的模型不会被弃用,也不会因为别人家的状态页出问题而跟着宕机。而真正一锤定音的那一条——你的提示词,是你产出的文字里最暴露信息的那部分。不是答案,是问题。你问了什么,关于谁,哪一天,按什么顺序。托管端点会看到这一切,还会把它和一个账单身份关联起来。一个跑在你租来的机器上的模型,这台机器不需要身份证件,注册在北欧司法管辖区,用 Monero 付款,它看到的是同样的文字,却不会向任何人报告。
Garrison(4 vCPU、8 GB、240 GB NVMe,$7.90/月)能跑一个 8B 模型,还留有上下文缓存和系统的空间——大多数人都应该从这个档位开始。Ravelin 把内存翻倍,用来跑 14B 和更长的上下文。注册不用邮箱,不用身份证件,也没有按 token 计费的账单。
最后审核 · 2026-08-24 · 来源 · Ollama 文档与 API 参考、llama.cpp 文档、Caddy 反向代理文档、文中引用的量化版本对应的公开模型卡 · 周期 · 每年
This guide is one spoke of a larger series. The pillar walks the three privacy layers end to end — the sibling spokes below dive into the specifics.
Three independent layers — signup, payment, network — explained, legal context included, common mistakes flagged.
Deploy your own MCP server on a no-KYC VPS — TLS, streamable HTTP, OAuth.
Host an MCP server with no ID — the privacy stack, crypto-paid.
把代理从笔记本电脑搬走 — 规格选择、systemd、密钥、支出上限。
Docker Compose、PostgreSQL、真正能用的 webhook——由您掌控的自动化。