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

Transformers用tokenizer对齐输入长度

来源:17golang原创

时间:2026-11-15 12:39:34 207浏览 收藏

批量文本长度不一致时,Transformers 的 tokenizer 可以在编码阶段统一输入形状:用 padding 补齐短文本,用 truncation 截断过长文本,再用 max_length 指定上限或固定长度。最常用的批处理写法是 tokenizer(texts, padding=True, truncation=True, return_tensors="pt"),它会返回形状一致的 input_ids 和 attention_mask。

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

如果目标是“同一批能组成张量”,先使用 padding=True, truncation=True;如果目标是“每批都固定为同一长度”,再改用 padding="max_length", max_length=N。补齐不会增加真实语义,截断却会丢掉超出上限的 token,所以两者要分开判断。

先弄清三个长度参数

padding 决定短序列补到哪里:True 或 "longest" 补到当前批次最长序列,"max_length" 补到 max_length 或 tokenizer 的模型上限,False 则不补齐。truncation 决定长序列是否裁剪;默认不裁剪,启用后才会按照 max_length 或模型最大输入长度截短。

max_length 同时是补齐和截断的目标长度,但只有配合相应策略时才生效。只写 max_length=128,并不会自动让一个批次变成 128;需要显式写出 padding="max_length" 或 truncation=True。

批量输入优先使用最长样本对齐

不要求每批固定长度时,推荐先让 tokenizer 找到当前批次的最长序列,再把较短序列补齐,同时把超过模型上限的内容截掉:

from transformers import AutoTokenizer

# 使用与模型配套的 tokenizer,避免词表和特殊 token 不一致
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
texts = [
    "Transformers 可以把文本编码成模型输入。",
    "批量样本长度可能不同,因此需要补齐。",
]

# 当前批次补到最长样本;过长文本按模型上限截断
batch = tokenizer(
    texts,
    padding=True,
    truncation=True,
    return_tensors="pt",
)

# input_ids 和 attention_mask 的第一维都对应批次大小
print(batch["input_ids"].shape)
print(batch["attention_mask"].shape)

这里的 padding=True 等价于当前批次的 "longest"。如果只传入一条文本,通常不会因为“批内对齐”额外补到模型上限;需要固定长度时,应使用下一节的写法。

Transformers tokenizer 将文本、长度策略和 BatchEncoding 字段连接起来的静态结构图
图1:tokenizer 输入、长度策略与 BatchEncoding 字段的静态结构说明图,不是运行截图。

需要固定长度时同时指定 max_length

分类模型、静态批处理或需要稳定张量形状的推理服务,通常会把目标长度写死。此时要同时打开固定长度补齐和截断:

max_length = 128

# 先截断超过 128 的 token,再把短样本补到 128
fixed_batch = tokenizer(
    texts,
    padding="max_length",
    truncation=True,
    max_length=max_length,
    return_tensors="pt",
)

# 两个字段的形状都应包含固定的 128
print(fixed_batch["input_ids"].shape)
print(fixed_batch["attention_mask"].shape)

固定长度的代价是:短文本会增加 padding token,长文本会丢掉超出 max_length 的内容。对于成批推理,若样本长度差异很大,也可以先按长度分桶,再在桶内使用 padding=True,减少无效补齐。

padding、truncation、max_length 和 pad_to_multiple_of 对输入长度的关系结构图
图2:不同长度策略对输入宽度和 attention_mask 的关系说明图,不是运行截图。

让长度适配批处理粒度

某些硬件或编译路径更适合长度为 8、16 等倍数的张量。tokenizer 支持用 pad_to_multiple_of 把补齐目标向上取整,但它不是截断上限:

# 当前批次先按最长样本确定目标,再向上补到 8 的倍数
aligned_batch = tokenizer(
    texts,
    padding=True,
    truncation=True,
    pad_to_multiple_of=8,
    return_tensors="pt",
)

# 这里检查的是最终宽度,不把“倍数补齐”误当成 max_length
width = aligned_batch["input_ids"].shape[-1]
print(width, width % 8)

如果你既要固定最大长度,又要倍数对齐,可以显式设置 padding="max_length"、max_length 和 pad_to_multiple_of;前提是目标长度与倍数关系合理。不要为了追求整齐,把 max_length 设得远大于模型允许的输入范围。

用 attention_mask 判断补齐位置

input_ids 保存 token id,attention_mask 表示哪些位置参与注意力计算。常见 tokenizer 会让真实 token 对应 1、padding 位置对应 0,但具体 padding 侧仍应以 tokenizer 配置为准。检查字段时不要只看 input_ids 的宽度:

# 打印一条样本的 token id 和掩码,观察补齐区域
ids = batch["input_ids"][0].tolist()
mask = batch["attention_mask"][0].tolist()
print("ids:", ids)
print("mask:", mask)

# 掩码长度应与 token id 长度一致,才能逐位置对应
assert len(ids) == len(mask), "input_ids 与 attention_mask 长度不一致"

如果模型报输入长度超限,优先检查是否启用了 truncation;如果张量无法堆叠,检查是否对一整个列表传入 tokenizer,或者是否遗漏了 padding。如果结果比预期长,确认是否把 padding=True 误认为了固定长度补齐。

常见问题

padding=True 和 padding="max_length" 有什么区别?

前者只补到当前批次最长样本,后者补到指定的 max_length 或模型上限。前者通常更省计算,后者更适合需要稳定 shape 的场景。

只有 truncation=True 可以吗?

可以,它会限制过长输入,但短文本仍可能长度不同;要把一批样本直接组成张量,通常还要打开 padding。

为什么设置 max_length 后长度没有变成这个数?

因为 max_length 是目标值,不是单独的开关。固定长度需要 padding="max_length",而超长样本还需要 truncation=True。

小结

把 Transformers 输入长度对齐,可以按三个问题选择参数:只求批内可堆叠就用 padding=True, truncation=True;需要固定宽度就加 padding="max_length", max_length=N;需要硬件友好的倍数就再考虑 pad_to_multiple_of。最后同时查看 input_ids 和 attention_mask,才能确认补齐和真实 token 的边界。

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