登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

Tokenizer 怎样处理超长输入的截断策略

来源:17golang原创

时间:2026-11-07 23:31:28 500浏览 收藏

在 Hugging Face Transformers 中,超长输入应显式设置 truncation 和 max_length:单段文本可用 truncation=True;问题与材料成对输入时,若要保住问题,通常用 only_second 截材料。若后文也可能包含答案,应返回重叠窗口,而不是把剩余内容直接丢掉。

官方文档:https://huggingface.co/docs/transformers/

下面讨论 Transformers 的 tokenizer 调用,不代表所有推理服务使用相同参数。它是一种输入处理能力的用法整理,不是某个新版本才出现的功能。所有代码均为供读者使用的示例,未在本文执行。

先把 max_length 当作总预算

max_length 是最终编码的长度预算,单位是token,不是字符数。模型需要的特殊token也占空间。对一对文本而言,总编码由第一序列、第二序列及特殊token组成;不能让两段文本各占满这个长度。

max_length总预算包含第一序列第二序列和特殊token的静态结构图
图1:静态结构说明图,max_length约束最终编码长度,成对输入还需为特殊token留出空间。

先用与模型配套的tokenizer,并明确一个不超过模型支持范围的长度。下面用已准备好的本地tokenizer目录举例,128只是示例预算,不表示所有模型都应设成128。

from transformers import AutoTokenizer

# 此目录需事先保存与目标模型匹配的 tokenizer 文件
tokenizer = AutoTokenizer.from_pretrained(
    "./tokenizer-assets", use_fast=True, local_files_only=True
)
text = "设备巡检记录需要包含检查位置、观察现象和处理备注。" * 80
# 单序列截断,并让短输入补齐到同一个示例长度
encoded = tokenizer(
    text, truncation=True, max_length=128, padding="max_length"
)
print(len(encoded["input_ids"]))

这个示例要求所选tokenizer已定义padding token;没有时应按目标模型约定处理,不能随意给任意模型加一个pad token就认为兼容。读者可观察编码长度是否为128;这只是示例检查方式,不是本机运行结果。

padding=True 只补到批次中最长样本,不负责截断;单独传一个max_length也不等于明确选择了截断策略。不指定长度时,tokenizer可能依赖模型配置;某些配置没有有意义的长度上限,因此不要把配置中的巨大占位值当成模型真实容量。以上参数区别见 官方padding与truncation说明。

成对输入要说明哪一侧可以舍弃

策略作用适用判断
longest_first / True从较长序列逐步移除token以满足总长度两边均允许缩短时使用
only_first只截第一序列第二段需要完整保留
only_second只截第二序列短问题配长材料
False / do_not_truncate不截断调用方负责长度处理
question = "巡检记录应填写哪些内容?"
context = "巡检记录应填写位置、现象和处理备注。" * 100

# 第一参数是问题、第二参数是材料,因此只截第二段
pair = tokenizer(
    question, context,
    truncation="only_second", max_length=128, padding=False
)
print(len(pair["input_ids"]))

这里的“保住问题”有前提:问题加特殊token本身就应装得下。如果受保护的一侧已经耗尽预算,只截另一侧可能失败;先约束问题长度或调整任务输入,不能把策略当作无限容量。

截哪一侧序列,与从序列左端还是右端舍弃,是不同维度。truncation_side 控制左右方向。保留开头还是末尾应服从任务含义;对聊天输入随意左截可能丢掉系统指令、角色边界或完整消息,不宜直接把普通文本示例套到聊天模板上。

需要完整覆盖时,用重叠窗口代替丢弃

长材料的关键证据可能在尾部。Fast tokenizer可借助 return_overflowing_tokens 返回额外窗口,stride 指定窗口重叠token数。重叠能减轻窗口边缘断开的影响,但不会自动恢复跨窗口的完整推理。

原样本与两个重叠窗口及样本映射的静态关系图
图2:静态关系说明图,窗口仍属于同一原样本,stride描述相邻窗口的重叠token,不是最终答案合并规则。
if not tokenizer.is_fast:
    raise ValueError("此示例需要支持 offset_mapping 的 Fast tokenizer")

# 仅对材料做窗口化;stride 应小于每个材料窗口的可用容量
windows = tokenizer(
    [question], [context],
    truncation="only_second", max_length=128, stride=16,
    return_overflowing_tokens=True,
    return_offsets_mapping=True, padding=False
)
# 一个原样本可对应多个窗口,不能再按窗口序号当作样本序号
for i, sample_id in enumerate(windows["overflow_to_sample_mapping"]):
    print(i, sample_id, len(windows["input_ids"][i]))

overflow_to_sample_mapping 将窗口关联回原始批次样本。offset_mapping 用于字符定位,但成对输入中需要结合 sequence_ids(i) 分清问题和材料的token;材料偏移对应材料字符串,不能直接用于问题字符串。特殊token没有普通文本定位含义,应排除。

成对输入的longest_first与overflow组合存在支持限制,不能假定所有tokenizer实现都支持任意组合。这里使用only_second并要求Fast tokenizer;仍需以当前安装版本及具体tokenizer能力为准。相关返回字段与限制见 官方Tokenizer API。

迁移旧调用时保留任务语义

把旧调用改成显式策略之前,先明确任务允许损失什么。短文本分类可以接受有条件截取,长文问答通常更需要检索或窗口聚合;窗口越多,推理量越大,也需要按原样本合并结果,不能让每个窗口都变成一条独立业务记录。

用于模型前向计算时,只传模型接受的字段;不要把offset_mapping或overflow_to_sample_mapping等辅助字段一股脑传入模型。窗口合并也应处理重复命中,序列标注、抽取问答和分类各有不同规则,tokenizer不会代替这些后处理。

max_length 能设得比模型上限更大吗?参数能接受某个整数不代表模型能处理对应长度。应结合模型结构、配置与服务限制确定预算,截断不会扩展上下文容量。

为什么设置 padding 后仍超长?padding负责补齐,truncation负责删减,分别配置。还要检查后续是否又拼接了特殊token或模板。

窗口能保证保住所有语义吗?不能。它保留局部token覆盖,却可能切断跨段依赖;需要完整篇章关系的任务应另选长上下文模型、检索或层次聚合方案。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>