SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-24

Ollama 如何设置 num_predict 输出长度上限

Ollama 的 num_predict 只限制输出 token 数。本文说明 Modelfile、请求 options 和环境变量三种设置位置,解释优先级,并教您通过 done_reason 判断为何停止。

Ollama 中的 num_predict

num_predict 是 Ollama 中用于限制模型单次响应最多生成多少个 token 的选项。它只统计输出 token,因此不会将提示词计入其中。模型达到上限后,生成会立即停止,有时会停在单词中间;此时响应中的 done_reason 会设置为 length。

这就是该功能的全部内容。难点在于,Ollama 提供了 3 个独立位置来设置此值,并且离请求最近的设置优先。几乎所有“num_predict 不起作用”的报告,原因都是某一层在无提示的情况下覆盖了另一层的设置。

num_predict 不是 num_ctx

在 Ollama 中,这两个选项比其他任何一组选项都更容易混淆,而且这种混淆会实际增加调试时间。

num_ctx表示模型可以读取多少内容。它是上下文窗口的大小,用于容纳提示词以及截至当前已生成的全部内容。增大该值会增加内存开销,因为模型为这些令牌维护的键值缓存会随窗口增大。为您的硬件确定 num_ctx 大小是另一项工作,也有其自身的故障模式。

num_predict表示模型将写入多少内容。它是停止规则,而不是内存分配。增大该值会增加实际运行时间,而不是 RAM 占用,并且不会预先保留资源。

二者会在一个地方发生关联。生成的令牌会在生成后进入上下文窗口,因此回复可能因为窗口已满而停止,而不是因为达到您设置的上限而停止。Ollama 在这两种情况下都会报告 length,因此用于区分二者的数字是 eval_count,下文将进一步介绍。

通过 Modelfile 一次性设置

Modelfile 会将该值写入您创建的模型。创建文件:

FROM qwen3:8b
PARAMETER num_ctx 8192
PARAMETER num_predict 512

然后构建模型,并读取构建结果:

ollama create qwen3-capped -f Modelfile
ollama show --parameters qwen3-capped

ollama show --parameters 会逐行输出每个已存储参数及其值。如果输出中缺少 num_predict,说明该模型未内置上限,Ollama 会使用自身的默认值。ollama show --modelfile qwen3-capped 会输出完整定义。这也是复制现有模型自带参数的最快方式。使用此方法创建带上限的模型几乎不会额外占用磁盘空间,因为新条目会复用基础模型已下载的权重 blob,而不是复制这些 blob。在 VPS 的 root 磁盘空间耗尽之前,最好了解 Ollama 保存这些 blob 的位置。

如果希望所有调用方都继承某个值,应在这一层设置它。如果希望该值不可被覆盖,则不应在这一层设置,因为它并非最终值。

在选项对象中按请求设置

每个生成端点都接收一个 options 对象,num_predict 放在该对象中:

curl http://localhost:11434/api/generate -d '{
  "model": "qwen3:8b",
  "prompt": "Explain what a reverse proxy does.",
  "stream": false,
  "options": { "num_predict": 128 }
}'

/api/chat 使用含义相同的 options 键。这里设置的值只对当前调用生效,不影响其他调用。这是工具使用的配置层:聊天前端、脚本、SDK 包装器或编码代理。无论界面是否显示对应输入框,它们都会发送一个 options 对象。

使用 /set 参数为单个会话设置

在 ollama run 中,交互式会话会为当前会话的剩余时间设置选项:

>>> /set parameter num_predict 256
>>> /show parameters

/show parameters 会显示会话在下一条消息中发送的内容,因此这是确认更改是否生效的最快方法。该值会一直保留,直到您输入 /bye。要保留该设置,请使用 /save qwen3-capped 将当前会话(包括参数)写入为新模型。在此处通过 /set 进行的任何操作都不会影响其他客户端。

哪个设置优先,以及为什么看起来没有生效

优先级顺序很简单。随请求发送的选项优先级最高。模型的 Modelfile 中的 PARAMETER num_predict 行,是请求未提供值时使用的回退设置。如果两者都没有设置,则使用 Ollama 的内置默认值。

/set parameter 不是第三条规则。交互式会话本身就是 API 客户端,因此你在那里设置的值会作为该请求的 options 发送。这正是它会在当前会话中覆盖 Modelfile 设置的原因。

