PyTorch 1.10+ 中 LongTensor 报错根源是 API 移除而非 dtype 不匹配;应统一用 torch.tensor(..., dtype=torch.long) 或 x.to(torch.long) 显式指定 long 类型。

PyTorch中LongTensor报错的根源是dtype不匹配,不是构造方式问题
PyTorch 1.10+ 已弃用 LongTensor 这类旧式构造函数,直接调用会触发 RuntimeError: LongTensor is not a valid constructor。这不是数据类型转换失败,而是 API 层面移除——它本质是 torch.tensor(..., dtype=torch.long) 的别名,但别名被删了。
常见误操作:写 torch.LongTensor([1, 2, 3]) 或 torch.LongTensor(data),尤其从老教程或 PyTorch 0.x 代码迁移时容易踩坑。
- 所有
XXXTensor(如FloatTensor、ByteTensor)在新版本中均不可直接调用 - 正确路径只有一条:显式传
dtype参数 - 如果原数据是 NumPy 数组或 Python list,
dtype必须与目标一致;否则会静默转为默认torch.float32,导致后续nn.Embedding或cross_entropy报Expected dtype long
用torch.tensor()替代LongTensor时,dtype必须显式指定
torch.tensor() 默认推断 dtype:Python int → torch.int64(即 long),但 Python float → torch.float32,NumPy array 会继承其 dtype。看似“自动”,实则隐患重重。
例如:torch.tensor([1, 2, 3]) 确实生成 torch.int64,但 torch.tensor([1, 2, 3.0]) 就变成 torch.float32 —— 因为列表含 float,整体升为 float。
- 安全写法永远加
dtype=torch.long:如torch.tensor([1, 2, 3], dtype=torch.long) - 从 NumPy 转换时,即使
np.array([1,2,3], dtype=np.int32),torch.tensor(arr)仍可能转成torch.int64(取决于平台),所以仍建议显式指定dtype - 若需保持 NumPy 原 dtype,用
torch.as_tensor(arr)更可靠,但它不复制数据,且不接受dtype参数 —— 所以该用哪个,取决于你是否需要控制 dtype
torch.LongTensor()未完全消失?那只是torch.empty()的别名
你可能发现 torch.LongTensor(3, 4) 没报错。这不是“还能用”,而是 PyTorch 把它重定向到了 torch.empty(3, 4, dtype=torch.long) —— 仅限**无数据输入的形状构造场景**。
一旦传入数据(哪怕一个 list),就立刻失败:torch.LongTensor([1,2,3]) → TypeError: new(): invalid data type 或更明确的 RuntimeError。
-
torch.LongTensor(2, 3)✅ 等价于torch.empty(2, 3, dtype=torch.long) -
torch.LongTensor([1,2,3])❌ 不再支持,必须改写为torch.tensor([1,2,3], dtype=torch.long)或torch.LongTensor().new_tensor([1,2,3])(不推荐) - 这种“半保留”设计容易让人误以为兼容,实际是过渡期残留,未来版本可能彻底移除
交叉验证dtype是否真为long:别只信.dtype打印结果
终端里打印 x.dtype 显示 torch.int64 并不等于能被 nn.Embedding 接收——某些模型内部会检查是否为 torch.long,而 torch.int64 == torch.long 在 Python 中为 True,但在 C++ 后端可能有细微差异(尤其跨设备或旧编译器)。
最稳妥的验证方式是直接喂给下游算子:
- 对
nn.Embedding:传入索引张量,看是否报Expected tensor for argument #1 'indices' to have scalar type Long - 对
F.cross_entropy:target必须是torch.long,哪怕target.dtype is torch.int64也可能失败(极少见,但存在) - 强制统一:用
x.to(torch.long)替代x.long(),前者更健壮,会做 dtype 检查和必要转换
真正麻烦的从来不是怎么转,而是转完你以为对了,结果在 loss 计算那步崩掉 —— 那往往是因为中间某次隐式转换又悄悄退回到了 float 或 int32。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











