Ollama 本地部署进阶教程 2026:从单模型到完整 AI 工作台

跑通第一个本地模型只是起点。按照 Ollama + WebUI 基础教程 把模型拉起来之后,真正决定体验的是一连串后续问题:这台机器能跑多大的模型、几个模型怎么轮换才不互相挤兑、参数改哪里才有效、服务怎么开放给其他工具用、慢的时候到底慢在哪。这一篇就按这个顺序往下走。
一、先算账:你的硬件到底能跑多大的模型
选模型最常见的错误是先看中某个模型,再发现机器带不动。顺序应该反过来:先估可用显存(或内存),再决定模型量级和量化档位。
1. 显存需求由三部分组成
- 模型权重:大头。粗算方法是参数量乘以每个参数占的字节数——FP16 约 2 字节,Q8 量化约 1 字节,Q4 量化约 0.55 字节(量化还要存缩放因子等附带数据,所以不是整除关系)。换算下来,8B 模型 Q4 权重约 4.5GB 上下,32B 的 Q4 在 19GB 上下。最可靠的数字不用算:
ollama list显示的文件大小就是权重体积,运行时占用只会更大。 - KV 缓存:对话越长吃得越多,由上下文长度(num_ctx)、层数和注意力头数决定。num_ctx 从 4K 拉到 32K,KV 缓存成倍增长,这是很多人「权重放得下、跑起来却爆显存」的真正原因。
- 运行时开销:推理框架自身的缓冲、计算图等,通常要再留出 1GB 以上的余量。
经验法则:可用显存 ≥ 权重大小 × 1.2 是能跑起来的底线,想开长上下文或并发再往上加。卡着上限跑的后果是部分层被卸载到 CPU,速度断崖式下跌。
2. 三个平台的「可用内存」算法不一样
- NVIDIA 独显:账最好算,显存是硬边界。先用
nvidia-smi看总显存和已被占用的部分(桌面显示、其他程序都在吃),剩下的才是模型的预算。 - Apple Silicon:统一内存由 CPU 和 GPU 共享,账面数字好看,但系统不会把全部内存都给 GPU,还要给 macOS 和其他应用留份。所以 16GB 的 M 芯片跑 8B Q4 没问题,硬塞 14B 就容易触发内存交换,体验反而比小模型差。
- 纯 CPU:没有显存概念,权重放内存、计算靠 CPU。能跑,但速度由内存带宽决定,定位是「能用」而不是「流畅」,适合小模型或低频调用。
3. 显存档位与模型量级速查
下表是定性对应关系,具体以 ollama list 的实际体积和 ollama ps 的卸载情况为准:
| 你的可用显存/内存 | 舒适区(全量装入) | 勉强区(短上下文或部分卸载) | 建议 |
|---|---|---|---|
| 无独显、内存 16GB(纯 CPU) | 3B–8B 的 Q4 | 14B Q4(慢) | 当离线工具用,别指望对话流畅度 |
| 独显 8GB | 7B–8B 的 Q4 | 14B Q4 低量化 | 主力用 8B,写代码和日常问答够用 |
| 独显 12GB | 8B 的 Q8 或 14B 的 Q4 | 32B 的低量化 | 12GB 是性价比甜点,14B Q4 体验完整 |
| 独显 16GB | 14B 的 Q8 或 32B 的 Q4 | 32B Q8(上下文受限) | 32B Q4 是这一档的上限选择 |
| 独显 24GB | 32B 的 Q6/Q8 | 70B 的 Q4 | 70B 能跑,但上下文和并发都要收着 |
| 统一内存 64GB 或双卡 | 32B 高量化、70B Q4 | 更大模型看总量 | 先确认多卡/统一内存的实际可用上限 |
4. 量化档位怎么选
量化是用精度换体积和速度。Q4_K_M 是目前生态里最主流的折中档:体积约为 FP16 的三成,质量损失在日常任务里不容易察觉,所以大多数模型的默认标签就是它。Q8_0 接近无损,适合显存富裕、拿本地模型干精细活(比如代码审查)的人。Q3、Q2 这类低档位对推理类模型的伤害明显大于对聊天模型——数学和逻辑题最先崩。所以除非机器实在带不动,不要为了塞下更大的参数量去压量化:低量化的大模型会实实在在地变笨,选型时先保量化档位,再谈参数量。
二、多模型管理:常驻、轮换与定制
模型拉多之后,管理问题就来了:磁盘被占满、切个模型等半天、调好的参数每次都要重设。这一节分开解决。
1. 日常管理就四条命令
ollama list # 本地有哪些模型、各占多大
ollama ps # 当前哪些模型正装在显存/内存里、装入比例
ollama stop <模型名> # 手动卸载一个正在运行的模型
ollama rm <模型名> # 从磁盘删除模型ollama ps 是进阶使用里最值得养成习惯的一条命令:它显示每个已加载模型的体积和处理器分配(100% GPU 表示全量装入,出现 CPU/GPU 混合就说明有层被卸载到了内存,速度必然受影响)。第五节排查的第一步就是看它。
2. 常驻与轮换:keep_alive 和加载上限
模型默认在最后一次请求后保留约 5 分钟就自动卸载,下次调用再重新装载——大模型装载要十几秒甚至更久,这就是「第一句话特别慢」的原因。三个层面的解法:
- 单次请求:在请求里带
keep_alive参数(比如"keep_alive": "30m",填 0 表示用完立即卸载,填 -1 表示常驻),适合脚本场景。 - 服务级:环境变量
OLLAMA_KEEP_ALIVE改默认保留时长,OLLAMA_MAX_LOADED_MODELS限制同时装入的模型个数。常驻越多越省切换时间,但显存是总账:都说常驻、显存只够一个,就会互相挤兑、频繁换入换出,比轮换还慢。 - 取舍原则:真正高频用的留一个常驻,其余按需加载。工作流是两个模型交替使用的,把 keep_alive 设长一点,比纠结加载上限更有效。
还有一个隐藏成本:OLLAMA_NUM_PARALLEL 控制单个模型的并发请求数,每个并发会话都要独占一份 KV 缓存。显存吃紧时把并发调低,比降量化更划算。
3. Modelfile:把调好的参数固化成自己的模型
每次调用都传一长串参数既容易错又难复用。Modelfile 类似 Dockerfile:基于现成模型,把系统提示词和参数打包成自己的新模型名。
FROM qwen3:14b
SYSTEM """
你是一个代码审查助手。
- 先指出问题,再给修改建议,最后才贴代码
- 不确定的地方明确标注「需人工确认」
"""
PARAMETER temperature 0.3
PARAMETER num_ctx 16384
PARAMETER num_predict 2048
PARAMETER top_p 0.9
PARAMETER repeat_penalty 1.1ollama create my-reviewer -f Modelfile # 构建
ollama run my-reviewer # 直接使用,参数已内置常用参数的含义和取舍,按「改错了会发生什么」来理解更牢靠:
| 参数 | 作用 | 调整建议 |
|---|---|---|
| temperature | 随机性,越高越发散 | 代码、事实问答 0.2–0.5;写作 0.7–1.0;超过 1.2 容易语无伦次 |
| num_ctx | 上下文窗口 | 决定能喂多长的材料,也是显存消耗大户;按任务给,别无脑拉满 |
| num_predict | 单次最大输出长度 | -1 表示不限制;设小了长回答会被截断在半句话 |
| top_p / top_k | 候选词筛选范围 | 一般保持默认,只动 temperature 就够了,三个一起动很难归因 |
| repeat_penalty | 抑制重复 | 略高于 1 即可,调太高会把正常复述也误伤 |
| seed | 随机种子 | 固定它才能复现结果,做对比测试时必设 |
| num_thread | CPU 线程数 | 纯 CPU 或混合卸载时才有意义,按物理核心数给 |
调参顺序建议:先固定 seed 做基线,只动 temperature 一项看变化,再考虑 num_ctx。一次改三四个参数,效果好了也不知是谁的功劳。
还有一条:TEMPLATE 指令涉及各模型自己的对话格式标记,写错会导致表现异常。不明确目标模型的模板长什么样就不要动它,只写 SYSTEM 和 PARAMETER 更稳妥。
三、API 与服务化:让其他程序来调用你的模型
Ollama 装好后默认就在本机 11434 端口提供 HTTP 服务,ollama serve 是手动启动它的命令(安装包部署的通常已在后台运行,不要重复启动,先用健康检查确认)。
curl http://localhost:11434/api/version # 服务活着会返回版本号
curl http://localhost:11434/api/tags # 当前本地模型列表1. 两个核心接口:generate 和 chat
/api/generate 是单次补全:给一段提示词,拿一段输出,适合摘要、改写、分类这类无状态任务。/api/chat 是对话接口:把完整的消息数组(system/user/assistant)发过去,上下文由调用方自己维护——服务端不替你记历史,这是最容易踩的认知误区。
import requests
# 单次补全
resp = requests.post(
"http://localhost:11434/api/generate",
json={"model": "qwen3:14b", "prompt": "用一句话解释什么是向量数据库", "stream": False},
)
print(resp.json()["response"])
# 多轮对话:历史要自己带上
messages = [
{"role": "user", "content": "什么是快速排序?"},
{"role": "assistant", "content": "一种基于分治思想的排序算法……"},
{"role": "user", "content": "它的平均时间复杂度是多少?"},
]
resp = requests.post(
"http://localhost:11434/api/chat",
json={"model": "qwen3:14b", "messages": messages, "stream": False},
)
print(resp.json()["message"]["content"])流式输出把 stream 设为 true,响应是逐行 JSON,自己拼接 response(chat 接口则是 message.content)字段即可。做交互界面必须用流式:本地生成本来就不快,让用户干等完整结果是体验灾难。
官方 Python 库把这些又封装了一层,写法更短:
pip install ollamaimport ollama
response = ollama.chat(model="qwen3:14b", messages=[{"role": "user", "content": "解释一下递归"}])
print(response.message.content)顺带纠正一个老教程里的常见写法:早期示例用 ollama.embeddings(...) 取向量,新版 SDK 已改为 ollama.embed(...),对应的 HTTP 接口也从 /api/embeddings 换成了 /api/embed。照老代码抄会直接报接口不存在,第四节的 RAG 示例用的就是新接口。
另外,Ollama 还提供 OpenAI 兼容接口(/v1/chat/completions 等)。凡是支持「自定义 OpenAI 接口地址」的客户端,把地址填成 http://localhost:11434/v1 就能接本地模型——这是接入各类工具时最省事的一条路,API 密钥字段随便填个非空值即可。
2. 服务化时必须想清楚的三件事
- 监听范围:默认只监听 127.0.0.1,本机以外访问不到,这是对的。要给局域网里的其他设备或容器用,设环境变量
OLLAMA_HOST=0.0.0.0:11434再重启服务。但要清楚:Ollama 的接口没有任何鉴权,开放到局域网意味着同网络里任何人都能调用你的模型;开放到公网更是等于把算力白送。真有远程需求,用反向代理加鉴权,或只走内网穿透到自己的设备,别裸奔。 - 模型存哪:模型文件默认放在用户目录下的
.ollama/models。磁盘紧张可设OLLAMA_MODELS指到大容量盘,但要在第一次拉模型之前就设好,事后搬家容易乱。 - 备份与迁移:先纠正一个流传很广的误解——Ollama 没有 export 这类导出命令,老教程里写的导出、恢复命令根本不存在。备份的正确做法就是备份模型目录本身(连同你自己的 Modelfile),换机器时拷回去、路径对上即可;自制模型也可以只把 Modelfile 发给对方,对方用同一个基础模型
ollama create一遍,权重不用传。
四、接入其他工具:从聊天窗口到工作流
1. Open WebUI:多模型工作台
命令行适合折腾,日常使用还需要一个像样的界面。Open WebUI 是目前最常见的选择,一条 Docker 命令就能起来:
docker run -d -p 3000:8080 \
--add-host=host.docker.internal:host-gateway \
-v open-webui:/app/data \
--name open-webui \
--restart always \
ghcr.io/open-webui/open-webui:main浏览器打开 3000 端口注册管理员账号即可,所有本地模型会自动出现在列表里,可在同一对话里切换模型对比效果。它同时也是最省事的 RAG 入口:把 PDF、Word、Markdown 传进它的知识库,对话时引用,检索和拼接上下文都由它代劳——适合先验证「文档喂给模型到底有没有用」,再决定要不要自建。
2. 自建 RAG:什么时候值得自己写
需要控制切分粒度、检索数量,或把问答嵌进自己的程序时,再走自建路线。原理只有四步:文档切分 → 用嵌入模型向量化 → 问题向量化后找最相近的片段 → 把片段拼进提示词让模型作答。最小实现如下,向量检索用最朴素的余弦相似度就能跑通(数据量大了再换向量数据库):
import ollama
import numpy as np
docs = [
"Ollama 是本地运行大模型的工具,模型文件默认存放在用户目录的 .ollama/models 下。",
"keep_alive 决定模型在最后一次请求后保留多久,设为 -1 表示常驻不卸载。",
"ollama ps 可以查看当前加载的模型以及 CPU/GPU 的装入比例。",
]
def embed(texts):
resp = ollama.embed(model="nomic-embed-text", input=texts)
return np.array(resp.embeddings)
doc_vecs = embed(docs)
def answer(question, top_k=2):
q_vec = embed([question])[0]
sims = doc_vecs @ q_vec / (np.linalg.norm(doc_vecs, axis=1) * np.linalg.norm(q_vec))
hits = np.argsort(sims)[::-1][:top_k]
context = "\n".join(docs[i] for i in hits)
prompt = f"只依据以下资料回答问题,资料里没有的就说不知道。\n\n资料:\n{context}\n\n问题:{question}"
return ollama.generate(model="qwen3:14b", prompt=prompt).response
print(answer("模型多久会被卸载?"))嵌入模型要选专门的 embedding 模型(如 nomic-embed-text 这类),不要拿对话模型凑数——向量质量直接决定检索准不准。另外记住 RAG 的边界:它解决「模型不知道你的私有资料」,解决不了「模型本身推理不行」;检索回来的片段不对,换再大的模型也救不回来,先查检索,再怪模型。
3. 其他接入方式
- 编程助手类客户端:支持自定义接口地址的,优先走第三节的 OpenAI 兼容接口;原生支持 Ollama 的选模型名即可。这类工具对速度和上下文长度都有要求,建议单独用 Modelfile 固化一个低温度、大 num_ctx 的模型给它。
- 多模型对比:不必装专门工具,一个循环脚本就够——依次请求、把答案并排存下来,记得给每个模型设相同的 temperature 和 seed,否则比的是随机性不是能力。对比结论怎么用,可参考 2026 年 AI Agent 实战终极指南 的选型部分。
- 更上层的编排:本地模型和云端模型分工(敏感内容本地处理、难题上云)时,以谁为主、怎么路由,就是 Agent 层面的设计了。云端一侧的能力边界可对照 Claude 完整指南 和 DeepSeek 使用指南 评估;写代码场景的组合用法,见 Cursor 完全使用指南 与 GitHub Copilot 使用指南。
五、性能与故障排查:慢,先定位再动手
本地模型慢的原因只有四类:没跑在 GPU 上、显存不够导致部分卸载、参数不合理、机器被别的东西拖累。按下面的顺序查,比逐个试设置快得多。
1. 排查清单(从上往下,命中即停)
- 模型到底在用什么算:运行
ollama ps看处理器一列。100% GPU 才算全量加速;出现 CPU/GPU 混合比例,说明有层在内存里跑——这是速度慢的最常见原因,先解决它,其他调优都是其次。 - 为什么装不全:混合卸载基本等于显存不够。依次减负:关掉其他吃显存的程序 → 把 num_ctx 调回实际需要的长度 → 把常驻的其他模型
ollama stop掉 → 还不行才考虑降量化档位或换小一号模型。 - GPU 根本没被识别:
ollama ps全是 CPU 时,NVIDIA 平台先看nvidia-smi能不能列出显卡——驱动没装好或版本太旧,Ollama 就只能退回 CPU。这里纠正一个老教程的误导:不需要为 Ollama 单独安装 CUDA 工具包,它自带所需的运行库,要保证的只有显卡驱动是近期的正式版;老教程里用apt-key添加 CUDA 仓库的命令已经淘汰,照做只会报错。Mac 则要确认用的是原生 arm64 版本,而不是跑在转译层上的旧包。 - 第一句慢、后面正常:这是模型在装载,不是故障。按第二节的方法给高频模型设 keep_alive 即可——装载十几秒对大模型是正常成本。
- 越聊越慢:上下文在变长,每一轮都要重处理更长的历史。把 num_ctx 和实际对话长度对齐、适时开新会话,比换模型有效。走 API 自己维护历史的,记得截断或摘要早期消息。
- 整机都卡:不只是模型慢,而是系统在换页——内存(含统一内存)被模型和 KV 缓存吃穿了。减小模型或 num_ctx,Mac 上再关掉不用的大型应用。纯 CPU 模式下再确认 num_thread 是否按物理核心数设置,不对会平白损失一截速度。
- 下载模型慢或中断:这跟服务配置无关,老教程里「改 OLLAMA_HOST 换镜像」的说法是错的——那个变量管的是服务监听地址。拉取支持断点续传,重新执行同一条 pull 就会接着下;长期龟速只能从自己的网络出口想办法,可先拉个小模型验证链路。
- 端口被占、服务起不来:11434 已被另一个 Ollama 实例占用的概率最大(比如手动
ollama serve时其实后台已经在跑)。先查占用再决定杀哪个,不要上来就改端口,改完客户端配置还要跟着改一圈。
2. 开机自启
- Linux:官方脚本安装的 Ollama 自带 systemd 服务,
sudo systemctl enable --now ollama确保启用即可;环境变量(监听地址、模型目录)要写进服务的 Environment 配置,改完daemon-reload并重启服务才生效,写在 shell 配置文件里对服务不起作用——这是最常见的「改了没生效」来源。 - macOS:通过官方应用安装的在登录项里管理;用 Homebrew 装的用
brew services start ollama。 - Windows:官方安装包会注册托盘程序随登录启动,在设置里可以关掉;需要长期对外提供服务的,建议还是放到 Linux 机器上跑。
3. 本地和云端怎么分工(收个尾)
把 Ollama 部署稳之后,剩下的决策是使用层面的:隐私敏感、离线、调用量大的任务放本地;需要最强推理和长上下文的难题交给云端。两条线都留着、按任务选,而不是非此即彼。本地这条线的价值不在于「免费」,而在于数据不出门和随时可用。
延伸阅读
免责声明
本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。