当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > Transformers 怎样用 repetition_penalty 缓解重复输出

Transformers 怎样用 repetition_penalty 缓解重复输出

来源:17golang原创 2026-11-14 21:04:54 0浏览 收藏

我在调本地文本生成时,最容易误判的一类问题就是“模型一直重复”。有时是生成长度没有设好,有时是停止条件不匹配,也有时确实需要给已经出现过的 token 增加一点惩罚。Transformers 的 repetition_penalty 正是控制这一倾向的参数,但它不是“禁止重复”的开关。

官方地址:https://huggingface.co/docs/transformers/

比较稳妥的做法是先把 max_new_tokens 固定,再从 1.0 逐步往上试。官方文档说明,1.0 表示不施加惩罚,数值越大,惩罚越强;因此它更适合缓解明显的复读,而不是替代提示词、停止条件或模型本身的修正。

先把“重复”与“输出太长”分开

如果每次生成的上限都不同,就很难判断重复是参数造成的,还是模型只是获得了更长的续写空间。第一轮比较时,固定提示词、模型、输入格式和 max_new_tokens,只改变 repetition_penalty。

from transformers import AutoModelForCausalLM, AutoTokenizer

# 这里只准备一次输入,比较时不要同时更换模型或提示词。
model_name = "your-model-id"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# 固定生成上限,避免把“更长所以更容易重复”误当成惩罚失效。
inputs = tokenizer("请用三点说明如何记录接口变更。", return_tensors="pt")

# 先用 1.0 建立没有 repetition penalty 的对照组。
output_ids = model.generate(
    **inputs,
    max_new_tokens=128,
    repetition_penalty=1.0,
)
print(tokenizer.decode(output_ids[0], skip_special_tokens=True))

这里的 max_new_tokens 只控制最多新增多少 token,不包括输入提示词。把它固定后,才有资格比较“相同长度预算下,重复程度有没有变化”。不要把示例中的模型 ID 当成通用可运行值;不同模型的加载方式、设备和对话模板可能不同。

输入提示词、已生成 token、候选 token 分数与输出文本之间的静态关系图
图1:输入提示词、已生成 token、候选分数和输出文本的关系说明图;它用于理解参数作用,不是运行截图或推理结果。

从 1.0 开始逐步提高惩罚值

我通常把 1.0 当作基线,然后只增加一个小幅度,观察三件事:重复短语是否减少、关键术语是否仍然保留、回答是否变得突兀或过早转向。以小步长比较,比直接把数值调得很大更容易找到模型与任务的平衡点。

penalties = [1.0, 1.05, 1.1, 1.15]

for penalty in penalties:
    # 只改变 repetition_penalty,其余生成条件保持不变。
    output_ids = model.generate(
        **inputs,
        max_new_tokens=128,
        repetition_penalty=penalty,
    )
    text = tokenizer.decode(output_ids[0], skip_special_tokens=True)
    print(f"penalty={penalty}: {text}")

这些数值是调参起点,不是官方保证的最佳区间。若 1.05 到 1.15 仍然复读,可以继续小步增加;一旦出现专有名词被替换、句子不完整或文本变得生硬,就应回退,而不是继续加大惩罚。repetition_penalty 影响的是生成倾向,并不承诺输出一定符合事实或格式。

把配置保存下来,避免比较时漏改参数

当同一个模型要在多个任务中使用时,把生成参数集中到 GenerationConfig 会更清楚。官方文档也建议通过它统一保存生成配置;直接传给 generate() 的同名参数则会覆盖配置中的值。

from transformers import GenerationConfig

# 用一份配置保存可复现的生成边界,便于之后只替换 penalty。
generation_config = GenerationConfig(
    max_new_tokens=128,
    repetition_penalty=1.1,
    do_sample=True,
    temperature=0.7,
    top_p=0.9,
)

# 生成调用显式接收配置,便于在日志中记录本轮参数。
output_ids = model.generate(
    **inputs,
    generation_config=generation_config,
)
result = tokenizer.decode(output_ids[0], skip_special_tokens=True)
print(result)

