解决 Pytorch RuntimeError: expected type torch.cuda.FloatTensor but got torch.FloatTensor

在使用Pytorch框架训练模型时,抛出RuntimeError: expected type torch.cuda.FloatTensor but got torch.FloatTensor。

产生原因及分析

待训练网络在GPU中运算,但有部分数据未进入GPU。
基于Pytorch框架使用GPU进行训练时,输入数据(样本、标记)、网络结构均会在GPU中进行计算,例如:

……
device = 'cuda:0'
model = models.resnet18(pretrained=True).to(device)
……
inputs = inputs.to(device)
labels = labels.to(device)
……

但如果在网络计算过程中,有新加入Tensor但没有明确指定其在GPU中运算(默认是在CPU中),则会抛出上述异常。

解决办法(单GPU)

通过上述分析可知,在网络中引入新的Tensor时,显式指定其运行设备为GPU,可解决上述问题,例如:

……
random_tensor += torch.rand([batch_size, 1, 1, 1], dtype=inputs.dtype).to(device)
……

在单GPU时,该方法能够解决上述问题;但在多GPU情况下,仍会抛出不在同一个GPU上计算的异常。

解决办法(多GPU)

对于多GPU,网络中新增Tensor一般会与输入(inputs)进行计算;因此获取inputs所在的GPU设备,将新Tensor的计算设备设置为与之相同,问题得解,例如:

……
random_tensor += torch.rand([batch_size, 1, 1, 1], dtype=inputs.dtype).to(inputs.device)
……

或者

……
random_tensor += torch.rand([batch_size, 1, 1, 1], dtype=inputs.dtype, device=inputs.device)
……
### PyTorch 中关于 Embedding 层的 RuntimeError 解决方案 在 PyTorch 的 `Embedding` 层中,输入张量(即索引张量)的数据类型必须为 `Long` 或者 `Int` 类型。如果传入的是其他类型的张量(例如 `FloatTensor` 或 `HalfTensor`),则会引发运行时错误(RuntimeError)。具体来说,当尝试传递一个数据类型不符合要求的张量作为嵌入层的索引参数时,会出现类似于以下的错误消息: - **错误描述**: - “Expected tensor for argument #1 'indices' to have scalar type Long; but got torch.cuda.IntTensor instead (while checking arguments for embedding)”[^1]。 - “Expected tensor for argument #1 'indices' to have scalar type Long; but got torch.cuda.FloatTensor instead”[^2]。 #### 错误原因分析 该问题的根本原因是,在调用 `nn.Embedding` 方法时,其第一个参数(通常称为 `input` 或 `indices`)被期望是一个整数类型的张量(`LongTensor` 或 `IntTensor`)。然而,实际传入的却是浮点数或其他不兼容的张量类型(如 `FloatTensor` 或 `HalfTensor`)。这违反了 PyTorch 对于 `Embedding` 输入的要求,因此抛出了上述异常。 --- #### 解决方法 为了修复此问题,可以采取以下措施之一来确保输入张量具有正确的数据类型: 1. **转换输入张量到合适的类型** 使用 `.long()` 将输入张量显式地转换成 `LongTensor` 类型。这是最常见的解决方案。例如: ```python import torch input_tensor = torch.tensor([[0, 1], [2, 3]], dtype=torch.float).cuda() correct_input = input_tensor.long() # 转换为 long 类型 ``` 这样做能够满足 `Embedding` 层对于输入张量的需求,并避免触发运行时错误[^5]。 2. **初始化阶段调整数据加载逻辑** 如果问题是由于数据预处理环节产生的,则可以在构建模型之前修正原始数据集中的数值表示形式。比如通过 NumPy 创建随机整数矩阵并将其转化为 PyTorch 长整型张量的方式如下所示: ```python data = torch.from_numpy(np.random.randint(2, 11, size=(2, 2))).long().cuda() ``` 此外还可以考虑直接指定创建张量时使用的默认数据类型为 `int64` 来减少后续不必要的类型转换操作次数。 3. **禁用混合精度训练模式下的潜在冲突** 当启用 FP16 半精度计算选项 (`args.fp16`) 并且未适当地管理各部分组件之间的相互作用关系时也可能间接引起此类问题的发生。可以通过注释掉某些特定条件下可能导致副作用的相关代码片段加以规避: ```python if not args.do_train and args.fp16: model.half() # 注释掉这一行可能有助于解决问题 ``` 上述修改旨在防止因半精度设置而导致的部分变量意外转变为非预期的数据格式从而干扰正常流程执行过程[^3]。 4. **确认设备一致性** 确保所有的张量都在同一个设备上(CPU 或 GPU)。如果不一致,可能会导致类似的错误。例如,“Input, output and indices must be on the current device”的提示表明存在跨设备的操作问题。此时应统一所有涉及对象所在的硬件资源位置[^4]: ```python embeddings = nn.Embedding(num_embeddings=10, embedding_dim=3).to('cuda') inputs = torch.LongTensor([1, 2, 3]).to('cuda') # 移动至相同设备 outputs = embeddings(inputs) ``` --- ### 总结 综上所述,要彻底解决 PyTorch 中有关 `Embedding` 层所遇到的 `RuntimeError` ,关键是保证提供给它的索引向量始终处于恰当的形式下——既符合长度规格又具备准确无误的数据类别属性;与此同时也要留意整个项目架构内部是否存在任何其它因素影响到了整体稳定性表现情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值