下面说明这种情况下的故障。你添加 PARAMETER num_predict 512,重新构建模型,但回复仍然达到数千个 token。你的设置确实存在,ollama show --parameters 也能证明这一点。但每个请求都会覆盖它,因为客户端会发送自己的 options 对象,其中包含自己的数值。这个数值通常是你几个月前在设置页面中输入后忘记修改的。ollama show 读取的是已存储的模型,无法显示通过 HTTP 到达的请求内容。

使用一条命令验证服务器端的行为。发送一个会生成较长回复的请求,强制设置较低的上限,然后读取两个字段:

curl -s http://localhost:11434/api/generate -d '{
  "model": "qwen3-capped",
  "prompt": "Describe the Linux boot process in detail.",
  "stream": false,
  "options": { "num_predict": 32 }
}' | jq '.done_reason, .eval_count'

该命令应输出 "length" 和 32。如果未安装 jq,请先使用 sudo apt install -y jq 安装。"length" 和 32 的响应表示服务器接受了该选项,而你的应用发送了其他设置。若要查看服务器对请求的记录,请在环境中设置 OLLAMA_DEBUG=1 后重启服务器,并在应用与服务器通信时监控 journalctl -u ollama -f。

负值,以及不应直接复制的数字

num_predict也接受负值,但负值表示哨兵值,而不是计数。其中一个负值表示“不限制,持续生成”。另一个负值表示“填充剩余上下文”。截至 August 2026,Ollama Modelfile 参考文档将默认值写为 -1,表示无限生成;同一表格的早期版本还将 -2 列为用于填充上下文的值。

请将这些内容都视为版本相关,因为它们曾发生变化。很长一段时间内,参考文档都将默认值记为 128,直到 2024 年底才修正,因此许多指南仍会重复旧数字。请阅读与你实际运行版本对应的 Modelfile 参数参考,然后使用上面的 eval_count 检查确认行为。你在自己的服务器上验证过的值,比在任何地方读到的值都更可靠,包括本文中的值。

CPU-only VPS 上,输出长度是主要成本

生成过程分为两个阶段,速度差异很大。提示词 token 会批量评估,一次处理多个 token。输出 token 则一次生成一个,每生成一个都需要完整遍历模型权重。在 CPU-only VPS 上,这个遍历过程受内存带宽限制,因此生成一个 token 的成本远高于处理一个提示词 token。由于每个权重都必须被读取,每个权重占用的字节数决定了 token 速率上限。这也是 q4 构建比同一模型的 q8 或 fp16 构建解码更快的原因。

请求不使用流式输出时,可以直接看到这些数值:

"prompt_eval_count": 26,
"prompt_eval_duration": 107345000,
"eval_count": 237,
"eval_duration": 4289432000

时长单位为纳秒。在这段数据中,示例响应来自 Ollama API 文档,并不是对某台特定服务器的测量。26 个提示词 token 用时约 0.1 秒,237 个输出 token 用时约 4.3 秒。您自己的生成速率是将 eval_count 除以 eval_duration 后换算为秒,在自己的硬件上测量每秒 token 数值得在进行其他调优前完成一次。该速率不仅取决于机器,也取决于模型。因此,如果长回答才是主要成本,选择针对快速解码构建的模型,例如 VPS 上的 Nemotron 3.5 Lightning,可以收回原本需要通过较低上限来限制的部分时间。

剩下的只是计算。在每秒生成 8 个 token 的情况下,包含 2,000 个 token 的回答会占用机器四分多钟,而模型并不知道您只需要一段文字。推理模型会先花费部分配额进行思考,然后才写出您要求的内容;这些思考同样是一次生成一个 token。因此,您要求的推理强度也是影响同一项成本的参数。有些模型还会循环生成,重复某个短语,直到某个条件停止它们。如果没有上限,一次请求可能会持续占用一个 CPU 核心,直到上下文窗口耗尽。num_predict 是用于限制该行为的设置。在一台小型 自托管 Ollama VPS 上,这一点尤其重要,因为一个长请求可能占满整台机器。

截断输出通常是达到上限,而不是模型损坏

这些现象看起来像模型故障:回答在句子中间停止;JSON 无法解析,因为末尾的右大括号始终没有出现。人们通常会立即归咎于模型或量化。请先查看响应。

