SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-21

本地LLM推理力度怎么设置,实际成本有多高

推理力度只改变模型的草稿令牌数,不改变权重或量化。了解聊天模板如何生效,以及为何本地硬件上的响应时间可能从2秒延长到2分钟。

本地 LLM 中推理力度会改变什么

推理力度是一项设置,用于指定模型在回答前思考的时长。它只会改变推理片段的长度,不会改变其他内容。各级别使用的磁盘权重完全相同,量化方式也相同,答案都来自同一次前向传播。变化的是模型首先用于自身草稿的 token 数量。

这一点很重要,因为这些 token 会产生不同的成本。在托管 API 中,推理 token 会计入账单。在您拥有的 VPS 上,它们会消耗本地 CPU 或 GPU 的生成时间,并占用上下文窗口空间。如果将模型保持在最高推理力度,它可能会在首个回答词出现前,将大部分输出用于推理。在自托管硬件上,这可能导致响应时间从 2 秒延长到 2 分钟。

级别在哪里生效:聊天模板,而不是权重

思考模型经过训练后,会在最终答案前输出一段推理内容,通常使用 <think></think> 标签包裹。思考强度级别是由模型的聊天模板写入提示词的指令。该模板是随模型发布的 Jinja 文件。它读取 reasoning_effort 等变量,并为每个取值生成不同的系统级指令;模型经过训练后,会根据该指令缩短或延长其草稿推理内容。

这会带来两点影响。级别名称属于模型,而不是运行时环境,因此某个模型卡片中的名称对另一个模型可能没有任何意义。如果处理链中的任何环节将模型的聊天模板替换为通用模板,变量就不会被渲染,相关设置也会静默失效。

截至 2026-08-20,Qwen3.8-27B 模型卡片记录了 3 个思考强度级别:lowmediumxhigh,默认值为 xhigh。其中没有 high。思考功能通过 enable_thinking 开关控制,默认启用。模型卡片还记录了默认启用的 preserve_thinking,用于保留对话历史中较早轮次的推理内容。gpt-oss 则使用 lowmediumhigh。许多其他模型系列只接受布尔值,不支持更多级别。请查看所下载的确切版本对应的模型卡片,因为这些名称并非标准。应先阅读 在 VPS 上运行 27B 模型。本页介绍模型能够响应后应如何设置这些选项。

为什么 VPS 上的高推理开销成本更高

输出令牌。 推理令牌和输出令牌都需要生成,并且在相同硬件上以相同的每秒令牌数通过解码循环。假设任务生成 200 个输出令牌和 4,000 个推理令牌,那么实际生成了 4,200 个令牌,但读者只能看到其中 200 个。解码速率由内存带宽和 所选的量化方案决定,因此剩下唯一可以调整的因素就是令牌数量本身。

实际等待时间。 用户等待的是答案的第一个令牌,因为在此之前屏幕通常是空白的,或只显示折叠的加载指示器。系统会先输出推理内容,因此等待时间大致等于推理令牌数量除以解码速率,再加上处理提示词所需的时间。推理长度翻倍,等待时间也会翻倍。

上下文。 推理令牌和其他令牌一样会占用上下文窗口。启用 preserve_thinking 后,第一轮生成的草稿内容在第五轮仍会保留在提示词中,因此每轮的提示词处理都会变慢,同时窗口两端都会不断填充。增大 num_ctx 以容纳这些内容会占用 KV 缓存内存;在没有 GPU 的 VPS 上,这部分内存来自系统 RAM,而系统 RAM 可能没有足够余量。

何时提高级别,何时保持较低级别

对于中间步骤出错会导致结果失真的任务,应提高级别:多步算术和单位换算、跨多个文件规划编辑、必须通过编译的代码,以及必须同时满足多个条件的约束问题。在这些任务中,思维草稿确实有助于完成工作。较长的思考过程可以用较低成本发现模型原本会直接提交的错误。

如果答案已经包含在输入中,任务只是搬运信息,则应保持较低级别。提取、分类、标记、翻译、改写、摘要和格式化都属于此类任务。推理过程大多只是在复述任务,还可能让模型推翻原本正确的第一判断。

对于交互式任务,也应保持较低级别。在聊天框或编辑器中,您可以参与处理过程,因此可快速纠正的答案优于需要等待的慢速答案。这正是让编码代理使用本地模型背后的权衡:代理会发起许多小型调用,而每次调用都会产生推理开销。

如何在 llama.cpp 中设置级别

llama.cpp 会直接将该变量写入模板,因此运行时可以确认级别是否已传入。将 -m 指向已有的 GGUF 文件。

llama-server -m ./qwen3.8-27b-Q4_K_M.gguf \
  --jinja \
  --reasoning-effort medium \
  --reasoning-format deepseek \
  -c 32768 \
  --host 127.0.0.1 --port 8080

