Day32 | 推理参数调参心法——temperature 调低就一定好?你可能调错了方向

发布时间:2026/7/20 12:23:05
Day32 | 推理参数调参心法——temperature 调低就一定好?你可能调错了方向 苦猿的大模型日记 · Day32 · 推理参数调参心法-帮普通人把AI学进简历系列前言我见过最多的推理参数错误不是调太猛——是调太保守我见过最多的推理参数错误不是 temperature 调到 1.5 让模型开始说胡话。是把 temperature 一路往 0 方向拧觉得越低越稳——然后发现模型的输出越来越像背书第一段讲清楚了第二段开始重复第三段绕圈第四段你会看到它把第一段的话用不同的方式又说了一遍。这是 greedy decoding 的经典陷阱。很多人以为调低 temperature 是在让模型更严谨实际上是在让它越来越贪——每一步只走局部概率最高的那条路结果走进了死角。temperature / top_p / repetition_penalty / max_new_tokens——这几个参数背后各有一套逻辑。盲调只是在瞎撞。理解每个参数真正控制的是什么、调错了会出现什么症状才能从症状倒推旋钮方向快速找到问题。这篇就讲这个。Qwen3-8B 的官方推荐 temperature 是 0.7很多人第一次用时直接设 0.1——这不是小事在 reasoning 任务上这个差距会直接影响模型能不能绕出来。PART 01temperature——不是越低越准是越低越贪先把底层机制一句话说清楚temperature 是 softmax 的缩放系数决定概率分布的尖锐/平坦程度。temperature1.0原始概率分布不做任何缩放。temperature1.0分布被压尖高概率词的优势被放大低概率词几乎没机会被选到。temperature1.0分布被拉平低概率词混进候选的机会变大。听起来 temperature 低 模型更确定是好事。问题就出在这里。temperature0或接近 0是 greedy decoding。每一步选当前概率最高的词听起来最理性。但这条路很容易走进本地最优前几步走得很好到了某个节点所有好的下文概率都差不多greedy 就会选那个最高概率的然后下一步发现自己被带进了一个重复的圈子——因为重复上一句往往是语言模型的高概率选择。症状你应该见过模型输出的后半段开始重复句式或者把结论翻来覆去说或者两段话之间的意思完全一样只是换了个措辞。temperature 太高也有问题概率分布被拉平之后低质量词甚至乱码词混进候选。症状是中英文随机切换、名词突然拼错、逻辑在某句话之后断裂。那经验值是多少按任务类型来不能一刀切知识问答 / RAG 检索增强0.3-0.5需要事实准确但不能 greedy代码生成0.1-0.3逻辑严格低随机创意写作 / 头脑风暴0.7-1.0需要多样性Reasoning CoT思维链0.6-0.8最后这条是反直觉的。很多人觉得 reasoning 任务要严谨应该把 temperature 调低。但思维链推理需要探索空间——模型要在脑子里走几条不同的路排除错误收敛到正确答案。temperature 太低推理路径变成一条直线遇到稍微复杂一点的题就绕不出来。看个代码from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_name Qwen/Qwen3-8B tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, device_mapauto ) prompt 请解释什么是注意力机制并举一个直觉类比。 inputs tokenizer(prompt, return_tensorspt).to(model.device) for temp in [0.1, 0.7, 1.2]: output model.generate( **inputs, max_new_tokens256, temperaturetemp, do_sampleTrue, # 关键不开这个temperature 完全失效下一节细讲 top_p0.9, ) decoded tokenizer.decode( output[0][inputs[input_ids].shape[1]:], skip_special_tokensTrue ) print(f\n temperature{temp} ) print(decoded)temperature0.1 的输出通常简洁工整但偶尔会在末尾重复一两句temperature0.7 输出最自然temperature1.2 有时能给出有趣的类比但也容易在细节上飘。监控信号temperature 调太低的时候输出文本里的 unique token 比例会下降重复 ngram 数量会上升。如果你有评测脚本可以顺手把这两个指标加进去。PART 02top_p 和 top_k——两把筛子别同时开到最大top_p 和 top_k 都是采样时的过滤器但工作方式不一样。top_pnucleus sampling先把所有词按概率从高到低排序然后只保留概率累积到 p 的那些词作为候选。top_p0.9候选集涵盖了 90% 的概率质量低概率的长尾词被排除。这个设计的好处是自适应如果模型对下一个词非常确定最高概率词的概率是 0.95top_p0.9 的候选集可能只有 1 个词如果模型比较迷茫概率分散候选集就会更大给多样性留空间。top_k直接截断只保留概率最高的 k 个词。top_k50 就是每次从概率排名前 50 的词里采样。逻辑更直接但有个问题——它不管概率分布的形状。词表大的模型在某些位置概率高度集中top_k50 里其实只有前 5 个词有意义后 45 个概率接近 0 却还在候选里浪费了筛选空间。两者叠加的陷阱top_p0.9 top_k50 不是双重保险。两个过滤器是串联的不是并联。先用 top_k 截断再用 top_p 过滤——如果 top_k 先把候选词集缩到 20 个top_p 在 20 个里再过滤最终候选可能只剩个位数。多样性直接崩了输出会变得跟纯 greedy 差不多。经验通常只开一个。推荐top_p0.9, top_k0top_k0 代表关掉 top_k 过滤。词表大的模型 top_k 的合理值不好判断top_p 更鲁棒。do_sample——最容易被漏掉的开关这个参数值得单独强调。do_sampleFalsegreedy decodingtemperature / top_p / top_k全部失效。不是效果变弱是完全失效。你把 temperature 调到 0.9top_p 调到 0.95如果 do_sample 没开模型完全不看这两个参数直接 greedy 选概率最高的词。我见过不止一次有人调了半天参数输出一点变化没有最后发现 do_sample 忘了开。症状非常明显多次采样输出完全一样改了 temperature 之后结果丝毫不变。# ❌ 错误用法do_sampleFalse 时temperature 和 top_p 完全不生效 output model.generate( **inputs, max_new_tokens256, temperature0.8, # 设了也没用 top_p0.9, # 设了也没用 do_sampleFalse, # 默认值greedy decoding ) # ✅ 正确用法 output model.generate( **inputs, max_new_tokens256, temperature0.7, top_p0.9, top_k0, # 关掉 top_k只用 top_p do_sampleTrue, # 必须显式开启 )PART 03repetition_penalty——调猛了比不调更坏repetition_penalty 的机制是对已经出现过的 token把它的 logit 除以 penalty 值。penalty 1.0压制重复值越大抑制越强。penalty 1.0鼓励重复少见场景。推荐范围1.05-1.2。1.1 是个不错的起点大部分情况够用。penalty 1.3 开始变危险。原理是penalty 是全局的不区分这个词是废话重复还是这个词是必须重复的专业术语。调猛了模型会主动回避刚出现过的词——包括那些本该重复的词。症状很微妙技术文档里同一个变量名在第二次出现时被替换成了不同的词模型变成了神经网络系统算法……。代码生成里同一个函数名在调用的时候被优化成了别的名字。输出语法上通顺语义上已经漂移。这才是最难排查的问题——不是明显的乱码而是悄悄偷换了概念。prompt 请详细介绍 Transformer 中的自注意力机制包括 Query、Key、Value 的计算过程。 inputs tokenizer(prompt, return_tensorspt).to(model.device) for penalty in [1.0, 1.2, 1.5]: output model.generate( **inputs, max_new_tokens300, do_sampleFalse, # 用 greedy单独观察 penalty 的效果排除 temperature 干扰 repetition_penaltypenalty, ) decoded tokenizer.decode( output[0][inputs[input_ids].shape[1]:], skip_special_tokensTrue ) print(f\n repetition_penalty{penalty} ) print(decoded)跑这段代码penalty1.5 的输出里Query/Key/Value 这几个词在第二次出现时大概率被换成了别的表达。如果主要问题是句尾循环复读更精准的方案是no_repeat_ngram_size3禁止连续 3 个 token 的 ngram 重复。比全局 penalty 精准不会误伤必要的术语重复。output model.generate( **inputs, max_new_tokens300, do_sampleTrue, temperature0.7, no_repeat_ngram_size3, # 只禁止 3-gram 重复不影响单词级别的重复 repetition_penalty1.0, # 关掉全局 penalty )监控信号penalty 调过头的输出里同一概念会出现多个不同的指代词用set(output_tokens)数一下 unique 词的数量反而会升高——听起来多样了实际上是语义在漂移。PART 04max_new_tokens——给模型一个收束点不是保险箱常见做法设一个大数4096 甚至 8192心想反正能输出就让它输出截断总比不够好。这个逻辑不完全对。对话 / 问答类任务max_new_tokens 太大模型会填充废话直到达到上限。不是模型不知道停下来——语言模型是会生成|endoftext|的。问题是在 stop token 出现之前模型会根据 context 判断我是不是应该再补充一点。如果 max 设得很大模型的补充意愿会相对强正文说完之后继续重申、补充、反复强调直到它觉得说得够了或碰到了上限。按任务类型给经验值简单问答 / 意图分类64-256摘要 / 分析 / 翻译512-1024代码生成单函数512-1024代码生成完整模块1024-2048Reasoning CoT思维链2048-4096最后一条又是反直觉的reasoning 模型越想越长这是特性不是 bug。模型在推理过程中会自我检查、修正、重算这些都会显著增加 token 数。如果 max_new_tokens 设太小thinking 过程被截断最终答案质量直接下降。还有一个配套参数min_new_tokens防止模型输出一两个词就停。对于强制要求完整回答的场景比如摘要任务你不希望模型只吐一句话把 min_new_tokens 设到预期最短输出长度可以避免意外截断。# 问答场景限制输出避免废话填充 output_qa model.generate( **inputs, max_new_tokens256, # 问答不需要很长 min_new_tokens10, # 至少说 10 个 token防止空回答 do_sampleTrue, temperature0.4, top_p0.9, ) # Reasoning 场景给足空间不要截断思维链 output_cot model.generate( **inputs, max_new_tokens3072, # CoT 需要足够空间 do_sampleTrue, temperature0.7, # reasoning 需要一定探索空间 top_p0.9, )PART 05一张表帮你从症状倒推旋钮调了这么多参数怎么在实际问题里快速定位答案是先看症状再选旋钮不要上来就调 temperature。症状大概率原因先动这个旋钮输出后半段重复、绕圈temperature 太低greedy 陷阱temperature ↑ 到 0.5-0.7输出语言混乱、逻辑断裂temperature 太高temperature ↓ 到 0.5 以下改了 temperature 输出没变化do_sampleFalse先开do_sampleTrue专业词汇被替换成同义词repetition_penalty 太高penalty ↓ 到 1.1-1.15回答没说完就停了max_new_tokens 太小翻倍再试回答说完了还在废话max_new_tokens 太大按任务类型收紧输出每次都一样多样性差top_p 太低或 top_k 太小top_p ↑ 到 0.9top_k 设 0Reasoning 推理答案质量差temperature 太低 CoT 被截断temperature ↑ 到 0.7max_new_tokens ↑最后一行是个组合症状也是最容易被漏掉的——你以为是模型推理能力不行实际上只是参数限制了它的思考空间。心法这 5 个参数背后控制的说到底是置信度和探索度的平衡。置信度太高temperature 低、top_p 低模型走最安全的路走进死角。探索度太高temperature 高、penalty 低模型走太远走进混乱。不同任务对这个平衡的要求不一样——把任务类型想清楚参数就基本对了。结尾参数只是表象任务类型才是锚这 5 个参数各有脾气但规律都是一样的每个参数背后都有一个对应的症状症状反向告诉你旋钮该往哪转。能在面试里讲清楚为什么 reasoning 模型的 temperature 要比代码生成模型高——这一题在大模型工程岗位面试里是真实考点问的就是你有没有跑过、有没有踩过坑。苦猿的观察大多数工程翻车在 do_sample 和 repetition_penalty 这两个地方。temperature 其实是最容易调的因为症状最直接一眼能看出来哪边出了问题。真正坑人的是 do_sample 忘了开——调了半天参数模型输出纹丝不动最后发现一行代码的事。推理参数调的不是随机性调的是你允许模型有多大的犯错空间——太严格它走进死角太宽松它走进混乱。找到那个平衡点就是这件事的全部。互动时间你跑推理时最常在哪个参数上翻车do_sample 没开还是 repetition_penalty 调过头评论区聊聊说不定能避一个坑。下一篇预告推理参数调好了下一步是怎么把微调好的模型高效部署起来——vLLM 本地部署实战我们接着聊。觉得有用的话点个在看帮更多想学 AI 的人看到这篇。— END —苦猿 · 帮普通人把 AI 学进简历