Transformers StoppingCriteriaList 怎样组合生成终止条件
来源:17golang原创
时间:2026-10-27 15:39:36 325浏览 收藏
StoppingCriteriaList 可以把多个生成终止条件装进一个列表,再一次传给 model.generate()。它的核心不是“按顺序执行到第一个条件就返回”,而是让每个条件针对当前 input_ids 和 scores 产生布尔结果,最后按 batch 样本逐位合并;因此长度、时间和业务标记可以同时作为停止信号。
官方文档地址:https://huggingface.co/docs/transformers/en/internal/generation_utils
先分清单个条件和条件列表的职责
StoppingCriteria 是单个规则的抽象基类,调用签名接收 input_ids、可能为空的 scores 以及额外参数,并返回形状接近 (batch_size,) 的布尔张量。StoppingCriteriaList 本身继承 Python 的 list,它只是把多个规则组织起来并提供统一的调用入口。
官方实现先创建一个全为 False 的 batch 向量,然后对列表中的每个条件执行按位 OR。换句话说,任意一个条件对某个样本返回 True,这个样本在合并结果中就会被标记为停止;不同样本可以在同一轮得到不同结果。

把最大长度、最长时间和自定义条件放入同一个列表
最小组合通常包含 MaxLengthCriteria、MaxTimeCriteria 和一个自定义条件。长度条件约束完整序列长度;对 decoder-only 模型,官方说明这个长度包含原始提示词。时间条件接收秒数,并可用 initial_timestamp 指定计时起点。自定义条件则适合“生成到某个业务标记就停止”这类领域规则。
import torch
from transformers import (
MaxLengthCriteria,
MaxTimeCriteria,
StoppingCriteria,
StoppingCriteriaList,
)
class StopOnMarker(StoppingCriteria):
def __init__(self, marker_id: int):
self.marker_id = marker_id
def __call__(self, input_ids, scores, **kwargs):
# 只检查每个样本最后一个 token,返回 batch 维度的布尔向量。
return input_ids[:, -1].eq(self.marker_id)
stopping = StoppingCriteriaList([
# max_length 是完整序列上限,包含提示词部分。
MaxLengthCriteria(max_length=256),
# max_time 使用秒作为单位,避免单次生成无限等待。
MaxTimeCriteria(max_time=8.0),
# 业务标记条件与内置条件共享同一套调用接口。
StopOnMarker(marker_id=32000),
])
# 生成时把组合后的容器作为一个参数传入。
output = model.generate(
**inputs,
stopping_criteria=stopping,
do_sample=False,
)
这个组合表达的是“任一条件满足即可停止”,不是“所有条件都满足才停止”。如果业务要求同时满足多个条件,应把联合逻辑写在一个自定义 StoppingCriteria 中,而不是期待列表自动做 AND。
在 generate 中传入列表并处理 scores 依赖
自定义条件如果只看最新 token 或序列长度,scores 可以不参与逻辑;如果条件依赖当前预测分数,就必须在生成配置中请求分数。官方文档特别说明,只有设置 return_dict_in_generate=True 和 output_scores=True,依赖 scores 的条件才会拿到相应数据。
class StopWhenConfidenceIsLow(StoppingCriteria):
def __init__(self, threshold: float):
self.threshold = threshold
def __call__(self, input_ids, scores, **kwargs):
# 没有 scores 时不能假设存在概率,先按未触发处理。
if not scores:
return torch.zeros(input_ids.shape[0], dtype=torch.bool, device=input_ids.device)
# 只取最后一步分数,避免把历史步骤误当成当前判断。
probabilities = scores[-1].softmax(dim=-1)
last_token = input_ids[:, -1]
confidence = probabilities.gather(1, last_token.unsqueeze(1)).squeeze(1)
return confidence
示例只展示接口关系,没有把输出写成已经在本机运行得到的结果。实际项目中还要根据模型、设备和显存代价决定是否长期打开 output_scores。
按 batch 结果理解提前停止
停止条件返回的是逐样本向量,不是一个全局布尔值。例如 batch 中三个样本的长度条件分别为 [True, False, False],时间条件为 [False, True, False],列表合并后是 [True, True, False]。这表示前两个样本已经满足至少一个条件,第三个样本仍未满足。

因此自定义条件不要返回 Python 的单个 True 或 False 来代替 batch 向量。最稳妥的做法是始终根据 input_ids.shape[0] 创建同设备的布尔张量,避免 CPU 与 GPU 张量混用。
参数冲突时先看这几项
| 现象 | 优先检查 |
|---|---|
| 列表没有按预期停止 | 自定义条件是否返回每个 batch 样本一个布尔值,设备和 dtype 是否匹配 |
| 依赖分数的条件拿不到数据 | 是否同时设置 return_dict_in_generate=True 与 output_scores=True |
| 长度比预想更快触发 | decoder-only 模型的 max_length 包含提示词,必要时改用明确的长度预算 |
| 列表和 generate 的长度参数不一致 | 不要同时维护互相矛盾的最大长度;官方辅助逻辑会检查并可能补入长度条件 |
可以把组合逻辑记成一句话:每个条件负责一个明确边界,列表负责按位 OR;条件内部负责返回正确的 batch 形状,生成调用负责提供它声明需要的输入。这样既能把硬上限和业务停止符放在一起,也不会把一个样本的停止误判成整批都结束。
StoppingCriteriaList 是 AND 还是 OR?官方实现对各条件结果做按位 OR,任一条件对某个样本为真即可停止。自定义条件一定要读取 scores 吗?不需要,只有条件依赖预测分数时才应显式请求 scores。能否只传自定义列表而不设置 max_length?可以,但仍应为生成任务设计清晰的长度或时间兜底,避免业务条件失效时无界生成。
参考:Hugging Face Transformers 生成工具文档、官方 stopping_criteria.py。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
351 收藏
-
240 收藏
-
252 收藏
-
149 收藏
-
132 收藏
-
352 收藏
-
491 收藏
-
110 收藏
-
208 收藏
-
447 收藏
-
344 收藏
-
285 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习