--jinja 使用模型自己的聊天模板,当前版本默认启用。--reasoning-effort 接受 defaultminimallowmediumhighxhighmax,其中 default 表示保留模板自身的默认设置。该列表属于 llama.cpp 的词汇,而不是模型的词汇,因此只能传入模型卡片列出的名称:如果模板未定义某个级别,请求运行时可能会出现模板错误。--reasoning-format deepseek 会将推理内容从 message.content 移到 message.reasoning_content,这样才能在下一节中测量两者的分离效果。

如果要关闭思考,而不是缩短思考内容,请自行设置模板变量:

llama-server -m ./qwen3.8-27b-Q4_K_M.gguf --jinja \
  --chat-template-kwargs '{"enable_thinking": false}'

--reasoning-budget 是另一种机制。它按 token 数限制推理片段,其中 0 会立即结束推理,-1 则不设置限制;它不是要求模型规划更短的推理内容。两个选项都作用于整个服务器。llama-server 不接受将 reasoning_effort 作为单个请求的字段,因此要同时提供两个推理级别,必须在两个端口上运行两个进程。

vLLM 支持在每个请求中设置相同的变量,并将其放在兼容 OpenAI 的请求体中:

{"model": "Qwen/Qwen3.8-27B",
 "messages": [{"role": "user", "content": "Summarise this changelog in two lines."}],
 "chat_template_kwargs": {"reasoning_effort": "medium"}}

如何在 Ollama 中设置级别

Ollama 在 think/api/chat/api/generate 上使用自己的字段 true。该字段接受 falselow,或 mediumhighmaxmax 中的一个;其中 message.thinking 表示请求模型提供的最高级别。支持思考功能的模型默认启用该功能。

ollama run qwen3.8:27b --think=low "Draft a one line commit message for a README typo fix"
{"model": "qwen3.8:27b",
 "messages": [{"role": "user", "content": "Which HTTP status code means the request body was too large?"}],
 "think": "low",
 "stream": false}

推理结果会返回在 message.content 中,答案会返回在 ollama run 中,系统已为您完成分离。在交互式 /set think 会话中,使用 /set nothinktemperature 即可切换该功能,无需重启。

现在可以看到其中的差异。Ollama 使用 low、medium、high 和 max。Qwen3.8 的模板定义了 low、medium 和 xhigh。两者必须进行映射。Ollama 模型在其标签中携带打包后的模板,而不是原始代码库中的 Jinja 文件。因此,您设置的级别能否传递到模型,取决于这个打包后的模板。不要假设设置已经生效。完成测量大约需要 1 分钟。

如何衡量该级别是否真正生效

temperature 为 0 时,使用多个级别发送相同的提示词,然后比较 token 数量。这里由 jq 构建请求正文,因此无需手动转义引号。

for level in low medium max; do
  body=$(jq -n --arg lvl "$level" '{
    model: "qwen3.8:27b",
    messages: [{role: "user", content: "A pump fills a 4500 litre tank in 25 minutes. A second pump is 40 percent slower. How long do both together take? Answer in minutes."}],
    think: $lvl,
    stream: false,
    options: {temperature: 0, num_ctx: 8192}
  }')
  echo "== $level"
  curl -s http://localhost:11434/api/chat -d "$body" | jq '{
    thinking_chars: (.message.thinking // "" | length),
    answer_chars: (.message.content | length),
    eval_count: .eval_count,
    seconds: (.total_duration / 1e9),
    tok_per_sec: (.eval_count / (.eval_duration / 1e9))
  }'
done

eval_count 统计生成的每个 token,其中包括推理 token,因此两个级别之间的差值几乎全部来自推理。thinking_chars 直接给出两者的拆分结果。应满足两个条件:数值随级别变化,并且在较低级别下答案仍然正确。如果 eval_count 在三次运行中的差异都处于噪声范围内,说明该级别被忽略了。此时应更换能够传递该参数的运行时,而不是改用其他级别名称。

总耗时只能说明一半情况,因此应通过流式传输进行测量,并在收到第一个非空的 content 块时停止,以获取首个答案 token 的等待时间。此操作需要 jqbc

start=$(date +%s.%N)
curl -sN http://localhost:11434/api/chat -d '{
  "model": "qwen3.8:27b",
  "messages": [{"role": "user", "content": "Explain what a reverse proxy does, in three sentences."}],
  "think": "low",
  "stream": true
}' |
while IFS= read -r line; do
  if [ -n "$(printf '%s' "$line" | jq -r '.message.content // ""')" ]; then
    echo "first answer token after $(echo "$(date +%s.%N) - $start" | bc)s"
    break
  fi
done

low 下运行一次,再在 max 下运行一次。两者的差值就是你为推理购买的等待时间。在 llama.cpp 中,相同的数值会直接返回在响应内,无需执行 shell 算术运算:

