直接调用pad_sequence报错,因输入列表含none、空张量或维度不一致;须确保全为非空tensor、≥1d、除第0维外形状相同,并显式检查device与长度排序。

PyTorch中pad_sequence怎么用才不报错?
直接调用 pad_sequence 报 RuntimeError: expected a non-empty list of Tensors,大概率是因为输入是 Python 列表但里面混了 None、空 tensor 或者维度不一致(比如有的是 2D,有的是 1D)。它只接受「同 batch 维度外形状一致」的非空 torch.Tensor 列表,且默认按第 0 维(即时间步)对齐。
实操建议:
- 确保每个序列都是
torch.Tensor类型,且至少是 1D(如torch.tensor([1, 2])),不能是标量或空张量 - 所有张量必须在除第 0 维外的维度上完全一致:例如
[3, 5]和[5, 5]可以 pad,但[3, 5]和[3, 7]不行(第二维不等) - 传入前显式检查:
assert all(t.dim() >= 1 for t in batch),并统一用.unsqueeze(-1)补维度(如需) - 默认
batch_first=False,输出 shape 是[max_len, batch_size, ...];设为True才得[batch_size, max_len, ...]
为什么pack_padded_sequence总提示lengths必须是CPU int64?
因为 pack_padded_sequence 内部对 lengths 做了严格类型和设备校验——它必须是 CPU 上的 torch.int64(即 torch.long),哪怕你的输入序列在 GPU 上也不行。常见错误是把 numpy array、Python list 或 GPU tensor 直接传进去。
实操建议:
-
lengths必须是 CPU tensor:torch.tensor([5, 3, 7], dtype=torch.long),不能是torch.tensor(...).cuda() - 如果从 DataLoader 拿到的是 list,别偷懒写
torch.LongTensor(lengths)(旧接口,不保证 device);改用torch.tensor(lengths, dtype=torch.long, device='cpu') - 顺序必须降序:传入前要
lengths, sort_idx = lengths.sort(descending=True),再对序列按sort_idx重排,否则会静默出错或结果错乱
自定义 padding 值(比如不用 0)怎么安全替换?
pad_sequence 的 padding_value 参数只支持标量(如 -1, 999),不能填向量或特殊 token ID。如果你需要按词表 ID 填 <pad></pad>(比如 ID=1),直接传 padding_value=1 就行;但若想在 embedding 层后屏蔽 padding 位置,光靠 padding 值不够,得配合 mask。
实操建议:
- padding 值要和后续模块语义一致:例如 tokenizer 的
pad_token_id是 0,那padding_value=0;是 1 就填 1 - 避免用浮点 padding 值处理整型 ID 序列(如
padding_value=0.0),会导致 dtype 自动转成float32,后续喂进 embedding 层报错 - 真正需要 mask 时,别依赖 padding 值推断:显式生成
attention_mask,例如(batch_seq != pad_value).long()
和 Hugging Face tokenizer 的 pad_token_id 冲突怎么办?
HF tokenizer 的 pad_token_id 是用于文本 tokenization 后的 ID 对齐,而 pad_sequence 是 tensor-level 操作。两者不自动联动——你用 tokenizer.pad() 得到的 batch 可能已经是正确 padding 的 tensor,此时再套一层 pad_sequence 会多 pad 一次,导致长度膨胀、mask 错位。
实操建议:
- 优先用 tokenizer 自带的 padding:设置
padding=True+truncation=True,返回的就是对齐好的input_idstensor,无需再pad_sequence - 只有当你手动构造序列(比如从原始 list[int] 开始)、没走 tokenizer.pad 流程时,才需要
pad_sequence - 混合使用时务必确认:是否已 pad 过?可用
torch.allclose(seq[0], seq[0].clone().fill_(pad_value))粗略检测全 padding 行
变长序列 padding 看似简单,真正卡住人的往往是 device 不一致、lengths 未排序、以及「以为 pad 了其实没 pad 对」这种隐性状态。动手前先 print 出一两个样本的 shape 和 device,比查文档更快定位问题。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











