来源:互联网 更新时间:2026-08-23 14:04
平时用大模型做推理的时候,总会碰到几个让人又爱又恨的超参数——temperature、repetition penalty 这些。大家都知道 temperature 控制着输出的“随机性”,repetition penalty 则是防止模型反复念叨同一句话,但到底它们是怎么做到的?背后的机制可没那么玄乎。
这次直接从 transformers 4.43.1 的源码出发,把 temperature、top-p、repetition penalty 和 top-k 这四个参数的真实作用拆开来看看。所有代码都能在 Hugging Face 的仓库里找到,链接附在后面。

下图是 LMDeploy API Server 的一张截图,展示了常用的推理超参数。OpenAI 接口也支持 temperature、top-p 和 repetition penalty,而 LMDeploy 额外多了个 top-k 参数。
先看看 TemperatureLogitsWarper 类的实现。它在第 236 行,去掉文档和合法性校验后,核心逻辑就这么几行:
class TemperatureLogitsWarper(LogitsWarper):
def __init__(self, temperature: float):
self.temperature = temperature
def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
scores_processed = scores / self.temperature
return scores_processed
temperature 的实质很简单:对模型输出的 logits(分类头在 softmax 之前的分数)做一次除法。因为 LLM 预测下一个 token 本质是个分类任务,temperature 就是放大或缩小 logits 之间的差异。加入温度参数的 softmax 公式是:p_i = exp(score_i / T) / sum_j exp(score_j / T)。
举个实例:假设三个 token A、B、C 的原始 logits 分别是 0.1、0.5、0.9。temperature 取不同值时,概率分布的变化如下图:
随着 temperature 变大,三个 token 的概率差距逐渐缩小,原来概率低的 token A 被选中的机会显著增加——这就是“随机性增大”的本质。
接着看第 411 行的 TopPLogitsWarper:
class TopPLogitsWarper(LogitsWarper):
def __init__(self, top_p: float, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1):
top_p = float(top_p)
self.top_p = top_p
self.filter_value = filter_value
self.min_tokens_to_keep = min_tokens_to_keep
def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
sorted_logits, sorted_indices = torch.sort(scores, descending=False)
cumulative_probs = sorted_logits.softmax(dim=-1).cumsum(dim=-1)
# Remove tokens with cumulative top_p above the threshold (token with 0 are kept)
sorted_indices_to_remove = cumulative_probs <= (1 - self.top_p)
# Keep at least min_tokens_to_keep
sorted_indices_to_remove[..., -self.min_tokens_to_keep :] = 0
# scatter sorted tensors to original indexing
indices_to_remove = sorted_indices_to_remove.scatter(1, sorted_indices, sorted_indices_to_remove)
scores_processed = scores.masked_fill(indices_to_remove, self.filter_value)
return scores_processed
Top-P 的作用是只保留那些概率高且累计概率超过 top_p 参数的 token。继续用上面的例子:三个 token 经 softmax 后概率分别为 0.21、0.32、0.47。设 top_p = 0.7,则累计概率需大于 1 - 0.7 = 0.3 的 token 才被保留。由于 B 和 C 的概率和(0.32 + 0.47 = 0.79)已经超过 0.7,而 A 的概率 0.21 小于 0.3 的阈值,所以 A 被剔除,只剩 B 和 C。
最终输出的 logits 变成:A 为 0,B 为 0.5,C 为 0.9。
第 302 行是 RepetitionPenaltyLogitsProcessor:
class RepetitionPenaltyLogitsProcessor(LogitsProcessor):
def __init__(self, penalty: float):
self.penalty = penalty
def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
score = torch.gather(scores, 1, input_ids)
# if score < 0 then repetition penalty has to be multiplied to reduce the token probabilities
score = torch.where(score < 0, score * self.penalty, score / self.penalty)
scores_processed = scores.scatter(1, input_ids, score)
return scores_processed
Repetition Penalty 的思路非常直接:如果某个 token 已经出现在之前生成的序列里,就给它施加一个惩罚。具体做法是:对已生成的 token 的 logits,如果 score 是正数,就除以 penalty;如果是负数,就乘以 penalty。这样无论正负,都能降低这个 token 再次出现的概率。
假设模型已经输出了三个 token “AAA”,三个候选 token 的 logits 分别为 A:-0.5,B:0.1,C:-0.4。不加 penalty 时,softmax 后的概率是 A:0.25,B:0.47,C:0.28。注意 A 的概率仍不低,尽管它的 logits 是负的。如果 penalty 设为 2.0,A 的负 score 会再乘以 2 变成 -1.0,B 和 C 不变。这时 softmax 后概率变为 A:0.17,B:0.51,C:0.31,A 被明显抑制。
最后是第 478 行的 TopKLogitsWarper:
class TopKLogitsWarper(LogitsWarper):
def __init__(self, top_k: int, filter_value: float = -float("Inf"), min_tokens_to_keep: int = 1):
self.top_k = max(top_k, min_tokens_to_keep)
self.filter_value = filter_value
def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
top_k = min(self.top_k, scores.size(-1)) # Safety check
# Remove all tokens with a probability less than the last token of the top-k
indices_to_remove = scores < torch.topk(scores, top_k)[0][..., -1, None]
scores_processed = scores.masked_fill(indices_to_remove, self.filter_value)
return scores_processed
Top-K 和 Top-P 功能类似,但策略不同:它只保留 logits 最大的 k 个 token。还用那个例子,logits 为 A:0.1,B:0.5,C:0.9。如果 top_k = 1,只保留 C,输出变成 A:0,B:0,C:0.9;如果 top_k = 2,保留 C 和 B,输出 A:0,B:0.5,C:0.9。虽然后来 OpenAI 接口移除了 top-k,但 transformers 里依然保留了它。
读完源码可以总结成这样:
腾讯ima怎么把微信内容一键导入知识库?
黄金价格不断创新高!黄金稳定币XAU、PAXG市值达11亿美元
腾讯ima怎么创建共享知识库?
Celestia价格预测2026-2032:TIA币能否引领山寨币上涨行情?历史价格回顾
新浪互联网热点小时报丨2026年07月26日16时_今日实时互联网热点速递
比特币(BTC)核心周期指标复刻历史走势 价格或跌破5.8万美元关键支撑位
新浪机器学习热点小时报丨2026年07月25日18时_今日实时机器学习热点速递
WorkBuddy微信版怎么获得积分?
新浪人工智能热点小时报丨2026年07月30日18时_今日实时人工智能热点速递
比特币 2025 年价格预测:BTC 的未来走势
车载冰箱重置到出厂设置几步?
5000元起的鼠标哪个最值得入手?
管线机怎么接云米净水器
短剧《史上最强洪荒修为》剧情介绍
Aptos(APT)2026-2032年价格预测与历史走势梳理
笔记本移动电源推荐哪款?
结婚家电首选:Leader懒人三筒Ultra热泵洗烘一体
kimi提示词专家使用方法新手指南
短剧《仙人跳获透视,古玩玉器我全拿捏》剧情介绍
腾讯ima知识库怎么分类管理?
手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc