跳到主要内容

生产环境中的采样参数:那些没人解释清楚的调参决策

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数工程师将 LLM 质量回归视为提示词工程问题或模型能力问题。他们会重写系统提示词、尝试更新的模型,或添加少样本示例。他们很少检查每次 API 调用顶部静静躺着的三个数字:temperature、top-p 和 top-k。但这些默认值正在悄然改变模型产出的每一个响应,错误的调参会导致输出方差——团队往往数月内都把锅甩给模型,直到意识到罪魁祸首不过是一个从未动过的配置值。

这不是入门教程。如果你在生产环境中运行 LLM——用于信息抽取管道、代码生成、摘要,或任何输出流入真实系统的任务——以下是你在智能调参之前必须理解的机制与权衡。

这些参数究竟做了什么

Temperature、top-p 和 top-k 各自作用于同一采样流水线的不同环节:原始 logits 从模型输出,经过过滤和重塑,最后从结果概率分布中抽取 token。

Temperature 在通过 softmax 转换为概率之前对 logits 进行缩放:P(token) = softmax(logits / temperature)。低于 1.0 的值会锐化分布——可能的 token 变得更可能,不可能的 token 变得几乎不可能。高于 1.0 的值会平坦化分布——概率趋于均匀,模型探索更宽泛的词汇。Temperature 控制分布的尖锐程度与扩散程度。

Top-p(核采样) 在 temperature 应用之后生效。它按概率对 token 排序,沿排名列表向下遍历,只保留累积概率达到阈值 p 的最小 token 集合,其余全部丢弃。若 p=0.95,你将从共同占据 95% 概率质量的 token 中采样。关键行为:当模型置信时,核很小(少数 token 覆盖 95%);当模型不确定时,核扩展(许多 token 共享概率质量)。

Top-k 更简单也更不自适应:无论实际概率如何,始终保留概率最高的 k 个 token。若 k=50,你始终从 50 个候选中采样。局限在于,即使第 50 名概率极低也会被纳入,即便它代表噪声。

重复/频率/存在惩罚 在截断步骤之前应用。Repetition penalty 将先前出现过的 token 的 logit 值除以惩罚系数。Frequency penalty 按 token 出现次数成比例地减去一个值。Presence penalty 对任何出现过的 token 施加固定扣分。惩罚类型比数值本身更重要:presence penalty 激进且二元化(出现一次 = 永久惩罚),这会破坏依赖代词、冠词和常见词的自然语言。

操作顺序——惩罚、截断、采样——并非任意而为。若在截断后再应用惩罚,意味着某些 token 受到惩罚后仍被纳入,因为截断集合是在惩罚调整之前确定的。

为何生产环境中 Temperature=0 并不确定

认为设置 temperature=0 能产生可重复、稳定输出的信念,是生产 AI 中最昂贵的误解之一。Temperature=0 意味着贪心解码:始终选择概率最高的单个 token。但在真实推理环境中,"概率最高的 token"并不是一个稳定量。

GPU 上的浮点运算不满足结合律。同一数学运算——例如 (a + b) + c——与 a + (b + c) 在浮点数表示下产生不同结果,因为舍入误差因计算顺序不同而累积不同。在 transformer 前向传播的数百次矩阵乘法中,这些舍入差异会复合。结果 logit 值与纯数学应产生的值略有不同,而"略有不同"在 logit 层面可能翻转哪个 token 概率最高。

现代推理服务器使用连续批处理来最大化吞吐量。同时到达的请求会被批量处理,而批次组成会影响计算。单独运行你的提示词与和其他 31 个请求一起批量运行会产生不同的注意力模式——进而产生不同的 logits。随着服务器负载波动,批次组成随之改变,这意味着"确定性"模型在高峰时段和非高峰时段产生不同输出。一篇论文(arxiv 2408.04667v5)直接描述了这一点:"对于给定的精确批次,前向传播可能是确定性的,但从用户角度来看,系统仍然是非确定性的,因为批次本身在每次运行中并不稳定。"

GPU 内存布局、量化变体和 KV 缓存优化都可能引入额外漂移。实际结论:temperature=0 显著降低随机性,但并不能消除它。如果你的架构需要可重现性——审计日志、确定性回归测试、逐位相同的输出——你需要固定批次大小、一致的硬件配置,以及平台级别的种子支持(如有)。仅靠 temperature 无法实现这一点。