这里把采样参数一并写出,是为了让实验条件完整;它们和 repetition_penalty 不是同一职责。do_sample=True 会启用采样,temperature 和 top_p 会改变候选分布。如果你正在定位重复原因,第一轮不要同时大幅修改这些值。

repetition_penalty、no_repeat_ngram_size、采样参数和输出长度的职责边界图
图2:生成配置的职责边界说明图,区分重复倾向、连续 n-gram 限制、随机性和长度上限;这是原创静态结构图,不是软件界面截图。

它与 no_repeat_ngram_size 有什么区别

两者都能处理重复,但强度和语义不同:

参数作用更适合的场景主要副作用
repetition_penalty调低已出现 token 的生成倾向重复明显但仍希望保留自然表达过高会让关键词和常用词变得难以再次出现
no_repeat_ngram_size限制同尺寸 n-gram 再次出现需要明确禁止连续片段复现固定术语、代码或模板句可能被误伤
max_new_tokens限制新增 token 数量控制回答长度和成本过小会截断正常答案,不能单独解决复读

如果需求是“同一段连续短语绝不能再次出现”,可以考虑 no_repeat_ngram_size;如果只是希望模型别围绕同一词打转,先试较小的 repetition_penalty。两者叠加前,先确认任务确实需要这么强的限制。

重复仍然存在时,检查这三个边界

一是提示词和对话模板

聊天模型通常依赖特定的角色格式或 chat template。输入格式不符合模型预期时,输出可能异常重复;这不是把惩罚值加大就能稳定修好的问题。

二是停止条件和长度预算

没有合适的结束 token,或者 max_new_tokens 设得过大,都会给重复留下更多空间。先确认模型的 eos_token_id、输入 padding 方式和长度设置,再判断是否需要惩罚。

三是解码策略的组合

Transformers 支持贪心、采样和 beam search 等生成方式。重复现象可能来自解码策略、温度、top-p、提示词和模型能力的组合。一次只改一个变量,并记录完整配置,才能知道是哪项改变产生了效果。

我的调参记录方式

不要只看“读起来好不好”,至少记录下面四列:惩罚值、重复片段、关键术语是否保留、答案是否提前结束。对摘要、代码解释、结构化输出分别准备固定提示词,因为不同任务对重复的容忍度不同。

experiment = {
    "prompt_id": "api-change-01",  # 用固定编号绑定同一条测试提示词。
    "max_new_tokens": 128,          # 每轮比较保持同一长度上限。
    "repetition_penalty": 1.1,      # 只记录本轮真正变化的惩罚值。
    "keep_terms": ["HTTP", "JSON"], # 检查专有名词是否被错误回避。
}

# 这里的字典只是记录实验条件,不代表已经得到某个模型的质量结论。
print(experiment)

如果较高惩罚值减少了重复,却让答案遗漏关键术语,那么这轮结果不能算成功。对面向用户的回答,完整、可读和术语准确通常比“绝不重复”更重要。

常见问题

repetition_penalty 设置为 1.0 会怎样?

官方文档将 1.0 定义为不施加重复惩罚,适合当作对照组。

是不是数值越大越好?

不是。数值越大代表更强的惩罚,但可能损伤关键词复用、固定格式和自然语句,应按任务逐步比较。

它能解决模型事实错误吗?

不能。它只改变生成过程中的候选倾向,不会补充知识,也不能替代检索、提示词设计或输出校验。

为什么我加了惩罚还是重复?

优先检查提示模板、停止 token、长度上限和解码策略,再确认你比较的确实是同一输入与同一模型。必要时才考虑 n-gram 限制或更换模型。

一句话总结:先用固定的 max_new_tokens 建立基线,再小步提高 repetition_penalty,同时观察重复减少和关键信息保留是否平衡;只有当任务需要硬限制连续片段时,才把 no_repeat_ngram_size 纳入比较。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Transformers save_pretrained 怎样保存可迁移模型Transformers save_pretrained 怎样保存可迁移模型
上一篇
Transformers save_pretrained 怎样保存可迁移模型
GitHub Actions 构件保留策略怎样影响流水线
下一篇
GitHub Actions 构件保留策略怎样影响流水线
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    1029次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    1030次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1173次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1133次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    973次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码