你花了一晚上把 Llama 3.1、Qwen3 拉到本地,灌进去一篇长文档,结果模型聊到一半"突然忘了开头说的是什么"——不是模型笨,是 Ollama 默认只喂给它 2048~4096 个 token 的上下文,超出的部分被静默截断、不留任何报错。这条配置 90% 的本地部署者从没动过,更没人告诉你:官方对跑 Agent 的场景明确推荐把上下文拉到 64000+。本文把 Ollama 里最值钱的 8 个隐藏开关一次拆开,每一个都附带可直接复制的命令——看完你今晚就能把"失忆"问题根治,还能顺手省下一半显存。
这是整篇文章最重要的一节,请重点看。
Ollama 的 Modelfile 规范里,num_ctx 的 baseline 默认值是 2048 token(官方文档原话:num_ctx ... (Default: 2048))。运行时会根据你的显存动态抬高一档,但绝大多数桌面用户只会落在第一档 4096:
| 可用显存 | 运行时默认 num_ctx |
|---|---|
| < 24 GiB | 4,096 |
| 24–48 GiB | 32,768 |
| ≥ 48 GiB | 262,144(256k) |
问题在于:当对话、文档或 Agent 循环的累计 token 超过这个数,Ollama 不报错、不警告,直接把最早的消息从上下文里悄悄丢掉。用户视角就是"模型失忆了"。GitHub 上 issue #9519("Cannot Increase num_ctx Beyond 2048")和 #2714 都是同一个坑炸出来的几千条讨论。
修复它,先确认现状,再选一种方式抬高:
# 1. 看当前模型用的 Modelfile
ollama show --modelfile llama3.1:8b
# 2. 看运行时实际分配的上下文(CONTEXT 列,最准)
ollama ps
# 3. REPL 里看当前参数
ollama run llama3.1:8b
>>> /show info
三种抬高方式,优先级是 API > 环境变量 > Modelfile PARAMETER > 内置默认(记住这条,90% 的"我改了不生效"都是因为搞反了优先级):
# 方式 A:环境变量,全局生效(旧名 OLLAMA_NUM_CTX,0.5+ 改叫 OLLAMA_CONTEXT_LENGTH)
OLLAMA_CONTEXT_LENGTH=32768 ollama serve
# 方式 B:API 单次请求覆盖
curl http://localhost:11434/api/chat -d '{
"model":"llama3.1:8b",
"messages":[{"role":"user","content":"总结这篇文档..."}],
"options":{"num_ctx":16384}
}'
# 方式 C:REPL 临时改,再存盘
>>> /set parameter num_ctx 32768
>>> /save mymodel-32k
适用场景:只要你跑过长文档、长对话,这个开关就是必修课。方式 B 最省显存——不同任务用不同上下文,能用 4k 就别开 32k。
第二个反直觉点:Agent 场景下,4096 的默认上下文会让工具调用中途直接失败。
Ollama 官方文档明确写道,凡是带工具调用(tool calling)的 Agent,建议 num_ctx ≥ 64000。原因很好理解:Agent 每一步都会把"系统提示 + 已有的多轮对话 + 一堆工具定义 + 工具返回结果"全部塞进上下文。10 个工具、每个定义 200 token,光工具描述就吃掉 2000 token,还没开始干活上下文就快满了。表现就是 Agent 跑到一半突然"瞎了"、反复调用同一个工具、或者直接卡死。
所以你的 Agent 专用模型,Modelfile 里直接焊死:
FROM qwen3:8b
PARAMETER num_ctx 65536
PARAMETER temperature 0.3
SYSTEM 你是一个严谨的编码助手,按步骤调用工具。
ollama create agent-qwen3 -f Modelfile
之后 Cline、Continue.dev、Roo Code、OpenCode 只要用 agent-qwen3 这个名字,就自动拿到 64k 上下文,Agent 稳定性会有质变。
知道怎么开大,更要知道什么时候该收手。这是个被严重低估的成本账。
模型权重是固定的,但 KV cache(存上下文的地方)随 token 数线性增长。以 7–8B 模型、Q4_K_M 量化为例:
| 上下文 | KV cache 占用 | 推理速度(同硬件) |
|---|---|---|
| 4,096 | ~0.25 GiB | ~86 tok/s |
| 32,768 | ~2 GiB | ~43 tok/s |
| 131,072 | ~8 GiB | ~9 tok/s |
真正的杀手锏在最后一行:当 KV cache 超出显存,Ollama 会把它卸载到 CPU 内存,速度从 50–100 tok/s 直接掉到 2–5 tok/s——慢 20 到 50 倍。如果你把上下文调大后"突然卡成 PPT",就是这个原因。解法:调小 num_ctx、换更激进的量化(Q4_K_M 替代 Q8_0),或者干脆加显存。
不同工作负载的甜点区间,照抄即可:
| 用途 | 推荐 num_ctx |
|---|---|
| 日常聊天/问答 | 4,096–8,192 |
| RAG 检索增强 | 8,192–16,384 |
| 文档摘要 | 16,384–32,768 |
| 编程助手 | 32,768+ |
| Agent + 工具调用 | 64,000+ |
下面这张决策流程图,建议存下来贴在墙上——每次"模型表现不对"时照着走一遍,能省你几小时瞎猜:
flowchart TD
A[模型失忆/Agent中断] --> B{ollama ps 看 CONTEXT}
B -->|只有 4096| C[命中 2048 默认陷阱]
C --> D{你的用途是?}
D -->|聊天/问答| E[设 num_ctx 8192]
D -->|长文档摘要| F[设 num_ctx 32768]
D -->|Agent/工具调用| G[设 num_ctx 65536]
E --> H[改完变慢?]
F --> H
G --> H
H -->|是| I{KV cache 溢出显存}
I -->|慢20-50倍| J[换 Q4_K_M 量化 或 加显存]
I -->|还慢| K[调小 num_ctx]
H -->|否| L[✅ 完成]
J --> L
K --> L
B -->|已 65536| M[检查系统提示是否太长<br/>或模型训练上限低于设定值]
M --> L
这是另一个几乎没人提的开关。Ollama 加载完模型后,默认会在内存里驻留 5 分钟(keep_alive=5m),方便你连续提问时秒回。但默认值未必适合你:
# 永久驻留:首问快,但一直占着显存(适合主力模型)
OLLAMA_KEEP_ALIVE=-1 ollama serve
# 用完立刻卸载:省显存给别的模型(适合偶尔用的模型)
OLLAMA_KEEP_ALIVE=0 ollama serve
# 单次请求临时指定(API)
curl http://localhost:11434/api/chat -d '{
"model":"llama3.1:8b",
"messages":[...],
"keep_alive":-1
}'
适用场景:机器显存紧张、要同时挂好几个模型时,给主力模型设 -1、给备用模型设 0,是性价比最高的内存调度策略。注意 ollama ps 会显示每个模型还剩多久卸载(UNTIL 列),一眼就能看出谁在赖着不走。
很多人把 Ollama 当 ollama run 的聊天框用,从没碰过 Modelfile。这是把"通用模型"变成"你的专属模型"的关键。
FROM qwen2.5:7b
PARAMETER num_ctx 16384
PARAMETER temperature 0.4
PARAMETER repeat_penalty 1.15
SYSTEM """你是资深通信协议工程师,回答必须基于 3GPP 标准,
不确定时明确说明,不要编造规范条款。"""
# few-shot 示例,引导输出风格
MESSAGE user "PDU 会话建立用哪条 NAS 消息?"
MESSAGE assistant "使用 5G NAS 的 UL NAS TRANSPORT 消息。"
ollama create telecom-qwen -f Modelfile
ollama run telecom-qwen
几个被忽略的细节:MESSAGE 可以堆多轮 few-shot 示例(zero-shot 调不好的任务,加 2-3 个例子立竿见影);TEMPLATE 用 Go 模板语法({{ .System }}、{{ .Prompt }}、{{ .Response }}),改对 stop 序列能解决"模型自问自答停不下来";Modelfile 大小写不敏感;ollama show --modelfile 模型名 能反向导出任意模型的配方,拿来改即可。还可以 FROM ./xxx.gguf 或 FROM <safetensors目录>,直接从 HuggingFace 原始权重构建,不依赖官方库。
Ollama 自带一个 OpenAI 兼容 API,端口 11434。这意味着任何支持"自定义 OpenAI Base URL"的工具都能白嫖本地模型:
# 注意:兼容端点里 num_ctx 要放在请求体顶层
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model":"llama3.1:8b",
"messages":[{"role":"user","content":"hi"}],
"num_ctx":16384
}'
在 Cursor / Continue / LobeChat / Open WebUI 里把 Base URL 填成 http://localhost:11434/v1,API Key 随便填,model 填你的模型名——0 token 费用、数据不出本机。再配合上面的 num_ctx 和 Modelfile,本地编程助手的体验能逼近云端。想让浏览器网页直接调本地模型,加个 CORS 开关即可:
OLLAMA_ORIGINS="*" ollama serve
最后一组高阶开关,属于"知道的人不多、用上就回不去"的那种:
1. 投机解码 draft_num_predict:官方 Modelfile 文档里这个参数专门给投机解码(speculative decoding)用,配合 draft 模型能让推理明显提速,默认 4。设为 0 则关闭。
2. min_p 采样替代 top_p:文档里的 min_p(默认 0.0)是比 top_p 更新的采样策略,用一个"相对最小概率阈值"过滤候选词,在质量与多样性之间比 top_p 更稳。很多人还停留在 temperature + top_p 的老组合,换成 min_p 0.05 往往更可控。
3. 多模型并发:默认 Ollama 一次只处理一个请求、最多驻留 2 个模型。给服务器场景放开:
OLLAMA_NUM_PARALLEL=4 ollama serve # 同时处理 4 个请求
OLLAMA_MAX_LOADED_MODELS=4 ollama serve # 同时驻留 4 个模型
适合搭 API 给团队用,或者一台机器跑多个角色模型(规划/编码/审查)的 Agent 编排。
| 维度 | 大多数人 | 知道信息差的人 |
|---|---|---|
| 失忆原因 | "模型不行/太小" | num_ctx 默认 2048,静默截断 |
| 修复方式 | 换更大的模型 | 三种方式抬高 num_ctx,按优先级生效 |
| Agent 配置 | 默认 4096,跑到一半崩 | 官方推荐 64k+,焊进 Modelfile |
| 速度变慢 | "电脑太烂" | KV cache 溢出到 CPU,慢 20-50 倍 |
| 内存调度 | 不知 keep_alive | -1 永驻 / 0 即卸,精细调度 |
| 接入方式 | 只用 ollama run 聊天 | OpenAI 兼容端点接 Cursor/Cline,0 成本 |
ollama ps 看你主力模型的 CONTEXT 列,如果只有 4096,恭喜你抓到问题了。num_ctx 设到 65536,ollama create 出一个命名模型,Cline 里换上它。一句话总结:Ollama 真正的门槛不是装模型,而是把那些被默认值藏起来的开关一个个拧到正确位置。 把 num_ctx 和 keep_alive 这两个搞明白,你本地的大模型才能从"玩具"变成"能干活的工具"。
参考来源:
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护。 聚焦5G/6G核心网、3GPP标准、AI工具实战。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