Top-P 与 Temperature 的交互陷阱

最常见的调参失误发生在工程师想要"更有创意的"输出并同时调整两个参数时。推理看似直觉:temperature 控制创意,top-p 控制多样性,同时提高两者应产生多样且有创意的输出。实际结果往往是语无伦次的乱码。

原因如下。当 temperature 从 0.5 升至 1.5 时,概率分布趋于平坦。在 temperature=0.5 时,顶级 token 可能有 80% 的概率——top-p=0.95 只需要少数几个 token 就能达到该阈值。在 temperature=1.5 时,同一模型可能对顶级 token 只分配 35% 概率——top-p=0.95 现在需要数十个 token 来累积到 95%,其中包括在较低 temperature 下本会被丢弃的低质量候选。提高 temperature 会自动扩展核,即使你没有动 top-p。

一个团队从 (temperature=0.8, top-p=0.95) 改为 (temperature=1.2, top-p=0.95),发现 15-20% 的响应出现语无伦次的输出。修复方案不是降低 temperature——他们确实需要更多变化——而是将 top-p 收紧至 0.80,以补偿高 temperature 带来的核扩展。语无伦次的比例降至 2% 以下。

一般规则:将 temperature 和 top-p 视为耦合参数,而非独立参数。若提高 temperature,降低 top-p。若提高 top-p,考虑降低 temperature。两者同向调整会以难以预测的方式放大它们的交互效应,不经测试无从把握。

近期研究已将此问题形式化。Min-p 采样(Nguyen 等,ICLR 2025)通过使阈值相对于模型自身置信度来解决这一问题。它不设固定累积概率,而是保留概率超过峰值 token 概率一定比例的 token。当模型置信时(峰值=0.95),阈值自动升高;当模型不确定时(峰值=0.1),阈值自动降低。这消除了平坦分布问题,因为核始终相对于模型置信度进行校准。0.05-0.1 的 min-p 值在大多数任务中均有效。它尚未在商业 API 中普遍可用,但 vLLM 已支持,采用率持续增长。

任务特定调参建议

没有通用的"好" temperature。正确的值取决于你需要模型优化什么。

结构化抽取与 JSON 生成: 使用 temperature 0.0-0.2。目标是一致性——你希望相同输入每次产生相同的符合 schema 的输出。较高的 temperature 会引入意外字符、格式偏差和解析失败。如果你可以使用约束解码(针对 JSON schema 的 logit 掩码),请使用它。它在采样前从数学上消除不符合 schema 的 token,使 temperature 对结构有效性几乎无关紧要。从 temperature=0.7 迁移至 temperature=0.1 并结合约束解码的团队报告,结构化输出成功率从约 85% 提升至 99% 以上。

代码生成: 使用 temperature 0.2-0.5。代码需要语法精确性,但完全贪心解码可能错过复杂问题的有效解。Temperature=0.3-0.5 在逻辑综合时允许探索,同时不牺牲语法正确性。将 repetition penalty 保持在或接近 1.0——代码合理地重复模式(变量名、常见习惯用法、样板代码),惩罚重复会破坏这一点。代码质量在 temperature 超过 0.8 后因无效语法而显著下降。

多步推理: 出乎意料的是,temperature=0 对复杂推理任务有害。研究表明,从 temperature=0.5 降至 temperature=0 时,多步数学问题的准确率下降约 17 个百分点。当模型在推理链中遇到决策点时,贪心解码强制它走一条路。略高的 temperature(0.5-0.7)允许探索替代方案。注意,推理专用模型(o1、o3)将 temperature 锁定在 1.0 且不暴露该参数——信任其默认值,不要假设你可以覆盖。

摘要与问答: Temperature 0.5-0.7 在事实准确性与可读措辞多样性之间取得恰当平衡。低于 0.3,摘要往往压缩且公式化;高于 0.8,事实偏差和幻觉增加。Top-p=0.9 在此场景下是合理的默认值。

创意写作: Temperature 0.8-1.2,top-p 0.95。创意质量受益于分布探索,但质量在约 1.2 以上会崩溃。这是一个非单调关系:更高的 temperature 在一定程度上有帮助,之后则有害。在确定配置前,请在你的具体模型上测试 1.0、1.1 和 1.2。

