首页 > Technology > 正文

Ollama 上下文被截断?调 num_ctx

fenij 2026-08-28 41 Technology

本机跑 Ollama,喂一份长文档让它总结,它答得挺顺,但你发现它完全没提文档前半段的内容;或者多轮对话聊到后面开始「失忆」、前后矛盾。这不是模型笨,是 Ollama 默认上下文窗口小得离谱——很多模型标称 128K,Ollama 默认只给 2048 token,超出的部分被静默丢掉,而且不会报错提醒你。

🧠
2048
默认 token 窗口

💾
+1.3G
16K 较 2K 多占显存

⚠️
静默
截断不报错

先确认是不是被截断了

最直观的办法看 prompt_eval_count:发一段明显超过默认窗口的长文本,让接口返回这个值。

curl http://localhost:11434/api/generate -d '{
  "model": "llama3.1:8b",
  "prompt": "在这里粘一段约 18000 词的文档",
  "options": { "num_ctx": 4096 },
  "stream": false
}' | python3 -c "import sys,json;print(json.load(sys.stdin)['prompt_eval_count'])"

如果返回接近 4096 而不是真实 token 数,说明被截了。把 num_ctx 调到 16384 再跑,数字会明显涨上去。

三种调大上下文的方法

方式 作用范围 适合
请求里 options.num_ctx 单次请求 临时任务 / 测试上限
Modelfile 写 PARAMETER 用模型名调用即生效 长文档/代码固定用
OLLAMA_CONTEXT_LENGTH 环境变量 服务端所有请求 统一调大省心

方式①单次优先级最高:

import requests
requests.post("http://localhost:11434/api/generate", json={
  "model": "llama3.1:8b",
  "prompt": long_doc,
  "options": {"num_ctx": 16384},
  "stream": False,
})

方式②写进 Modelfile 固化一个新模型:

FROM llama3.1:8b
PARAMETER num_ctx 16384
ollama create llama3.1-16k -f ./Modelfile
ollama run llama3.1-16k

方式③改全局默认(systemd 用 drop-in 改,别动原 unit):

sudo systemctl edit ollama
# 写入
[Service]
Environment="OLLAMA_CONTEXT_LENGTH=16384"

之后 sudo systemctl daemon-reload && sudo systemctl restart ollama

代价:显存随上下文线性涨

num_ctx 显存占用(llama3.1:8b Q4) 速度
2048 ~5.6 GB ~47 tok/s
8192 ~6.9 GB ~44 tok/s
16384 ~8.8 GB ~39 tok/s
32768 ~11.9 GB,OOM 风险 ~31 tok/s

7-8B 的 Q4 模型,8K 几乎免费,16K 在 12G 显存上稳,32K 要 16G+ 或换更小量化。别一上来就拉满 128K,速度掉一半还容易 OOM。笔记本 8G 显存别缩 ctx,把 num_batch 调小到 128 更稳。

长文还断?再看 num_predict

有时不是输入被截,是输出被砍——回答到一半没了。那是 num_predict(最大生成 token)太小。请求里加 "num_predict": 4096,并开 "stream": true 边生边收,避免一次性大响应超时。

踩坑实录

用 Ollama 跑代码助手,让它改一个 600 行的文件,它只动了文件尾巴、前半段逻辑全忽略。查 ollama ps 的 CONTEXT 列才发现模型只加载了 2048 token。本地 llama3.1 标称 128K,但默认 2048。在 Modelfile 里写死 PARAMETER num_ctx 16384 重建模型后,前后逻辑才对上。后来养成习惯:长文档/长代码任务一律显式带 num_ctx,别赌默认。

常见问题

Q1:为什么标称 128K 实际只有 2048?

Ollama 默认按可用显存给保守值,不同版本默认值还不一致(文档里 2048 / 4096 都出现过)。以你自己 ollama ps 显示的 CONTEXT 列为准,别信文档页。

Q2:RAG 检索内容很长也被截?

是。检索回来的 chunks 拼进 prompt 后同样受 num_ctx 限制。除了调大窗口,更要控制 chunk 数量(3-5 个、每块 200-300 token)并加 reranker,否则塞再多也没用,模型还是只看到尾部。

Ollama 这类本地大模型排障,关键是用接口返回的真实数值说话。更多 AI 与运维实操笔记,欢迎来 fenij.com 交流。

排错自查清单

  • ☐ 先确认是不是被截断了:最直观的办法看 prompt_eval_count:发一段明显超过默认窗口的长文本,让接口返回这个值。
  • ☐ 三种调大上下文的方法:方式①单次优先级最高:
  • ☐ 代价:显存随上下文线性涨:7-8B 的 Q4 模型,8K 几乎免费,16K 在 12G 显存上稳,32K 要 16G+ 或换更小量化。别
  • ☐ 长文还断?再看 num_predict:有时不是输入被截,是输出被砍——回答到一半没了。那是 num_predict(最大生成 token)太小。请求
  • ☐ 踩坑实录:用 Ollama 跑代码助手,让它改一个 600 行的文件,它只动了文件尾巴、前半段逻辑全忽略。查 ollam
  • ☐ 常见问题:Ollama 默认按可用显存给保守值,不同版本默认值还不一致(文档里 2048 / 4096 都出现过)。以你

关键命令速查

  • curl http://localhost:11434/api/generate -d '{ "model": "llama3.1:8b", "prompt": "在这里粘一段约
  • import requests requests.post("http://localhost:11434/api/generate", json={ "model": "llam
  • FROM llama3.1:8b PARAMETER num_ctx 16384
  • ollama create llama3.1-16k -f ./Modelfile ollama run llama3.1-16k
  • sudo systemctl edit ollama # 写入 [Service] Environment="OLLAMA_CONTEXT_LENGTH=16384"

相关延伸

更系统的排查思路,见 Technology 分类归档

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: