重复惩罚是什么
repetition_penalty 是文本生成的采样参数:对已经出现过的 token 的 logits 施加惩罚,压低它们再次被选中的概率,用来打断复读与自我循环。取值大于 1 表示抑制,等于 1 相当于关闭,小于 1 则反向鼓励重复。Hugging Face 的 generate 与 vLLM 的 SamplingParams 都实现了这个参数,但两套实现处理数值口径的方式并不完全一致,迁移时不能直接照搬数值。
基本信息
| 参数名 | repetition_penalty |
|---|---|
| 取值含义 | >1 抑制重复;=1 关闭;<1 鼓励重复 |
| 常见起点 | 1.05 ~ 1.2 |
| 适用平台 | HF transformers generate、vLLM SamplingParams、部分 OpenAI 兼容实现 |
| 生效时机 | 每个解码步,对已出现 token 的 logits 做修正 |
典型使用场景
- 模型陷入复读循环:同一句或同一段格式被反复输出,小幅上调到 1.1 附近通常能打断循环
- 结构化输出场景:模型倾向重复输出相同字段名,用惩罚压低重复 token 的概率
- 多轮长对话:上下文里已堆积自身历史输出,重复倾向被放大,需要一层兜底
- 批量生成同质内容(短标题、标签)时抑制模板化复读
- 对比实验:把它与 frequency_penalty、presence_penalty 一起当候选,取效果与副作用都小的那个
常见写法
常见写法
# vLLM:在线与离线都通过 SamplingParams 传入
from vllm import SamplingParams
sp = SamplingParams(temperature=0.8, top_p=0.9, repetition_penalty=1.1)
# HF transformers 生成
# out = model.generate(**inputs, repetition_penalty=1.1, max_new_tokens=256)
# OpenAI 兼容端点:部分实现支持 repetition_penalty 扩展字段
# {"model": "<模型名>", "messages": [...], "repetition_penalty": 1.1}
# 校验:同一 prompt 生成三次,确认复读被打断而不是被压成换词与其它去重参数对照
| 参数 | 作用对象 | 特点 |
|---|---|---|
| repetition_penalty | 已出现的 token | 只看是否出现过,出现次数不额外加权 |
| frequency_penalty | 已出现的 token | 按出现次数线性累加,出现越多压得越狠 |
| presence_penalty | 已出现的 token | 出现即一次性惩罚,与次数无关 |
| no_repeat_ngram_size | 长度为 N 的片段 | 硬约束:禁止同一片段重复出现 |
惩罚对所有出现过的 token 一视同仁:代码、JSON、公式里本该复现的符号会被一同压低,长文本里表现更明显。
两套实现的数学形式不同(HF 对负 logits 乘、正 logits 除),迁移时用同一 prompt 做小样本对照再定值,而不是把 1.1 直接搬过去。