done_reason 表示模型直接回答了问题。stop 表示模型自行完成了生成,原因可能是输出了序列结束标记,或匹配了 stop 选项中的某个字符串。length 表示生成因空间不足而被截断。看到 length 时,将 eval_count 与上限比较:两者完全相等,表示是 num_predict 停止了生成;如果前者更小,表示上下文窗口先被填满。

使用流式传输时,这些字段会出现在最后一个数据块中,也就是包含 "done": true 的数据块。许多客户端库会丢弃这个数据块,只把文本交给您的代码。因此,同样的截断在应用内部看起来无法解释,而在 curl 下却很明显。如果库隐藏了该信息,请发送一个包含 curl 的请求,以确认服务器实际返回了什么。

还有一点可以避免浪费时间。提高 num_predict 不会让模型生成更多内容,只会提高上限。如果回复在 200 个 token 处以 done_reason 结束,且对应的是 stop,说明模型认为回复已经完成;提高上限不会改变结果。带有 stop 的简短回答属于提示词问题。带有 length 的简短回答属于上限问题。

选择数值

  • 对于交互式聊天,不要设置上限;按 Ctrl+C 可停止失控的回复。因为您始终在查看屏幕。
  • 对于任何脚本任务,都应设置上限。在循环中进行不限长度的生成,会导致本应运行十分钟的批处理任务到第二天早上仍未结束。
  • 对于结构化输出,将上限设置为高于预期最大有效文档的值,然后将 done_reason of length 视为硬错误并重试,不要解析已返回的内容。
  • 对于编码代理,该值应配置在代理自身的配置中,因为代理会在每次请求中发送自己的选项。将编码代理指向 Ollama介绍了这些设置的位置。

上限计算的是 token 数量,而不是单词数或字符数,因此不要进行估算。在不设上限的情况下生成一个有代表性的回答,读取 eval_count,然后将限制设置为明显高于该值的数值。不同模型系列的分词方式不同,因此适用于 Llama 模型的数值,可能会截断同一 VPS 上Qwen 3 模型返回的相同答案。

FAQ

Ollama 中 num_ctx 和 num_predict 有什么区别?

num_ctx 是上下文窗口的大小,决定模型可以读取多少内容:提示词加上当前为止生成的全部内容。它会占用内存,因为键值缓存会随窗口增大。num_predict 决定模型在一次响应中最多可以生成多少个 token。它主要增加耗时,而不是内存占用,并且不会预先预留空间。生成的 token 会同时计入两者,因此响应可能因任一限制而提前结束。

为什么我的 num_predict 设置似乎没有生效?

因为随请求发送的值会覆盖模型中保存的值。将 PARAMETER num_predict 512 写入 Modelfile,然后通过聊天前端或编码代理使用该模型时,客户端会发送自己的 options 对象,其中的数值优先。ollama show --parameters 仍会显示您设置的值,因为它读取的是模型中保存的配置,无法看到通过 HTTP 到达的内容。使用 "options": {"num_predict": 32} 发送一个包含 curl 的请求,并检查返回的 eval_count 是否为 32。这样可以确认服务器本身运行正常,并将排查范围转向应用程序。

如何判断输出是否因 num_predict 而被截断?

使用 "stream": false 发送请求,并读取 done_reason。stop 表示模型自行完成了生成。length 表示可用空间已耗尽。然后将 eval_count 与您的上限进行比较:如果两者完全相同,说明是 num_predict 停止了生成;如果 eval_count 更小,说明上下文窗口先填满了。使用流式响应时,这两个字段会随最终数据块中的 "done": true 一起到达,但许多客户端库会在代码读取前丢弃它。

num_predict 的默认值是多少?

请从您自己的安装中读取默认值,不要依据文章判断。截至 2026 年 8 月,Ollama Modelfile 参考文档将默认值列为 -1,表示不限制生成;该条目在 2024 年末经过修正,此前多年一直记录为 128。负值表示特殊标记,而不是数量;同一表格的旧版本还曾将 -2 列为用于填充剩余上下文的值。请查看适用于您版本的 Modelfile 参数参考,然后使用 ollama show --parameters 和一个 curl 请求进行确认。

提高 num_predict 会让模型生成更长的回答吗?

不会。它只会移除上限。如果回答以 done_reason 结束,并且 stop,说明模型判断生成已经完成;提高上限不会改变结果。这种情况下,长度取决于提示词:要求特定结构、指定章节数量或明确详细程度。只有在 done_reason 返回 length 时,才应提高 num_predict。