推理参数
推理参数决定同一个模型、同一个 prompt 最终怎样生成输出。
在工程系统里,推理参数不是“随手调一调”的体验开关,而是影响稳定性、成本、延迟、评估结果和线上复现的重要配置。
一句话概括:
推理参数控制模型如何从概率分布生成内容,也决定生成过程能否被评估、压测、复现和回滚。
如果不了解推理参数,常见问题会很难定位:
- 同一个问题每次回答不一样。
- JSON 偶尔无法解析。
- 回答突然变得很长,成本飙升。
- RAG 问答开始编造引用。
- 压测结果和线上结果对不上。
- 模型升级后无法判断是模型变了,还是参数变了。
基础解码原理可以先看:生成与解码。本文重点放在工程配置和线上治理。
参数在请求链路中的位置
一次典型请求里,推理参数通常在模型服务调用阶段生效。
messages / prompt
-> chat template
-> tokenizer
-> input token ids
-> model forward
-> logits
-> 推理参数处理 logits / 候选集合 / 停止条件
-> output token ids
-> detokenize
-> response
其中:
temperature、top_p、top_k影响候选 token 的采样范围和随机性。max_tokens、stop、eos_token_id决定什么时候停止。presence_penalty、frequency_penalty、repetition_penalty影响重复内容。seed影响随机采样的复现性。n、best_of、num_beams影响候选数量和计算成本。
工程上要把这些参数看成 API 契约的一部分,而不是 UI 层临时变量。
参数速查
| 参数 | 控制什么 | 常见风险 | 工程建议 |
|---|---|---|---|
temperature | 概率分布尖锐程度 | 过高导致发散,过低导致死板 | 从低值开始,按任务调高 |
top_p | 按累计概率截断候选集合 | 过高增加不稳定,过低可能过窄 | 常和 temperature 一起保守调整 |
top_k | 只保留前 k 个候选 token | 固定 k 不够自适应 | 不熟悉时优先调 top_p |
max_tokens / max_new_tokens | 最大输出长度 | 成本和延迟失控,回答被截断 | 必须设置上限 |
stop / stop_token_ids | 命中序列后停止 | 提前截断或停不住 | 结构化协议要显式测试 |
presence_penalty | 出现过就惩罚 | 破坏必要重复 | 轻量使用 |
frequency_penalty | 出现越多惩罚越强 | 术语和字段名变形 | 文案类任务更适合 |
repetition_penalty | 惩罚重复 token | 过强导致不自然 | 本地模型常见,需压测 |
seed | 随机种子 | 误以为完全确定 | 只作为复现辅助手段 |
num_beams | beam search 宽度 | 成本增加,输出保守 | 聊天模型通常少用 |
n / best_of | 生成多个候选 | 成本按候选数放大 | 只给明确需要多候选的场景 |
不同推理框架和 API 对参数命名不完全一致。接入时要把外部 API 参数、内部网关参数、模型服务参数做一层显式映射。
Temperature
temperature 控制采样分布的随机性。
- 越低:输出越稳定、越保守。
- 越高:输出越多样、越容易发散。
- 接近 0:通常接近 greedy decoding。
常见起点:
| 任务 | 建议起点 |
|---|---|
| 分类、判断、路由 | 0 - 0.2 |
| 信息抽取、结构化输出 | 0 - 0.3 |
| RAG 问答 | 0.1 - 0.5 |
| 总结、改写 | 0.2 - 0.6 |
| 代码生成 | 0.1 - 0.5 |
| 头脑风暴、创意写作 | 0.7 - 1.0 |
需要注意:
- 低
temperature不保证事实正确。 - 高
temperature不代表模型更聪明。 - 在高风险任务里,不应该用高随机性掩盖上下文或检索质量问题。
如果线上需要稳定体验,应该把 temperature 的可调范围限制在任务允许区间内。
Top-p 和 Top-k
top_p 按累计概率截断候选集合,也叫 nucleus sampling。
例如 top_p = 0.9 表示系统从概率最高的 token 开始累加,只保留累计概率达到 0.9 的候选集合,再从里面采样。
top_k 则更直接:只保留概率最高的 k 个 token。
工程实践里:
top_p比top_k更自适应。top_k在一些本地推理框架中很常见。- 不建议同时把
temperature、top_p、top_k都调得很激进。
常见配置:
| 场景 | 建议 |
|---|---|
| 稳定问答 | 低 temperature + top_p 0.8 - 0.95 |
| 创意生成 | 中高 temperature + top_p 0.9 - 0.98 |
| 严格结构化输出 | 低 temperature,必要时关闭采样或使用约束解码 |
| 本地模型重复严重 | 先检查 prompt 和 stop,再轻量调整 top_k / penalty |
top_p = 1 通常表示不做 nucleus 截断,但仍可能受其他参数影响。
最大输出长度
max_tokens 或 max_new_tokens 控制最多生成多少输出 token。
这类参数同时影响:
- 成本。
- 延迟。
- GPU decode 时间。
- 流式输出时长。
- 回答是否完整。
- 下游 parser 是否能拿到完整结构。
常见错误是只关注输入上下文长度,不限制输出长度。
例如一个客服问答场景,如果没有限制输出 token,模型可能在异常 prompt 下生成很长的解释,导致:
- 单请求成本异常。
- 用户等待时间变长。
- decode 阶段占用 GPU,影响其他请求。
- 日志和审计存储膨胀。
建议:
- 每个业务场景都设置默认
max_tokens。 - 按任务类型设置不同上限,而不是全站一个值。
- 对外部用户请求设置硬上限。
- 对 agent、代码生成、长文总结等任务单独设更高配额。
- 监控输出 token 分布,而不是只看平均值。
max_tokens 太小会导致回答被截断。结构化输出尤其危险,因为 JSON、XML、SQL 可能在末尾被截断后无法解析。
Stop 条件
停止条件决定生成什么时候结束。
常见停止方式:
| 停止条件 | 说明 |
|---|---|
| EOS token | 模型学到的结束标记 |
max_tokens | 达到最大输出长度 |
stop sequence | 命中特定字符串停止 |
stop_token_ids | 命中特定 token id 停止 |
| 工具调用边界 | 生成 tool call 后交给工具执行 |
| 网关超时 | 服务层强制中断 |
| 用户取消 | 前端或客户端取消请求 |
stop 在工程协议里很有用。例如让模型输出:
<answer>
...
</answer>
然后把 </answer> 设为 stop sequence,可以避免模型继续输出解释性尾巴。
但 stop 也容易出问题:
- stop 字符串出现在正文里,导致提前截断。
- tokenizer 切分后和预期不一致。
- 多语言内容里命中意外边界。
- 不同模型的 EOS token 不一致。
- chat template 自带结束标记,但服务层又额外加了 stop。
上线前要用真实样例测试 stop 条件,尤其是工具调用、JSON 输出、多轮对话和流式输出。
重复惩罚
重复惩罚用于缓解模型反复输出相同词、句子或结构。
常见参数包括:
presence_penalty:某个 token 只要出现过就惩罚。frequency_penalty:出现次数越多,惩罚越强。repetition_penalty:常见于 Hugging Face、vLLM 等本地推理生态,用于惩罚已经出现过的 token。no_repeat_ngram_size:禁止重复 n-gram。
适合使用的场景:
- 文案生成重复句式。
- 长文生成反复绕圈。
- 小模型出现循环输出。
- 对话模型不断复述用户问题。
不适合过强使用的场景:
- 代码生成,因为变量名和关键字需要重复。
- JSON 输出,因为字段名可能需要重复。
- 法律、医学、标准文档,因为术语需要一致。
- 表格和列表,因为结构重复是正常的。
建议先排查 prompt、上下文和 stop 条件,再调重复惩罚。重复惩罚是修正手段,不应该替代任务设计。
Seed 与复现性
seed 用于控制随机采样的随机数种子。
它可以提高复现概率,但不能保证所有环境完全一致。
影响复现性的因素包括:
- 模型权重版本。
- tokenizer 版本。
- chat template。
- prompt 内容。
temperature、top_p、top_k。seed。- 推理框架版本。
- GPU、驱动、算子实现。
- batch 调度和并发。
- speculative decoding。
因此工程上不能只记录 seed。至少要记录:
{
"model": "model-name-or-version",
"tokenizer": "tokenizer-version",
"prompt_version": "prompt-v12",
"chat_template_version": "template-v3",
"temperature": 0.2,
"top_p": 0.9,
"max_tokens": 512,
"stop": ["</answer>"],
"seed": 42
}
对于评估和回归测试,建议固定完整推理配置,并把配置文件纳入版本管理。
Greedy、Sampling 和 Beam Search
推理参数通常和解码策略一起使用。
| 策略 | 含义 | 适合场景 | 风险 |
|---|---|---|---|
| Greedy | 每步选概率最高 token | 分类、抽取、格式转换 | 可能死板、局部最优 |
| Sampling | 按概率随机采样 | 创意、开放问答、多方案 | 不稳定、难复现 |
| Beam search | 同时保留多条高分路径 | 翻译、受限生成 | 成本高、输出保守 |
现代聊天 LLM 服务里,最常见的是 greedy 或 sampling。Beam search 在传统 seq2seq 任务中更常见,在开放式对话里未必更好。
如果业务要求“同样输入尽量同样输出”,优先考虑:
- 低
temperature。 - 固定
top_p。 - 固定
seed。 - 禁止用户随意覆盖参数。
- 固定模型、prompt、template 和工具 schema 版本。
结构化输出参数建议
结构化输出包括 JSON、SQL、XML、YAML、表格、函数参数等。
这类任务的核心不是“看起来像”,而是能被下游稳定解析。
建议:
- 使用低
temperature。 - 设置合理
max_tokens,避免结构被截断。 - 使用 JSON mode、function calling 或 schema constrained decoding。
- 设置明确 stop 条件。
- 输出后用 parser 校验。
- 校验失败后走修复链路。
- 记录失败样例,用于回归测试。
不要只靠 prompt 写“请严格输出 JSON”。模型仍可能输出注释、Markdown 代码块、额外说明或半截结构。
如果下游是生产系统,必须把 parser、schema、重试和错误处理作为链路的一部分。
RAG 场景参数建议
RAG 问答通常要求模型基于检索内容回答,不能自由编造。
建议:
| 参数 | 建议 |
|---|---|
temperature | 低到中,常从 0.1 - 0.4 起步 |
top_p | 保守设置,避免候选过宽 |
max_tokens | 根据答案模板设置上限 |
stop | 对引用、答案边界、JSON 包装做测试 |
| penalty | 轻量使用,避免破坏引用格式 |
RAG 里调低 temperature 只能减少表达发散,不能解决检索错误。
如果模型编造来源,优先检查:
- 检索是否召回了正确文档。
- rerank 是否把相关内容排在前面。
- prompt 是否要求只基于上下文回答。
- 引用格式是否可校验。
- 无答案时是否允许拒答。
不要把检索质量问题当成采样参数问题。
Agent 和工具调用参数建议
Agent 或工具调用场景通常更需要稳定性,而不是创意。
建议:
- 低
temperature。 - 使用明确 tool schema。
- 对工具参数做 schema 校验。
- 给工具调用设置 stop 或专用结束边界。
- 限制单轮最大 token 和最大工具调用次数。
- 记录每次工具选择、参数和返回值。
如果模型经常选错工具,优先检查工具描述、工具数量、路由 prompt 和 few-shot 示例。
如果模型参数经常错,优先检查 schema 约束、字段描述和解析器,而不是单纯降低 temperature。
评估中的参数管理
评估时必须固定推理参数。
否则不同实验结果无法比较:
模型 A + prompt v1 + temperature 0.2
模型 A + prompt v1 + temperature 0.8
这不是同一个实验。
评估记录至少包含:
- 模型版本。
- prompt 版本。
- tokenizer / chat template。
- 检索配置。
- 工具 schema。
- 推理参数。
- 评估集版本。
- 评估时间。
对于高随机性任务,可以对同一条样本生成多次,统计均值、方差和失败率。只看一次输出,很容易被偶然结果误导。
压测中的参数管理
压测不仅要固定 QPS,还要固定输入输出 token 分布和推理参数。
这些参数会直接影响性能:
max_tokens越大,最坏 decode 时间越长。- 实际输出越长,GPU 占用越久。
n、best_of、num_beams会放大计算量。- 高并发下 batch 调度会影响 TTFT 和 ITL。
- stop 条件不同会改变平均输出长度。
压测报告里至少要写清楚:
| 项目 | 示例 |
|---|---|
| 输入 token 分布 | p50 / p90 / p99 |
| 输出 token 分布 | p50 / p90 / p99 |
max_tokens | 512 |
temperature / top_p | 0.2 / 0.9 |
| 并发策略 | fixed concurrency / ramp up |
| 流式输出 | 开启或关闭 |
| 超时设置 | 60s |
只写“100 QPS 压测通过”没有太大意义,因为 LLM 服务的瓶颈通常和 token、decode、KV Cache 更相关。
线上治理
线上系统不应该允许任意调用方随意传入所有推理参数。
建议采用分层配置:
平台默认值
-> 业务场景默认值
-> 模型默认值
-> 请求级允许覆盖项
-> 网关硬限制
例如:
- 客服问答可以覆盖
max_tokens,但不能超过 800。 - 创意写作可以调高
temperature,但不能超过 1.0。 - 工具调用链路不允许调用方传入高随机性参数。
- 外部 API 用户不能传
best_of = 20。 - 所有请求必须有超时和最大输出限制。
需要记录的日志字段:
- 请求 id。
- 模型版本。
- prompt / template 版本。
- 推理参数。
- input tokens。
- output tokens。
- stop reason。
- latency、TTFT、ITL。
- 是否重试。
- 是否命中安全拦截。
当线上出现质量波动时,推理参数日志能帮助判断问题来自模型、prompt、检索、工具、参数还是流量分布变化。
发布和回滚
推理参数变化也应该走发布流程。
例如把 temperature 从 0.2 调到 0.8,可能带来:
- 回答更自然。
- 格式失败率上升。
- 引用编造增加。
- 审核风险增加。
- 用户感知更活跃但不稳定。
因此参数变更要像 prompt 变更和模型变更一样管理:
- 有版本号。
- 有变更说明。
- 有评估结果。
- 有灰度范围。
- 有回滚方案。
- 有线上指标监控。
回滚模型时,也要确认推理参数是否一起回滚。否则看似回滚了模型,实际行为仍然不同。
推荐默认值模板
下面是工程起点,不是固定答案。
| 场景 | temperature | top_p | max_tokens | 其他建议 |
|---|---|---|---|---|
| 分类 / 路由 | 0 - 0.2 | 0.8 - 1.0 | 64 - 256 | 使用枚举校验 |
| 信息抽取 | 0 - 0.3 | 0.8 - 0.95 | 256 - 1024 | schema + parser |
| RAG 问答 | 0.1 - 0.5 | 0.8 - 0.95 | 512 - 2048 | 引用校验 |
| 总结 | 0.2 - 0.6 | 0.85 - 0.95 | 512 - 4096 | 按输入长度分档 |
| 代码生成 | 0.1 - 0.5 | 0.8 - 0.95 | 512 - 4096 | 必须运行测试或静态检查 |
| 工具调用 | 0 - 0.2 | 0.8 - 0.95 | 256 - 1024 | tool schema + guardrails |
| 创意写作 | 0.7 - 1.0 | 0.9 - 0.98 | 1024 - 4096 | 可生成多候选 |
上线后要用真实数据校准这些值。不同模型、不同 tokenizer、不同 chat template 下,同一组参数的体感可能不一样。
常见误区
参数能解决所有质量问题
不能。参数只能控制生成方式,不能补足模型能力、检索质量、工具结果和 prompt 设计。
Temperature 设为 0 就完全可复现
不一定。框架实现、并发调度、浮点计算和模型服务版本都可能影响结果。
max_tokens 越大越安全
不是。过大的 max_tokens 会增加成本和长尾延迟,也可能让模型输出无关内容。应该按任务设置合理上限。
top_p 越高越好
不是。top_p 越高,候选集合越宽,输出越容易发散。严肃任务通常不需要很高的 top_p。
重复惩罚越强越好
不是。过强惩罚会破坏代码、JSON、术语、表格和必要重复。
小结
推理参数是大模型工程化中的核心配置。
它们影响的不只是输出风格,还包括:
- 稳定性。
- 复现性。
- 结构化输出成功率。
- RAG 可信度。
- 工具调用可靠性。
- 成本和延迟。
- 评估可比性。
- 压测可信度。
- 发布和回滚边界。
工程上应把推理参数纳入版本管理、日志记录、评估配置、压测报告和灰度发布流程。不要凭感觉调参数,也不要让不同环境默默使用不同默认值。