Same server, no num_ctx: some models return HTTP 400 naming 4096, others return 200 with prompt_eval_count 2050

这个报错发生在 Ollama 0.32.9(Windows,GGUF,POST /api/chat)同一服务器上,不同模型对超长 prompt(约 7.9k tokens)响应不一致:部分模型返回 HTTP 400 提示上下文不足(4096),而另一些返回 HTTP 200 但静默截断 prompt

快速结论:这个报错发生在 Ollama 0.32.9(Windows,GGUF,POST /api/chat)同一服务器上,不同模型对超长 prompt(约 7.9k tokens)响应不一致:部分模型返回 HTTP 400 提示上下文不足(4096),而另一些返回 HTTP 200 但静默截断 prompt(prompt_eval_count 为 2050)。优先排查模型是否使用了 Jinja 模板(而非 Ollama 的 Go 模板),因为模板差异是已确认的影响因素。

适用环境:Ollama 0.32.9,Windows,RTX 5080 16GB,使用 GGUF 模型文件,通过 POST /api/chat 调用。模型来自官方 registry 或通过 `ollama create` 导入 GGUF。所有模型均未在 Modelfile 或请求中显式设置 `num_ctx`。

最快修复方案:暂无确认的一步修复方案。但可优先尝试为使用 Jinja 模板的导入模型替换为 Ollama 官方模型的 Go 模板(`ollama show –template qwen3:4b`),已有实验证据表明这能让行为从不返回错误(HTTP 400)变为截断处理(HTTP 200)。注意:这只是改变了溢出处理路径,并不能解决静默截断本身。

注意事项:此方案仅针对 Jinja 模板导致的 400 错误,不解决截断导致的问题。即使更换模板,模型仍可能静默丢弃 prompt 前半部分(系统提示、规则等),导致看似合理但错误的回答。需自行评估截断影响。另外,prompt 截断到 2050 是自动选择的默认窗口(4096)的固定行为(4096/2 + 2 = 2050),并非模型本身问题。

问题场景

在 Ollama 0.32.9(Windows)上,同一服务器、同一超长 prompt(约 7.9k tokens)下,不同模型返回不同结果:官方的 qwen3:4b、qwen3:14b 以及基于这些模型的衍生模型返回 HTTP 200,但静默截断 prompt(prompt_eval_count 为 2050);而用户自行导入的 GGUF 模型(一个 4B qwen3 架构、一个 9B nemotron_h 架构)则返回 HTTP 400,提示上下文不足 4096。所有模型均未设置 num_ctx,服务器自动分配 4096 上下文窗口。

报错原文

request (7851 tokens) exceeds the available context size (4096 tokens),
try increasing it
"type": "exceed_context_size_error"

Same server, no num_ctx: some models return HTTP 400 naming 4096, others return 200 with prompt_eval_count 2050

原因分析

可能原因:模型使用的模板类型差异导致溢出处理路径不同。用户导入的 GGUF 模型自带上游 Jinja 模板,当 prompt 超长时直接返回 400 错误;而官方 registry 模型无 Jinja 模板,回退到 Ollama 的 Go 模板,超长时选择静默截断(而非报错)。已通过实验证实:将导入模型的模板替换为 qwen3:4b 的 Go 模板后,行为从不报错变为截断。另外,即使更换模板,模型仍只处理截断后的 2050 tokens(4096/2 + 2 = 2050),这是服务器的固定截断逻辑,与模板无关。关于 `OLLAMA_GO_TEMPLATE` 环境变量:Jinja 模板是默认选项,仅当无 Jinja 模板或显式设置 `OLLAMA_GO_TEMPLATE=1` 时才使用 Go 模板。

环境排查

  • Ollama 版本:0.32.9(Windows)
  • GPU:RTX 5080,16,303 MiB(15.92 GiB),导致自动选择的上下文窗口为 4096
  • 环境变量:确认 `OLLAMA_CONTEXT_LENGTH` 未设置(Windows 三个作用域均未设置);确认 `OLLAMA_GO_TEMPLATE` 也未设置
  • 模型来源:区分官方 registry 拉取(`ollama pull`)和本地 GGUF 导入(`ollama create`),两者模板不同
  • 模型模板:通过 `ollama show –template ` 检查使用 Jinja 还是 Go 模板
  • 模型架构:确认导入模型的架构(如 qwen3、nemotron_h),但架构不是决定因素(同为 qwen3 架构,导入和官方行为不同)

解决步骤

  1. 确认模型使用的模板:运行 ollama show --template <model_name>,识别返回的是 Jinja 还是 Go 模板。
  2. 如果是导入的 GGUF 模型(自带 Jinja 模板),想避免 400 报错,可参考下面的模板替换方案。
  3. 获取官方模型的 Go 模板:运行 ollama show --template qwen3:4b(以官方 qwen3:4b 为例)复制其 Go 模板。
  4. 基于原模型创建一个新 Modelfile,内容仅包含:
    FROM 
    TEMPLATE """"""
  5. ollama create <new_model_name> -f <Modelfile> 创建新模型。
  6. 用新模型重新发送原超长请求,观察 HTTP 状态码和 prompt_eval_count 变化。
  7. 注意:即使更换模板,模型仍会静默截断 prompt 到 2050 tokens,截断的是 prompt 开头部分(系统提示、规则、few-shot 示例等),可能导致看似合理但错误的回答。请确认你的场景可以接受这种截断。

验证方法

使用同一超长 prompt(约 7.9k tokens)分别请求原导入模型和替换模板后的新模型:

  • 原导入模型应返回 HTTP 400,报错 exceed_context_size_error,提示 4096 tokens。
  • 新模型应返回 HTTP 200,且 prompt_eval_count 为 2050(与官方模型相同)。
  • 至此可确认模板差异是导致两种行为不同的原因,问题定位完成。

参考来源

ollama/ollama #17889

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 19800

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注