提供商差异比你想象的更重要

如果你在提供商之间迁移提示词,或在多个模型上运行同一提示词,采样参数并不可移植。OpenAI GPT-4o 上的 temperature=0.7 与 Anthropic Claude 上的 temperature=0.7 并不等价。量程不同(OpenAI 支持 0-2.0,Anthropic 上限为 1.0),底层分布也不同。相同的 temperature 值在不同模型上产生不同的输出方差。

各提供商的参数支持矩阵差异显著:

  • OpenAI 不支持 top_k。这是有意为之——他们认为 top-p 在大多数使用场景下严格优于 top-k。
  • Anthropic 支持 top_k,但不暴露 frequency_penaltypresence_penalty。他们的观点是这些参数引入的复杂性足以导致用户错误。
  • Google Gemini 同时支持 top_ktop_p,以及高达 2.0 的 temperature。

如果你依赖 frequency_penalty 处理对话输出并需要从 OpenAI 迁移至 Anthropic,你没有直接的等价选项。你可以通过收紧 top-k 来限制 token 重复来近似,但行为并不相同。同样,从 Anthropic(你可以明确设置 top_k)迁移至 OpenAI 需要转向基于 top-p 的控制。

一个微妙但重要的点:即使在 OpenAI 的 API 内,frequency_penalty 和 presence_penalty 的语义也不同。Frequency penalty 按 token 出现次数成比例地减去(logits -= penalty * count),因此使用了五次的 token 受到的惩罚是使用一次的五倍。Presence penalty 对任何出现过的 token 施加固定扣分,无论频率如何。如果你想温和地阻止重复同时保持自然语言流畅,frequency penalty 是正确的工具。如果你想积极阻止任何 token 复用,使用 presence penalty——但它会破坏自然复现的代词和常见词。

生产调参的系统化方法

大多数团队设置 temperature=0.7,因为他们在某个教程中看到过它,从未重新审视。少数人在没有基准的情况下凭经验调参且不度量任何指标。两种方法都找不到真正的最优配置。

正确的方法论包含四个阶段:

建立基准测试集。 整理 100-500 个覆盖实际输入分布的示例——包括边缘情况、模糊输入,以及针对你关心的失败模式的对抗性示例。通过人工审核或当前设置下的模型生成参考输出。这个集合是你的回归锚点。

每次仅调整一个参数。 固定其他所有参数,在 [0.0, 0.3, 0.5, 0.7, 0.9, 1.2] 范围内变化 temperature,并用任务适配的指标对基准进行度量(代码的语法有效性、摘要的蕴含分数、连贯性的 LLM 作为裁判)。识别拐点——质量开始提升、趋于平稳、开始下降的位置。

协调耦合参数。 如果单变量扫描显示较高 temperature 有益,相应收紧 top-p 并重新运行。如果你在添加 repetition penalty,验证它不会破坏输出中预期的模式。

在生产中 A/B 测试。 将新配置部署到 5-10% 的流量。在生产中跟踪质量指标,而不仅仅是在评估中——批次动态、真实输入分布和实际用户模式会揭示评估框架遗漏的问题。持续监控,因为当提供商更新模型权重或改变批处理行为时,模型行为可能会漂移。

要避免的反模式:针对不代表生产流量的调参集优化采样参数。如果你的测试用例是干净、格式良好的提示词,而生产用户发送模糊、混乱的输入,最优参数不会迁移。基准必须反映模型实际看到的内容。

在归咎于模型之前先检查配置

实际结论是:当输出质量回归或行为不稳定时,在重新设计提示词或切换模型之前先检查采样参数。Temperature、top-p 和 top-k 容易被忽视,因为它们存在于基础设施配置中而非提示词模板里,而且它们的影响是渐进且随机的,而非立竿见影且显而易见的。

做对这件事的团队将采样配置视为一流的调参面——与提示词一起版本化、在生产中监控、系统化测试。做不到这一点的团队花数月重新设计提示词,而模型实际上从一开始就配置错误了。

这些参数不是魔法。但一旦你知道要看哪里,错误的默认值是最具成本效益的失败模式之一。

References:Let's stay in touch and Follow me for more thoughts and updates