curl -s http://localhost:8080/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model": "local", "temperature": 0,
       "messages": [{"role": "user", "content": "A pump fills a 4500 litre tank in 25 minutes. A second pump is 40 percent slower. How long do both together take?"}]}' | jq '{
  reasoning_chars: (.choices[0].message.reasoning_content // "" | length),
  answer_chars: (.choices[0].message.content | length),
  predicted_n: .timings.predicted_n,
  tok_per_sec: .timings.predicted_per_second
}'

请在自己的服务器上执行此测试。已发布的性能对比是在不属于你的硬件上测得的,而你的解码速率决定了 token 数量对应的秒数。在自己的服务器上测量每秒 token 数 可获得该速率:推理 token 数除以解码速率,就是你刚刚增加的等待时间。

问题排查

回答被截断,或 content 为空而 thinking 有内容。 生成上限被推理过程耗尽。Ollama 的 num_predict 会限制整个生成过程,其中包括推理;而推理先于回答执行,因此在高强度模式下将上限设为 512 个 token,可能会在回答开始前耗尽上限。Ollama 会在该响应中报告 "done_reason": "length"。请提高上限或降低推理强度。num_predict 如何计算 token详细说明了两者的关系。

调整级别没有任何变化。 每个级别的 token 数量都相同。这表示运行时没有传递该变量,或模板没有读取该变量。请检查运行时实际使用的模板,而不是原始仓库中的模板。llama.cpp 配合 --jinja--chat-template-kwargs 会手动写入该变量,因此可用于对照:如果级别在 llama.cpp 中生效,而在其他位置都不生效,说明模型正常,其他运行时丢弃了该变量。

级别名称被拒绝。 如果请求时出现模板错误,或服务器本身正常但处理第一条消息时失败,通常表示你传递了模板未定义的级别。例如,模型卡只列出 low、medium 和 xhigh,但你传递了 high

多轮对话每一轮都变慢。 历史记录中保留了旧的推理内容。如果模型支持,请将 preserve_thinking 设置为 false;或者从发回的消息中删除 thinking 字段。否则,每一轮的提示词处理量都会增加,而回答长度保持不变。

在你认为简单的任务上降低推理强度后,质量下降。 有些提取任务并不只是提取。如果输入需要进行单位换算,或按顺序应用规则,那么这仍是推理任务,只是输出较短。请仅为这次调用提高级别,不要提高整个服务器的级别。

同时运行两个级别

llama.cpp 会在启动时固定级别,因此一台同时为编辑器和夜间批处理作业提供服务的主机,需要在两个端口上运行两个进程,并分别配置各自的 --reasoning-effort。运行两个进程还意味着内存中会保留两份权重,除非改为分时运行这些作业。在一台 VPS 上,更经济的安排通常是:为用户正在等待的请求运行低工作量服务器,再通过计划任务运行高工作量任务,用于处理无人监控的作业。多个用户共享同一本地模型时会发生什么同样适用于这里:推理 token 属于解码工作,因此提高工作量会使有效并发数大致按 token 数增加的相同比例下降。

FAQ

默认应使用哪个推理强度级别?

从模型提供的最低级别开始,仅在您确认某些任务会失败时再提高级别。多种思考模型的默认级别都较高;截至 2026 年 8 月,Qwen3.8-27B 默认使用 xhigh,即最高级别。这个默认值是为了在基准测试表中取得较好结果,而基准测试表不会计算等待时间。在您自己的硬件上,等待时间会直接增加,因此应按任务选择更高级别,而不是让每个请求都继承该设置。

推理 token 会占用上下文窗口吗?

会。推理 token 是输出中的普通 token,会与其他内容一起占用上下文窗口。下一轮是否保留这些 token,取决于运行时和模型。Qwen3.8 的模型卡记录了 preserve_thinking,该选项默认启用,会将较早的推理保留在历史记录中,因此长对话会携带模型生成的全部草稿。将其设置为 false,或从要重新发送的消息中删除 thinking 字段,即可停止增加提示词处理量。

为什么更改思考级别后,token 计数没有变化?

该设置没有传递到聊天模板。级别是模板变量,只有运行时传递该变量,且打包的模板读取该变量时才会生效。有些运行时会随模型附带自己的模板,而不是使用原始仓库中的 Jinja 文件;此时变量会被直接丢弃,且不会在任何位置输出错误。将同一个提示词分别以最低和最高级别发送,在 temperature 设置为 0 的情况下进行测试,然后比较 eval_count,即可验证这一点。如果两次计数在误差范围内一致,说明该级别被忽略了。

降低推理强度会降低模型的准确性吗?

这取决于任务,应通过测量而不是假设来判断。如果答案已经存在于输入中,例如提取或改写,较短的草稿通常不会带来变化。如果最终答案依赖某个必须正确的中间步骤,例如多步算术或必须通过编译的代码,较短的草稿确实会降低准确性。从实际工作负载中准备 20 个提示词,在两个级别下运行,并将 temperature 设置为 0,然后统计错误答案的数量。这个数量取决于您的工作负载,任何已发布的基准测试表都无法替您确定该结果。